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 .