Emacs命令

Emacs启动:
直接打emacs,如果有X-windows就会开视窗.如果不想用X的版本,
就用emacs-nw(Nowindows)起动.
符号说明
C-X表示按住CTRL键,然後按X,再把CTRL,X一起放开.
M-XMETAMETA

在没有META键的电脑上,M-X等於先按ESC键,接著按X键.
Sun上面META键就是菱形的那个键.
有些系统META键就是ALT键.(或者某一边的ALT键)

C-X或M-X的X没有大小写分别.
Emacs按键命令基本上是一串C-<chr>;和M-<chr>;组成的.
超过两个以上的按键命令,Emacs会在萤幕最下面一行显示你按过什麽.
这一行叫作minibuffer

结束Emacs按C-xC-c

取消执行C-g
有些Emacs命令会跑很久,可以用C-g中断之.按错键也可以按C-g取消.

上下移动C-p向上(previousline)C-n向下(nextline)
左右移动C-f向右(forward)C-b向左(backward)

其实Emacs内部没有行的概念,把一篇文章放在一个大buffer
里面,所以C-f(forward)就是向档尾移动,C-b(backward)
是移回去的意思,一次一个字.

翻页下一页C-v(viewnextscreen)
上一页M-v

翻页时,上一末尾会留一点在萤幕最上面,以维持连续性.

Emacs在游标接近萤幕最下方时会自动跳半页,把档案往前挪一点,
方便阅读.

重画萤幕C-L

Emacs里面游标的专有名词叫point.point==游标目前的点

游标一次跳一个字(word)M-f往後跳M-b

注意C-f与M-f,C-b与M-b的对称性.

移到行头C-a行尾C-e
移到句首M-a到句尾M-e
(M-a到上一个句点後面,一个句子的起头.
M-e到句点後面)

移到档头M-<档尾M->;

删除游标目前指的/後面的字C-d
前面的字DEL(Delete键)
DEL的正名叫Rubout(Rubout)

M-DEL往回删一个字(word)
M-d往前删(游标後面)
C-k删至行尾(kill)
M-k删到一句子结尾(删到句点)(kill)


注意Backspace=C-h在Emacs下是help的意思
後面有(kill)的,表示此删除的动作是kill,不太等於delete.
emacs会把kill掉的东西放到killring去,算是一种暂存的地方,
以後可以叫出来.见yank说明.


Undo:C-xu
C-_等於C-xu有些DEC终端机,C-/就是C-_
有时等於C-Shift--

重复执行

举例,向右移8个字,C-u8C-f
C-u在Emacs里是蛮特别的,用来设定一些引数(argument/repeatcount)
给其後的命令.

C-u20C-n向下移20行

有一个特别的例外,C-u3C-v不是翻三页,而是整个萤幕向上移三行.
据说这比较有意义.

C-u10C-xuUNDO10次

给C-L一个引数会怎麽样:
C-u0C-l会重画萤幕,并且把目前的行移到萤幕第一行.

另外,C-u100等於M-100
C-u数字等於M-数字

Xwindows下,
C-leftC-right一次移一个字(word).
C-upC-down移动一段(paragraphs/C语言的话是block)
Home=C-a
End=C-e
C-Home=M-<
C-end=M->;
PgUpPgDn=M-vC-v
设定重覆次数更加简单,
比如要向右移10个字C-1C-0right-arrow
就是按住CTRL,然後打10就对了,比C-u10简单.

Mouse中键用来选取有hi-light的地方.
右键是menu-button

如果不小心按两次ESC,等於M-ESC,会有一个讯息跑出来
说你按到一个被disable的命令.这是高级指令,作者认为
初学者用不道,所以会问你要不要启动它,一般回答no.

如果某一行太长,萤幕显示不下,Emacs会在萤幕最右边打个$,
表示此行未完,右边还有.

把一行拆成两行:在想拆处按Enter即可.
合并两行为一行:在行尾按C-d(或行首按DEL)

Yank:吐出被删掉的(killed)东西.

只要用kill(C-k,M-k等)删除,超过一个字的资料,
emacs就会把它存起来,然後C-y可以把它叫出来.
功能跟Cut&Paste一样.Kill和delete不一样,只有被
kill掉的东西才能用yank吐回来.

游标在同一地方不动,连续kill掉的资料会被当成一次kill掉的,
yank时会一起回来.

