学习Emacs系列教程(一):基本使用
学习Emacs系列教程(二):导航
学习Emacs系列教程(三):编辑(1)
学习Emacs系列教程(四):Minibuffer
学习Emacs系列教程(五):编辑(2)
学习Emacs系列教程(六):编辑(3)
学习Emacs系列教程(七):剪切板
学习Emacs系列教程(八):查找替换
学习Emacs系列教程(九):缓冲管理
学习Emacs系列教程(十):多窗口
学习Emacs系列教程(一):基本使用
前言的前言:本人也是初学Emacs,之前对Vim也只接触了一点,所以也谈不上对哪个更喜欢,也分不出哪个更好。写这个教程的目的一是方便自己更好的学习Emacs,
二是没事找事。如果有专家路过还望多指点。符号 | 表示 |
%% | 只读,未更改 |
-- | 可写,未更改 |
** | 可写,已更改 |
%* | 只读,已更改 |
教程的第一部分就写到这儿,虽然没有太多实际的东西,总算开了个头吧。
学习Emacs系列教程(二):导航
上回开了个头,简单的介绍了Emacs的一些基本常识,这回继续说基本常识,怎么移动你的光标。可能有人会说,这上下左右键不是很好用吗,还用你来讲。呶,Emacs的强大在于你能够只使用键盘左边那堆键来完成任何事情(不包括顶上的ESC和Function),这也是Emacs的设计宗旨。
为了试验这些按键,大家在进入Emacs时选择页面中间的Emacs Tutorial,这里面可以随便乱按不用担心出什么岔子。
一、基本导航
看下面这张图片:
按键 |
命令 |
作用 |
---|---|---|
C-f |
forward-char |
向前一个字符 |
C-b |
backward-char |
向后一个字符 |
C-p |
previous-line |
上移一行 |
C-n |
next-line |
下移一行 |
M-f |
forward-word |
向前一个单词 |
M-b |
backward-word |
向后一个单词 |
C-a |
beginning-of-line |
移到行首 |
C-e |
end-of-line |
移到行尾 |
M-e |
forward-sentence |
移到句首 |
M-a |
backward-sentence |
移到句尾 |
M-} |
forward-paragraph |
下移一段 |
M-{ |
backward-paragraph |
上移一段 |
C-v |
scroll-up |
下移一屏 |
M-v |
scroll-down |
上移一屏 |
C-x ] |
forward-page |
下移一页 |
C-x [ |
backward-page |
上移一页 |
M-< |
beginning-of-buffer |
移到文档头 |
M-> |
end-of-buffer |
移到文档尾 |
M-g g n |
goto-line |
移到第n行 |
(none) |
goto-char |
移到第n个字符 |
C-l |
recenter |
将当前位置放到页面中间(Emacs最喜欢的地方) |
M-n |
digit-argument |
重复下个命令n次 |
C-u n |
universal-argument |
重复下个命令n次,n默认为4 |
学习Emacs系列教程(三):编辑(1)
上回说到怎么在Emacs中移动光标,这回将介绍如何在Emacs中编辑文本。
任何一款文本编辑软件的核心功能当然就是编辑文本,Emacs也不例外,虽然它也有许多其它强大的本领,但都离不开文本编辑。闹,文本编辑说白了也就是打字,专业点说我们需要实现一种所见即所得输入方式。在Emacs中打字和Notepad中没什么区别,一样也是打开一个文件直接往里面敲字符就可以了,中文也行。这个和Vim区别比较大,我们还需要知道自己是在哪个模式下,不然乱敲一气也不见屏幕有什么反应。
一、文件操作
刚才我们说到编辑文本就是打开一个文件往里面敲字符,所以我们第一件事就是打开一个文件。
C-x C-f 输入这个命令后在回显区会看到一个提示“Find file: ”,然后是我的文档的路径,这时需要输入你编辑的文件的名称。注意,这里的输入的文件名可以包含路径,比如 D:\text.txt,或者是相对路径。还有就是在Windows中我们可以使用Windows风格的反斜杠"\",当然了也可以使用正斜杠"/"。如果输入了一个新的路径,Emacs的当前路径会跳转到你输入的地方,(实际上是新开了一个buffer)。如果Emacs没找到你输入的文件,它会以你输入的名字自动新建一个文件。另外Emacs还支持拖拽,就是说可以把文件图标拖到Emacs中来打开它。
当你不小心错打开一个文件时,可以使用C-x C-v 来换一个,操作和C-x C-f 一样,这个区别嘛是Emacs在buffer中处理有些不同。
C-x C-s 这个命令是用来保存文件的,另存是C-x C-w ,这两个都比较简单,一看就会。
二、输入文本
除了一些基本的输入方式,Emacs还可以输入非打印字符,就是ASCII表中前面的那些字符。
使用C-q (n), 这里的n代表一个八进制数,就能打出n对应的ASCII表中的符号。
还有就是Unicode字符比如日文啊韩文啊,使用C-x 8 后面接Unicode标准中字符的名字或者编码就可以输出这个乱七八糟的东西了。这我相信不会有谁闲的无聊来记这种一长串数字的,而且我们有更为先进的方案,(广告时间)当。。当。。当。。,现在隆重推出Unicode字符超级输入工具——搜狗软键盘,省去了你记忆一大堆16进制数的烦恼,还能输入中文,实在是居家旅行必备良品。
三、删除文本
相比输入,Emacs删除文本的花样就比较多了。
Backspace,退格键,这个比较传统就不说了。
Del键,删除光标处的字符,虽然这个也很常见,但它违背了Emacs的原则,“你的手不用离开主键盘区”,所以我们用C-d来代替。
M-d ,这个用来删除一个单词(记住在中文中单词表示两个相邻标点符号中的句子,所以如果你是打中文这个键还是少用,稍不留神多长一截句子就不见了)。而且它删除的是从光标当前位置到单词结束,还会把单词前半截留给你。
相对应,删除单词前半截可以用,M-Backspace。
M-k, 删除一段句子,这个在中英文有些不同。中文里面它只会删除到句号为止,包括句号。而英文中,它不认'.', '!‘,这些东西,而是把整段都删了(英文的分段用两个回车表示)。和M-d一样,它也是从光标处开始删。对应删回去是C-x Backspace。
C-k, 从光标起删除当前行。
一个比较详细的例子见下图:(宽线覆盖的文字就是使用箭头指向的命令删除的部分,注意中英文的区别)
按键 |
命令 |
作用 |
---|---|---|
C-x C-f | find-file | 打开文件 |
C-x C-v | find-alternate-file | 打开另一个文件 |
C-x C-s | save-buffer | 保存文件 |
C-x C-w | write-file | 另存文件 |
C-q (n) | quoted-insert | 插入字符,n表示字符的八进制ASCII码 |
C-x 8 | ucs-insert | 插入Unicode字符 |
C-d |
delete-char |
删除光标处字符 |
Backspace |
delete-backward-char |
删除光标前字符 |
M-d |
kill-word |
删除光标起单词 |
M-Backspace |
backward-kill-word |
删除光标前单词 |
C-k |
kill-line |
删除光标起当前行 |
M-k |
kill-sentence |
删除光标起句子 |
C-x Backspace |
backward-kill-sentence |
删除光标前句子 |
(none) | kill-paragraph | 删除光标起段落 |
(none) | backward-kill-paragraph | 删除光标前段落 |
C-/ |
undo |
撤销 |
C-_ | undo | 撤销 |
C-x u | undo | 撤销 |
C-g | keyboard-quit | 撤销命令 |
C-h t | help-with-tutorial | 调出Emacs Tutorial |
C-h r | info-emacs-manual | 调出Emacs Manual |
C-h k (command) | describe-key | 查看对应command帮助 |
C-o | open-line | 插入空行 |
C-x C-o | delete-blank-line | 删除空行 |
C-x z | repeat | 重复前个命令 |
学习Emacs系列教程(四):Minibuffer
上回介绍了在Emacs中如何插入删除文本的简单操作,以及一些杂七杂八的命令,都还是蛮容易的。这回先跳过编辑这部分,介绍Emacs中的Minibuffer,呃,翻译过来叫迷你缓冲,听着比较难受,后面还是用E文吧。
一、初识Minibuffer
Minibuffer 乃是Emacs命令读取复杂参数的位置。比如说文件名,缓冲名,命令名以及Lisp表达式这些东西。Minibuffer 显示在echo area中,当Minibuffer处于使用状态时,会出现一个彩色的提示符并以冒号结尾,根据提示符信息输入参数,以回车提交。取消Minibuffer 使用C-g,也就是上节介绍的取消命令。
其实Minibuffer并不是太神秘,最常见的地方就是打开文件时提示我们输入文件名:
按键 |
命令 |
作用 |
---|---|---|
(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 | 自动补全是否删除重复项 |
学习Emacs系列教程(五):编辑(2)—— 标记
有段时间没写这个教程了,自己险些放弃,不过回头想想看个小说都讨厌太监,自己写更不能太监,还是要坚持下去。闲话不多说,进入这次的正题,关于编辑文本的另一些内容。
一、标记和区域
所谓区域(region)就是平时我们使用鼠标选中的一段文字,在emacs中用样可以使用鼠标来选择一段文字表示区域,如果使用键盘操作的话需要用一个术语叫标记(mark),也就是一个基准点,或者说是区域的起点,使用命令C-SPC 用来设定标记,不幸的是这个组合键通常情况是被输入法给截获了,我们得使用C-@来代替,要多按个Shift,操作起来感觉有点别扭。OK,在设定好标记后我们可以让光标移动到任何想去的地方,在光标和标记之间就是选定的区域,emacs里面会高亮显示这个区域,参见下图,注意,这个区域是动态存在的,只要光标位置变了,区域也随着变化,只是其起点永远是那个标记。
这个时候就可以对选中的区域进行操作了,比如说C-w (kill-region) 删除选中的区域,或者C-x C-u 将所选区域字母改成大写字母,这是个禁用命令需要确认后才能生效。还有个常用的操作是C-x C-x (exchange-point-and-mark),交换光标和标记,就是说把区域的起点改在光标所在处。取消标记和区域直接使用C-g 就可以了。
除了这种手工选择区域之外,emacs还内置了一些快捷的选取方式。像常用的全选就是C-x h ,全选后标记在文档的最后,而光标在文档的最前面。C-x C-p 选择整页,页是由分页符界定的。选取一段使用M-h 。M-@ 从当前位置选到单词尾(中文里的单词是两个标点符号间的文字),重复按这个命令会一直往后选取单词。这四个命令有个共同的特点就是选取的区域标记在最后,光标在最前,这个和常规理解有些区别,记住就是了。
在Emacs 23之后还有个新特性叫shift选择(shift selection),故名思意就是用shift键来快速选择区域,通过使用shift键和C-n, C-p之类的组合来选择区域,和常规选择有些区别的是,在shift选择过程中使用了任何非shift组合都会取消当前选择区域。
二、标记环
标记的一个主要功能是界定区域,此外还有个作用就是记忆一个点供今后使用,在一个buffer里面可以用标记记忆16个点,称为“标记环”,标记环实际是个先进先出的队列。
我们使用命令C-@ C-@ 把一个标记加入标记环,这个命令做了两件事,第一次按C-@时标记了一个点(此时已经加入标记环了),第二次按C-@时取消了当前标记的激活状态,我们可以在minibuffer中看到提示Mark deactivated。而命令C-u C-@ 来选择上一个加入标记环的标记,如果选中的标记处于激活状态,它会取消其激活。使用C-u C-@不会删除标记,仅是在标记环中不停的向前跳跃,注意这里我们只可能在当前buffer中的标记间跳跃,不会跑到其它的buffer里面去。
如果修改变量set-mark-command-repeat-pop 为 non-nil,在按下C-u C-@后,我们可以就使用C-@在标记环中跳跃了。
变量mark-ring-max 表示了一个buffer中标记环中的最大标记数,默认为16。
还有变量mark-even-if-nonactive 和标记环相关,当其为nil 时,表示只能使用激活状态的标记,默认为non-nil 。
另外在emacs中还存在一个全局标记环,C-@ C-@在把标记加入当前buffer标记环同时,也把标记加入了全局标记环,我们可以用命令C-x C-@ (pop-global-mark)在全局标记环中选择。
三、非持久性标记模式
这个东西这里只是稍微提及一下,平时用到的地方很少,所谓非持久性标记就是指我们在选择了一个区域后,任何修改该区域的操作都会改变区域的激活状态。而我们可以将非持久性标记模式关闭,这样选择的区域永远处于激活状态,命令是transient-mark-mode ,这是个切换变量只有开启和关闭两个状态,我们每次使用M-x transient-mark-mode命令都会将其值从一个切换到另一个。关闭该模式后最显著的特点是选择区域时没有高亮(不过使用鼠标选择和shift选择高亮还是有的)。令人头疼的也是这个特点,我们根本不知道自己选择了哪些地方。
我们会使用这个东西只有一种情况,某些命令在关闭非持久性标记模式时,其作用有少许差异,不过基本上这些差异很少去关注,所以这段大家看看就行。
小结:
按键 |
命令 |
作用 |
---|---|---|
C-@ | set-mark-command | 设定标记 |
C-x C-x | exchange-point-and-mark | 交换标记和光标位置 |
C-w | kill-region | 删除区域中内容 |
C-x C-u | upcase-region | 将区域中字母改为大写 |
C-x h | mark-whole-buffer | 全选 |
C-x C-p | mark-page | 选取一页 |
M-h | mark-paragraph | 选取一段 |
M-@ | mark-word | 选取一个单词 |
C-@ C-@ | 加入点到标记环 | |
C-u C-@ | 在标记环中跳跃 | |
C-x C-@ | pop-global-mark | 在全局标记环中跳跃 |
(none) | transient-mark-mode | 非持久化标记模式 |
变量 |
作用 |
---|---|
set-mark-command-repeat-pop | 是否使用C-@连续跳跃 |
mark-ring-max | 标记环最大容量 |
mark-even-if-nonactive | 是否只使用激活状态标记 |
ps: 久了没写感觉生疏了,大家见谅。
学习Emacs系列教程(六):编辑(3)
这次介绍编辑中关于粘贴复制的部分,不过在Emacs中称粘贴复制为Killing和Yanking,而不是通常说的Cutting和Pasting,当然差别不会太多。
一、Killing
Killing就是指删除指定的一段内容并将其放入kill 环中,kill 环和上章所介绍的标记环差不多也是一个先进先出的队列,我们还可以理解为Windows里的粘贴板。在Emacs中删除命令分为两大类,一类称为kill 命令,这种命令删除的文本会放入kill 环中,比如kill-line,kill-word命令,非常好认。kill命令相对比较安全,我们删除的内容都可以找回来。另一类删除命令称为delete 命令,就是说它们删掉的内容是不会放入kill 环中的,比如说delete-char这样子的。虽然delete 命令删除的内容不放入kill 环,但实际上这两种方式删掉的文本我们都可以用undo命令(C-/,C-_)找回来。
有些时候我们打开的文档是只读属性的不允许修改,不过我们可能会想复制点内容,但直接使用kill命令是不行的,有两个解决办法,一是使用命令M-w (kill-ring-save),这个需要首先标记好一个区域再使用,其实这个命令就是Copy命令,仅将选中内容放入kill 环而不删除。另一个办法是修改变量kill-read-only-ok 为non-nil,这样就可以直接使用kill 命令了,在使用时minibuffer中会有提示。两个办法各有所长,第一个不用改变量选择范围相对灵活,第二个快捷操作更多,大家根据需要选择。
下面分类列出delete命令和kill命令,有些在第三章已经介绍过了,这里再提一下:
C-d (delete-char),删除光标处的字符。
Backspace (delete-backward-char),删除光标前字符。
M-\ (delete-horizontal-space),删除光标处的所有空格和Tab字符。
M-SPC (just-one-space),删除光标处的所有空格和Tab字符,但留下一个。
C-x C-o (delete-blank-lines),删除光标周围的空白行,保留当前行。
M-^ (delete-indentation),将两行合为一行,删除之间的空白和缩进。参见下面两图。
这里我们可以看出delete命令基本上只能删个把字符,或者一些空白字符,干不了什么大事,也避免了意外删掉大段内容而找不会来。接着我们整理下kill 命令:
C-k (kill-line),从光标处起删除该行。
C-S-Backspace (kill-whole-line),删除整行。
C-w (kill-region),删除区域。
M-w (kill-ring-save),复制到kill 环,而不删除。
M-d (kill-word),删除光标起一个单词。
M-Backspace (backward-kill-word),删除光标前单词。
C-x Backspace (backward-kill-sentence),往前删一句。
M-k (kill-sentence),删除光标起一句。
M-z char (zap-to-char),删至字符char为止。
二、Yanking
前面讲了怎么把文本放入kill 环中,下面接着介绍如何把这些内容拿出来。这里面最常用的便是C-y (yank) 命令,也就是粘贴命令。将光标移到文本中的任何一处使用此命令便可把最近一次放入kill 环中的内容提取出来,其实除了kill 环里的,如果你在任何其它窗口程序中使用了复制命令,紧接着在Emacs里使用C-y,都可以把系统粘贴板中的内容调出。C-y在调出内容后还把使用该命令的点加入了标记环,我们可以很方便的使用C-x C-x 找到是哪个位置插入的文本。
召回的另一个命令是M-y (yank-pop),这个命令只能在刚用完C-y后使用。它的作用是用kill 环中再前一个内容替换掉刚用C-y粘贴出来的内容。简单点说,假如kill 环中有1号、2号、3号记录,使用C-y后3号记录调出,紧接着使用M-y,删掉3号记录,换成2号记录,还有M-y是可以连着多次使用的,我们再按一下1号记录就出来了。虽然这个命令可以使用前一条记录替换此条记录,但它并不会更改kill 环中记录的顺序,仅是一个指针的移动而已。另外M-y 命令可以接受参数调用,比如说C-u 2 M-y 就等价于C-y M-y。
还有一个是C-M-w (append-next-kill),这个命令只有在它下一个命令是kill 命令时才有效,作用是把下个kill 命令删掉的东西和kill 环中最后一个记录合并。
说了这么多关于kill 和yank 的内容,其实最重要的一点还是kill 环,即存放删掉东西的地方。Emacs维持的是一个全局kill 环,所有打开的buffer都可以使用。在kill 环中默认是保存前面60个删除的内容,可以使用变量kill-ring-max 来修改这个值。而kill 环中的内容是保存在kill-ring 这个变量中的,命令C-h v kill-ring 可以查看我们之前删了些什么东西。
正常情况来说,每次使用kill 命令都会在kill 环中新建一个记录来保存这次删除的东西,不过如果我们连续使用kill 命令,这一系列命令所删除的内容只会保存在一个记录中。比如我们有下面一段文本:
I have nothing◇to say. Good luck!
光标在nothing 和to之间,连续按M-d,M-Backspace,M-d,M-Backspace,文本变为:
I ◇. Good luck!
此时使用C-y会一次性将所有删除全部召回。这就说明了kill环具有一定的智能性,并不是简单的保存每次删除。不过,一旦在kill 命令中间插入了任何其它命令,包括移动光标都会使下次删除的内容在kill 环中新建立一个记录。所以我们还有C-M-w 命令强制下次删除加入上一个记录中。呃,需要注意的是M-w命令在任何时候都是新建一个记录。
三、快速复制
有的时候我们可能会想把一段内容临时保存在一个地方可供单独编辑或者以后使用,很明显kill 环不是个好地方,那新建立一个文件呢?kill 环反正也是全局的,通过它来进行复制。这个办法是不错,不过步骤稍显多了点,Emacs为了解决这种问题提供了下面几个命令:
append-to-buffer 将区域中内容加入到一个buffer中。
prepend-to-buffer 将区域中内容加入到一个buffer中,不过加入位置在该buffer的光标前。
copy-to-buffer 将区域中内容加入到一个buffer中,删除该buffer原有内容。
insert-buffer 在该位置插入指定的buffer中所有内容。
append-to-file 将区域中内容复制到一个文件中。
这些命令都只能通过M-x 来调用,而且基本都需要选中一个区域再进行操作,作用都很好理解,这里就不详细说了。
四、CUA绑定
CUA(Common User Access),Windows,Linux,Mac 都是CUA系统。CUA绑定就是说常规的C-c (copy),C-v (Paste),C-x (Cut)还是按系统定义来使用。通过M-x cua-mode 命令可以将Emacs的粘贴复制设为上述方式。这是CUA一个常见的应用方式,不过这里我不推荐大家使用这种方式,毕竟Emacs已经形成了自己的风格何必将就别人。CUA绑定还有其它很多注意的地方,改了后反而麻烦。
小结:
按键 |
命令 |
作用 |
---|---|---|
C-d | delete-char | 删除光标处字符 |
Backspace | delete-backward-char | 删除光标前字符 |
M-\ | delete-horizontal-space | 删除光标处的所有空格和Tab字符 |
M-SPC | just-one-space | 删除光标处的所有空格和Tab字符,但留下一个 |
C-x C-o | delete-blank-lines | 删除光标周围的空白行,保留当前行 |
M-^ | delete-indentation | 将两行合为一行,删除之间的空白和缩进 |
C-k | kill-line | 从光标处起删除该行 |
C-S-Backspace | kill-whole-line | 删除整行 |
C-w | kill-region | 删除区域 |
M-w | kill-ring-save | 复制到kill 环,而不删除 |
M-d | kill-word | 删除光标起一个单词 |
M-Backspace | backward-kill-word | 删除光标前单词 |
M-k | kill-sentence | 删除光标起一句 |
C-x Backspace | backward-kill-sentence | 删除光标前删一句 |
M-z char | zap-to-char | 删至字符char为止 |
C-y | yank | 召回 |
M-y | yank-pop | 召回前一个 |
C-M-w | append-next-kill | 下一个删掉内容和上次删除合并 |
C-h v | describe-variable | 显示变量内容 |
(none) | append-to-buffer | 将区域中内容加入到一个buffer中 |
(none) | prepend-to-buffer | 将区域中内容加入到一个buffer光标前 |
(none) | copy-to-buffer | 区域中内容加入到一个buffer中,删除该buffer原有内容 |
(none) | insert-buffer | 在该位置插入指定的buffer中所有内容 |
(none) | append-to-file | 将区域中内容复制到一个文件中 |
(none) | cua-mode | 启用/停用CUA绑定 |
变量 |
作用 |
---|---|
kill-read-only-ok | 是否在只读文件启用kill 命令 |
kill-ring | kill环 |
kill-ring-max | kill环容量 |
学习Emacs系列教程(七):剪切板
Emacs 在不同的操作系统中表现会有一些小的差异,这里我接着上一章所提到的粘贴复制来比较一下不同操作系统中Emacs的剪切板。
一、复制到剪切板
在Emacs中我们剪切、复制文本除了使用命令之外,还可以利用工具栏上的快捷按钮或者菜单栏里面菜单项,在默认情况使用工具栏和菜单栏进行剪切复制都会把相关内容发送到系统剪切板供其它程序使用。在Windows 和Mac OS X中使用C-w 或M-w也会复制内容到剪切板,不过Linux不行。
我们选择区域的另一种方式是使用鼠标,它也有小小的差别,如下表:
使用鼠标选择区域 | |||
---|---|---|---|
Linux | Windows | Mac OS X | |
是否发送到系统剪切板 | no | yes | yes |
是否发送到Kill环 | yes | yes | yes |
在Linux中想要发送到系统剪切板除了使用鼠标点工具栏还可以利用几个剪切板命令,比如clipboard-kill-region 剪切区域并发送到系统剪切板和Kill 环中,clipboard-kill-ring-save 复制区域内容到系统剪切板和Kill 环中。当然这两个命令Windows 和Mac里面也可以用。本质上这两个命令就是菜单栏中对应的剪切和复制。
二、从剪切板中提取
既然从Emacs到系统剪切板有差异那从剪切板复制到Emacs里面也有些不同,直接看下表:
从系统剪切板粘贴 | |||
---|---|---|---|
Linux | Windows | Max OS X | |
C-y粘贴 | yes | yes | yes |
工具栏粘贴按钮 | yes | yes | no |
菜单栏粘贴菜单项 | yes | yes | no |
鼠标中键 | yes | yes | yes |
M-x clipboard-yank | yes | yes | yes |
这里解释几个地方,一是鼠标中键,有的鼠标没中键就是滑轮了,它也有粘贴功能,而命令clipboard-yank 从剪切板中粘贴对应的是菜单栏上的粘贴功能。
小结:
本章内容很少,就是一些简单的对比,在以后的学习中还能见到更多的不同平台下Emacs的差异。
按键 |
命令 |
作用 |
---|---|---|
clipboard-kill-region | 剪切区域并发送到系统剪切板和Kill 环中 | |
clipboard-kill-ring-save | 复制区域内容到系统剪切板和Kill 环中 | |
clipboard-yank | 从剪切板中粘贴到Emacs中 |
学习Emacs系列教程(八):查找替换
查找替换是任何编辑器都不可能缺少的功能,就连小小的Notepad都有快速查找,更不用说像Emacs这样的庞然大物了。其重要性这里就不多说了,接下来将一步一步给你介绍如何在Emacs中进行查找和替换。
Emacs将查找分成了四个大类,分别是:简单查找,增量查找,词组查找和正则查找。四种方式各有特点,适用范围也不同,大家根据需要熟悉一两种即可。
一、增量查找
先介绍增量查找的原因是这个是用的最多的查找方式,使用也很方便,直接C-s (isearch-forward)便进入增量查找状态,Minibuffer出现如下提示:
其实增量查找很好理解,就是边输入边查找,在输入的过程中离光标最近的匹配会用深色高亮,一屏中其它的匹配字符串会浅色高亮,参见这张图:
只要是单词中包含"to" 的都会标记出来,比如tutorial。在输入查找字符串过程中可以随时用Backspace删除输入字符,当输入完成后按下回车会定位到向前最近的匹配字符串,并出现提示“Mark saved where search started”,就是说将你开始查找时光标所在位置加入了标记环,我们可以通过C-u C-@回到那个点。如果没找到字符串提示为“Failing I-search”,后接查找内容。C-s搜索时是向前进行查找,我们还可以使用C-r (isearch-backward)向后进行查找,注意这种方式的查找光标会定位到匹配字符串的最前方。虽然查找过程只会向一个方向进行,但到了文档底部或者头部还是会回到文档的头或底继续找,这就是常说的循环查找。
在搜索的过程中并不一定第一个匹配项就是我们需要的内容,或者说我们需要找的地方不止一处,这样我们想能够快速的定位到下一个匹配项位置,解决办法也很简单,接上例我们输入"to"后不要急着按回车,而是再用C-s就会向后定位,或者用C-r 向前定位,总之停到你想要的地方为止。另外,如果你退出了这次的查找,后面又想找同一个东西,那么使用C-s C-s 即可,同理C-r C-r 。
Emacs在多次查找的过程中会维护一个查找环(search ring) ,这是我们见到的第三个环了,前面两个是mark ring、kill ring。在输入C-s后,使用M-n和M-p可以调出查找环中上一个和下一个查找的内容。虽然这个也叫环但它是个标准的队列,有头有尾不会循环。
在增量查找中还有些特殊的功能:通常查找时是忽略了大小写的,但如果我们输入的查找内容有小写字母还有小写字母,Emacs会自动进入大小写匹配查找状态中;也可以在查找的过程用M-c 快速切换是否大小写敏感,不过只对此次查找启用;如果我们想找回车符用C-j 代替;还可以使用M-Tab (isearch-complete)对查找进行自动完成,候选项是查找环中的东西,当然你用M-Tab 是没效果的,用了后连Emacs都不在了,我们需要对isearch-complete重新绑定;在增量查找状态中按C-h C-h 会进入增量查找的帮助,里面的内容大家可以自己研究;使用C-w 可以将光标处单词复制到查找区域中进行快速输入,这个功能比较常用;与其类似的是C-y 它能够把光标所在处直到行尾的内容都复制到查找区域,提醒一点这两个命令在复制的过程中会把所有字母变成小写;M-y 还能把kill 环里的内容复制到查找区域;C-M-w 用于删除查找区域中最后一个字符;而C-M-y 把光标处字符复制到查找区域最后;复制光标处的字符还有个方法,进入增量查找状态后,首先按M-e 定位到查找区域的最后,再使用C-f 就可以开始复制了。
二、简单查找
简单查找顾名思义就是简单的查找方式(其实不一定有增量查找来的快),有时候又叫它非增量查找。使用命令是C-s RET string RET ,首先用C-s调出增量查找,然后回车取消掉进入简单查找,再输入需要查找的字符串,最后回车Emacs会向后开始找,直到第一个满足的字符串后面。大家在按命令的过程中可以观察Minibuffer中的提示,按下C-s后,会出现一个蓝色的“I-search:”,回车后变为“Search:”,当找到所输入的内容后出现提示“Mark saved where search started”,其实简单查找和增量查找大部分都没什么区别,增量查找中命令基本上这儿也能用,最大的区别就是等你输入完成后它才开始搜索,还有一点就是没有高亮。向前查找的话一回事,C-r RET string RET 。向后向前分别对应命令search-forward, search-backward。
三、词组查找
词组查找一般用在大段文本编辑中,比如写新闻、写信之类的。它在查找的过程中会忽略掉一些标点符号,比如换行符,逗号,句号之类的,查找时也是进行的增量查找,边输入边找,不过对于单词来说是全词匹配。其命令是M-s w (isearch-forward-word)。查找的示例如下图:
我在找"it"的时候,红框圈出来的permitted并没高亮,而我输入"it under"时,逗号和回车符都忽略掉了,这些特点在查找大段句子的时候相当好用。词组查找也可以使用非增量搜索的方式,对应命令M-s w RET words RET (word-search-forward) ,向回找M-s w C-r RET words RET (word-search-backward),这里面的words就是你需要查找的词组。词组查找其余大部分使用方式和前面的类似就不多叙述了。
四、正则查找
这种查找方式使用正则表达式,功能相当的强大,其主要还是看各人正则表达式的水平了,Emacs中的正则语法放到后面再讲,这里只说下怎么调出正则查找。命令 C-M-s (isearch-forward-regexp),咳,用快捷键的时候把QQ关了,这个是向前找,命令可以看出来使用的是增量查找方式,向后是C-M-r (isearch-backward-regexp)。
五、替换
本次的另一半内容就是介绍Emacs中的替换功能,就是将一个字符串变成另一个字符串。
最简单粗暴的方式就是使用replace-string 这个命令,用法如下:M-x replace-string RET oldstring RET newstring RET,第一次回车输入需要替换的字符串,第二次回车输入想要变成的字符串,最后确认。它将会把所有匹配oldstring 的字符串全部替换掉,建议大家在没绝对把握前还是不要用这个的好。在替换的过程中Emacs对大小写有比较智能化的处理,比如输入M-x replace-string RET abc RET efg RET,所有的"abc"都变成了"efg",但是"ABC"会替换成"EFG",不止这样"aBc"会改为"eFg",大写对大写,小写对小写。当然我们可能不想做这样的变化,那么把变量case-replace 设为nil 即可,还有个相关的变量case-fold-search ,设为nil后,它会在查找的时候就强制匹配大小写。
暴力替换的正则版命令replace-regexp,用法和上面一样,只是oldstring改为正则表达式。
实际上,我们在替换的时候并不希望所有的东西都换掉,还是想中间有个给自己判断选择的过程,在Emacs中称其为查找替换,M-% (query-replace) ,用的时候和前面一样,先输入oldstring,再输newstring,但是它是一个一个找的,对每个找到的匹配询问用户该如何处理,根据你的回答它再做出下个动作。下面这张表列出了所有可能的回答和相应。
输入 | 响应 |
---|---|
SPC 或者 y | 替换当前匹配并前进到下一个匹配处 |
DEL 或者 n | 忽略此次匹配并前进到下一个匹配处 |
. | 替换当前匹配并退出 |
, | 替换当前匹配并停在此处,再按y后前进 |
! | 替换所有剩余匹配 |
^ | 回到前一个匹配处 |
RET 或者 q | 直接退出 |
e | 修改新字符串 |
C-r | 进入递归编辑状态 |
C-w | 删除当前匹配并进入递归编辑状态 |
C-M-c | 退出递归编辑状态,返回查找替换 |
C-] | 退出递归编辑状态,同时退出查找替换 |
C-h | 显示帮助 |
这些命令中,相对y,n,q用的会多点。但如果按了任何其它的键都会退出查找替换状态,不小心退出后还能使用C-x ESC ESC返回。
最后说下什么是递归编辑状态,简单的说就是你在查找替换的过程中突然发现需要修改点东西,但又不想直接退出查找替换,这时Emacs提供了一个临时的编辑状态可以让你先干刚想起的事,等你做完了还可以回到查找替换状态,这个临时的状态就叫递归编辑状态。
注意看,这时mode line中的模式名外面加了一层方括号"[]",标明进入了递归编辑状态。干完事后使用C-M-c 就可以回到前一个状态,实际上,在任何时候都可以用命令 recursive-edit 进入递归编辑,用abort-recursive-edit 或者top-level 退出,也可以用C-M-c 返回前一状态。
小结:
按键 |
命令 |
作用 |
---|---|---|
C-s |
isearch-forward |
向前进行增量查找 |
C-r |
isearch-backward |
向后进行增量查找 |
M-c |
|
(查找状态)切换大写敏感 |
C-j |
newline-and-indent |
(查找状态)输入换行符 |
M-Tab |
isearch-complete | (查找状态)自动匹配 |
C-h C-h |
|
(查找状态)进入查找帮助 |
C-w | (查找状态)将光标处单词复制到查找区域 | |
C-y | (查找状态)将光标处直到行尾内容复制到查找区域 | |
M-y | (查找状态)把kill 环中最后一项复制到查找区域 | |
C-M-w | (查找状态)删除查找区域最后一个字符 | |
C-M-y | (查找状态)将光标处字符复制到查找区域最后 | |
C-f | (查找状态)将光标处字符复制到查找区域最后 | |
C-s RET | search-forward | 向前进行简单查找 |
C-r RET | search-backward | 向后进行简单查找 |
M-s w | isearch-forward-word | 向前进行词组查找 |
M-s w RET | word-search-forward | 向前进行词组查找(非增量方式) |
M-s w C-r RET | word-search-backward | 向后进行词组查找(非增量方式) |
C-M-s | isearch-forward-regexp | 向前进行正则查找 |
C-M-r | isearch-backward-regexp | 向后进行正则查找 |
replace-string | 全文替换 | |
replace-regexp | 全文正则替换 | |
M-% | query-replace | 查找替换 |
recursive-edit | 进入递归编辑 | |
abort-recursive-edit | 退出递归编辑 | |
top-level | 退出递归编辑 |
变量 |
作用 |
---|---|
case-replace | 设置大小写自动替换 |
case-fold-search | 设置大小写匹配查找 |
学习Emacs系列教程(九):缓冲管理
首先提及一点,这里的缓冲就是Emacs中的buffer。闹,所谓的缓冲就是当前你正在编辑的东东。比如,你打开一个文件Emacs会建立一个缓冲来装载这个文件,当你调用帮助时Emacs会建立一个叫"*Help*"的缓冲来显示帮助内容,打开Tutorial则会出现TUTORIAL.cn这个缓冲。本质上来说缓冲就是内存中开辟的一段空闲空间。
每个缓冲都有自己的名字,像上面说的"TUTORIAL.cn" ,或者"*scratch*",这个是Emacs默认建立的缓冲用于调试Lisp表达式,缓冲的名字显示在mode line上。在一个Emacs里面我们可以建立N多个缓冲,但同时只能有一个缓冲处于激活状态,称之为“当前缓冲”,大部分操作命令只会对当前缓冲起作用。
一、操作缓冲
我们可以通过命令 C-x b buffer (switch-to-buffer) 来建立一个缓冲,这里buffer指你对这个缓冲起的名字,如果这个缓冲已经存在则会直接打开它。其实当你输完C-x b 后会出现一个默认的缓冲,就是上一个使用的缓冲,可以用回车直接切换过去。建立了多个缓冲之后使用C-x LEFT 或者 C-x RIGHT 来左右切换,LEFT和RIGHT是左右方向键。还有另外两个建立缓冲的命令,C-x 4 b buffer (switch-to-buffer-other-window) 在另一个window中建立缓冲和C-x 5 b buffer (switch-to-buffer-other-frame) 在另一个frame中建立缓冲,windows和frame的概念将会在下一章中介绍,这里只是告诉大家这两个命令。采用这种方式建立的缓冲一开始里面是一篇空白,并没有与某个文件联系起来,在随便编辑过后可以直接关掉且不会写到磁盘上,当然,除了你想把它存为文件。另一种建立缓冲的方式是,新建或打开一个文件,Emacs会默认建立已这个文件名为名的缓冲,所以这里可以看出文件和缓冲的区别,缓冲不一定是文件,但文件一定对应了一个缓冲。需要注意的一点是,缓冲名不要用空格开头,这种缓冲在Emacs中有其它用途,大家应尽量避免。
显示所有的缓冲使用命令C-x C-b (list-buffers) ,可以看到下面的效果。
最前面有个"."标识的是当前缓冲。在CRM这一栏中,还有些特殊符号,%表示是只读缓冲,*表示缓冲已经被修改过了。剩下四栏根据名字也可以理解了。这个命令加个前缀,C-u C-x C-b 则只会现在映射到文件的缓冲,对于上图就是dde。
在使用Emacs一段时间后可能积累了大量的缓冲,甚至拖慢了程序的速度,这时我们需要关闭一些不用的缓冲,释放点内存。命令C-x k buffer (kill-buffer)就是关闭指定的缓冲,如果这个缓冲对了一个修改过的文件则会出现提示是否直接关闭。一次也可以关掉很多缓冲,使用 kill-some-buffers,这个命令会出现很多提示,然后根据用户确认来关闭,首先会问是否关闭所有未修改过的缓冲,如果回答"no",则会从未修改的到修改过的缓冲一个一个询问是否关闭。如果你三天都没关过Emacs那就试试 clean-buffer-list ,默认帮你关掉三天都未使用过的缓冲。
下面再介绍一些杂项操作:
C-x C-q (toggle-read-only),切换当前缓冲的只读属性。
C-u M-g M-g num ,跳至前一使用缓冲的第num行,这个在写参考文献引用行的时候稍微有用。
rename-buffer,重命名一个缓冲。
rename-uniquely,重命名当前缓冲,直接在其后加一个数字后缀。
view-buffer,只读方式打开一个缓冲,而且什么都不能修改,按q退出view模式。
二、Buffer Menu
上一节说到我们可以使用C-x C-b 来查看所有的缓冲,另外还有个命令可以起到同样的效果buffer-menu,但是这个命令不仅能让你看看现在有哪些缓冲,更重要的是它能对这些缓冲进行各种管理。在使用buffer-menu这个命令后,我们可以看见Emacs的模式名变成了"Buffer Menu",说明现在进入了另一种模式,具体怎么操作这些缓冲详见下表:
按键 | 效果 | 备注 |
---|---|---|
SPC, n | 移动到下一项 | |
p | 移动到上一项 | |
d, k | 标记删除缓冲,并移动到下一项 | 按x后生效 |
C-d | 标记删除缓冲,并移动到上一项 | 按x后生效 |
s | 标记保存缓冲 | 按x后生效 |
x | 执行标记删除或保存的缓冲 | |
u | 取消当前缓冲的标记,并移动到下一项 | |
Backspace | 取消当前缓冲的标记,并移动到上一项 | |
~ | 设置缓冲为未修改 | |
% | 切换缓冲的只读属性 | |
1 | 将选中缓冲满窗口显示 | |
2 | 将选中缓冲显示在一半窗口中 | |
t | 缓冲用tags table 方式显示 | |
f, RET | 显示选择缓冲 | |
o | 缓冲在新窗口显示,并选中该窗口 | |
C-o | 缓冲在新窗口显示,但不选中该窗口 | |
b | 将选中缓冲移动到最后一行 | |
m | 标记缓冲在新窗口显示 | 按v后生效 |
v | 显示标记的缓冲 | |
g | 刷新buffer menu | |
T | 切换显示文件关联缓冲 | |
q | 退出Buffer Menu |
需要注意的是大部分功能是立即生效的,但像d,s,m这些只会起标记作用,在确认之后才会执行,而且按了这三个键后对应会在缓冲名前显示"D", "S", ">" 三个符号用作提示。
三、间接缓冲
间接缓冲是指与其它缓冲共享内容的一种缓冲,它链接在一个基缓冲之上。命令 M-x make-indirect-buffer RET base-buffer RET indirect-buffer 会建立一个叫"indirect-buffer" 的缓冲,它和"base-buffer" 绑定。或者使用 clone-indirect-buffer 来快速复制当前缓冲。间接缓冲和基缓冲之间有一个同步,就是他们的内容是完全一样的,不过也仅仅是内容一样,本质上却是两个完全分离的缓冲。不同于基缓冲,间接缓冲是不能和文件关联的,如果你试图保存一个间接缓冲只会作用到其基缓冲上。另外,由于两种缓冲的关联性,你关闭基缓冲时间接缓冲也会被关闭,而关闭间接缓冲不会有任何事发生。
使用间接缓冲的地方也少,尤其当一篇文章或代码很长,既想编辑页头又想看看页尾,这时间接缓冲是最好的选择。
小结:
按键 |
命令 |
作用 |
---|---|---|
C-x b |
switch-to-buffer | 打开或新建一个缓冲 |
C-x 4 b |
switch-to-buffer-other-window |
在另一个window中打开或新建一个缓冲 |
C-x 5 b |
switch-to-buffer-other-frame |
在另一个frame中打开或新建一个缓冲 |
C-x LEFT |
next-buffer |
移动到下一个缓冲 |
C-x RIGHT |
previous-buffer | 移动到前一个缓冲 |
C-x C-b | list-buffers | 显示所有缓冲 |
C-u C-x C-b | 显示映射到文件的缓冲 | |
C-x k | kill-buffer | 关闭缓冲 |
kill-some-buffers | 关闭多个缓冲 | |
clean-buffer-list | 关闭三天未使用的缓冲 | |
C-x C-q | toggle-read-only | 切换缓冲只读属性 |
C-u M-g M-g num | 跳至前一缓冲num行 | |
rename-buffer | 重命名缓冲 | |
rename-uniquely | 重命名缓冲,在其名后加数字 | |
view-buffer | 只读方式打开缓冲 | |
buffer-menu | 打开Buffer Menu | |
make-indirect-buffer | 建立间接缓冲 | |
clone-indirect-buffer | 建立当前缓冲的间接缓冲 |
首先先明确下Emacs窗口的概念,我们双击Emacs图标打开程序见到的Windows窗口叫做Frame,包含了标题栏,菜单栏,工具栏,最下面的Mode Line和回显区域,而中间一大块显示文本的区域则是Window,实际上每个窗口都有自己的Mode Line。下文中我将称Frame为框,Window为窗口,这里和我们平时理解的Windows窗口有点区别。
在Emacs里面,一个框可以分割出多个窗口,多个窗口可以显示同一个或者不同Buffer,但是一个窗口只能属于一个Frame。一个窗口同时也只能显示一个Buffer,但是同时打开两个窗口也能显示一个Buffer的不同部分,这两个窗口是同步的,就是说如果在一个窗口中对Buffer做了修改,在另一个窗口中可以立即表现出来。但在一个窗口中移动光标之类的操作不会影响另一个窗口。多缓冲中有当前缓冲这个概念,同样对于多窗口也有当前窗口,对于当前选中的窗口其Mode Line相对于其它窗口颜色会深一些。
一、显示窗口
命令C-x 2 (split-window-vertically) 垂直拆分窗口,就是把一个窗口上下等分为两个,拆分出来的窗口默认是显示当前Buffer。可以多次使用这个命令,会把一个窗口不停的两等分。对应也有水平拆分窗口的命令C-x 3 (split-window-horizontally),这两个命令也可以混合使用,如果你屏幕够大画个迷宫出来也不是不可能的。拆分命令还可以加参数,比如M-5 C-x 2就是说上面那个窗口只占5行,其余的位置都给下面的窗口。
C-x o (other-window) 可以在多个窗口中切换,从上到下一个一个的来。使用参数来控制选中下面第几个窗口,想往回选的话参数设为负数。
C-M-v (scroll-other-window),用来滚动下一个窗口。
上一章我们看到有些命令加了C-x 4这个前缀,这一类命令都是用来操作多窗口的。
C-x 4 b bufname (switch-to-buffer-other-window) 在另一个窗口打开缓冲。
C-x 4 C-o bufname (display-buffer) 在另一个窗口打开缓冲,但不选中那个窗口。
C-x 4 f filename (find-file-other-window) 在另一个窗口打开文件。
C-x 4 d directory (dired-other-window) 在另一个窗口打开文件夹。
C-x 4 m (mail-other-window) 在另一个窗口写邮件。
C-x 4 r filename (find-file-read-only-other-window) 在另一个窗口以只读方式打开文件。
这一类的命令默认是垂直拆分窗口。
二、重排窗口
窗口排的密密麻麻看上去肯定不舒服,这时使用C-x 0 (delete-window) 来关闭当前窗口,需要注意的是窗口和缓冲是两个概念,关闭一个窗口对缓冲,或者我们正在编辑的文件没有任何影响。也可以使用C-x 1 (delete-other-windows) 关闭其它所有窗口。如果想连窗口打开的缓冲一并关掉使用C-x 4 0 (kill-buffer-and-window)。
我们还可以对窗口的大小做些改变:C-x ^ (enlarge-window)让窗口变得高点,C-x { (shrink-window-horizontally) 这个是把窗口变窄,变宽的话是C-x } (enlarge-window-horizontally) ,C-x - (shrink-window-if-larger-than-buffer)这个看字面意思就能理解,如果窗口比缓冲大就缩小点,C-x + (balance-windows)这个命令和前面那个没有任何关系是将所有窗口变得一样高。
最后再说一个在窗口中切换的命令,有时候窗口开的太多自己也记不住顺序,使用C-x o就会很麻烦。有一类命令能让你在上下左右切换当前窗口,M-x windmove-right 就是移到右边那个窗口,对应的"left","up“, "down",向四个方向都能移。
不知不觉写了十章了,虽然慢了点,但还坚持下来了,继续努力!
小结:
按键 |
命令 |
作用 |
---|---|---|
C-x 2 |
split-window-vertically | 垂直拆分窗口 |
C-x 3 |
split-window-horizontally |
水平拆分窗口 |
C-x o |
other-window |
选择下一个窗口 |
C-M-v |
scroll-other-window |
滚动下一个窗口 |
C-x 4 b | switch-to-buffer-other-window | 在另一个窗口打开缓冲 |
C-x 4 C-o | display-buffer | 在另一个窗口打开缓冲,但不选中 |
C-x 4 f | find-file-other-window | 在另一个窗口打开文件 |
C-x 4 d | dired-other-window | 在另一个窗口打开文件夹 |
C-x 4 m | mail-other-window | 在另一个窗口写邮件 |
C-x 4 r | find-file-read-only-other-window | 在另一个窗口以只读方式打开文件 |
C-x 0 | delete-window | 关闭当前窗口 |
C-x 1 | delete-other-windows | 关闭其它窗口 |
C-x 4 0 | kill-buffer-and-window | 关闭当前窗口和缓冲 |
C-x ^ | enlarge-window | 增高当前窗口 |
C-x { | shrink-window-horizontally | 将当前窗口变窄 |
C-x } | enlarge-window-horizontally | 将当前窗口变宽 |
C-x - | shrink-window-if-larger-than-buffer | 如果窗口比缓冲大就缩小 |
C-x + | balance-windows | 所有窗口一样高 |
windmove-right | 切换到右边的窗口(类似:up, down, left) |
转自:http://www.cnblogs.com/robertzml/archive/2010/03/31/1701374.html#2468580