szermatt / emacs-bash-completion

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

bash-completion for Emacs test melpa melpa-stable

bash-completion.el defines dynamic completion hooks for shell-mode and shell-command prompts that is based on bash completion.

Bash completion for Emacs:

However, bash-completion.el only works with bash. If you run other shells or other interactive programs that support completion, bash-completion will not be able to help.

A more powerful alternative to bash-completion.el is MisTTY, as it works with all shells and most interactive programs that support completion. On the other hand, MisTTY cannot integrate with Emacs completion and is not able to provide completion in shell-command prompts nor in eshell mode.

[!NOTE] While I'm still maintaining bash-completion.el, I've switched to MisTTY for day-to-day operation, so that package is more likely to receive updates. -- szermatt

INSTALLATION

Copy bash-completion.el into a directory that's on Emacs load-path. You can do that manually, or by installing it from MELPA.

Shell completion

To enable bash completion in shell buffers as well as in command prompts, such as the prompt started by compile, add the hook bash-completion-dynamic-complete to shell-dynamic-complete-functions.

For example:

        (autoload 'bash-completion-dynamic-complete
          "bash-completion"
          "BASH completion hook")
        (add-hook 'shell-dynamic-complete-functions
          'bash-completion-dynamic-complete)

or simpler, but forces you to load bash-completion at startup:

        (require 'bash-completion)
        (bash-completion-setup)

After that reload your .emacs (M-x eval-buffer) or restart.

When called from a bash shell buffer, bash-completion-dynamic-complete communicates with the current shell to reproduce, as closely as possible the normal bash auto-completion, available on full terminals.

When called from non-shell buffers, such as the prompt of M-x compile, bash-completion-dynamic-complete creates a separate bash process just for doing completion. Such processes have the environment variable EMACS_BASH_COMPLETE set to t, to help distinguish them from normal shell processes.

Completion at point

You can also use bash completion as an additional completion function in any buffer that contains bash commands. To do that, add bash-completion-capf-nonexclusive to the buffer-local completion-at-point-functions. For example, you can setup bash completion in eshell-mode by invoking

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

There is also a lower-level function bash-completion-dynamic-complete-nocomint which allows you to construct your own completion-at-point function.

(bash-completion-dynamic-complete-nocomint COMP-START COMP-POS DYNAMIC-TABLE)

COMP-START is where the bash command starts --- it depends on the mode of the calling buffer. In most cases, line-beginning-position works because it uses field boundaries.

COMP-POS is usually the current position of the cursor.

When calling from completion-at-point, make sure to pass a non-nil value to the DYNAMIC-TABLE argument so it returns a function instead of a list of strings. This isn't just an optimization: returning a function instead of a list tells Emacs it should avoids post-filtering the results and possibly discarding useful completion from bash.

TROUBLESHOOTING

If completion in a bash shell doesn't behave as you think it should, check the following:

CONTRIBUTING

To report bugs, features or even to ask questions, please open an issue. To contribute code or documentation, please open a pull request.

See CONTRIBUTING.md for more details.

COMPATIBILITY

bash-completion.el is known to work with Bash 4.2 and later and Bash 5, on Emacs, starting with version 25.3, under Linux and OSX.