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-XM-XX没有大小写分别.

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-fM-f,C-bM-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-hEmacs下是help的意思

後面有(kill)的,表示此删除的动作是kill,不太等於delete.

emacs会把kill掉的东西放到killring,算是一种暂存的地方,

以後可以叫出来.见yank说明.

Undo:C-xu

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

有时等於C-Shift--

重复执行

举例,向右移8个字,C-u8C-f

C-uEmacs里是蛮特别的,用来设定一些引数(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一样.Killdelete不一样,只有被

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,不过较麻烦.

首先,要先设标记.MarkC-SPCC-@.然候

把游标移到另一端,M-w就可以把markpoint间的

字存到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-ffind-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-x1C-xC-b.

一般超过一个按键组合的命令都是用C-x开头.

另外你也可以直接下命令.M-x之後就可以打一个Emacs

令来执行.一般这些命令名字都很长,不过都不常用.等一下

我们会介绍一些.还有介绍怎麽把这些命令设成按键指令.

C-xC-c就是结束Emacs.不过一般Emacs很笨重,一旦起动就不轻易

退出.所以比较常用的是C-z

C-zEmacs暂停,回到命令列.当你下次再需要编辑时,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可以变回来.

这里要说明一下,emacsminibuffer下有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-rincreamentalsearch,

就是你打字的同时,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-qemacs

MajorModes

一般常见的emacsmajormode

fundamental-mode

text-mode

lisp-mode有自动对括号/重排,直接执行lispcode功能.

c-mode/cc-modec-mode是比较旧的c-mode,cc-mode应该是

目前新的c-mode.有自动重排/对括号的功能.

也可以在emacscompile,跳到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建议elmmutt.

除非参加maillinglist配合procmail.不然不实用.

用mh-e须要装mh这个外部程式,不太好.建议vmgnus.

写完信,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.Infognu用来取代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-hvdescribevariablefunction.

C-haapropos的意思(approximate).lispfunction的部份

字串,emacs帮你找.

C-hb列出目前所有的keybinding

C-hmmodehelp.列出目前的mode的特殊说明.

C-cC-h列出以C-c开头的所有key-binding.虽然说Emacs

可以定义按键,可是Ctrl-开头的所有组合大概都用光了,

只有C-c算是可以自定指令.不过有些mode也侵犯这个空间.

目前的conventionC-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,4atom组成.

pair:中间是句点.

(apple.2)

alist(associatedlist)

就是一堆pair的集合,就像perl/tclassociativearray.

或者说是一个资料库,一堆(key,value)pair.

'((Apple.1)

(Orange.2)

(PineApple.3))

vector(?)

emacs19vector来表示按键(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,并且把结果appendbuffer.

lisp程式由一堆list构成.称为expression.

每个expression都回传回一个值.

有些expression有副作用,如删掉一个字.

(这跟Cintdelete_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[i].first)==i;

pair[i].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));loadsearchpath.

(autoload...)不像load会直接evaluate整个档案,而是需要时再

load.

(local-unset-key[(controlc)])

(local-set-key[(controlc)a]'forward-sexp)

sexp就是一个expession,nexpression如果用括号括起来就算一个.

(expression的定义随语言的不同而有不同,C,lisp

tex,html,fortran下皆有差异)

你可能感兴趣的:(emacs)