学习Emacs系列教程(四):Minibuffer
学习Emacs系列教程(一):基本使用
学习Emacs系列教程(二):导航
学习Emacs系列教程(三):编辑(1)
上回介绍了在Emacs中如何插入删除文本的简单操作,以及一些杂七杂八的命令,都还是蛮容易的。这回先跳过编辑这部分,介绍Emacs中的Minibuffer,呃,翻译过来叫迷你缓冲,听着比较难受,后面还是用E文吧。
一、初识Minibuffer
Minibuffer 乃是Emacs命令读取复杂参数的位置。比如说文件名,缓冲名,命令名以及Lisp表达式这些东西。Minibuffer 显示在echo area中,当Minibuffer处于使用状态时,会出现一个彩色的提示符并以冒号结尾,根据提示符信息输入参数,以回车提交。取消 Minibuffer 使用C-g,也就是上节介绍的取消命令。
其实Minibuffer并不是太神秘,最常见的地方就是打开文件时提示我们输入文件名:
按下C-x C-f 后,回显区就会变成这个样子,其中Find file 就是Minibuffer的提示符,因为它是蓝色的。后面的路径是Minibuffer自动添加的默认值,我们可以把参数选项insert- default-directory设置为nil,关闭这个默认路径。
这里插入一下如何设置Emacs参数选项,我们键入M-x set-variable RETinsert-default-directoryRET后输入nil 即可,这里的RET代表回车。改回默认,前面输入一样最后输入t 。其实我们按下M-x set-variable也激活了Minibuffer。
二、在Minibuffer中编辑
我们可以将Minibuffer看成和主输入区类似的缓冲,Minibuffer中也有个buffer嘛,就是说某些主输入区的命令 Minibuffer也可以用。同样我们看上面那张图,使用C-a 可以把光标移到d字符的位置,再按C-e 光标又回到最后,还可以使用M-Backspace删除“info/” 回到上级目录。不过需要注意的一点是,RET是Minibuffer的结束符而不是换行符,所以如果我们需要插入新行就不能使用回车,而是用C-o。同样 对于TAB、SPC、?(前两个分别对应Tab键和空格键)在Minibuffer中经常用于自动补全,所以也不能直接输入,我们需要使用C-q 来插入,比如TAB,就用C-q TAB来替换。可以说Minibuffer和主输入区基本上一样,同样的快捷键、同样的操作方式,复制粘贴功能一应俱全。
通常情况,Minibuffer在屏幕中只有一行,随着你输入的增多,Minibuffer会自动调整大小来适应。变量 resize-mini-windows用于控制Minibuffer的大小变化,其默认值是grow-only,大小只增不减,设为t 后,如果你删除一行会自动缩小,设为nil,就不会动了。变量max-mini-window-height控制Minibuffer高度的最大值,设为浮点数表示占整个窗口的百分比,整数表示最大可以有多少行。默认值是0.25。
当我们操作Minibuffer时也可以控制另一个窗口,C-M-v 命令就是用来滚动另一个窗口的文本,这个是往下翻页,C-M-S-v是
往上翻页,大家要看清楚,这不是四个键一起按,如果你不小心按的是s键,你会发现出来的是QQ聊天窗口,所以出于对中国广大QQ用户的考虑,Emacs把
它改成了大写的s,就是说还要加上Shift键,呃,这是我目前见的最长的按键了而且比较变态。其实,也有简洁的方式,M-PageUp和M-PageDown,不过这两个键不在主键盘区,就看各位心情了。
Minibuffer 一般情况是不允许递归调用的,也就是我们不能连按两次C-x C-f,它会提示Minibuffer正在使用,我们也可以设置变量enable-recursive-minibuffers 为t 来激活递归调用,不过容易引起错误,大家还是尽量避免吧。
三、自动补全
Emacs中的命令有那么多,我们也不可能每一个都记的住,电脑里的路径也很长,记漏几个字符也很正常,这个时候自动补全就显得很重要了。常用的自动补全有四个键TAB、SPC、RET和?。我们先看它们的准确定义。
TAB 尽可能的补全Minibuffer中的字符,如果没有满足要求的,则列出所有可能的补全。对应命令minibuffer-complete。
SPC 最多补全Minibuffer中的一个词,如果没有满足要求的,则列出所有可能的补全,在输入路径时SPC不可用。对应命令minibuffer-complete-word。
RET 提交Minibuffer中的文本,或者选取第一个可能的补全提交。对应命令minibuffer-complete-and-exit。
? 列出所有可能的补全。对应命令minibuffer-completion-help。
下图就是我们按ins TAB TAB后自动补全的例子:
第一个TAB补全了“ert-”,第二TAB列出了所有可能的补全。
再仔细解读下这几个键,TAB是用的最多的自动补全,可以说每个操作系统的shell都支持TAB自动补全,它的设计目标也是尽可能的补全我们的输入,而一次补全需要满足下面三个准则:
- 光标前Minibuffer中的文本必须和补全候选项中开头的内容一致,如果光标后还有文本则其需为补全候补项剩下内容的字串。
- 如果不满足上一条件,则使用部分匹配补全,即将Minibuffer中的文本以"-"或者空格分开,分别补全。比如输入"em-l-m",再按TAB,则会补全至"emacs-list-mode"。
- 如果仍无满足的候选项,则继续使用第一条准则,不过忽略光标后的文本。
空格键的匹配模式与TAB类似,不过它只匹配到下一个"-"或者空格,比如输入auto-f 后按空格会完成auto-fill-,需要再按一个空格才会完全补全为auto-fill-mode。此外,在TAB和SPC的匹配当中可以使用通配 符"*",代表任意一个或多个字符。
在没有完全匹配项时,Emacs会列出所有满足条件的匹配,我们可以使用多种方法来选择某一项。
Mouse-1, Mouse-2,就是鼠标左右键。
或者在Minibuffer中按M-v,就会切换到补全候选项窗口,然后我们可以使用RET选择光标位置的项(choose-completion)。或者使用左右箭头键移动光标(next-completion、previous-completion)。很遗憾,除了使用上下左右,没有更快的方法了,M-f 和M-b 都是移到"-"字符的位置。再说明一点,上面几个命令想要能用,就必须把Minibuffer递归调用打开。
在我们使用RET提交输入时,会出现三种不同情况的自动补全,三种情况根据提交内容的使用情况区分。
- 严格匹配,故名思意,就是说输入的内容要完全匹配某一项才行。我们使用C-x k 来关闭某一个buffer时会提示输入buffer名,这个时候就是使用的严格匹配。如果找不到这个buffer 命令就不会执行。
- 谨慎匹配,这个和严格匹配类似,区别在于回车后如果没有找到一个完全匹配的项Minibuffer不会退出,而是进行自动补全,再按RET就可以提交输入,然后退出Minibuffer。谨慎匹配用在读取必须存在的文件时。
- 宽松匹配,C-x C-f 就是典型的宽松匹配,有一致的就打开这个文件,没有一至的就新建个文件。
自动补全还有种icomplete 模式,使用M-x icomplete-mode 启动,作用是自动更新可能的补全。
接下来再介绍一些自动补全的变量。
completion-auto-help ,设为nil 时不会出现补全候选项列表,必须使用? 手动调出。设为lazy,在按第二次TAB时会出现补全候选项列表。
completion-ignored-extensions, 它的值包含了一些字符串,包含了比如".o", ".elc", "~" 之类的,这样在输入文件名自动补全时就不会选择以这些结尾的文件了,不过当所有可能的候选都在忽略后缀里面,所有忽略全部无效。比如有foo.c 和 foo.elc 两个文件,输入foo TAB,会得到foo.c,但你输入foo.e TAB 还是会出现foo.elc。此外如果它的某项值是以"/" 结尾,则代表的是一个文件夹。
read-file-name-completion-ignored-case ,值为non-nil 表示忽略大小写,nil 为不忽略大小写。
四、Minibuffer 历史
在Minibuffer中的每次输入都保存在Minibuffer的历史当中,我们可以很方便的调出之前输入的某次命令。
M-p 移到Minibuffer历史中的前一条,previous-history-element。
M-n 移到Minibuffer历史中的后一条,next-history-element。
M-r regexp RET 移到Minibuffer历史中的前一条,使用正则表达式,previous-matching-history-element。
M-sregexp RET 移到Minibuffer历史中的后一条,使用正则表达式,next-matching-history-element。
提醒一下,这些要Minibuffer处于激活状态才能使用。每次移动后取出的历史会替换当前的输入,而当我们在最后一条记录时继续使用M-n,还是会 照样出现一条记录,不过这个记录是Emacs猜的。此外还需要说明的是,Emacs 维护了多个不同的历史,比如我们打开文件的路径历史,或者我们调用编译器的编译参数历史,而Emacs搜索历史也是在相应的历史列表中进行。
关于Minibuffer历史的参数常用有两个,history-length 历史队列最大值,history-delete-duplicates 是否删除相同的历史。都是字面意思就不仔细说了。
如果我们现在在主窗口也可以快速的调出最近执行的命令,使用C-x ESC ESC (repeat-complex-command)再执行一次最近的Minibuffer中的命令,Emacs会提示你是否执行。我们还可以使用M-p, M-n 来选择其他的历史。命令M-x list-command-history 可以列出最近所有的历史。
最后说下Minibuffer历史的本质,它们都是储存在Lisp变量command-history中项,其中每一项都保存的每次执行的命令和参数。
小结:
这次讲的东西不少哈。
按键 |
命令 |
作用 |
---|---|---|
(none) | set-variable | 设置变量 |
C-M-v | scroll-other-window | 向下滚动另一个窗口 |
M-PageDown | 同上 | 同上 |
C-M-S-v | scroll-other-window-down | 向上滚动另一个窗口 |
M-PageUp | 同上 | 同上 |
TAB | minibuffer-complete | 自动补全Minibuffer |
SPC | minibuffer-complete-word | 自动补全Minibuffer中一个词 |
RET | minibuffer-complete-and-exit | 提交Minibuffer |
? | minibuffer-completion-help | 列出所有可能补全 |
RET(候选列表中) | choose-completion | 选择候选项 |
← | previous-completion | 上一个候选项 |
→ | next-completion | 下一个候选项 |
C-x k | kill-buffer | 关闭一个buffer |
(none) | icomplete-mode | 自动更新补全模式 |
M-p | previous-history-element | 前一历史 |
M-n | next-history-element | 后一历史 |
M-r (regexp) | previous-matching-history-element | 前一历史,使用正则表达式 |
M-s (regexp) | next-matching-history-element | 后一历史,使用正则表达式 |
C-x ESC ESC | repeat-complex-command | 重复最近一次命令 |
(none) | list-command-history | 列出所有命令历史 |
变量 |
作用 |
---|---|
insert-default-history | 打开文件是否插入默认路径 |
resize-mini-window | Minibuffer大小变化模式 |
max-mini-window-height | Minibuffer最大高度 |
enable-recursive-minibuffers | 是否允许Minibuffer递归调用 |
completion-auto-help | 自动补全帮助模式 |
completion-ignored-extensions | 自动补全忽略后缀名列表 |
read-file-name-completion-ignored-case | 自动补全是否大小写敏感 |
history-length | 自动补全历史长度 |
history-delete-duplicates | 自动补全是否删除重复项 |
ps:文中出现的高亮文本含义,红色为快捷键,前几章也是这么用的;绿色为命令,即按M-x 后输入的内容;蓝色为Emacs的变量名。
转自:http://www.cnblogs.com/robertzml/archive/2009/09/27/1574557.html