szermatt/emacs-bash-completion

Official EShell support

Closed this issue · 9 comments

I use eshell in Emacs 25, and enabled bash-completion with the hack in issue #13 .
Can we support bash-completion feature in eshell by default?

The lisp config that I'm using is:
"""
(when (require 'bash-completion nil t)
(setq eshell-default-completion-function 'eshell-bash-completion))

(defun eshell-bash-completion ()
(while (pcomplete-here
(nth 2 (bash-completion-dynamic-complete-nocomint (save-excursion (eshell-bol) (point)) (point))))))
"""
It has a bug that "\ " is added at the end of the line when triggering auto-completion with .

The bug was fixed by adding "(setq-local bash-completion-nospace t)" inside eshell-bash-completion func.

I'd be happy to add to bash-completion whatever makes sense to support eshell - but what makes sense? I don't use eshell, so it's hard for me to answer.
As far as I know, eshell is not bash.

What motivated you to use bash completion for eshell?

Your solution replaces the default eshell completion with bash completion. That works for you, but is this what users of eshell will want? There could be strange completions proposed by bash completion - the bash builtin commands and functions, at the very least, might be confusing to shell users.

Thanks for the reply!

I agree that the solution described above is not ideal, but it was sufficient enough to fix my problem.

My specific use-case is using bash auto-completion for gcloud and kubectl commands in eshell. They provide auto-completion scripts only for bash.
Whether we use bash or eshell, bash auto-completion helps in this case.

Also see https://github.com/Ambrevar/emacs-fish-completion, which fallbacks on bash-completion in Eshell.

@mihnjong Thanks. Very useful for me. It deserves an entry in the README or in the wiki I guess.

I would like to get support for bash completion in Eshell as well.

Here is an extract of my configuration:

(use-package esh-mode
  :hook (eshell-mode . my/configure-esh-mode)
  :config
  (progn
    (defun my/esh-mode-completion-at-point ()
      "Same as `completion-at-point' except for some commands."
      (interactive)
      ;; unbinding pcomplete/make gives a chance to `bash-completion'
      ;; to complete make rules. Bash-completion is indeed more
      ;; powerfull than `pcomplete-make'.
      (cl-letf (((symbol-function 'pcomplete/make) nil))
        (completion-at-point)))

    ;; We can't use use-package's :bind here as eshell insists on
    ;; recreating a fresh eshell-mode-map for each new eshell buffer.
    (defun my/configure-esh-mode ()
      (bind-key "M-p" #'counsel-esh-history eshell-mode-map)
      (bind-key "<tab>" #'my/esh-mode-completion-at-point eshell-mode-map))))

(use-package em-cmpl
  :hook (eshell-mode . eshell-cmpl-initialize)
  :init
  (progn
    (defun my/eshell-bash-completion ()
      (let ((bash-completion-nospace t))
        (while (pcomplete-here
                (nth 2 (bash-completion-dynamic-complete-nocomint
                        (save-excursion (eshell-bol) (point))
                        (point)))))))

    (when (require 'bash-completion nil t)
      (setq eshell-default-completion-function #'my/eshell-bash-completion))))

I put an example of using bash-completion from eshell https://github.com/szermatt/emacs-bash-completion#completion-at-point

I still don't feel confident calling it official support, as I don't know how well this integrates into eshell or even how eshell and bash-completion should interact, but that should at least help people get started into writing their own.