szermatt / emacs-bash-completion

Add programmable bash completion to Emacs shell-mode
GNU General Public License v2.0
279 stars 33 forks source link

Add eshell setup #68

Closed xiaoyuechen closed 1 year ago

xiaoyuechen commented 1 year ago

Motivation

The built-in completion function of eshell, pcomplete, works well with elisp functions but does not cover all the shell commands. bash-completion needs to be added as an additional completion method in eshell.

Changes

Related issues

This fixes #24 in a convenient way. Users do not need to bind a different key for bash-completion to work in eshell. It adds a completion function to completion-at-point-functions for eshells buffers and prompts.

szermatt commented 1 year ago

Thank you for the pull request. This is a great addition! Following the instructions worked well for me, even as a complete eshell noob :)

One thing, though: I think that it'd be better to split the eshell support into its own file, since it depends on eshell. Strictly-speaking, bash-completion.el should now (require esh-mode) just so it can call (eshell-bol), but it doesn't seem reasonable to require all users of bash completion to load eshell.

I'd suggest extracting the eshell support files into bash-completion-eshell.el (or esh) and rename the functions to start with bash-completion-eshell. Please let me know if you'd like to do it yourself. Otherwise, I'd pull your change and move the function before pushing to github.

xiaoyuechen commented 1 year ago

Thanks for the feedback.

I just checked the documentation (emacs 30) of eshell-bol and saw:

eshell-bol is an alias for ‘beginning-of-line’ in ‘esh-mode.el’.

This function is obsolete since 30.1; use ‘beginning-of-line’ instead.

Since eshell-bol will soon be obsolete, I think we can just use beginning-of-line or better, line-beginning-position, in a function called bash-completion-capf-nonexclusive:

(defun bash-completion-capf-nonexclusive ()
  (let ((compl (bash-completion-dynamic-complete-nocomint
                (line-beginning-position)
                (point) t)))
    (when compl
      (append compl '(:exclusive no)))))

This is all we need. There is no dependency on eshell. The function is also more generic --- it works in any mode as long as beginning-of-line works correctly. Eshell users can simply invoke this:

(add-hook 'eshell-mode-hook
          (lambda ()
            (add-hook 'completion-at-point-functions
                      'bash-completion-capf-nonexclusive nil t)))

What do you think?

szermatt commented 1 year ago

That sounds like a good solution! It's much simpler than having to bother with multiple files :)

xiaoyuechen commented 1 year ago

I have pushed the changes including documentations.

szermatt commented 1 year ago

Thank you!