被Kill掉的资料是放在称作killring的资料结构上面,ring就是个圆圈,
被kill掉的东西会依序摆在圆圈上.yank会放回最近一次kill掉的资料.
如果不是你想要的话,用M-y可以换.(M-y就是告诉emacs,不对不对,
我不是要这一个,换前一个给我).

M-y要紧接在C-y之後.

拷贝文字的方法==连续C-k几次,把要拷贝的行全部删掉,
然後按C-y弄回来.再到想复制的地方按一次C-y,就成了.

把要拷贝的资料kill掉在yank回来好像很笨.是有比较文明的
方法,那就是M-w,不过较麻烦.

首先,要先设标记.Mark用C-SPC或C-@设.然候
把游标移到另一端,按M-w就可以把mark到point间的
字存到killring上.point就是游标的意思.

Emacs不会把Mark起来的地方用highlight表示,除非在X下.
在X下,可以用M-w来拷贝用滑鼠反白的文字.

kill&yank就是cut&paste的意思.


以上大部份指令对Bash的命令列编辑也有效

档案操作
读档:Emacs术语叫findingafile.
C-xC-f然後在mini-buffer输入档名.输入档名时,SPC键有
auto-complete的功能,或者会秀出到目前为止档名前几
个字和输入一样的.(TAB键也有类似功能)

C-xC-f叫find-file

C-xC-s存档(savecurrentfile,savecurrentbuffer)
C-xs存所有的档

C-xi插入档案把另外的档案的内容读入目前编辑区内

视窗
Emacs把档案读进来,存在buffer中.
我们透过window来看/编辑buffer.

两个视窗会把萤幕切成两部份,他们可以同时显示
相同的,或不同的档案.

对初学者而言,最需要的是记住怎样让不想要的视窗消失:

C-x0关掉目前的视窗
C-x1会让目前的视窗占满整个萤幕(OneWindow),
取消/关掉其他的视窗.

Emacs里面有许多功能都会开一个小视窗来和使用者沟通,显示讯息.
有时候不会自动消失很讨厌,C-x1就很有用.

另一个功能是如何跳到另一个视窗.
C-xo(other-window)


C-x2把目前的视窗切成两个(水平分割)
C-x3(垂直分割)
C-x4是一串与视窗有关的指令.
C-x4是一串与视窗有关的指令.
C-x5则是扩展到X的视窗,称为frame.
C-x52就是再开另一个X视窗(frame).


多档编辑
C-xC-b看目前有那些buffer(buffer就是emacs放开起的档案的地方).
C-xb然後在minibuffer输入buffer的名字,可以切换编辑buffer.
TAB键也有作用.有些内部的buffer(就是没有档案的buffer),
是用*开头和结束,这个也要打,如*scratch*

最候提醒:
C-x1可以把多馀的视窗关掉.


Emacs扩充指令

前面介绍的emacs按键大部份都是C-<chr>;或者M-<chr>;的形式.
这是最简单的按法,由一对按键构成一个指令.

Emacs的按键可以超过2个以上.如C-x1或C-xC-b.
一般超过一个按键组合的命令都是用C-x开头.

另外你也可以直接下命令.按M-x之後就可以打一个Emacs命
令来执行.一般这些命令名字都很长,不过都不常用.等一下
我们会介绍一些.还有介绍怎麽把这些命令设成按键指令.

C-xC-c就是结束Emacs.不过一般Emacs很笨重,一旦起动就不轻易
退出.所以比较常用的是C-z

C-z把Emacs暂停,回到命令列.当你下次再需要编辑时,打fg%emacs
就可以把Emacs唤醒.

在X下,C-z会把emacs缩成icon


modeline

emacs编辑画面由编辑区(buffer)状态列(modeline)和对话区(minibuffer)
构成.这里解释modeline显示的讯息.

以下是个范例:

--**-XEmacs:xemacs.qs(Fundamental)----74%-------

由後面往前解释,74%表示游标的位置.

(Fundamental)表示编辑模式.这是最原始的模式.编辑不同种类的文章
可能希望用不同的模式,比如说C-mode,lisp-mode,tex-mode,text-mode
等等.在不同模式下可能多一些按键出来.举例text-mode.
M-xtext-mode
可以切入text-mode,这是一般人编辑文字使用的模式.和Fundamentalmode
没什麽差异.不过游标移动时,Emacs对一个字的定义就有所不同,因而
M-fM-b等移动一个字,一个段落的指令就可能会停在标点符号的前面.
此时状态列变为...(Text)----70%---

