Skip to content

Conversation

@xiaoyuechen
Copy link
Contributor

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

  • bash-completion-setup-eshell registers bash completion for eshell buffers and command prompt.
  • bash-completion-dynamic-complete-eshell returns the same list as the one returned by bash-completion-dynamic-complete-nocomint appended with (:exclusive no) so that pcomplete is tried when bash-completion fails to match the text at point.
  • Related documentation.

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
Copy link
Owner

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
Copy link
Contributor Author

xiaoyuechen commented Jun 11, 2023

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
Copy link
Owner

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

@xiaoyuechen
Copy link
Contributor Author

I have pushed the changes including documentations.

@szermatt szermatt merged commit f1daac0 into szermatt:master Jun 12, 2023
@szermatt
Copy link
Owner

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Official EShell support

2 participants