在GNOME终端中,Bash执行智能自动完成功能。例如
apt-get in<TAB>
变为
apt-get install
在Emacs shell模式下,即使在我明确地提供/etc/bash_completion
之后,此自动完成也不起作用。以上示例为in
或自动完成,并在当前目录中使用文件名而不是有效的apt-get
命令选项。据推测,这是因为Emacs正在拦截Tab键按下。如何在shell-mode
启用智能自动完成功能?
答案 0 :(得分:85)
我知道这个问题已经有三年了,但是我也有兴趣解决这个问题。一个网络搜索引导我到一个elisp,使得Emacs使用bash在shell模式下完成。无论如何,它对我有用。
答案 1 :(得分:20)
在emacs shell中,它实际上是emacs进行自动完成,而不是bash。如果shell和emacs不同步(例如通过使用pushd,popd或某些更改shell当前目录的bash用户函数),则自动完成将停止工作。
要解决这个问题,只需在shell中输入'dirs'即可恢复同步。
我的.emacs中也有以下内容:
(global-set-key "\M-\r" 'shell-resync-dirs)
然后只需按Esc-return重新同步自动完成。
答案 2 :(得分:14)
我不知道答案。但是它没有按预期工作的原因可能是因为emacs shell中的完成由内部的emacs处理(通过comint-dynamic-complete函数),并且没有内置的那些智能完成函数。 / p>
我担心这不是一件容易的事情。
编辑:njsf关于使用term-mode的建议可能和它一样好。从
M-x term开始 它包含在标准的emacs发行版中(至少在Ubuntu和Debian的emacs21-common或emacs22-common中)。
答案 3 :(得分:6)
就像Matli所说的那样,这不是一件容易的事,因为bash是以--noediting开头的,而TAB必然是comint-dynamic-complete。
有人可能会在使用local-set-key的shell-comand-hook中将TAB重新绑定到self-insert-command 并使shell模式无法启动 - 由M-x自定义变量RET explicit-bash-args编写,但我怀疑它不适合所有其他编辑。
您可能想尝试使用term-mode,但它有另一组问题,因为其他一些常规键绑定被term-mode超越。
编辑:通过其他常规关键词被术语模式所取代,我的意思是除了C-c之外的其他所有关键词都可以转换缓冲区。因此,代替C-x k来杀死缓冲区,你必须使用C-c C-x k。或者切换到另一个缓冲区'C-c C-x o'或'C-c C-x 2'
答案 4 :(得分:6)
请考虑另一种模式M-x term
,就像我在2011年遇到问题时所做的那样。我当时试图通过Inet收集所有努力来使shell工作完成Bash,包括这个问题。但是,面对term-mode
发现替代方案,我甚至不想尝试eshell
。
它是完整的终端模拟器,所以你可以在里面运行交互式程序,比如午夜指挥官。或者切换到zsh
完成,这样您就不会浪费时间进行Emacs配置。
您可以免费使用bash完成TAB。但更重要的是,您可以获得完整的Readline功能,例如增量或前缀命令搜索。要使此设置更方便,请检查我的.inputrc,.bashrc,.emacs。
.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's 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
"\C-x\C-e": edit-and-execute-command
$endif
# Define my favorite Emacs key bindings.
"\C-@": set-mark
"\C-w": kill-region
"\M-w": 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
"\C-p": history-search-backward
"\eOA": history-search-backward
"\e[B": history-search-forward
"\C-n": 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!在~/.bash_history
中的任何单词都有Bash中的dabbrev:
set -o emacs
if [[ $- == *i* ]]; then
bind '"\e/": dabbrev-expand'
bind '"\ee": edit-and-execute-command'
fi
.emacs
使术语缓冲区的导航更加舒适:
(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\C-h"))
(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)
由于C-x o
这样的常用命令在终端仿真模式下无法工作,因此扩展了keymap:
(unless
(ignore-errors
(require 'ido)
(ido-mode 1)
(global-set-key [?\s-d] #'ido-dired)
(global-set-key [?\s-f] #'ido-find-file)
t)
(global-set-key [?\s-d] #'dired)
(global-set-key [?\s-f] #'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)
请注意,我使用super
键,因此term-raw-map
可能任何其他键映射与我的键绑定不冲突。要从左super
键生成Win
键,我使用.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
你应该记住2个命令:C-c C-j
- 进入正常的Emacs编辑模式(用于在缓冲区文本中复制或grepping),C-c C-k
- 返回到终端仿真模式。
鼠标选择和Shift-Insert
的工作方式与xterm
相同。
答案 5 :(得分:2)
我知道这个职位已经超过11岁了。但是我创建了一个函数来在Emacs中完成本机shell的完成。它只是将Tab键发送到基础进程并拦截输出,因此它与您在shell本身中获得的完全相同。
https://github.com/CeleritasCelery/emacs-native-shell-complete
答案 6 :(得分:1)
我使用Prelude,当我点击Meta + Tab时,它就完成了。
另外,Ctrl + i似乎做同样的事情。
答案 7 :(得分:0)
答案 8 :(得分:-2)
我没有声称自己是emacs专家,但这可以解决您的问题:
创建:〜/ .emacs
添加到它:
(要求'shell-command) (壳的命令完成模式)
Emacs接管shell,因此BASH设置无法执行。这将为EMACS本身设置自动完成。