以上说的是Majormode.另外还有minormode,其实就是一些额外的功能.
比如说,M-xauto-fill-mode则状态列显示(TextFill).
auto-fill就是自动断行,让文章每行固定有70个字.

M-Xfundamental-mode可以变回来.

这里要说明一下,emacs在minibuffer下有auto-completion的功能,
也就是打M-xfund然後按SPC,它会自动补全fundamental-mode,
不用全打.如果有两个以上的选择,它会告诉你.这个功能对
find-file(C-xC-f)等等档案编辑功能也有效.前面提过.
最後解释两个**号.右边的*表示文章被修改过了.
左边的*表示这个编辑区(buffer)可以修改.
有一些emacs的buffer是read-onlybuffer,就会标成%
%%表示档案是read-only.

C-xC-q可以解开read-only的锁定,无论如何你要改这个编辑区.
这是个toggle指令,如果原来是可以修改的,C-xC-q会把它切成
read-only.


Search

没有Search功能的编辑器简直就是小朋友的玩具.Search
是一项很重要的功能,所以emacs也提供的很完善.
C-s
C-r
M-xre-search-forward
M-xre-search-backward
M-xsearch-forward
M-xsearch-backward
以上这些指令是基本的search指令.C-s,C-r是increamentalsearch,
就是你打字的同时,emacs就直接帮你找.一个是forward,一个是backward.
找到了怎麽办?按C-g可以取消搜寻,跳回原来的位置.按Enter就让游标
停在找到的地方--此时minibuffer显示:Marksavedwheresearchstarted
什麽意思?就是isearch帮你在原来的位置设了一个mark,然後把point
(cursor)移到新的位置.
想跳回去原先的地方?
C-xC-x就可以了.(exchange-point-and-mark)
C-uC-SPC可以依序跳回前几次设mark的地方.
(C-SPC是设mark,给它一个argument,就是作)
(还记不记得C-u可以给後面的指令设一些参数.
有些指令拿这个参数来当作repeatcount,
有些指令就只拿来当作on/off,true/false,set/clear而已)

M-xre-search-forward可以让你用regularexpression搜寻.
M-xsearch-forward则没有increamental的功能.

另外一个指令,作用和grep很像:
M-xoccure

和search相提并论的就是replace.
M-xreplace然後按SPC,就知道了.

Emacs的设定:

Emacs的设定档是$HOME/.emacs
你应该多少知道,emacs是用lisp写成的编辑器,.emacs档也都是
要用lisp的语法设定.emacs用的lisp称为elisp,和一般的lisp差一点点.

有一个infopage,emacs-lisp-intro,深入浅出的介绍emacslisp.
如果你还不会,不懂programming,强烈建议你看这份文件.如果你
会texinfo,你可以把它很漂亮的印出来.(内容一点点而已,两三
天就看完了)

如果你把.emacs搞砸了,进emacs很奇怪,怎麽办?
1.用vi改.emacs:>;
2.emacs-q进emacs


MajorModes

一般常见的emacsmajormode有
fundamental-mode
text-mode
lisp-mode有自动对括号/重排,直接执行lispcode功能.
c-mode/cc-modec-mode是比较旧的c-mode,cc-mode应该是
目前新的c-mode.有自动重排/对括号的功能.
也可以在emacs内compile,跳到compilererror
修正错误.执行程式时debug.(配合dbx/gdb)
compile是透过Makefile进行.
tex-modeTex/Latex编辑模示.可能是打一些奇怪的标点
符号比较方便.
<programming-language>;-mode
同lisp/cc-mode.如果是interpreter的话,
emacs通常都可以直接执行/debug.
<programming-language>;-mode还有tags的功能,後述.

html-mode,texinfo-mode,sgml-mode:编写html,texi,sgml之用.
w3-modeWWWbrowser.在x-win上不满意,但可以接受...


Tags

Tags是一个显为人知的功能?所以我想提一下.这不是emacs发明的,
而是vi原本的特异功能.emacs只是发扬光大而已.
假设你有一个目录,里面是一个程式的原始码,比如说,tin的原始码,
放在~/tin-1.3beta下面.你想看它们.

首先,叫emacscd到该目录:
M-xcd

然後,建立tagtable.
tagtable就是一张对照表,记录哪个符号(variable/functioncall)
对映到哪个档案的哪个地方.有这张表,emacs可以让我们快速的在程
式码内游走.一般这张表是一个档案,叫作TAGS(大写)

M-!etags*.[ch]

M-!是执行externalshellcommand的意思.etags就是emacs的建表程式.
你只要告诉它你的sourcecode在那□即可.

