
| 让 Emacs 为您工作,第 1 部分 | |||||||||||
| 摘自: IBM developerWorks China 被阅读次数: 82 | |||||||||||
由 yangyi 于 2008-04-14 22:22:08 提供 | |||||||||||
2008 年 2 月 18 日 这是一篇介绍如何定制和修改 Emacs 以提高文本编辑效率的介绍文章。文中通过作者个人的 Emacs 使用经验,抛砖引玉,提供给大家一些提高工作效率,降低工作强度的经验和途径
今天我们讨论的是一个 下面就让我们通过一些简单的实例,来与大家共同体验 前段时间 我来举这样一个例子。这是我们每天最常进行的操作——拷贝和粘贴。准确地说,应该是 拷贝 。粘贴很简单,我们大家都会喜欢做。尤其是在 但是说到拷贝,那可就是另一回事情了。也许你还没有注意到,每一个拷贝操作总要伴随着一个非常繁琐的准备工作,那就是你必须选中,或者说标记出所有要拷贝的内容。而且是每一次,每一次,精确地,标记出来。这个就是我所认为的,既没有技术含量,又很繁琐,每天不断重复,又脏又累的,文本编辑当中的“脏活”“累活”。标记工作完成之后, 那么为什么我们不能够摆脱这些繁琐的工作呢?为什么我们不能端着一杯香浓的乌龙茶,为什么我们的编辑器不能够替我们去操心这些事情呢?计算机技术发展这么多年了,为什么拷贝不能够变得像粘贴一样的充满乐趣呢? 问得好!事实上,
这段代码定义了三个 接下来我们就可以试试看,看看这些代码究竟效果如何。请你打开一篇文档。为了方便起见,我们就用上面这篇代码作为测试文档。 现在我们要尝试拷贝
为了验证刚刚完成的拷贝工作,你可以在编辑缓冲区的任何地方,按下 Ctrl-y 组合键,将刚刚拷贝出来的 "Save current line into Kill-Ring without mark the line " 重新粘贴回去。 下面我们尝试拷贝单词。首先将你的光标移动到刚才那个文本行当中的 without 这个单词上面。你可以采用输入 ESC-b 组合键的方法,或者使用任何你喜欢的方法。按下 ESC-x 组合键,在提示缓冲区里面输入 copy-word 命令,相信我,你已经成功地,不多不少地,正好将 without 这个单词拷贝到了 Emacs 的 kill-ring 当中去了。同样的,你可以使用 Ctrl-y 组合键来验证它。
最后一步,我们就要尝试激动人心的整段拷贝操作了。调节一下呼吸。选择一种你喜欢的方式,移动光标到“Copy words at point into kill-ring”这一行。小心翼翼的按下 ESC-x 组合键,再提示缓冲区当中输入 copy-paragraph 命令。
现在先不要松劲儿。赶紧移动你的光标,找到一片空白的编辑缓冲区。输入 Ctrl-y。一个完整的代码段落就在你的光标位置出现了。那就是你刚刚拷贝的那个段落。
是不是可以开香槟庆祝了?事实上,精彩的地方还远不止这些。正如你所想象的,这里所有的三个函数统统都支持 Emacs 功能强大的 Ctrl-u 命令前缀。你只需在输入命令之前首先按下 Ctrl-u 组合键,然后输入一个数字,例如 4,然后输入 copy-line,copy-word 或者 copy-paragraph 命令,你就可以任意拷贝你所希望的数量的行,单词和段落。 这不是魔术。这只是在 Emacs 带给我们的一小部分快乐。下面我们就来探索一下这些“神奇”的事情究竟是怎么实现的。事实上非常简单,这里的每一个函数都只有 6 行代码。这些代码都可以用自然语言的方式来阅读和理解。那么如果我们希望能够更进一步的了解这些代码里面的细节,又该怎么样呢?大家一定还记得我曾经提到过,Emacs 的设计是非常人性化的。其中的一个人性化的细节就是 Emacs 自身就携带了丰富的文档。我们只需要按下 ESC-x 组合键,在提示缓冲区输入 describe-function 命令,然后在 Describe function: 提示符后面输入想要了解的函数名称。例如 interactive
然后就可以在屏幕的下方看到一个帮助缓冲区,缓冲区里的内容就是对 interactive 函数的具体描述。
同时,我们也可以使用 Ctrl-h f 组合键来调出 describe-function 命令。有兴趣的读者可以使用 describe-function 命令逐一了解这些代码里面的每一个函数。 只有一个需要特别说明的地方,就是 copy-word 函数比其他两个函数多出了一段 if 语句。那么这个 if 语句又是做什么用的呢? 这里面有一个细节问题。在大多数情况之下,没有这段 if 语句,我们的函数也将完美的完成我们希望的任务。但是如果在我们执行操作之前,光标恰好位于一个单词的首字母之上,例如 without 单词的 w 字母之上的时候,就会发生一些意想不到情况了。(backward-word 1) 这条语句所做的操作是将当前光标向后移动到它所遇到的第 1 个单词首字母位置。因为 backward-word 函数并不会理会当前光标位于什么位置,他只是无条件的 向后 寻找满足条件的下一个首字母位置。那么在这个时候,被找到的就会是 Ring 这个单词的 R 字母。那么,copy-word 拷贝出来的就将不再是 without 而是 Ring 这个单词了。这显然不是我们所希望发生的事情。而且更加不幸的是,当我们使用 ESC-b 组合键在 Emacs 当中移动的时候,光标的位置恰恰就是位于每一个单词的首字母位置。显然这不是 Emacs 的问题。这是我们的问题。解决起来也很简单。就是在移动光标之前首先进行一个判断。如果光标当前恰好位于一个单词的首字母之上,我们就无需进行移动,直接执行 point 函数返回光标位置就行了。 事实上同样的问题也会发生在 copy-paragraph 函数的身上。因为 copy-paragraph 函数和 copy-word 函数使用的是相似的移动光标的机制。但是在我的代码里面并没有为 copy-paragraph 函数添加类似的 if 语句。原因是这样的。对于通常包含大量文本的段落来说,光标位置落在段落内部的概率要远大于恰好落在段落开始位置的概率 ( 当然,ESC-{ 组合键会帮你做到这一点。 :-p )。因此我选择不去添加这段 if 语句。这样可以最大限度的保持代码的简单性。有兴趣的读者可以试着自己去添加 copy-paragraph 当中所需要的 if 语句。
在本文当中,我们介绍了一组非常简单的 Emacs 扩展。但是这些扩展虽然简单但却彻底改变了文本编辑器的使用方式。通常情况下,文本编辑器所做的工作就是接受我们的输入,并把这些输入按照指定的样式显示出来。剩下的事情都得由使用者负责考虑。换句话说文本编辑器的工作是非常轻松的。疲惫的是我们这些使用者。所以很多时候我都很希望能和我的文本编辑器互换一下我们的工作。直到有一天我选择不再忍受了。我选择让我的 Emacs 为我工作。我选择让 Emacs 去操心所有的编辑细节而我只需要考虑真正有价值的事情,也就是编辑的内容。有一天我把这个想法告诉了我的 Emacs,你们猜她说什么?
学习
获得产品和技术
讨论
| |||||||||||