summaryrefslogtreecommitdiff
path: root/lisp/eshell/esh-cmd.el
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2019-03-20 12:51:31 -0400
committerStefan Monnier <monnier@iro.umontreal.ca>2019-03-20 12:51:31 -0400
commit99b3d64e54bb896e7b35567ac7022f9d3fb16bbb (patch)
treebddffc159651734c227ccf1a2c8a145d571c3e62 /lisp/eshell/esh-cmd.el
parent9efc43f34adfff2f00162fb85685824557d00eb1 (diff)
downloademacs-99b3d64e54bb896e7b35567ac7022f9d3fb16bbb.tar.gz
emacs-99b3d64e54bb896e7b35567ac7022f9d3fb16bbb.tar.bz2
emacs-99b3d64e54bb896e7b35567ac7022f9d3fb16bbb.zip
Eshell: Mostly cosmetic changes to be more explicit about dynbind
* lisp/eshell/em-dirs.el (eshell-dirs-initialize): Reveal the lambdas. (eshell-expand-multiple-dots): Fix ^+$ => \`+\' in the regexp. * lisp/eshell/esh-cmd.el (eshell-this-command-hook): Declare as dynamically scoped. (eshell-trap-errors): Use `mapc funcall` since this can't have global/local settings like a true hook. (eshell-do-eval): Split the `let` case from the rest so we can use `cl-progv` rather than `eval` for it. (eshell/which): Use `fboundp` test instead of ugly gymnastics to try and hide the function call from the compiler. * lisp/eshell/esh-var.el (eshell-variable-aliases-list): Reveal the lambdas. (eshell-parse-variable-ref): Use backquotes.
Diffstat (limited to 'lisp/eshell/esh-cmd.el')
-rw-r--r--lisp/eshell/esh-cmd.el92
1 files changed, 44 insertions, 48 deletions
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index ee4dbd5550f..1ed5d5d7018 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -122,24 +122,20 @@ however."
(defcustom eshell-prefer-lisp-functions nil
"If non-nil, prefer Lisp functions to external commands."
- :type 'boolean
- :group 'eshell-cmd)
+ :type 'boolean)
(defcustom eshell-lisp-regexp "\\([(`]\\|#'\\)"
"A regexp which, if matched at beginning of an argument, means Lisp.
Such arguments will be passed to `read', and then evaluated."
- :type 'regexp
- :group 'eshell-cmd)
+ :type 'regexp)
(defcustom eshell-pre-command-hook nil
"A hook run before each interactive command is invoked."
- :type 'hook
- :group 'eshell-cmd)
+ :type 'hook)
(defcustom eshell-post-command-hook nil
"A hook run after each interactive command is invoked."
- :type 'hook
- :group 'eshell-cmd)
+ :type 'hook)
(defcustom eshell-prepare-command-hook nil
"A set of functions called to prepare a named command.
@@ -149,8 +145,7 @@ the value of these symbols if necessary.
To prevent a command from executing at all, set
`eshell-last-command-name' to nil."
- :type 'hook
- :group 'eshell-cmd)
+ :type 'hook)
(defcustom eshell-named-command-hook nil
"A set of functions called before a named command is invoked.
@@ -165,7 +160,7 @@ In order to substitute an alternate command form for execution, the
hook function should throw it using the tag `eshell-replace-command'.
For example:
- (add-hook \\='eshell-named-command-hook \\='subst-with-cd)
+ (add-hook \\='eshell-named-command-hook #\\='subst-with-cd)
(defun subst-with-cd (command args)
(throw \\='eshell-replace-command
(eshell-parse-command \"cd\" args)))
@@ -173,8 +168,7 @@ For example:
Although useless, the above code will cause any non-glob, non-Lisp
command (i.e., `ls' as opposed to `*ls' or `(ls)') to be replaced by a
call to `cd' using the arguments that were passed to the function."
- :type 'hook
- :group 'eshell-cmd)
+ :type 'hook)
(defcustom eshell-pre-rewrite-command-hook
'(eshell-no-command-conversion
@@ -182,8 +176,7 @@ call to `cd' using the arguments that were passed to the function."
"A hook run before command rewriting begins.
The terms of the command to be rewritten is passed as arguments, and
may be modified in place. Any return value is ignored."
- :type 'hook
- :group 'eshell-cmd)
+ :type 'hook)
(defcustom eshell-rewrite-command-hook
'(eshell-rewrite-for-command
@@ -202,8 +195,7 @@ so by adding a function to this hook. The first function to return a
substitute command form is the one used. Each function is passed the
command's full argument list, which is a list of sexps (typically
forms or strings)."
- :type 'hook
- :group 'eshell-cmd)
+ :type 'hook)
(defvar eshell-post-rewrite-command-function #'identity
"Function run after command rewriting is finished.
@@ -228,16 +220,14 @@ If an entry is a function, it will be called with the name, and should
return non-nil if the command is complex."
:type '(repeat :tag "Commands"
(choice (string :tag "Name")
- (function :tag "Predicate")))
- :group 'eshell-cmd)
+ (function :tag "Predicate"))))
;;; User Variables:
(defcustom eshell-cmd-load-hook nil
"A hook that gets run when `eshell-cmd' is loaded."
:version "24.1" ; removed eshell-cmd-initialize
- :type 'hook
- :group 'eshell-cmd)
+ :type 'hook)
(defcustom eshell-debug-command nil
"If non-nil, enable Eshell debugging code.
@@ -247,9 +237,8 @@ you must re-load `esh-cmd.el'."
:initialize 'custom-initialize-default
:set (lambda (symbol value)
(set symbol value)
- (load-library "esh-cmd"))
- :type 'boolean
- :group 'eshell-cmd)
+ (load "esh-cmd"))
+ :type 'boolean)
(defcustom eshell-deferrable-commands
'(eshell-named-command
@@ -259,16 +248,14 @@ you must re-load `esh-cmd.el'."
If they return a process object, execution of the calling Eshell
command will wait for completion (in the background) before finishing
the command."
- :type '(repeat function)
- :group 'eshell-cmd)
+ :type '(repeat function))
(defcustom eshell-subcommand-bindings
'((eshell-in-subcommand-p t)
(default-directory default-directory)
(process-environment (eshell-copy-environment)))
"A list of `let' bindings for subcommand environments."
- :type 'sexp
- :group 'eshell-cmd)
+ :type 'sexp)
(put 'risky-local-variable 'eshell-subcommand-bindings t)
@@ -307,7 +294,7 @@ otherwise t.")
(set (make-local-variable 'eshell-last-command-name) nil)
(set (make-local-variable 'eshell-last-async-proc) nil)
- (add-hook 'eshell-kill-hook 'eshell-resume-command nil t)
+ (add-hook 'eshell-kill-hook #'eshell-resume-command nil t)
;; make sure that if a command is over, and no process is being
;; waited for, that `eshell-current-command' is set to nil. This
@@ -317,16 +304,17 @@ otherwise t.")
(function
(lambda ()
(setq eshell-current-command nil
- eshell-last-async-proc nil))) nil t)
+ eshell-last-async-proc nil)))
+ nil t)
(add-hook 'eshell-parse-argument-hook
- 'eshell-parse-subcommand-argument nil t)
+ #'eshell-parse-subcommand-argument nil t)
(add-hook 'eshell-parse-argument-hook
- 'eshell-parse-lisp-argument nil t)
+ #'eshell-parse-lisp-argument nil t)
(when (eshell-using-module 'eshell-cmpl)
(add-hook 'pcomplete-try-first-hook
- 'eshell-complete-lisp-symbols nil t)))
+ #'eshell-complete-lisp-symbols nil t)))
(defun eshell-complete-lisp-symbols ()
"If there is a user reference, complete it."
@@ -724,6 +712,8 @@ ensconced in a list."
eshell-current-subjob-p)
,object))
+(defvar eshell-this-command-hook nil)
+
(defmacro eshell-trap-errors (object)
"Trap any errors that occur, so they are not entirely fatal.
Also, the variable `eshell-this-command-hook' is available for the
@@ -736,9 +726,9 @@ this grossness will be made to disappear by using `call/cc'..."
(eshell-condition-case err
(prog1
,object
- (run-hooks 'eshell-this-command-hook))
+ (mapc #'funcall eshell-this-command-hook))
(error
- (run-hooks 'eshell-this-command-hook)
+ (mapc #'funcall eshell-this-command-hook)
(eshell-errorn (error-message-string err))
(eshell-close-handles 1)))))
@@ -1059,16 +1049,8 @@ be finished later after the completion of an asynchronous subprocess."
((eq (car form) 'setcdr)
(setcar (cdr args) (eshell-do-eval (cadr args) synchronous-p))
(eval form))
- ((memq (car form) '(let catch condition-case unwind-protect))
- ;; `let', `condition-case' and `unwind-protect' have to be
- ;; handled specially, because we only want to call
- ;; `eshell-do-eval' on their first form.
- ;;
- ;; NOTE: This requires obedience by all forms which this
- ;; function might encounter, that they do not contain
- ;; other special forms.
- (if (and (eq (car form) 'let)
- (not (eq (car (cadr args)) 'eshell-do-eval)))
+ ((eq (car form) 'let)
+ (if (not (eq (car (cadr args)) 'eshell-do-eval))
(eshell-manipulate "evaluating let args"
(dolist (letarg (car args))
(if (and (listp letarg)
@@ -1076,6 +1058,21 @@ be finished later after the completion of an asynchronous subprocess."
(setcdr letarg
(list (eshell-do-eval
(cadr letarg) synchronous-p)))))))
+ (cl-progv
+ (mapcar (lambda (binding) (if (consp binding) (car binding) binding))
+ (car args))
+ ;; These expressions should all be constants now.
+ (mapcar (lambda (binding) (if (consp binding) (eval (cadr binding))))
+ (car args))
+ (eshell-do-eval (macroexp-progn (cdr args)) synchronous-p)))
+ ((memq (car form) '(catch condition-case unwind-protect))
+ ;; `condition-case' and `unwind-protect' have to be
+ ;; handled specially, because we only want to call
+ ;; `eshell-do-eval' on their first form.
+ ;;
+ ;; NOTE: This requires obedience by all forms which this
+ ;; function might encounter, that they do not contain
+ ;; other special forms.
(unless (eq (car form) 'unwind-protect)
(setq args (cdr args)))
(unless (eq (caar args) 'eshell-do-eval)
@@ -1158,10 +1155,9 @@ be finished later after the completion of an asynchronous subprocess."
(setq name (substring name 1)
direct t))
(if (and (not direct)
- (eshell-using-module 'eshell-alias)
+ (fboundp 'eshell-lookup-alias)
(setq alias
- (funcall (symbol-function 'eshell-lookup-alias)
- name)))
+ (eshell-lookup-alias name)))
(setq program
(concat name " is an alias, defined as \""
(cadr alias) "\"")))