vi的话是使用ctags这个程式,它建出来的档名叫tags(小写).因为
我们介绍emacs,所以不管它.

然後,怎麽看程式?你知道所有的C程式都是由main()开始,所以你想
找到main()在哪个档案.这时只要按M-.然後emacs会问你tagtable
在哪里.因为我们已经cd到该目录,直接按enter就好了.然後输入main,
emacs就会把你带到main(){...}去.

如果你看到某个程式片断呼叫一个你没看过的函式,你可以把游标
移到该函式的名字上,M-.ENTER就搞定了.

如果emacs找错了(比如有变数和函式同名,emacs跳到变数去),
那你可以用C-uM-.找下一个.

在编辑程式码的时候,M-SPC很有用,它会把游标附近的空白缩成一个.
在其它地方也有效.

Emacs的一些package:

M-xdired(或C-xd)
游走/编辑目录,就是档案总管的意思:)

M-xman就是manpage
M-xshell开个commandprompt,不过不能跑vi,elm,tin...
M-xgnus读新闻/读信
M-xrmail读信
M-xvmviewmail
M-xmh-rmail读信(packagemh-e)
M-xmh-smail送信(packagemh-e)

强列建议改用emacs读news/bbs.世界会更美好!

读信的话就要看你的感觉.这些读信程式都会把信从系统的mailfolder
搬到自己的目录下,占用quota,我不喜欢:p建议elm或mutt.
除非参加maillinglist配合procmail.不然不实用.
用mh-e须要装mh这个外部程式,不太好.建议vm或gnus.
写完信,C-cC-c就可以送信.

如果你的资料用rcs/sccs作版本管理,emacs自动会起动versioncontrol
(minormode.),c-xc-q变成check-in/check-out.

如何取得更多的资讯:

Emacs的lisp经过多年的发展,已成为完整的self-documenting系统.
很多东西都可以线上找到你要的资讯.

前面说过,或者你已经不小心按backspace遇到了,C-h(就是backspace
的ascii码)在emacs里面是help的意思,它可以带出一串指令.
常用的有:

C-hFEmacsFAQ
C-htEmacs使用教学
C-hnEmacsNEWSfile,介绍最近改版的新功能
C-hiInfosystem.Info是gnu用来取代manpage的系统,
基本上和文字模示的WWW差不多.有许多重要的资讯
可以在这边找到.如果你是新手,建议你在x-win下
看.不然,按键m(menuitem),SPCnextpage
l(lastnode:node就是章节的意思)u(upnode)
d(directory,索引).BS(Backspace,backapage).
如果全部只按SPC,就跟man一样.
C-hkdescribekey,告诉你按这个键执行那个lispfunction.
C-hfdescribefunction.告诉你function在作什麽.
如果只按SPC,emacs会给你所有lisp函数的列表,和说明.
C-hvdescribevariable同function.
C-haapropos的意思(approximate).给lispfunction的部份
字串,emacs帮你找.
C-hb列出目前所有的keybinding
C-hmmodehelp.列出目前的mode的特殊说明.
C-cC-h列出以C-c开头的所有key-binding.虽然说Emacs
可以定义按键,可是Ctrl-开头的所有组合大概都用光了,
只有C-c算是可以自定指令.不过有些mode也侵犯这个空间.
目前的convention是C-c<chr>;留给user,C-cC-<chr>;
留给package.

有以上这些help,你的emacs/elisp功力会随著时间成长.


Elisp简介:

Emacs有三份手册.第一份是使用手册,第二份是Elisp手册,第三份是
Elisp简介.第三份的程度是入门级,值得看.Elisp手册其实也写的
很简单,还教你lisp,不过有点长,适合参考.

因为我lisp没有仔细学过,所以:
以下所言,如有巧合,那才是真的.

Basicdatatype
字串(string)"Hello,World"
字元(char)?a;问号开头
atom&list:
(1234)是一个list,由4个atom组成.
pair:中间是句点.
(apple.2)
alist(associatedlist)
就是一堆pair的集合,就像perl/tcl的associativearray.
或者说是一个资料库,一堆(key,value)pair.
'((Apple.1)
(Orange.2)
(PineApple.3))
vector(?)
emacs19用vector来表示按键(keystroksequence)
[f1][f2][f1a]

