学习Emacs系列教程(四:Minibuffer)、(五:编辑 -2)、(六:编辑-3) 、(七:剪切板)、(八:查找替换)

转载 2012年03月23日 13:11:35
 上回介绍了在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 RET insert-default-directory RET后输入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-s regexp 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的变量名。



学习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
是否只使用激活状态标记

 


学习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),将两行合为一行,删除之间的空白和缩进。参见下面两图。

使用M-^之前

 

使用M-^之后
 

 

  这里我们可以看出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-forwardsearch-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
设置大小写匹配查找


相关文章推荐

Common Lisp中的apply和append

append Lisp中的append就是把多个list合并成一个list。如: > (append '(a) '(b) '(c d)) (A B C D) 注意: 1.append后...

emacs 复制和剪切一行

在编码的过程中,经常需要复制和剪切一整行代码,如果用emacs本来的快捷键,复制一行的话,需要C-a C-@ C-e M-w 4步操作才能完成,比较麻烦。 于是,我改造了一下emacs的M-w和...
  • ruglcc
  • ruglcc
  • 2012年08月17日 07:37
  • 8606

学习Emacs系列教程(七):剪切板

Emacs 在不同的操作系统中表现会有一些小的差异,这里我接着上一章所提到的粘贴复制来比较一下不同操作系统中Emacs的剪切板。   m - w  复制 c - w   剪切 c - y...
  • ruglcc
  • ruglcc
  • 2012年08月02日 09:40
  • 992

学习Emacs系列教程(六):编辑(3)

这次介绍编辑中关于粘贴复制的部分,不过在Emacs中称粘贴复制为Killing和Yanking,而不是通常说的Cutting和Pasting,当然差别不会太多。   一、Killing   Ki...
  • ruglcc
  • ruglcc
  • 2012年08月02日 09:39
  • 983

学习Emacs系列教程(五):编辑(2)—— 标记

有段时间没写这个教程了,自己险些放弃,不过回头想想看个小说都讨厌太监,自己写更不能太监,还是要坚持下去。闲话不多说,进入这次的正题,关于编辑文本的另一些内容。 一、标记和区域   所谓区域...
  • ruglcc
  • ruglcc
  • 2012年08月02日 09:32
  • 725

学习Emacs系列教程(四):Minibuffer

上回介绍了在Emacs中如何插入删除文本的简单操作,以及一些杂七杂八的命令,都还是蛮容易的。这回先跳过编辑这部分,介绍Emacs中的Minibuffer,呃,翻译过来叫迷你缓冲,听着比较难受,后面还是...
  • ruglcc
  • ruglcc
  • 2012年08月02日 09:21
  • 901

学习Emacs系列教程(三):编辑(1)

上回说到怎么在Emacs中移动光标,这回将介绍如何在Emacs中编辑文本。 任何一款文本编辑软件的核心功能当然就是编辑文本,Emacs也不例外,虽然它也有许多其它强大的本领,但都离不开文本编辑。闹,...
  • ruglcc
  • ruglcc
  • 2012年08月02日 09:18
  • 899

学习Emacs系列教程(八):查找替换

学习Emacs系列教程(八):查找替换   查找替换是任何编辑器都不可能缺少的功能,就连小小的Notepad都有快速查找,更不用说像Emacs这样的庞然大物了。其重要性这里就不多...
  • alivio
  • alivio
  • 2011年10月23日 14:03
  • 520

让 emacs 在命令行下支持剪切板共享

1、在网上广为流传的一种让emacs和系统剪切板共享的方法是在.emacs文件中加入...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:学习Emacs系列教程(四:Minibuffer)、(五:编辑 -2)、(六:编辑-3) 、(七:剪切板)、(八:查找替换)
举报原因:
原因补充:

(最多只允许输入30个字)