Fish-like history autosuggestions in eshell
This package is on melpa. If you have melpa in your package repositories, you
can use M-x RET package-install RET esh-autosuggest
or install
with use-package:
(use-package esh-autosuggest
:hook (eshell-mode . esh-autosuggest-mode)
;; If you have use-package-hook-name-suffix set to nil, uncomment and use the
;; line below instead:
;; :hook (eshell-mode-hook . esh-autosuggest-mode)
:ensure t)
Alternatively, consider installing with straight.el or quelpa-use-package.
Otherwise, download the files to somewhere on your load path, and require esh-autosuggest:
(require 'esh-autosuggest)
This package assumes you use something other than company for eshell completion
(e.g. eshell-pcomplete
, completion-at-point
, helm-esh-pcomplete
).
company-mode
is used solely as a mechanism for history autosuggestions.
Unless you’re using use-package’s hook keyword as described in Installation, you can enable the autosuggestions with:
(add-hook 'eshell-mode-hook #'esh-autosuggest-mode)
<right>
andC-f
are used to select the suggestion.M-<right>
andM-f
are used to select the next word in the suggestion.
Keys can be modified using esh-autosuggest-active-map
.
If instead you don’t want company-active-map
to be overridden, you may set
esh-autosuggest-use-company-map
to t
. This may cause unexpected
behavior when pressing RET
or TAB
, depending on what you want those to do.
To emulate fish-shell most closely, it is recommended you leave this nil
, as
that will explicitly run your input (regardless of suggestion) on RET
, and
bring up your preferred completion system on TAB
.
esh-autosuggest-delay
defaults to 0 seconds. This is most like
fish shell’s instant history autosuggestions, but can be customized.
It is technically possible to group this backend with other company backends
like e.g. company-capf
like so:
;; don't add esh-autosuggest-mode to eshell-mode-hook
(defun setup-eshell-grouped-backends ()
(setq-local company-backends
'((company-capf esh-autosuggest))))
(add-hook 'eshell-mode-hook #'setup-eshell-grouped-backends)
This isn’t recommended since the history suggestions will be neither fish-like, nor will they work after typing the first word on the command line, since company-backends need to share a prefix to work together smoothly. See company-mode/company-mode#744 for more information.
If you’re using evil-collection, there’s a known issue that occurs when
evil-collection-company-use-tng
is set to t
(the default). If you don’t
need that feature, you can set it to nil
for the time being.
I made this package to help ease a transition from zsh to eshell as my main shell. The reason the main mechanism is a minor-mode that overrides company-mode is that I didn’t find company-mode that useful for eshell completion.
While the default popup-buffer frontend to pcomplete can be a bit annoying, I’ve found there are alternatives that make pcomplete behave more like normal shell completion. Try one or more of the following for tab completion:
- Ambrevar/emacs-fish-completion
- If you use helm
(defun setup-eshell-helm-completion () (define-key eshell-mode-map [remap eshell-pcomplete] 'helm-esh-pcomplete)) (add-hook 'eshell-mode-hook #'setup-eshell-helm-completion)
- If you use ivy
(setq ivy-do-completion-in-region t) ; this is the default (defun setup-eshell-ivy-completion () (define-key eshell-mode-map [remap eshell-pcomplete] 'completion-at-point) ;; only if you want to use the minibuffer for completions instead of the ;; in-buffer interface (setq-local ivy-display-functions-alist (remq (assoc 'ivy-completion-in-region ivy-display-functions-alist) ivy-display-functions-alist))) (add-hook 'eshell-mode-hook #'setup-eshell-ivy-completion)