nil就是空的list,或者表示false
ttrue
Forms
我们写程式最好有样版让我们填空最简单了.
Form就是样版,不过意义不太一样.
Form就是Elisp可以接受的句型.
lisp解译器预设是对list的每个元素求值(evaluate),
除非是specialform,有特殊的定义.比如说

(defunFUNC(ARG-LIST)
BODY...)
就是一个specialform,用来定义函式,所以FUNC不会被
求值,被当成symbol,...

(quote(LIST))

这也是个specialform,叫lisp把(LIST)当做symbol就好了,
不要evaluate.

quote很常用,所以有个缩写:
'(LIST)等於(quote(LIST))
'Asymbol可以表示一个Atom,名称叫Asymbol

set可以产生/定义新的变数.
(set'hello1)
;hello=1
;注意我们用'hello,所以lisp不会evaluatehello的值.

这家伙很常用,也有简写.
(setqhello1)
setq就是setquote的缩写.这是个specialform,不会对
第二个元素求值.
valuation

在Emacs下,C-xC-e可以执行(evaluate,求值)游标左边的叙述.
结果会出现在minibuffer.

lisp-interaction-mode中C-j可以evaluate,并且把结果append到buffer.

lisp程式由一堆list构成.称为expression.
每个expression都回传回一个值.
有些expression有副作用,如删掉一个字.
(这跟C的intdelete_char()意思一样,它传回int,
并且删掉某个char)

定义函式:

(defunNAME(ARGS-LIST)
"注解";optional
(interactive);optional
BODY)

定义一个叫NAME的函式.BODY是一堆expression.
注解是用来给C-hf显示的.
(interactive)表示这个函示会和user/buffer作用.
(interactive"B")表示执行此函式先问user一个buffer的名字,
然後当作参数传给它.(如,当user透过key-binding
或者M-x呼叫此函式时)
(interactive"BAppendtobuffer:\nr")
问userbuffername时,提示号Appendtobuffer:
此function有两个引数,第一个是B,就是buffer
第二个是r,region
用\n隔开.
(interactive"p")用C-u设的prefix把它当作参数传给我.
预设值==4.C-uC-f向右移四个字

一些lisp函式:

(list1234)产生'(1234)
(car'(1234)1
(cdr'(1234)'(234)
(cons1'(234))'(1234)
(cons12)(1.2)
(cons0(cons1(cons2nil)))
等於'(012)
{list是用pair串起来的,
用C表示:
pair:{Object*first,Object*second};
*(pair.first)==i;
pair.second==pair[i+1];}

(cons'(12)'(34))'((12)34)
(setqa1)
(1+a);a+1
(+2a);a+2
(*1234)
(current-buffer);传回目前buffer的资料物件
(switch-to-buffer(other-buffer))
(set-buffer)
(buffer-size)
(setqcurrent-pos(point))
(point-min)
(point-max)
(message"Hello");在minibuffer显示Hello
(if(test)
(then-part)
(else-part))
(cond((test1)BODY1)
((test2)BODY2)
(tOTHER-WISE)
(let((var1value);localvariable
var2;novalue
(var3value)
...)
BODY...)
(lambda(ARG-LIST)...)同defun,但是没有名字(anonymous).
可以存到变数去:
(setqhello(lambda()(message"Hello,World")))
(funcallhello)
(goto-char(point-max))
(defvarVARVALUE"*注解")如果VAR不存在才定义.有注解可以用
C-hv看.注解打*号表是使用者可以直接改/这个变数本来就是
给使用者设定用的.
可以用M-xedit-options来线上设定(emacs结束就没有了,
不过edit-options可以给你所有可修改的变数的列表,你可以
放到.emacs档内.

(directory-files"./"t"\\..*")
returnalistoffilesunderdirectoryX
(load"xxxx.el")同#include<stdio.h>;
给使用者设定用的.
可以用M-xedit-options来线上设定(emacs结束就没有了,
不过edit-options可以给你所有可修改的变数的列表,你可以
放到.emacs档内.

(directory-files"./"t"\\..*")
returnalistoffilesunderdirectoryX
(load"xxxx.el")同#include<stdio.h>;
(setqload-path(cons"~/emacs"load-path));load的searchpath.
(autoload...)不像load会直接evaluate整个档案,而是需要时再
load.
(local-unset-key[(controlc)])
(local-set-key[(controlc)a]'forward-sexp)
sexp就是一个expession,n个expression如果用括号括起来就算一个.
(expression的定义随语言的不同而有不同,在C,lisp
tex,html,fortran下皆有差异)

你可能感兴趣的:(C++,c,C#,emacs,lisp)