Bash Emacs shell autocomplete

The GNOME Bash terminal runs intelligent auto-complete. for example

apt-get in<TAB> 

becomes

 apt-get install 

In Emacs shell mode, this autocomplete does not work even after the explicit source /etc/bash_completion . The above example looks like in or ends automatically with the file name in the current directory, and not with a valid apt-get command. Presumably, this is because Emacs intercepts the Tab key. How to enable intelligent auto-completion in shell-mode ?

+74
bash shell autocomplete emacs
Oct 02 '08 at 17:37
source share
8 answers

I know that this question is three years old, but this is what I was also interested in the solution. A web search directed me to a piece of elisp that forces Emacs to use bash to complete in shell mode. Anyway, this works for me.

Check it out at https://github.com/szermatt/emacs-bash-completion .

+78
Nov 16 2018-11-11T00:
source share

In the emacs shell, it actually does make autocomplete, not bash. If the shell and emacs are not synchronized (for example, using pushd, popd, or some custom bash function that changes the current shell directory), autocomplete fails.

To fix this, simply enter β€œdirs” into the shell and everything will return to synchronization.

I also have the following in my .emacs:

 (global-set-key "\M-\r" 'shell-resync-dirs) 

Then just pressing Esc-return repeats autocomplete.

+16
Oct 21 '08 at 6:24
source share

I do not know the answer to this. But the reason is that it does not work the way you expect, probably because emacs shell completion is handled by emacs internally (using the comint-dynamic-complete function) and does not have built-in smart completion functions.

I'm afraid this is not easy to fix.

Edit: njsf's suggestion for using term-mode is probably as good as it gets. Start with

  MX term 
It is included in the standard emacs distribution (and in emacs21-common or emacs22-common on Ubuntu and Debian at least).
+13
Oct 02 '08 at 18:09
source share

As Matley said, this is no easy task since bash starts with -noediting and TAB is bound to comint-dynamic-complete.

It would be possible to reinstall TAB to insert the command into shell-comand-hook by using a local key set and force shell mode to not start with -noediting using Mx customize-variable RET explicit-bash -args, but I suspect it is not Will go well with all other editing.

You might want to try term-mode, but it has another set of problems because some of the regular regular keys overlap with term-mode.

EDIT: by other regular keywords superimposed by terminal mode, I mean everything except Cc, which becomes an escape to be able to switch buffers. Therefore, instead of Cx k, to kill the buffer, you must have Cc Cx k. Or switch to another buffer "Cc Cx o" or "Cc Cx 2"

+5
Oct 03 '08 at 2:55
source share

Please consider another Mx term mode, as I did when I hit the problem in 2011. I am trying to put all my efforts on Inet at the time to get the shell to work with the completion of Bash, including this question. But, having found an alternative before term-mode , I never want to try eshell .

This is a complete terminal emulator, so you can run an interactive program inside, for example, the Midnight commander. Or switch to zsh completion so you don’t lose the time spent setting up Emacs β€” do it once a lifetime.

With this feature, completing TAB in Bash is free. But more importantly, you get the full power of Readline, such as incremental or prefix command searches . To make this setting more convenient to use, check .inputrc , .bashrc , .emacs .

The essential part of .inputrc :

 # I like this! set editing-mode emacs # Don't strip characters to 7 bits when reading. set input-meta on # Allow iso-latin1 characters to be inserted rather than converted to # prefix-meta sequences. set convert-meta off # Display characters with the eighth bit set directly rather than as # meta-prefixed characters. set output-meta on # Ignore hidden files. set match-hidden-files off # Ignore case (on/off). set completion-ignore-case on set completion-query-items 100 # First tab suggests ambiguous variants. set show-all-if-ambiguous on # Replace common prefix with ... set completion-prefix-display-length 1 set skip-completed-text off # If set to 'on', completed directory names have a slash appended. The default is 'on'. set mark-directories on set mark-symlinked-directories on # If set to 'on', a character denoting a file type is appended to the # filename when listing possible completions. The default is 'off'. set visible-stats on set horizontal-scroll-mode off $if Bash "\Cx\Ce": edit-and-execute-command $endif # Define my favorite Emacs key bindings. "\C-@": set-mark "\Cw": kill-region "\Mw": copy-region-as-kill # Ctrl+Left/Right to move by whole words. "\e[1;5C": forward-word "\e[1;5D": backward-word # Same with Shift pressed. "\e[1;6C": forward-word "\e[1;6D": backward-word # Ctrl+Backspace/Delete to delete whole words. "\e[3;5~": kill-word "\C-_": backward-kill-word # UP/DOWN filter history by typed string as prefix. "\e[A": history-search-backward "\Cp": history-search-backward "\eOA": history-search-backward "\e[B": history-search-forward "\Cn": history-search-forward "\eOB": history-search-forward # Bind 'Shift+TAB' to complete as in Python TAB was need for another purpose. "\e[Z": complete # Cycling possible completion forward and backward in place. "\e[1;3C": menu-complete # M-Right "\e[1;3D": menu-complete-backward # M-Left "\e[1;5I": menu-complete # C-TAB 

.bashrc (YEA! There is dabbrev in Bash from any word in ~/.bash_history ):

 set -o emacs if [[ $- == *i* ]]; then bind '"\e/": dabbrev-expand' bind '"\ee": edit-and-execute-command' fi 

.emacs to make navigation convenient in the terminal buffer:

 (setq term-buffer-maximum-size (lsh 1 14)) (eval-after-load 'term '(progn (defun my-term-send-delete-word-forward () (interactive) (term-send-raw-string "\ed")) (defun my-term-send-delete-word-backward () (interactive) (term-send-raw-string "\e\Ch")) (define-key term-raw-map [C-delete] 'my-term-send-delete-word-forward) (define-key term-raw-map [C-backspace] 'my-term-send-delete-word-backward) (defun my-term-send-forward-word () (interactive) (term-send-raw-string "\ef")) (defun my-term-send-backward-word () (interactive) (term-send-raw-string "\eb")) (define-key term-raw-map [C-left] 'my-term-send-backward-word) (define-key term-raw-map [C-right] 'my-term-send-forward-word) (defun my-term-send-m-right () (interactive) (term-send-raw-string "\e[1;3C")) (defun my-term-send-m-left () (interactive) (term-send-raw-string "\e[1;3D")) (define-key term-raw-map [M-right] 'my-term-send-m-right) (define-key term-raw-map [M-left] 'my-term-send-m-left) )) (defun my-term-mode-hook () (goto-address-mode 1)) (add-hook 'term-mode-hook #'my-term-mode-hook) 

Since any regular command like Cx o does not work in terminal emulation mode, I expand the layout with:

 (unless (ignore-errors (require 'ido) (ido-mode 1) (global-set-key [?\sd] #'ido-dired) (global-set-key [?\sf] #'ido-find-file) t) (global-set-key [?\sd] #'dired) (global-set-key [?\sf] #'find-file)) (defun my--kill-this-buffer-maybe-switch-to-next () "Kill current buffer. Switch to next buffer if previous command was switching to next buffer or this command itself allowing sequential closing of uninteresting buffers." (interactive) (let ( (cmd last-command) ) (kill-buffer (current-buffer)) (when (memq cmd (list 'next-buffer this-command)) (next-buffer)))) (global-set-key [s-delete] 'my--kill-this-buffer-maybe-switch-to-next) (defun my--backward-other-window () (interactive) (other-window -1)) (global-set-key [s-up] #'my--backward-other-window) (global-set-key [s-down] #'other-window) (global-set-key [s-tab] 'other-window) 

Please note that above I am super key so term-raw-map and maybe any other keyboard layout does not conflict with my key bindings. To make the super key from the left Win key, I use .xmodmaprc :

 ! To load this config run: ! $ xmodmap .xmodmaprc ! Win key. clear mod3 clear mod4 keycode 133 = Super_L keycode 134 = Hyper_R add mod3 = Super_L add mod4 = Hyper_R 

You just have to remember command 2: Cc Cj - switch to the usual Emacs editing mode in the buffer - I use it for copying or grepping, Cc Ck - return to the terminal emulation mode.

Mouse selection and Shift-Insert work like in xterm .

+3
Feb 19 '15 at 23:06
source share

I use Prelude, and when I press Meta + Tab, it ends for me.

Also, Ctrl + i seems to do the same.

+1
Apr 16 '13 at 2:45
source share

I use steering mode. It has this functionality (after pressing "TAB"): enter image description here

0
Feb 08 '17 at 9:04 on
source share

I do not pretend to be an emacs expert, but this should solve your problem:

Create: ~ / .emacs

Add to this:

(command shell required) (Shell-command-end-mode)

Emacs takes a shell, so BASH options are not migrated. This will be automatically completed for EMACS.

-2
Oct 02 '08 at 19:16
source share



All Articles