Add New Notes
126
Zim/Utils/emacs/shell-mode/2.txt
Normal file
@@ -0,0 +1,126 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-04T20:39:29+08:00
|
||||
|
||||
|
||||
|
||||
====== 为什么要在 Emacs 里面使用 Shell? ======
|
||||
杨 博华 (dove.young@gmail.com), 软件工程师, IBM
|
||||
杨博华是 IBM 中国软件开发中心的软件测试工程师。负责 IBM Tivoli 软件产品的测试工作。
|
||||
|
||||
简介: Shell 是 Unix 系统管理员生活的一部分。早期的 Shell 直接运行在各种各样的 Terminal 里面,随着时间的推移,我们有了 X Window。大量的 Shell 开始运行 Xterm 里面。对于笔者来说呢,更加喜欢让 Shell 运行在 Emacs 里面。将 Shell 运行在 Emacs 里面与运行在 Xterm 里面到底有什么不同呢?相信我,将 Shell 从 Xterm 里面搬出来绝对不是一个赚取眼球,标新立异的决定。这篇文章介绍了将 Shell 从 Xterm 里面搬到 Emacs 里面带来的各种改变。这篇文章适合 Emacs 的初级与中级用户,需要读者具有一定的 Shell 使用经验。最好具有较长时间的 Shell 使用经历,以更加充分的体会到 Emacs 带来的变化。文章中的内容谨代表作者的个人观点。不代表 IBM 的任何官方观点。所附代码仅在运行于 Cygwin 环境下的 GNU Emacs 当中测试通过。
|
||||
|
||||
|
||||
===== Emacs 编辑环境 =====
|
||||
|
||||
为什么要使用 Shell? 我不也太清楚,但是,在这样一个 Windows 横行的年代里,总是有着无数的 Unix 管理员在遍布全球的各个角落里默默奉献,保证着我们的世界继续运行。那么,为什么要在 Emacs 里面使用 Shell? 在 Emacs 里面使用 Shell 和在其他地方相比,比如说 xterm,甚至是 Windows 的命令行窗口里面使用 Shell 有什么不一样呢?这个问题,我个人认为不是一个技术问题,而是一个**生活舒适度**的问题。之所以选择在 Emacs 里面使用 Shell,就是因为在 Emacs 里面会使你的生活的更加舒适。
|
||||
|
||||
===== 生活舒适度的问题 =====
|
||||
|
||||
信不信由你,人们总是希望生活的更加舒适。那么,把 Shell 搬到 Emacs 环境里究竟能够带来那些生活舒适度的提高呢?在回答这个问题之前,让我们先进行一个简单的热身运动。
|
||||
|
||||
大家都知道,现代的 Bourn Again Shell(bash) 要比古老的 Bourn Shell(sh) 用起来舒服多了。因为 Bourn Again Shell(Bash) 引入了很多非常舒服的新的特性。比如说**历史** (History) 功能,比如说**命令行编辑**功能。这些都是大家非常喜欢的功能。不是吗?但是,问题是,如果你想在 Shell 的世界中生活的更加舒适,就会发现很多时候他都不能真正的让你满意。
|
||||
|
||||
通常来说,但凡有过在古老的 Bourn Shell(sh) 或者某些缺乏历史功能的 Korn Shell(ksh) 环境下的使用经验的人来说,Bourn Again Shell(bash) 的历史 (History) 功能都是一个非常可爱的功能。它提供了很多很好的重复历史命令的有趣方式,我们可以使用 ! 命令去全部或者部分的引用上一条刚刚执行过的命令,我们可以使用 ^^ 命令简单编辑上一条命令并且生成一条新的命令,我们可以也使用向上的箭头键去回朔查找许久以前曾经执行过的命令,然后使用命令行编辑功能随心所欲的编辑这条命令。但是这里面有一个非常隐蔽的问题:所有这一切,都是集中在“**命令行**”这个概念中的。__说白了,各种各样的不同的 Shell 版本提供给我们的就是一个命令解释器,外加一个命令行编辑环境__。
|
||||
|
||||
这样有什么不对吗?对,但是欲望总是没有止境的。为什么不能够**全屏幕编辑**呢?
|
||||
|
||||
让我们来看看一个很简单的例子。我有一个 Omegamon XE for Messaging 的安装。这是 IBM Tivoli 旗下的一款监控产品。通过与 IBM Tivoli Monitor 产品的集成,实现对 WebSphere MQ,WebSphere Message Broker 产品的运行监控,以及对 WebSphere MQ 产品的修改与配置。由于某种需要,现在我需要将一个 MQ Monitoring agent 停止下来。我不想将那个漫长的命令从头到尾输入一遍,因为我知道我可以使用 history | grep ‘itmcmd agent’ 命令从已经存在的命令历史里面找到曾经启动这个 agent 的命令,然后我所要做的,仅仅只是在原来命令的基础上将 start 参数修改为 stop 就可以了。但是……事实上 Shell 并没有给我一个修改这条命令的机会。
|
||||
{{./image001.jpg}}
|
||||
|
||||
图 1
|
||||
|
||||
|
||||
事实上我必须先用鼠标将屏幕上的第 437 条命令复制到剪贴板里面,然后把它粘贴到我的命令提示符后面,之后再使用 bash 的命令行编辑功能,将那个可爱的 start 参数修改为 stop。说实话,我的某些同事每天就是这样做的,另一些则是干脆将停止命令从头到尾再输入一遍。回答我一个问题,你有没有曾经也像我一样,在看到 history | grep 的输出的时候,曾经梦想过,能够直接在第 437 条命令上面改几个字母,然后就直接敲下回车呢?现在你可以了——在 Emacs 里面。在 Emacs 里面,你可以将你的 Shell“扩展”到全屏幕编辑。
|
||||
|
||||
让我们重新查找刚才提到的那条命令。这一次,我们不用 history | grep 的方法。是的,这个方法仍然管用。但是既然是在 Emacs 里面,我希望介绍一些**更加 Emacs 化的使用方法**,我们使用** Ctrl-r** 组合键。如果你已经使用过 Emacs,但是从来还没有在 Emacs 里面看到过 shell 提示符的话,不妨跟我一起来,在 Emacs 当中输入 ESC-x 组合键,然后在提示缓冲区里面输入 shell(全部字母小写)回车,然后你就会在 Emacs 的编辑缓冲区里面看到熟悉的 shell 提示符了。在接下来的例子里面我们假设你已经执行过启动 MQ Monitoring agent 的那条命令了,大约是在 4 个小时前或者别的什么时候。现在要做的,就是把这个特定的 agent 停止下来。跟我一起在 Emacs 里面输入 Ctrl-r 组合键,这个时候你会在提示缓冲区里面看到** I-search backward:** 这样的字样。没错,这个组合键对应的就是 Emacs 当中的**回朔查找**的功能。我们所要做的,就是像通常在一篇文档里面查找一个句子一样,在回朔查找提示符的后面输入 itmcmd agent,Emacs 非常迅速的就把光标定位到了曾经执行过的 bin/itmcmd agent –o QM_106 start mq 这一行命令上面。就在这里,让我们把 start 修改为 stop,然后,直接就在这里按下回车键——修改以后的命令会自动的被复制到正确的 shell 提示符后面并且被执行。无穷无尽的拷贝与粘贴终于被终结了。
|
||||
|
||||
更理想的情况下,如果你想修改的命令还仍然显示在你当前的屏幕范围内(这在我的工作当中覆盖了大多数情况),甚至可以省略使用 Ctrl-r 组合进进行查找的过程,直接移动光标到你需要的命令,修改,或者回车就是了。
|
||||
{{./image002.jpg}}
|
||||
|
||||
图 2
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
===== 技术性击倒 =====
|
||||
|
||||
上面提到的还只是一些很简单的事情。或者说是一些使用习惯方面的事情。每个人都有自己的生活习惯。我就见过一些人,他们甚至很少使用 History 功能。他们执行每一条命令都会从头到尾输入进去。如果中间有什么东西写错了,他们会停下来再输一遍。我只能承认我没有他们那么勤奋了。
|
||||
|
||||
下面我们要谈论一些真正技术性的问题。一个实际工作中的案例问题。我在上面提到过,我的日常工作的一部分就是使用 Omegamon XE for Messaging 产品,既然他是监控 WebSphere MQ 的一款产品,那么同样意味着我也会频繁使用 WebSphere MQ 产品。一天,我需要处理这样一个问题,我有 11 个处于停止状态的队列管理器(Queue Manager),他们全部需要启动起来。
|
||||
{{./image003.jpg}}
|
||||
|
||||
图 3
|
||||
|
||||
|
||||
通常在 shell 环境下,会有两个选择。第一个选择,一条一条的编写 11 条 strmqm 命令,将所有这些队列管理器一个一个地启动起来。第二个选择,我可以使用 **SED** 实用工具编写一些小脚本,利用 dspmq 命令产生的输出内容来生成这 11 条命令,并把它们输出到一个文件里面。是的,在使用 Emacs 之前我是使用这第二种方法的。现在,在 Emacs 里面,我可以使用第三种选择,一种所见即所得的选择。
|
||||
|
||||
Emacs 不仅提供了__全屏幕编辑__的全套功能,而且还提供了超越传统编辑方式的__矩形编辑__功能。使用这个功能,你可以把屏幕上的任何内容__作为一个矩形块进行剪切或粘贴操作__。现在跟我一起,把光标定位到 QM_100 的字母 Q 的位置,并输入** Ctrl-@ **组合键设置起始的标记位。接下来把光标移动到 QM_110 的数字 0 的后面,输入 __Ctrl-x r k __组合键(对,一共是 4 个按键。但是仍然非常容易记忆,只要记住中间的 r 是 rectangle 的缩写就行了,所有的矩形编辑命令都会有这个 r 字母加入)。看看屏幕上面发生了什么?是的,所有的队列管理器的名字全都不见了。他们被作为一个矩形块剪切进了 Emacs 的__删除环(king-ring)__当中。
|
||||
|
||||
{{./image004.jpg}}
|
||||
图 4
|
||||
|
||||
|
||||
接下来,让我们将这些剪切下来的队列管理器的名字粘贴到一个用来启动这些队列管理器的脚本文件中去。在这里我们使用最简单的 **here 文档**的功能 ** cat <<eof >strmqm.sh**,创建一个空白的脚本文件。然后,在 Emacs 当中输入** Ctrl-x r y **组合键,这个组合键的作用是将删除环里面的矩形文本块作为一个矩形,粘贴回去。下面的截图就是你在屏幕上所看到的结果。
|
||||
|
||||
{{./image005.jpg}}
|
||||
图 5
|
||||
|
||||
没错,你注意到了,我们真正需要的并不是队列管理器的名字列表,而是一连串 strmqm QM_100 这样的 shell 命令。没问题,接下来让我们继续使用 Emacs 的矩形编辑功能来完成这些命令。再次把光标移动到 QM_100 的字母 Q 的位置,输入 Ctrl-@ 组合键设置标志,然后移动光标到 QM_110 的字母 Q 的位置,输入__ Ctrl-x r p__ 组合键。这个组合键的作用是在选定的**位置前面填充一个矩形区域**,填充的内容在提示缓冲区里面输入。现在在提示缓冲区里面 string insert rectangle: 的提示符后面输入 strmqm 加空格。下面的截图就是这个时候你在屏幕上所看到的结果。
|
||||
|
||||
{{./image006.jpg}}
|
||||
图 6
|
||||
|
||||
|
||||
这里面有一个小秘密需要提示一下,因为在 here 文档的提示符下事实上是不可能进行这样的修改的。但是,直到目前为止 Emacs **还没有**将编辑缓冲区里的内容传递给 here 文档提示符。以上所做的一切还都仅仅发生在 Emacs 内部。
|
||||
|
||||
现在输入一个回车键,已经编辑好的 11 条 strmqm QM_1xx 命令就已经传递给 here 文档提示符了。最后输入 eof 结束文档编辑。一个简单清晰的队列管理器启动脚本就已经完成了。只要在 shell 提示符下通过 bash strmqm.sh 命令运行它,就可以启动所有这 11 个队列管理器了。
|
||||
{{./image007.jpg}}
|
||||
|
||||
图 7
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
====== 一些有趣的小技巧 ======
|
||||
|
||||
===== 第一个小技巧:在 Emacs 里面同时打开多个 shell 会话 =====
|
||||
|
||||
这听起来应该是理所当然的,既然 Emacs 可以同时运行多个窗口……但是即使是在我买的那本关于 Emacs 的书里面也没有提到如何能够真的打开多个 shell 会话。让我们试试看,输入 ESC-x shell 启动 shell 会话,在 shell 提示符下执行 cd /tmp 命令,然后输入 Ctrl-x 2 组合键将屏幕切分成上下两个窗口,然后再次输入 ESC-x shell 启动 shell 会话,你会发现 Emacs 不为所动。在上下两个窗口里面仍然还是 cd /tmp 命令执行后的结果,也就是说仍然还是原先的那个 shell 会话。说起来 O’reilly 公司应该退还我一部分书钱,因为他们没有将我想知道的问题讲明白。后来我终于发现了解决的办法。只要我将当前的 shell 会话所在的缓冲区重新命名,然后就可以再次启动一个新的 shell 会话。让我们来试试看。输入 ESC-x rename-buffer,在 Rename buffer (to new name): 提示符后输入一个新名字,例如 *shellA*。这个时候你会看到上下两个窗口中的缓冲区都被重命名为 *shellA* 了,是的,他们显示的是同一个缓冲区。现在在任意一个窗口里面输入 ESC-x shell 启动 shell 会话,这时你会看到一个新的 *shell* 缓冲区创建了出来,并且有了一个新的 shell 提示符。现在让我们在这个新的 shell 提示符下执行 cd / 命令,你会发现,缓冲区 *shellA* 当中的 shell 会话并没有受到新的命令的影响,因为他们是两个不同的 shell 会话。重复同样的方法,可以得到更多的 shell 会话,满足你的使用需要。
|
||||
{{./image008.jpg}}
|
||||
|
||||
图 8
|
||||
|
||||
|
||||
===== 第二个小技巧:history | grep 的输出结果可以直接输入回车使用 =====
|
||||
|
||||
让我们再回到当初提到过的第 437 条命令。如果需要再次运行这条命令,你只需要把光标定位到这条命令所在行,**删除掉命令前面的 437 这个号码**,然后直接输入回车,Emacs 会提你把它复制到正确的 shell 提示符后并且启动执行。似乎这个方式描述起来并没有 shell 本身提供的 !437 命令来的迅速,但是他毕竟提供了一个更加直观的操作可能。另外,如果希望在运行之前对于这条命令进行一些修改,我指的是删除,例如删除掉某个参数,或者单词,你也尽可以尽情删除,然后在最终的删除结果上面输入回车,告诉 Emacs 去复制运行就是了。这个状况目前似乎还没有发现 ! 命令有可以搞定的可能。另外,如果希望在运行之前对于这条命令进行一些添加性质的修改,例如添加一些新的参数,或者把第 437 条命令中的 start 单词删掉,添加上 stop 单词,在目前的 Emacs 里面还没有提供直接的支持。但是我们可以通过增加一步操作来实现它。第一步,让我们首先把光标定位到第 437 条命令的位置,然后输入回车,这个时候命令不会成功运行,一行提示信息 bash: 437: command not found 会显示在你的 shell 提示符下面。没关系,让我们稍微修改一下刚刚运行失败的这条命令。重新定位光标到刚刚执行过的这条命令所在的行,然后把命令中的 start 参数修改为 stop 参数,并且删除命令前面的 437 这个号码,再次输入回车,修改之后的命令就会成功运行了。这里增加的第一步操作实际上代替了通常情况下需要的拷贝粘贴操作,拷贝和粘贴事实上是交由 Emacs 替我们实现了。
|
||||
|
||||
{{./image009.jpg}}
|
||||
图 9
|
||||
|
||||
|
||||
===== 第三个小技巧,整理你的屏幕 =====
|
||||
|
||||
在前面讲到生活舒适度话题的时候,我们曾经提到过在 Emacs 里面使用 shell 的一个很常用的方法就是**在屏幕上已有的命令上面稍作修改,或者直接回车来复用已经执行过的历史命令**。但是如果你所感兴趣的命令因为种种原因已经不在当前屏幕显示的范围之内了,除了不断的通过使用 Ctrl-r 组合键进行回朔查找以外,还有没有什么更方便的办法呢?答案是有,而且还有不止一种选择。如果在你的当前提示符和你感兴趣的命令之间仅仅只是由于时间的关系隔着太多无关的命令记录,那么你尽可以简单的将这些多余的内容删除掉就行了。不要担心,这些内容仅仅只是在 *shell* 编辑缓冲区里的普通文本内容而已,将他们删除和将一篇文档里面的文本删除没有什么区别。如果这些中间的命令记录并不是完全无用了,仅仅只是在现在这段时间不感兴趣的话,你还可以选择使用__ hide-region-hide __命令将这些中间的命令记录作为一个文本块隐藏起来。这些隐藏起来的内容仅仅只是不再在屏幕上显示而已,他们仍然存留在原有的编辑缓冲区里面,以后当你再次需要他们的时候,可是使用 __hide-region-unhide __命令再把他们重新显示出来。还有一种情况就是仅仅因为你刚刚执行了一个产生大量输出的命令而已,比如说使用 cat 命令书出了一个较大的日志文件,从而导致你感兴趣的历史命令被日志文件的内容冲出了当前屏幕显示范围,这个时候只需要输入 __Ctrl-c Ctrl-o__ 组合键,将刚刚执行过的那条命令的屏幕输出清除掉就是了。通常我在每次 cat 日志文件或者列出一个含有较多文件的目录之后都会使用 Ctrl-c Ctrl-o 组合键来清理一下我的屏幕。
|
||||
|
||||
===== 最后我们再来说一个非常有用的小技巧,使用缩写词 =====
|
||||
|
||||
Emacs 的强大的缩写词(abbrev)功能,这些缩写词功能同样可以应用到 Emacs 当中的 shell 环境里来。通常在使用 Emacs 便写文章的时候,我们会使用缩写词功能来减少频繁输入冗长的单词或者语句时候的击键次数,或者使用缩写词功能避免一些可能的拼写错误。当我们在 Emacs 里面使用 shell 的时候,我们同样可以使用缩写词功能来缩写一些冗长的命令,路径,和避免一些常见的输入错误,这样在每天的工作当中会为我节省大量的击键次数。有些读者看到这里一定会想到 shell 本身提供的别名(Alias)功能也能完成命令的缩写,但是,别名功能有很多局限性。首先,**别名功能缩写的命令只能通过别名单独引用,无法和其他 shell 命令一同组合运行**。例如我可以定义一个别名来进入常用的 IBM Tivoli Monitoring 产品的安装目录,alias cditm=’cd /opt/IBM/ITM’, 然后输入 cditm 执行这条命令来进入 IBM Tivoli Monitoring 产品的安装目录。但是我不能够定义一个别名来缩写这个目录本身,alias itmm=’/opt/IBM/ITM’, 然后输入 cd itmm 执行这条命令来进入这个目录,或者输入 itmm/bin/cinfo –r 来直接引用该目录下的可执行文件。还有一个问题,**通过别名定义的命令缩写只能够直接引用执行**,**没有可能对于很多相似的命令定义通用的一个“别名模板”**,然后每次使用的时候引用模板,然后稍作修改之后运行。例如启动 Omegamon XE for Messaging 产品中的 MQ Monitoring agent 的常用命令,bin/itmcmd agent –o QM_101 start mq。我可以把它定义为一个别名,alias strkmq_QM101=’bin/itmcmd agent –o QM_101 start mq’, 但是事实上每次在启动一个 MQ Monitoring Agent 的时候,其中的队列管理器(Queue Manager)的名称都是不同的,我不可能为每一个队列管理器都定义一个单独的别名。况且还有其他的 agent,这样的话别名的数量将会相当可观。
|
||||
|
||||
Emacs 的缩写词功能在这里提供了两步走的设计方法,避免了以上提到的所有问题。让我们还是以上面提到的目录和命令的两个例子来了解一下在 Emacs 里面如何使用缩写词功能来解决这些问题。首先是常用目录的缩写词定义。在 shell 提示符下输入 cd /opt/IBM/ITM 命令,不用专门为了缩写词去输入这条命令,就在你日常工作当中需要的时候输入就是了,只是记得先不要输入回车,然后,让我们数一数究竟有多少个单词将被包含在这个缩写词定义当中,在这里是 3 个单词,分别是 opt, IBM 和 ITM,现在输入__ Ctrl-u 3 Ctrl-x a l __组合键,稍微有点儿复杂,我在这里简单解释一下,Ctrl-u 在 Emacs 里面是一个非常有用的组合键,它代表一个通用前缀,通常在后面跟一个数字参数,表示随后输入的命令将被重复多少单元,在这个例子里是 3 个单元,后面的 Ctrl-x a l 组合键代表在当前主模式下添加缩写词定义(__add-mode-abbrev__)命令,其中的 l 代表将该缩写词的定义添加到当前的主模式中,如果希望这个缩写词定义在任何主模式下都可以使用,那么将组合键中的 l 替换成 g,即 Ctrl-x a g, 代表 __add-global-abbrev__ 命令。然后,在提示缓冲区确认定义无误之后,输入希望的缩写单词,itmm,即可完成缩写词定义。
|
||||
{{./image010.jpg}}
|
||||
|
||||
图 10
|
||||
|
||||
|
||||
接下来我们来使用这个缩写词。例如我们需要进入到 IBM Tivoli Monitoring 产品的安装目录,在 shell 提示符下输入__ cd /itmm__ 加空格,你会发现 Emacs 立刻将这条命令扩展成为 cd /opt/IBM/ITM 显示在刚才的输入位置。现在我们要执行 IBM Tivoli Monitoring 产品目录下的 cinfo 可执行程序,在 shell 提示符下输入 /itmm 加空格,Emacs 立刻将这条命令扩展成为 /opt/IBM/ITM 显示在刚才的输入位置,然后我们只需要输入一个退格键删掉刚才那个空格,继续在后面输入 bin/cinfo –r 就可以了。事实上由于在我的工作当中 , 对于 cinfo 命令来说,-r 这个参数非常常用,所以在我的 Emacs 里,bin/cinfo –r 已经被缩写成了 rcinfo 这个缩写词了。那么在我的 Emacs 里面我只需要输入 /itmm 空格键,退格键和 rcinfo 就可以实现完整的 /opt/IBM/ITM/bin/cinfo –r 这条命令了。
|
||||
|
||||
再下来我们来看看启动 MQ Monitoring Agent 的命令的缩写词。在 shell 提示符下输入 bin/itmcmd agent –o start mq 命令,注意,在–o 参数后面没有提供队列管理器的名字。因为每次执行这条命令的时候,队列管理器的名字都有可能变化,因此我们不把它定义到缩写词内部。输入 __Ctrl-u 6 Ctrl-x a l __组合键,然后,在提示缓冲区确认定义无误之后,输入希望的缩写单词,strkmq 即可完成缩写词定义。(在进行光标移动时字是由数字和字母组成的,其它的符号都被视为空格)
|
||||
{{./image011.jpg}}
|
||||
|
||||
图 11
|
||||
|
||||
现在让我们来使用这个缩写词。首先我们需要使用 itmm 这个缩写词进入到 IBM Tivoli Monitoring 产品的安装目录,然后,在 shell 提示符后面输入 strkmq 空格,Emacs 立刻将这条命令扩展成为 bin/itmcmd agent –o start mq 显示在刚才的输入位置,现在移动光标到–o 参数后面,输入队列管理器的名称并且回车,你就会看到希望的命令得到运行。
|
||||
|
||||
发明一个完美无缺的 shell 是一件相当困难的事情,但是将现有的资源整合起来却会产生很多意想不到的效果。这个世界已经有了很多现成的科技资源,如果我们在这些资源上面进行创新,整合,不仅很多问题都可能迎刃而解,而且还可以为我们自己再节省一些喝茶和咖啡的时间
|
||||
BIN
Zim/Utils/emacs/shell-mode/2/image001.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image002.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image003.jpg
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image004.jpg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image005.jpg
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image006.jpg
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image007.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image008.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image009.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image010.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
Zim/Utils/emacs/shell-mode/2/image011.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
195
Zim/Utils/emacs/shell-mode/plan.txt
Normal file
@@ -0,0 +1,195 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2011-04-16T18:38:37+08:00
|
||||
|
||||
====== plan ======
|
||||
Created Saturday 16 April 2011
|
||||
计划你的人生
|
||||
rokia
|
||||
|
||||
计划你的人生 by John Wiegley (译注:这是一篇关于Emacs扩展 Planner包的说明文件,被誉为最有哲理的说明文件之一) 什么是计划?这个很难准确定义。不过,本质上,很简单,计划就是如何实现我 们的梦想。 我们的每一天都是由时间也可以说是活动组成,不论是思想上还是体力上的。但 是,活动分为两种:被动性的和创造性的。 被动性活动是对环境和刺激的反应。 只要我们有足够的生存本能,我们就可以只依靠这种活动一直生活下去。这是我 们跟其它的生物共有的行为方式。 与被动反应相对应的是创造力,当我们决定采取一组行动时,这完全是个人选择 的结果。 然后我们决定实现这些活动所需要的步骤。 这就是计划。 计划本质上 就是在每一步骤上采取的创造性的努力。 首先,产生一个想法,你想达成什么。 非常短期的想法不需要过多的去.....
|
||||
计划你的人生
|
||||
by John Wiegley
|
||||
(译注:这是一篇关于Emacs扩展 Planner包的说明文件,被誉为最有哲理的说明文件之一)
|
||||
|
||||
什么是计划?这个很难准确定义。不过,本质上,很简单,计划就是如何实现我
|
||||
们的梦想。
|
||||
|
||||
我们的每一天都是由时间也可以说是活动组成,不论是思想上还是体力上的。但
|
||||
是,活动分为两种:被动性的和创造性的。 被动性活动是对环境和刺激的反应。
|
||||
只要我们有足够的生存本能,我们就可以只依靠这种活动一直生活下去。这是我
|
||||
们跟其它的生物共有的行为方式。
|
||||
|
||||
与被动反应相对应的是创造力,当我们决定采取一组行动时,这完全是个人选择
|
||||
的结果。 然后我们决定实现这些活动所需要的步骤。 这就是计划。 计划本质上
|
||||
就是在每一步骤上采取的创造性的努力。
|
||||
|
||||
首先,产生一个想法,你想达成什么。 非常短期的想法不需要过多的去思考如
|
||||
何去做。 但是长期目标就需要计划,因为你的大脑无法容纳所有的细节。
|
||||
|
||||
其次,决定这些想法如何反应在你所处的环境之中。 有些环境因素可以帮助你达
|
||||
成梦想,而还有一些会成为你的障碍。 但是,一步步来,找出每一个阻碍你实现
|
||||
梦想的障碍,然后想办法去克服他们。 一旦你把所有的未知的事情从头到尾尽
|
||||
你最大努力找到相应方案,你就已经拥有的你的计划了。
|
||||
|
||||
第三步,把你的计划按照阶段分成不同的部分,以降低它们的复杂度。 在这个
|
||||
过程中,你的计划会变成多个任务项,每一项会在一天的时间跨度内完成。 如
|
||||
果一个任务需要多天完成,就把它们进一步的细分。 任务越小,你就越不会害
|
||||
怕去完成它。
|
||||
|
||||
第四是在你执行的过程中监控你的进度,找出问题并解决它们。有些计划看似永
|
||||
远无法达成,只是因为少了一些监督。 如果事情毫无进展,那么就改变它。 否
|
||||
则,你的计划只是一个美好的愿望。
|
||||
|
||||
第五,耐心的去完成你的工作。 所有好的计划都需要花费大量的时间,不可能
|
||||
一蹴而就。 基础工作必须一步步坚实的完成,否则你的计划的地基就会非常不
|
||||
可靠。 如果你能顽强的每天,每星期都按照你的计划前进,那么他就会实现。
|
||||
记住龟兔赛跑的故事。 我还写了另外一篇关于持续进步的必要性的文章 ,你可
|
||||
以在这里找到:http://emacswiki.org/johnw/essays/node2.html
|
||||
|
||||
|
||||
那么这个软件(planner)能做什么呢? 计算机是理想的管理信息的工具,它们让
|
||||
你可以轻松的修改而不需要擦除或重写。 既然计划需要经常的改动,一个计划工
|
||||
具此时非常有用。
|
||||
|
||||
在你的.emacs(或 _emacs)文件中加入这句话:
|
||||
|
||||
(load "planner")
|
||||
|
||||
现在,构思你的梦想。 我不相信你在人生中没有任何想要的东西。 世界和平?
|
||||
有足够的时间享受这个世界?结束战争? 每个人都有自己需要的东西。 仔细的
|
||||
寻找,你会找到无数的隐藏的你未曾注意过的梦想。 现在就选择其中的一个,并且
|
||||
开始认真的考虑它。
|
||||
|
||||
然后在'planner-directory'变量指定的目录中打开一个文件(用'C-x C-f').
|
||||
Emacs 会自动的把这个文件识别为一个计划文件。 给你的计划想个名字,例如
|
||||
叫'BetterHealth'。
|
||||
|
||||
|
||||
选择一个你确实想达成的梦想。 要努力区分那些由于别人的原因你才想要的和你
|
||||
自己真实想要的。 这个需要很大的努力,可能需要很长时间你才能注意到其中的
|
||||
区别。很多人想要更健康,以便更有魅力,而这就是个外部的驱动力。 除非梦想
|
||||
_的的确确_是你想要的目标,否则你就可能失败。 只有我们自己的梦想才会让我
|
||||
们投入足够的精力去把它实现。 对我们中的大多数人来说经常发生的一件事是我
|
||||
们从没有搞清楚:什么是我们所爱的,什么是我们最想要的。 当我跟朋友们聊天
|
||||
的时候,经常听到的是他们想要某样东西,而原因仅仅是他们觉得他们应该想要
|
||||
。 我们经常没有足够的动力去赶上计划,因为几乎绝大部分的动力都是负面的。
|
||||
|
||||
你知道什么是你真正想要的吗? 别担心,很多人都不知道。 (It's not a question
|
||||
anyone really wants us to pursue, because often we don't want what others
|
||||
do; it doesn't contribute to the social welfare,and all that nonsense.)
|
||||
问题不在于别人要我们去做,因为我们经常不希望别人去做,它不能增加社会财富,它很无
|
||||
聊。(译注:实在不知道咋翻) 但是我们不应该忘记,许多对当今社会产生好处
|
||||
的东西在很多年前只是某人一个疯狂的梦想。 害怕改变总是人们最大的敌人,所
|
||||
以不要再浪费时间让它变的可怕。
|
||||
|
||||
为了举例,我假设你想变得更健康是因为你非常喜欢纯净,或者你理解了你的肉
|
||||
体和你周围世界的关系,你知道这样可以敞开你的心灵以得到更多。 我只是假设
|
||||
:)
|
||||
|
||||
那么你现在已经打开一个文件,名字叫'BetterHealth'。 开始输入。 输入任何
|
||||
跟你梦想有关的东西:你是如何考虑的,你的想法,特别是最终你的想法会变成
|
||||
什么样。 如果你无法想象出最终的结果,你就无法计划,因为计划就是从现在到
|
||||
未来画出一条线。
|
||||
|
||||
当你输入了足够多的信息,并且得到一个关于你的目标的蓝图,就开始起草可能
|
||||
的中间步骤。 然后停下来,站起身,四处走走,享受一下你的生活,然后再回来
|
||||
。 在开始的时候多花点时间是个不错的主意,只要不是永远处在开始阶段。
|
||||
|
||||
当你对你的梦想深思熟虑的时候,它就会变得越来越清晰。 你会对其中最大和最
|
||||
小的部分都有了一些概念。 这样一直到你的梦想在你的面前呈现,在你脑海中你
|
||||
看到你一步步从现在走到将来。 把中间的过程写下来,包括所有你一路上可能遇
|
||||
到的问题。
|
||||
|
||||
在这个过程中,你会很自然的发现一些清晰的阶段,有些经理人很喜欢叫它们里
|
||||
程碑。 这些非常重要,因为它们让你知道你在前进。 我建议每次你达到一个里
|
||||
程碑,就去和朋友们搞一个大的聚会。 通常一个计划会包括三到十个里程碑。
|
||||
|
||||
各个里程碑之间是你计划中比较大的分段。 用混合大小写(CamelCase)的方式给
|
||||
他们命名,你会发现Emacs会在这些名字加上颜色和下划线。 例如:FindGoodGym.
|
||||
在这个高亮的词上面敲回车,你会打开另外一个空文件。在这个文件里,起草你
|
||||
的子计划,就象你刚才做更大的计划那样。 你会发现现在计划变得更容易了,
|
||||
因为范围变小了。
|
||||
|
||||
继续分下去,你会注意到有一些很小的事情需要你完成,这些就是你的任务。每
|
||||
一个计划都是一连串的任务。 任务和被动性活动的区别就是,所有的任务都是属
|
||||
于一个更大的计划的一部分。 这样就成为一个系统化的过程:你做的每一件事都
|
||||
引导着你进一步完成你的计划。 如果在你的任务中有些事情没有属于任何计划,
|
||||
那它就是一个被动性的活动。 当然,人生中充满了这些活动,但是,不要让它们
|
||||
占据你一天时间的20%。 如果你的生活被这些被动性任务所占领,那么在你生命
|
||||
最后的时间里你会后悔莫及。 I don't know this personally(译注:咋翻?)
|
||||
,但是我知道为理想而努力并看到梦想成真是一个人能够拥有的最大的快乐。 这
|
||||
是自由,生存和创造的精髓所在。 被动性活动正相反,它只会榨干我们的精力,
|
||||
懈怠我们的灵魂。
|
||||
|
||||
现在你已经想到了一个简单的任务,敲 'C-c C-t'。 Emacs会提示你为这个任务
|
||||
输入一个简短的说明 ,还有准备要开始做这个任务的时间。 如果你在填开始
|
||||
时间的时候直接敲回车,就表示是今天。 Emacs会弹出一个3个月的日历让你来选
|
||||
择,你可以看到哪天你比较有空。 你要保证你在.emacs(_emacs)里把变量
|
||||
'mark-diary-entries-in-calendar' 的值设置成了t。 这样,你可以看到你在哪
|
||||
天里有安排。
|
||||
|
||||
(setq mark-diary-entries-in-calendar t)
|
||||
|
||||
添加好你的第一个任务之后,回到你的计划页中继续添加其它的任务。 基本上,
|
||||
这就是所有的操作了。全面的描述所有必要的细节会帮助你完成你的子计划。 不
|
||||
要为其它的子计划创建任务。 你可能感觉你有很好的想法,但是不要现在去描述
|
||||
它们。 事情一直在变化,所以要善用你的时间。
|
||||
|
||||
现在你已经为达到第一个里程碑而描述清楚你的所有任务了吗?太棒了! 这就是
|
||||
planner.el 所要达到的目的。 而其它的就看你了。 如果你发现你经常在拖延任
|
||||
务,甚至从不去执行,那么这是一个非常明显的信号,你计划的是别人的梦想,
|
||||
而不是你自己的。
|
||||
|
||||
下面是planner.el可以做的一些事情,帮你管理跟踪你的任务:
|
||||
|
||||
在每一天开始的时候,敲'M-x plan'。 会列出一个到今天为止最近的任务列表
|
||||
。 如果你想跳到其它天,你需要自己去打开那些文件。
|
||||
|
||||
如果有些任务无法按时完成,没关系。 学会正确的估计时间是一个神奇而又神秘
|
||||
的艺术,很少有人能非常精通。 移动你的光标到未完成的任务,敲'C-c C-c'。
|
||||
这样可以把这个任务移动到今天的任务页中。 任何时候你都可以敲'C-c C-n'以
|
||||
跳到今天的任务页(在Wiki或者planning页中)。我真诚的建议你把它绑定到'C-c
|
||||
C-n',让你在任何地方都可以跳到今天的任务页中:
|
||||
|
||||
(define-key mode-specific-map [?n] 'planner-goto-today)
|
||||
|
||||
每天打开你的任务页时所要做的第一件事是对其中的一项'clock in'(开始计时)
|
||||
。 这不是必要的,而且只有你一直在电脑旁边才有用。 敲'C-c C-i'(假设你在
|
||||
load-path中已经包括了'timeclock.el'),会记录你花在你的子计划上的时间。
|
||||
这个对观察你的进度非常有用。 敲'C-c C-o'可以'clock out'(结束计时)。
|
||||
|
||||
'C-M-p' 和 'C-M-n' 可以调高和调低任务的优先级。 优先级用A-C的一个字母
|
||||
来表示。 'A'级任务意味着你当天必须完成它,否则你的计划就会泡汤而你必须
|
||||
重新计划。 'B'意味着你应该在当天完成它以推进你的计划,否则事情就会被推
|
||||
迟。 'C'意味着如果有必要的话你可以推迟它,虽然最终它还是需要完成。
|
||||
|
||||
对于被动性任务,这个字母的含意有所不同:'A'意味着你必须当天做完,否则有
|
||||
人就会把你烤了吃。 'B'意味着你需要当天完成,否则有人在当天结束的时候会
|
||||
很难受。 而'C'意味着如果你没有完成这个任务,没有人会注意到它。
|
||||
|
||||
重申一次,被动性任务是计划的大敌。 事实上,如果你认识不到这个问题,那么
|
||||
你就会被周遭的问题搞的团团转,而你的人生也不再属于你。 我们总共只有这么
|
||||
几十年可以用,而每个人都想贪婪的把它拿走。 这个问题很隐蔽,你甚至看不见
|
||||
它。 对被动性活动的正常的厌恶会让你能更好的按照事物本身真正的优先级来安
|
||||
排任务。
|
||||
|
||||
最后一个需要注意的词是‘角色’。 每个人在生活中都有不同的位置:丈夫,
|
||||
员工,经理等等。 这些角色为了保持自己的正常运作会产生一些毫无关联的任
|
||||
务。 我的建议是尽可能的减少任务的数量,以便让他们保持良好的状态。 如
|
||||
何安排你的时间完全是个个人问题,无论你是想实现你的远大目标,还是想维系
|
||||
非常好的人际关系。 如果你能做出正确选择,那么这些不同的任务之间会相得
|
||||
益彰。
|
||||
|
||||
我提到这一点是想说并非所有没有一个固定计划的活动都是被动性活动,例如作
|
||||
为一个父亲,很少会遵循一个有着严格时间顺序的计划。但是父亲这个角色有它
|
||||
自己的计划,它的目标是尽力做到自己的最好,它的任务是花时间解决随时可能
|
||||
发生的问题。 某种意义上说,这是一个隐性的计划。 但是被动性活动根本没
|
||||
有任何计划,它们是时间的寄生虫,随时在侵蚀你的精神,而正确的选择你的角
|
||||
色确实可以帮助你完成你的走在需要。 至少,我是这么认为的。
|
||||
|
||||
(这是一个Planner的截图)
|
||||
|
||||
|
||||
plannergr6.png
|
||||
|
||||