Eshell no longer needs this function, since all command parsing is
performed first, with special syntax annotated with text properties as
needed, as opposed to marking literal text with a property (bug#54486).
* lisp/eshell/em-pred.el (eshell-modifier-alist): Make "q" modifier
obsolete.
(eshell-modifier-help-string): Remove mention of "q".
* lisp/eshell/esh-arg.el (eshell-escape-arg): Make obsolete.
(eshell-parse-backslash, eshell-parse-literal-quote)
(eshell-parse-double-quote): Don't call 'eshell-escape-arg'.
* lisp/eshell/esh-var.el (eshell-parse-variable): Don't call
'eshell-escape-arg'.
* test/lisp/eshell/em-extpipe-tests.el (em-extpipe-test-2)
(em-extpipe-test-9, em-extpipe-test-11): Remove 'eshell-escape-arg'.
* test/lisp/eshell/em-pred-tests.el (em-pred-test/modifier-quote):
Remove test.
* test/lisp/eshell/esh-var-tests.el
(esh-var-test/quoted-interp-var-indices)
(esh-var-test/quote-interp-var-indices-subcommand): Remove workaround in
tests.
* doc/misc/eshell.texi (Argument Modifiers): Remove documentation of
obsolete "q" modifier.
(cherry picked from commit
b4655ff99b512f30220f22226514267d78a70605)
final extension. For example, @samp{foo/bar/baz.tar.gz(:r)} expands
to @samp{foo/bar/baz.tar}.
-@item q
-Marks that the value should be interpreted by Eshell literally, so
-that any special characters like @samp{$} no longer have any special
-meaning.
-
@item s/@var{pattern}/@var{replace}/
Replaces the first instance of the regular expression @var{pattern}
with @var{replace}. Signals an error if no match is found.
(?r . (lambda (lst) (mapcar #'file-name-sans-extension lst)))
(?e . (lambda (lst) (mapcar #'file-name-extension lst)))
(?t . (lambda (lst) (mapcar #'file-name-nondirectory lst)))
- (?q . (lambda (lst) (mapcar #'eshell-escape-arg lst)))
+ (?q . #'identity) ; Obsolete as of Emacs 31.1.
(?u . (lambda (lst) (seq-uniq lst)))
(?o . (lambda (lst) (sort lst #'string-lessp)))
(?O . (lambda (lst) (sort lst #'string-greaterp)))
:type '(repeat (cons character sexp))
:risky t)
+(defvar eshell-predicate-help-string
+ "Eshell predicate quick reference:
+
+ - follow symbolic references for predicates after the `-'
+ ^ invert sense of predicates after the `^'
+
+FILE TYPE:
+ / directories s sockets
+ . regular files p named pipes
+ * executable (files only) @ symbolic links
+
+ %x file type == `x' (as by ls -l; so `c' = char device, etc.)
+
+PERMISSION BITS (for owner/group/world):
+ r/A/R readable s setuid
+ w/I/W writable S setgid
+ x/E/X executable t sticky bit
+
+OWNERSHIP:
+ U owned by effective uid
+ G owned by effective gid
+ u(UID|\\='user\\=') owned by UID/user
+ g(GID|\\='group\\=') owned by GID/group
+
+FILE ATTRIBUTES:
+ l[+-]N +/-/= N links
+ a[Mwhms][+-](N|\\='FILE\\=') access time +/-/= N months/weeks/hours/mins/secs
+ (days if unspecified) if FILE specified,
+ use as comparison basis; so a+\\='file.c\\='
+ shows files accessed before file.c was
+ last accessed
+ m[Mwhms][+-](N|\\='FILE\\=') modification time...
+ c[Mwhms][+-](N|\\='FILE\\=') change time...
+ L[kmp][+-]N file size +/-/= N Kb/Mb/blocks
+
+EXAMPLES:
+ *(^@) all non-dot files which are not symlinks
+ .#*(^@) all files which are not symbolic links
+ **/.#*(*) all executable files, searched recursively
+ ***/*~f*(-/) recursively (though not traversing symlinks),
+ find all directories (or symlinks referring to
+ directories) whose names do not begin with f.
+ e*(*Lk+50) executables 50k or larger beginning with `e'")
+
+(defvar eshell-modifier-help-string
+ "Eshell modifier quick reference:
+
+FOR SINGLE ARGUMENTS, or each argument of a list of strings:
+ E evaluate again
+ L lowercase
+ U uppercase
+ C capitalize
+ h dirname
+ t basename
+ e file extension
+ r strip file extension
+
+ S split string at any whitespace character
+ S/PAT/ split string at each occurrence of PAT
+
+FOR LISTS OF ARGUMENTS:
+ o sort alphabetically
+ O reverse sort alphabetically
+ u uniq list (typically used after :o or :O)
+ R reverse list
+
+ j join list members, separated by a space
+ j/PAT/ join list members, separated by PAT
+ i/PAT/ exclude all members not matching PAT
+ x/PAT/ exclude all members matching PAT
+
+ s/pat/match/ substitute PAT with MATCH
+ gs/pat/match/ substitute PAT with MATCH for all occurrences
+
+EXAMPLES:
+ *.c(:o) sorted list of .c files")
+
(defvar eshell-pred-delimiter-pairs
'((?\( . ?\))
(?\[ . ?\])
(defsubst eshell-escape-arg (string)
"Return STRING with the `escaped' property on it."
+ (declare (obsolete nil "31.1"))
(if (stringp string)
(add-text-properties 0 (length string) '(escaped t) string))
string)
(when (= (1+ (point)) (point-max))
(throw 'eshell-incomplete "\\"))
(forward-char 2) ; Move one char past the backslash.
- (let ((special-chars (if eshell-current-quoted
- eshell-special-chars-inside-quoting
- eshell-special-chars-outside-quoting)))
- (cond
- ;; Escaped newlines are extra-special: they expand to an empty
- ;; token to allow for continuing Eshell commands across
- ;; multiple lines.
- ((eq (char-before) ?\n)
- 'eshell-empty-token)
- ((memq (char-before) special-chars)
- (list 'eshell-escape-arg (char-to-string (char-before))))
- ;; If the char is in a quote, backslash only has special
- ;; meaning if it is escaping a special char. Otherwise, the
- ;; result is the literal string "\c".
- (eshell-current-quoted
- (concat "\\" (char-to-string (char-before))))
- (t
- (char-to-string (char-before)))))))
+ (cond
+ ;; Escaped newlines are extra-special: they expand to an empty
+ ;; token to allow for continuing Eshell commands across
+ ;; multiple lines.
+ ((eq (char-before) ?\n)
+ 'eshell-empty-token)
+ ;; If the char is in a quote, backslash only has special
+ ;; meaning if it is escaping a special char. Otherwise, the
+ ;; result is the literal string "\c".
+ ((and eshell-current-quoted
+ (not (memq (char-before) eshell-special-chars-inside-quoting)))
+ (concat "\\" (char-to-string (char-before))))
+ (t
+ (char-to-string (char-before))))))
(defun eshell-parse-literal-quote ()
"Parse a literally quoted string. Nothing has special meaning!"
- (if (eq (char-after) ?\')
- (let ((end (eshell-find-delimiter ?\' ?\')))
- (if (not end)
- (throw 'eshell-incomplete "'")
- (let ((string (buffer-substring-no-properties (1+ (point)) end)))
- (goto-char (1+ end))
- (while (string-match "''" string)
- (setq string (replace-match "'" t t string)))
- (list 'eshell-escape-arg string))))))
+ (when (eq (char-after) ?\')
+ (let ((end (eshell-find-delimiter ?\' ?\')))
+ (unless end
+ (throw 'eshell-incomplete "'"))
+ (let ((string (buffer-substring-no-properties (1+ (point)) end)))
+ (goto-char (1+ end))
+ (while (string-match "''" string)
+ (setq string (replace-match "'" t t string)))
+ string))))
(defun eshell-parse-double-quote ()
"Parse a double quoted string, which allows for variable interpolation."
(when (eq (char-after) ?\")
(let* ((end (eshell-find-delimiter ?\" ?\" nil nil t))
- (eshell-current-quoted t))
- (if (not end)
- (throw 'eshell-incomplete "\"")
- (prog1
- (save-restriction
- (forward-char)
- (narrow-to-region (point) end)
- (let ((arg (eshell-parse-argument)))
- (if (eq arg nil)
- ""
- (list 'eshell-escape-arg arg))))
- (goto-char (1+ end)))))))
+ (eshell-current-quoted t))
+ (unless end
+ (throw 'eshell-incomplete "\""))
+ (prog1
+ (save-restriction
+ (forward-char)
+ (narrow-to-region (point) end)
+ (or (eshell-parse-argument) ""))
+ (goto-char (1+ end))))))
(defun eshell-unescape-inner-double-quote (bound)
"Unescape escaped characters inside a double-quoted string.
(setq value `(eshell-list-to-string ,value)
splice nil)
(setq value `(eshell-stringify ,value t))))
- (setq value `(eshell-escape-arg ,value))
(when splice
(setq value `(eshell-splice-args ,value)))
value))
(skip-unless (executable-find "rev"))
(should-parse
'(eshell-execute-pipeline
- '((eshell-named-command "echo" (list (eshell-escape-arg "bar")))
+ '((eshell-named-command "echo" (list "bar"))
(eshell-named-command "sh" (list "-c" "rev >temp")))))
(with-substitute-for-temp
(eshell-match-command-output input "^$")
(em-extpipe-tests--deftest em-extpipe-test-9 "foo \\*| bar"
(should-parse
'(eshell-execute-pipeline
- '((eshell-named-command "foo"
- (list (eshell-escape-arg "*")))
+ '((eshell-named-command "foo" (list "*"))
(eshell-named-command "bar")))))
(em-extpipe-tests--deftest em-extpipe-test-10 "foo \"*|\" *>bar"
'(eshell-named-command "sh" (list "-c" "foo \"*|\" >bar"))))
(em-extpipe-tests--deftest em-extpipe-test-11 "foo '*|' bar"
- (should-parse '(eshell-named-command
- "foo" (list (eshell-escape-arg "*|") "bar"))))
+ (should-parse '(eshell-named-command "foo" (list "*|" "bar"))))
(em-extpipe-tests--deftest em-extpipe-test-12 ">foo bar *| baz"
(should-parse
'("/path/to/file.el" "/other/path/") ":r")
'("/path/to/file" "/other/path/"))))
-(ert-deftest em-pred-test/modifier-quote ()
- "Test that \":q\" quotes arguments."
- (should (equal-including-properties
- (eshell-eval-predicate '("foo" "bar") ":q")
- (list (eshell-escape-arg "foo") (eshell-escape-arg "bar")))))
-
(ert-deftest em-pred-test/modifier-substitute ()
"Test that \":s/PAT/REP/\" replaces PAT with REP once."
(should (equal (eshell-eval-predicate "bar" ":s/a/*/") "b*r"))
(let ((eshell-test-value '("zero" "one" "two" "three" "four")))
(eshell-command-result-equal "echo \"$eshell-test-value[0]\""
"zero")
- ;; FIXME: These tests would use the 0th index like the other tests
- ;; here, but evaluating the command just above adds an `escaped'
- ;; property to the string "zero". This results in the output
- ;; printing the string properties, which is probably the wrong
- ;; behavior. See bug#54486.
- (eshell-command-result-equal "echo \"$eshell-test-value[1 2]\""
- "(\"one\" \"two\")")
- (eshell-command-result-equal "echo \"$eshell-test-value[1 2 4]\""
- "(\"one\" \"two\" \"four\")")))
+ (eshell-command-result-equal "echo \"$eshell-test-value[0 2]\""
+ "(\"zero\" \"two\")")
+ (eshell-command-result-equal "echo \"$eshell-test-value[0 2 4]\""
+ "(\"zero\" \"two\" \"four\")")))
(ert-deftest esh-var-test/quote-interp-var-indices-subcommand ()
"Interpolate list variable with subcommand expansion for indices inside double-quotes."
(eshell-command-result-equal
"echo \"$eshell-test-value[${*echo 0}]\""
"zero")
- ;; FIXME: These tests would use the 0th index like the other tests
- ;; here, but see above.
(eshell-command-result-equal
- "echo \"$eshell-test-value[${*echo 1} ${*echo 2}]\""
- "(\"one\" \"two\")")))
+ "echo \"$eshell-test-value[${*echo 0} ${*echo 2}]\""
+ "(\"zero\" \"two\")")))
(ert-deftest esh-var-test/quoted-interp-var-split-indices ()
"Interpolate string variable with indices inside double-quotes."