Subject: bug#30724: eshell: escaped tilde is not treated as such

From: Noam Postavsky <[email-masked]>
Date: Mon, 16 Jul 2018 20:14:03 -0400

Jonathan Kyle Mitchell <[email-masked]> writes:

> After tracing through the execution of eshell some more, I noticed that
> eshell sets an escaped text property on the arguments when the user
> escaped them with `\' or quote characters but there is nothing in
> eshell that does anything with it apparently.

Yeah, this sort of half-finished thing seems to pop up in eshell quite a
bit.

> Subject: [PATCH] Check for special filenames in eshell (Bug#30724)
>
> 	* lisp/eshell/em-dirs.el (eshell/cd): Add
> 	eshell-escape-special-filenames to symbol plist.
> 	(eshell/pushd): Likewise.
> 	(eshell/popd): Likewise.
>
> 	* lisp/eshell/em-ls.el (eshell/ls): Add
> 	eshell-escape-special-filenames to symbol plist.
>
> 	* lisp/eshell/em-unix.el (eshell/rm): Add
> 	eshell-escape-special-filenames to symbol plist.
> 	(eshell/mkdir): Likewise.
> 	(eshell/rmdir): Likewise.
> 	(eshell/mv): Likewise.
> 	(eshell/cp): Likewise.
> 	(eshell/ln): Likewise.
> 	(eshell/cat): Likewise.
> 	(eshell/du): Likewise.
> 	(eshell/diff): Likewise.
>
> 	* lisp/eshell/esh-cmd.el (eshell-lisp-command):	Check for
> 	single character escaped string arguments (Bug#30724).
>
> 	* lisp/eshell/esh-ext.el (eshell/addpath): Add
> 	eshell-escape-special-filenames to symbol plist.

The "Add eshell-escape-special-filenames to symbol plist" should be
coalesced, as in:

* lisp/eshell/em-dirs.el (eshell/cd, eshell/pushd, eshell/popd):
* lisp/eshell/em-ls.el (eshell/ls):
* lisp/eshell/em-unix.el (eshell/rm, eshell/mkdir, eshell/rmdir)
(eshell/mv, eshell/cp, eshell/ln, eshell/cat, eshell/du, eshell/diff):
* lisp/eshell/esh-ext.el (eshell/addpath): Add
eshell-escape-special-filenames to symbol plist.

* lisp/eshell/esh-cmd.el (eshell-lisp-command):	Check for
single character escaped string arguments (Bug#30724).

> +		  (let ((numeric (not (get object
> +                                           'eshell-no-numeric-conversions)))
> +			(escaped (get object 'eshell-escape-special-filenames)))

I'm not sure 'escaped' or 'eshell-escape-special-filenames' are really
the right names here, as they're not actually indicating any escaping.
Maybe the property should be something like 'eshell-filename-arguments'?

> +		    (when (or numeric escaped)
> +		      (while args
> +			(let ((arg (car args)))
> +			  (cond ((and numeric (stringp arg) (> (length arg) 0)
> +				      (text-property-any 0 (length arg)
> +							 'number t arg))
> +				 ;; if any of the arguments are flagged as
> +				 ;; numbers waiting for conversion, convert
> +				 ;; them now

Comments should be capitalized and end with a period (I know the
original didn't, but since we're updating the code, now is a good time
to fix it).

> +				 (setcar args (string-to-number arg)))
> +				((and escaped (stringp arg) (= (length arg) 1)
> +				      (text-property-any 0 (length arg)
> +							 'escaped t arg))
> +				 ;; if any of the arguments are single
> +				 ;; character escaped filenames,
> +				 ;; prepend "./"
> +				 (setcar args (concat "./" arg)))))

It looks like this kind of escaping isn't actually needed for "*" which
your previous patch mentioned.  Perhaps just check for "~" explicitly,
rather than any single character filenames.  Or are there other examples
besides "~" which need "./" to prevent interpretation?