diff options
Diffstat (limited to 'lisp/eshell')
-rw-r--r-- | lisp/eshell/em-cmpl.el | 7 | ||||
-rw-r--r-- | lisp/eshell/em-dirs.el | 8 | ||||
-rw-r--r-- | lisp/eshell/em-hist.el | 63 | ||||
-rw-r--r-- | lisp/eshell/em-pred.el | 5 | ||||
-rw-r--r-- | lisp/eshell/em-prompt.el | 1 | ||||
-rw-r--r-- | lisp/eshell/em-script.el | 2 | ||||
-rw-r--r-- | lisp/eshell/em-tramp.el | 2 | ||||
-rw-r--r-- | lisp/eshell/em-unix.el | 2 | ||||
-rw-r--r-- | lisp/eshell/em-xtra.el | 6 | ||||
-rw-r--r-- | lisp/eshell/esh-ext.el | 2 | ||||
-rw-r--r-- | lisp/eshell/esh-mode.el | 3 | ||||
-rw-r--r-- | lisp/eshell/esh-opt.el | 34 | ||||
-rw-r--r-- | lisp/eshell/esh-proc.el | 11 | ||||
-rw-r--r-- | lisp/eshell/esh-util.el | 5 | ||||
-rw-r--r-- | lisp/eshell/esh-var.el | 2 |
15 files changed, 94 insertions, 59 deletions
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el index f4b7872f8c9..e79b49095f2 100644 --- a/lisp/eshell/em-cmpl.el +++ b/lisp/eshell/em-cmpl.el @@ -262,8 +262,9 @@ to writing a completion function." eshell-cmpl-ignore-case) (set (make-local-variable 'pcomplete-autolist) eshell-cmpl-autolist) - (set (make-local-variable 'pcomplete-suffix-list) - eshell-cmpl-suffix-list) + (if (boundp 'pcomplete-suffix-list) + (set (make-local-variable 'pcomplete-suffix-list) + eshell-cmpl-suffix-list)) (set (make-local-variable 'pcomplete-recexact) eshell-cmpl-recexact) (set (make-local-variable 'pcomplete-man-function) @@ -437,7 +438,7 @@ to writing a completion function." (setq comps-in-path (cdr comps-in-path))) (setq paths (cdr paths))) ;; Add aliases which are currently visible, and Lisp functions. - (pcomplete-uniqify-list + (pcomplete-uniquify-list (if glob-name completions (setq completions diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index ba3bdb5cd53..5180a0700db 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el @@ -207,7 +207,7 @@ Thus, this does not include the current directory.") (when eshell-cd-on-directory (make-local-variable 'eshell-interpreter-alist) (setq eshell-interpreter-alist - (cons (cons #'(lambda (file args) + (cons (cons #'(lambda (file _args) (eshell-lone-directory-p file)) 'eshell-dirs-substitute-cd) eshell-interpreter-alist))) @@ -282,7 +282,7 @@ Thus, this does not include the current directory.") (defvar pcomplete-stub) (defvar pcomplete-last-completion-raw) (declare-function pcomplete-actual-arg "pcomplete") -(declare-function pcomplete-uniqify-list "pcomplete") +(declare-function pcomplete-uniquify-list "pcomplete") (defun eshell-complete-user-reference () "If there is a user reference, complete it." @@ -293,14 +293,14 @@ Thus, this does not include the current directory.") (throw 'pcomplete-completions (progn (eshell-read-user-names) - (pcomplete-uniqify-list + (pcomplete-uniquify-list (mapcar (function (lambda (user) (file-name-as-directory (cdr user)))) eshell-user-names))))))) -(defun eshell/pwd (&rest args) +(defun eshell/pwd (&rest _args) "Change output from `pwd' to be cleaner." (let* ((path default-directory) (len (length path))) diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el index 3f863171bd9..62e2f57d0fd 100644 --- a/lisp/eshell/em-hist.el +++ b/lisp/eshell/em-hist.el @@ -218,9 +218,6 @@ Returns nil if INPUT is prepended by blank space, otherwise non-nil." (defun eshell-hist-initialize () "Initialize the history management code for one Eshell buffer." - (add-hook 'eshell-expand-input-functions - 'eshell-expand-history-references nil t) - (when (eshell-using-module 'eshell-cmpl) (add-hook 'pcomplete-try-first-hook 'eshell-complete-history-reference nil t)) @@ -584,21 +581,30 @@ See also `eshell-read-history'." (defun eshell-expand-history-references (beg end) "Parse and expand any history references in current input." - (let ((result (eshell-hist-parse-arguments beg end))) + (let ((result (eshell-hist-parse-arguments beg end)) + (full-line (buffer-substring-no-properties beg end))) (when result (let ((textargs (nreverse (nth 0 result))) (posb (nreverse (nth 1 result))) - (pose (nreverse (nth 2 result)))) + (pose (nreverse (nth 2 result))) + (full-line-subst (eshell-history-substitution full-line))) (save-excursion - (while textargs - (let ((str (eshell-history-reference (car textargs)))) - (unless (eq str (car textargs)) - (goto-char (car posb)) - (insert-and-inherit str) - (delete-char (- (car pose) (car posb))))) - (setq textargs (cdr textargs) - posb (cdr posb) - pose (cdr pose)))))))) + (if full-line-subst + ;; Found a ^foo^bar substitution + (progn + (goto-char beg) + (insert-and-inherit full-line-subst) + (delete-char (- end beg))) + ;; Try to expand other substitutions + (while textargs + (let ((str (eshell-history-reference (car textargs)))) + (unless (eq str (car textargs)) + (goto-char (car posb)) + (insert-and-inherit str) + (delete-char (- (car pose) (car posb))))) + (setq textargs (cdr textargs) + posb (cdr posb) + pose (cdr pose))))))))) (defvar pcomplete-stub) (defvar pcomplete-last-completion-raw) @@ -633,20 +639,31 @@ See also `eshell-read-history'." (setq history (cdr history))) (cdr fhist))))))) +(defun eshell-history-substitution (line) + "Expand quick hist substitutions formatted as ^foo^bar^. +Returns nil if string does not match quick substitution format, +and acts like !!:s/foo/bar/ otherwise." + ;; `^string1^string2^' + ;; Quick Substitution. Repeat the last command, replacing + ;; STRING1 with STRING2. Equivalent to `!!:s/string1/string2/' + (when (and (eshell-using-module 'eshell-pred) + (string-match + "^\\^\\([^^]+\\)\\^\\([^^]+\\)\\(?:\\^\\(.*\\)\\)?$" + line)) + ;; Save trailing match as `eshell-history-reference' runs string-match. + (let ((matched-end (match-string 3 line))) + (concat + (eshell-history-reference + (format "!!:s/%s/%s/" + (match-string 1 line) + (match-string 2 line))) + matched-end)))) + (defun eshell-history-reference (reference) "Expand directory stack REFERENCE. The syntax used here was taken from the Bash info manual. Returns the resultant reference, or the same string REFERENCE if none matched." - ;; `^string1^string2^' - ;; Quick Substitution. Repeat the last command, replacing - ;; STRING1 with STRING2. Equivalent to `!!:s/string1/string2/' - (if (and (eshell-using-module 'eshell-pred) - (string-match "\\^\\([^^]+\\)\\^\\([^^]+\\)\\^?\\s-*$" - reference)) - (setq reference (format "!!:s/%s/%s/" - (match-string 1 reference) - (match-string 2 reference)))) ;; `!' ;; Start a history substitution, except when followed by a ;; space, tab, the end of the line, = or (. diff --git a/lisp/eshell/em-pred.el b/lisp/eshell/em-pred.el index 2c12cacfff8..b3b16d909ba 100644 --- a/lisp/eshell/em-pred.el +++ b/lisp/eshell/em-pred.el @@ -131,7 +131,7 @@ The format of each entry is (?e . #'(lambda (lst) (mapcar 'file-name-extension lst))) (?t . #'(lambda (lst) (mapcar 'file-name-nondirectory lst))) (?q . #'(lambda (lst) (mapcar 'eshell-escape-arg lst))) - (?u . #'(lambda (lst) (eshell-uniqify-list lst))) + (?u . #'(lambda (lst) (eshell-uniquify-list lst))) (?o . #'(lambda (lst) (sort lst 'string-lessp))) (?O . #'(lambda (lst) (nreverse (sort lst 'string-lessp)))) (?j . (eshell-join-members)) @@ -545,7 +545,8 @@ that `ls -l' will show in the first column of its display. " (function (lambda (str) (if (string-match ,match str) - (setq str (replace-match ,replace t nil str))) + (setq str (replace-match ,replace t nil str)) + (error (concat str ": substitution failed"))) str)) lst))))) (defun eshell-include-members (&optional invert-p) diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el index da2cfe4dfdd..e61b0eb1c87 100644 --- a/lisp/eshell/em-prompt.el +++ b/lisp/eshell/em-prompt.el @@ -80,7 +80,6 @@ re-entered for it to take effect." For highlighting other kinds of strings -- similar to shell mode's behavior -- simply use an output filer which changes text properties." :group 'eshell-prompt) -(define-obsolete-face-alias 'eshell-prompt-face 'eshell-prompt "22.1") (defcustom eshell-before-prompt-hook nil "A list of functions to call before outputting the prompt." diff --git a/lisp/eshell/em-script.el b/lisp/eshell/em-script.el index 1b0b220d5bc..a5d8e96ba84 100644 --- a/lisp/eshell/em-script.el +++ b/lisp/eshell/em-script.el @@ -61,7 +61,7 @@ This includes when running `eshell-command'." "Initialize the script parsing code." (make-local-variable 'eshell-interpreter-alist) (setq eshell-interpreter-alist - (cons (cons #'(lambda (file args) + (cons (cons #'(lambda (file _args) (string= (file-name-nondirectory file) "eshell")) 'eshell/source) diff --git a/lisp/eshell/em-tramp.el b/lisp/eshell/em-tramp.el index c45453bf288..9475f4ed949 100644 --- a/lisp/eshell/em-tramp.el +++ b/lisp/eshell/em-tramp.el @@ -26,6 +26,7 @@ ;;; Code: (require 'esh-util) +(require 'esh-cmd) (eval-when-compile (require 'esh-mode) @@ -106,6 +107,7 @@ Uses the system sudo through TRAMP's sudo method." '((?h "help" nil nil "show this usage screen") (?u "user" t user "execute a command as another USER") :show-usage + :parse-leading-options-only :usage "[(-u | --user) USER] COMMAND Execute a COMMAND as the superuser or another USER.") (throw 'eshell-external diff --git a/lisp/eshell/em-unix.el b/lisp/eshell/em-unix.el index b00b6654cc5..c912c15ac75 100644 --- a/lisp/eshell/em-unix.el +++ b/lisp/eshell/em-unix.el @@ -974,7 +974,7 @@ Show wall-clock time elapsed during execution of COMMAND.") (eshell-stringify-list (eshell-flatten-list (cdr time-args)))))))) -(defun eshell/whoami (&rest args) +(defun eshell/whoami (&rest _args) "Make \"whoami\" Tramp aware." (or (file-remote-p default-directory 'user) (user-login-name))) diff --git a/lisp/eshell/em-xtra.el b/lisp/eshell/em-xtra.el index ce73474fb73..cc84d198544 100644 --- a/lisp/eshell/em-xtra.el +++ b/lisp/eshell/em-xtra.el @@ -25,8 +25,10 @@ (require 'esh-util) (eval-when-compile - (require 'eshell) - (require 'pcomplete)) + (require 'eshell)) +;; Strictly speaking, should only be needed at compile time. +;; Require at run-time too to silence compiler. +(require 'pcomplete) (require 'compile) ;; There are no items in this custom group, but eshell modules (ab)use diff --git a/lisp/eshell/esh-ext.el b/lisp/eshell/esh-ext.el index fdb77d32265..244cc7ff1f3 100644 --- a/lisp/eshell/esh-ext.el +++ b/lisp/eshell/esh-ext.el @@ -37,8 +37,8 @@ (eval-when-compile (require 'cl-lib) - (require 'esh-io) (require 'esh-cmd)) +(require 'esh-io) (require 'esh-arg) (require 'esh-opt) (require 'esh-proc) diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index bbb74c3d86f..9f854c7d907 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -884,8 +884,7 @@ If SCROLLBACK is non-nil, clear the scrollback contents." (interactive) (if scrollback (eshell/clear-scrollback) - (let ((eshell-input-filter-functions - (remq 'eshell-add-to-history eshell-input-filter-functions))) + (let ((eshell-input-filter-functions nil)) (insert (make-string (window-size) ?\n)) (eshell-send-input)))) diff --git a/lisp/eshell/esh-opt.el b/lisp/eshell/esh-opt.el index 7d0b362b4c4..d7a449450f9 100644 --- a/lisp/eshell/esh-opt.el +++ b/lisp/eshell/esh-opt.el @@ -80,6 +80,10 @@ arguments, some do not. The recognized :KEYWORDS are: If present, do not pass MACRO-ARGS through `eshell-flatten-list' and `eshell-stringify-list'. +:parse-leading-options-only + If present, do not parse dash or switch arguments after the first +positional argument. Instead, treat them as positional arguments themselves. + For example, OPTIONS might look like: ((?C nil nil multi-column \"multi-column display\") @@ -95,8 +99,8 @@ BODY-FORMS. If instead an external command is run (because of an unknown option), the tag `eshell-external' will be thrown with the new process for its value. -Lastly, any remaining arguments will be available in a locally -interned variable `args' (created using a `let' form)." +Lastly, any remaining arguments will be available in the locally +let-bound variable `args'." (declare (debug (form form sexp body))) `(let* ((temp-args ,(if (memq ':preserve-args (cadr options)) @@ -111,6 +115,8 @@ interned variable `args' (created using a `let' form)." ;; `options' is of the form (quote OPTS). (cadr options)))) (args processed-args)) + ;; Silence unused lexical variable warning if body does not use `args'. + (ignore args) ,@body-forms)) ;;; Internal Functions: @@ -194,11 +200,7 @@ will be modified." (if (eq (nth 2 opt) t) (if (> ai (length eshell--args)) (error "%s: missing option argument" name) - (prog1 (nth ai eshell--args) - (if (> ai 0) - (setcdr (nthcdr (1- ai) eshell--args) - (nthcdr (1+ ai) eshell--args)) - (setq eshell--args (cdr eshell--args))))) + (pop (nthcdr ai eshell--args))) (or (nth 2 opt) t))))) (defun eshell--process-option (name switch kind ai options opt-vals) @@ -243,18 +245,22 @@ switch is unrecognized." (list sym))))) options))) (ai 0) arg - (eshell--args args)) - (while (< ai (length eshell--args)) + (eshell--args args) + (pos-argument-found nil)) + (while (and (< ai (length eshell--args)) + ;; Abort if we saw the first pos argument and option is set + (not (and pos-argument-found + (memq :parse-leading-options-only options)))) (setq arg (nth ai eshell--args)) (if (not (and (stringp arg) (string-match "^-\\(-\\)?\\(.*\\)" arg))) - (setq ai (1+ ai)) + ;; Positional argument found, skip + (setq ai (1+ ai) + pos-argument-found t) + ;; dash or switch argument found, parse (let* ((dash (match-string 1 arg)) (switch (match-string 2 arg))) - (if (= ai 0) - (setq eshell--args (cdr eshell--args)) - (setcdr (nthcdr (1- ai) eshell--args) - (nthcdr (1+ ai) eshell--args))) + (pop (nthcdr ai eshell--args)) (if dash (if (> (length switch) 0) (eshell--process-option name switch 1 ai options opt-vals) diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index 94401c5daa5..a7855d81db5 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -158,7 +158,7 @@ The signals which will cause this to happen are matched by (defalias 'eshell/wait 'eshell-wait-for-process) -(defun eshell/jobs (&rest args) +(defun eshell/jobs (&rest _args) "List processes, if there are any." (and (fboundp 'process-list) (process-list) @@ -167,7 +167,8 @@ The signals which will cause this to happen are matched by (defun eshell/kill (&rest args) "Kill processes. Usage: kill [-<signal>] <pid>|<process> ... -Accepts PIDs and process objects." +Accepts PIDs and process objects. Optionally accept signals +and signal names." ;; If the first argument starts with a dash, treat it as the signal ;; specifier. (let ((signum 'SIGINT)) @@ -178,12 +179,12 @@ Accepts PIDs and process objects." ((string-match "\\`-[[:digit:]]+\\'" arg) (setq signum (abs (string-to-number arg)))) ((string-match "\\`-\\([[:upper:]]+\\|[[:lower:]]+\\)\\'" arg) - (setq signum (abs (string-to-number arg))))) + (setq signum (intern (substring arg 1))))) (setq args (cdr args)))) (while args (let ((arg (if (eshell-processp (car args)) (process-id (car args)) - (car args)))) + (string-to-number (car args))))) (when arg (cond ((null arg) @@ -198,6 +199,8 @@ Accepts PIDs and process objects." (setq args (cdr args)))) nil) +(put 'eshell/kill 'eshell-no-numeric-conversions t) + (defun eshell-read-process-name (prompt) "Read the name of a process from the minibuffer, using completion. The prompt will be set to PROMPT." diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 5d38c27eb1d..5ef1ae41297 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el @@ -295,7 +295,7 @@ Prepend remote identification of `default-directory', if any." (nconc new-list (list a)))) (cdr new-list))) -(defun eshell-uniqify-list (l) +(defun eshell-uniquify-list (l) "Remove occurring multiples in L. You probably want to sort first." (let ((m l)) (while m @@ -305,6 +305,9 @@ Prepend remote identification of `default-directory', if any." (setcdr m (cddr m))) (setq m (cdr m)))) l) +(define-obsolete-function-alias + 'eshell-uniqify-list + 'eshell-uniquify-list "27.1") (defun eshell-stringify (object) "Convert OBJECT into a string value." diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el index 1af03d367c3..b5dce80de8c 100644 --- a/lisp/eshell/esh-var.el +++ b/lisp/eshell/esh-var.el @@ -343,6 +343,8 @@ This function is explicit for adding to `eshell-parse-argument-hook'." obarray 'boundp)) (pcomplete-here)))) +;; FIXME the real "env" command does more than this, it runs a program +;; in a modified environment. (defun eshell/env (&rest args) "Implementation of `env' in Lisp." (eshell-init-print-buffer) |