123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- (eval-when-compile
- (require 'esh-util))
- (require 'eshell)
- (eshell-defgroup eshell-alias nil
- "Command aliases allow for easy definition of alternate commands."
- :tag "Command aliases"
-
- :group 'eshell-module)
- (defcustom eshell-aliases-file (expand-file-name "alias" eshell-directory-name)
- "The file in which aliases are kept.
- Whenever an alias is defined by the user, using the `alias' command,
- it will be written to this file. Thus, alias definitions (and
- deletions) are always permanent. This approach was chosen for the
- sake of simplicity, since that's pretty much the only benefit to be
- gained by using this module."
- :type 'file
- :group 'eshell-alias)
- (defcustom eshell-bad-command-tolerance 3
- "The number of failed commands to ignore before creating an alias."
- :type 'integer
-
- :group 'eshell-alias)
- (defcustom eshell-alias-load-hook nil
- "A hook that gets run when `eshell-alias' is loaded."
- :version "24.1"
- :type 'hook
- :group 'eshell-alias)
- (defvar eshell-command-aliases-list nil
- "A list of command aliases currently defined by the user.
- Each element of this alias is a list of the form:
- (NAME DEFINITION)
- Where NAME is the textual name of the alias, and DEFINITION is the
- command string to replace that command with.
- Note: this list should not be modified in your '.emacs' file. Rather,
- any desired alias definitions should be declared using the `alias'
- command, which will automatically write them to the file named by
- `eshell-aliases-file'.")
- (put 'eshell-command-aliases-list 'risky-local-variable t)
- (defvar eshell-failed-commands-alist nil
- "An alist of command name failures.")
- (defun eshell-alias-initialize ()
- "Initialize the alias handling code."
- (make-local-variable 'eshell-failed-commands-alist)
- (add-hook 'eshell-alternate-command-hook 'eshell-fix-bad-commands t t)
- (eshell-read-aliases-list)
- (add-hook 'eshell-named-command-hook 'eshell-maybe-replace-by-alias t t)
- (make-local-variable 'eshell-complex-commands)
- (add-to-list 'eshell-complex-commands 'eshell-command-aliased-p))
- (defun eshell-command-aliased-p (name)
- (assoc name eshell-command-aliases-list))
- (defun eshell/alias (&optional alias &rest definition)
- "Define an ALIAS in the user's alias list using DEFINITION."
- (if (not alias)
- (dolist (alias eshell-command-aliases-list)
- (eshell-print (apply 'format "alias %s %s\n" alias)))
- (if (not definition)
- (setq eshell-command-aliases-list
- (delq (assoc alias eshell-command-aliases-list)
- eshell-command-aliases-list))
- (and (stringp definition)
- (set-text-properties 0 (length definition) nil definition))
- (let ((def (assoc alias eshell-command-aliases-list))
- (alias-def (list alias
- (eshell-flatten-and-stringify definition))))
- (if def
- (setq eshell-command-aliases-list
- (delq def eshell-command-aliases-list)))
- (setq eshell-command-aliases-list
- (cons alias-def eshell-command-aliases-list))))
- (eshell-write-aliases-list))
- nil)
- (defvar pcomplete-stub)
- (autoload 'pcomplete-here "pcomplete")
- (defun pcomplete/eshell-mode/alias ()
- "Completion function for Eshell's `alias' command."
- (pcomplete-here (eshell-alias-completions pcomplete-stub)))
- (defun eshell-read-aliases-list ()
- "Read in an aliases list from `eshell-aliases-file'."
- (let ((file eshell-aliases-file))
- (when (file-readable-p file)
- (setq eshell-command-aliases-list
- (with-temp-buffer
- (let (eshell-command-aliases-list)
- (insert-file-contents file)
- (while (not (eobp))
- (if (re-search-forward
- "^alias\\s-+\\(\\S-+\\)\\s-+\\(.+\\)")
- (setq eshell-command-aliases-list
- (cons (list (match-string 1)
- (match-string 2))
- eshell-command-aliases-list)))
- (forward-line 1))
- eshell-command-aliases-list))))))
- (defun eshell-write-aliases-list ()
- "Write out the current aliases into `eshell-aliases-file'."
- (if (file-writable-p (file-name-directory eshell-aliases-file))
- (let ((eshell-current-handles
- (eshell-create-handles eshell-aliases-file 'overwrite)))
- (eshell/alias)
- (eshell-close-handles 0))))
- (defsubst eshell-lookup-alias (name)
- "Check whether NAME is aliased. Return the alias if there is one."
- (assoc name eshell-command-aliases-list))
- (defvar eshell-prevent-alias-expansion nil)
- (defun eshell-maybe-replace-by-alias (command args)
- "If COMMAND has an alias definition, call that instead using ARGS."
- (unless (and eshell-prevent-alias-expansion
- (member command eshell-prevent-alias-expansion))
- (let ((alias (eshell-lookup-alias command)))
- (if alias
- (throw 'eshell-replace-command
- (list
- 'let
- (list
- (list 'eshell-command-name
- (list 'quote eshell-last-command-name))
- (list 'eshell-command-arguments
- (list 'quote eshell-last-arguments))
- (list 'eshell-prevent-alias-expansion
- (list 'quote
- (cons command
- eshell-prevent-alias-expansion))))
- (eshell-parse-command (nth 1 alias))))))))
- (defun eshell-alias-completions (name)
- "Find all possible completions for NAME.
- These are all the command aliases which begin with NAME."
- (let (completions)
- (dolist (alias eshell-command-aliases-list)
- (if (string-match (concat "^" name) (car alias))
- (setq completions (cons (car alias) completions))))
- completions))
- (defun eshell-fix-bad-commands (name)
- "If the user repeatedly a bad command NAME, make an alias for them."
- (ignore
- (unless (file-name-directory name)
- (let ((entry (assoc name eshell-failed-commands-alist)))
- (if (not entry)
- (setq eshell-failed-commands-alist
- (cons (cons name 1) eshell-failed-commands-alist))
- (if (< (cdr entry) eshell-bad-command-tolerance)
- (setcdr entry (1+ (cdr entry)))
- (let ((alias (concat
- (read-string
- (format "Define alias for \"%s\": " name))
- " $*")))
- (eshell/alias name alias)
- (throw 'eshell-replace-command
- (list
- 'let
- (list
- (list 'eshell-command-name
- (list 'quote name))
- (list 'eshell-command-arguments
- (list 'quote eshell-last-arguments))
- (list 'eshell-prevent-alias-expansion
- (list 'quote
- (cons name
- eshell-prevent-alias-expansion))))
- (eshell-parse-command alias))))))))))
- (provide 'em-alias)
|