Skip to content

dieggsy/esh-autosuggest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 
 
 
 
 
 
 

Repository files navigation

esh-autosuggest

https://melpa.org/packages/esh-autosuggest-badge.svg https://stable.melpa.org/packages/esh-autosuggest-badge.svg

Fish-like history autosuggestions in eshell

demo.gif

Installation

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)

Usage

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)

Key Bindings

  • <right> and C-f are used to select the suggestion.
  • M-<right> and M-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.

Delay

esh-autosuggest-delay defaults to 0 seconds. This is most like fish shell’s instant history autosuggestions, but can be customized.

With other backends (not recommended)

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.

Known bugs and workarounds

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.

Rationale and tips

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)