views:

3560

answers:

4

In the GNOME Terminal, Bash does smart auto-completion. For example

apt-get in<TAB>

becomes

apt-get install

In Emacs shell-mode, this auto-completion doesn't work, even after I explicitly source /etc/bash_completion. The above example sticks as in or auto-completes with a filename in the current directory rather than a valid apt-get command option. Presumably, this is because Emacs is intercepting the Tab key-press. How do I enable smart auto-completion in shell-mode?

+2  A: 

I don't know the answer to this. But the reason that it doesn't work as you expect is probably because the completion in emacs shells is handled by emacs internally (by the comint-dynamic-complete function), and doesn't have those smart completion functions built-in.

I'm afraid it is not an easy thing to fix.

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

M-x term
It is included in the standard emacs distribution (and in emacs21-common or emacs22-common on Ubuntu and Debian at least).

matli
A: 

I make no claims to being an emacs expert but this should solve your problem:

Create: ~/.emacs

Add to it:

(require 'shell-command) (shell-command-completion-mode)

Emacs takes over the shell so BASH settings don't carry through. This will set auto completion for EMACS itself.

Scott Alan Miller
No, this doesn't solve the problem. It only works on shell-command, not in shell-mode. And besides, it doesn't enable the smart completion that was requested in the question (it will only complete commands and filenames).
matli
shell-command-completion-mode does filename completion and is enabled by default. I want Bash's completion feature (which is extensible to include, e.g., sub-commands for apt-get and svn).
Chris Conway
+1  A: 

Like Matli said, it is not an easy task, since bash is started with --noediting and TAB is bound to comint-dynamic-complete.

One could possibly rebind TAB to self-insert-command in shell-comand-hook with local-set-key and make shell-mode not start with --noediting by M-x customize-variable RET explicit-bash-args, but I suspect that it will not sit well with all other editing.

You might want to try term-mode, but it has another set of problems, because some of the other regular keybindings are overtaken by term-mode.

EDIT: By other regular keybidings being overtaken by term-mode, I mean all but C-c which becomes the escape to be able to switch buffers. So instead of C-x k to kill the buffer you'd have to C-c C-x k. Or to switch to another buffer 'C-c C-x o' or 'C-c C-x 2'

njsf
self-insert-command is not it: it inserts the TAB character rather than passing the TAB key-press through to Bash.
Chris Conway
I don't have a term-mode command and I can't figure out where to get it.
Chris Conway
+1  A: 

In the emacs shell, it's actually emacs doing the auto-completion, not bash. If the shell and emacs are out of sync (e.g. by using pushd, popd or some bash user function that changes the shell's current directory), then auto-completion stops working.

To fix this, just type 'dirs' into the shell and things get back in sync.

I also have the following in my .emacs:

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

Then just hitting Esc-return resyncs the auto-completion.

Steve Lacey
This is a nice answer to a different question!
Chris Conway