青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

初步認(rèn)識emacs的lisp編程

參考:Learning GNU Emacs 3/e,9.8.The Lisp Modes,11.Emacs Lisp Programming

Emacs有三種Lisp模式,其命令名稱如下:

emacs-lisp-mode 用于Emacs Lisp代碼的編輯(文件名.emacs或后綴.el)
lisp-mode 用來編輯另一個Lisp系統(tǒng)的Lisp代碼(后綴.l或.lisp)
lisp-interaction-mode 用來編輯和運行Emacs Lisp代碼(交互模式)

本文只討論 lisp-interaction-mode模式。

缺省情況下*scratch*就是處于這種模式,無后綴的文件名一般也會讓Emacs進(jìn)入Lisp交互模式,當(dāng)然你可以使用變量auto-mode-alist進(jìn)行設(shè)置。

鍵 入 M-x lisp-interaction-mode Enter(回車)可以讓任何buffer進(jìn)入Lisp交互模式;如要新建一個Lisp交互buffer,只需鍵入C-x b(即switch-to-buffer命令),輸入buffer名,然后令該buffer進(jìn)入Lisp交互模式。

Lisp交互模式和 Emacs Lisp模式完全一致,除一個重要特性外:C-j已綁定到eval-print-last-sexp命令上。該命令提取point之前的那個S- expression,對其進(jìn)行評估,然后在buffer里打印結(jié)果。如果要使用其它模式里綁定到C-j的常見功能newline-and- indent,你必須按下Enter,并緊跟Tab鍵。

記住 S-expression是任何符合Lisp語法的表達(dá)式。因此,可以使用 Lisp交互模式的C-j來檢查變量的值,確認(rèn)函數(shù)定義,運行函數(shù)等等。比如,如果你輸入auto-save-interval并按下C-j,就會顯示該 變量的值(缺省為300)。如果你輸入一個defun并在其最右邊的括號后按下C-j,Emacs會保存所定義的函數(shù)(供以后調(diào)用)并輸出其名稱;這種情 況下,C-j類似C-M-x(即eval-defun命令),不過光標(biāo)必須位于所定義的函數(shù)之后(因為有可能在定義前或中間)。如果你調(diào)用了一個函數(shù), Emacs就會評估(運行)該表達(dá)式并顯示函數(shù)的所有返回值。

Lisp交互模式的C-j提供了很棒的功能,你可以用它來增量方式開發(fā)和調(diào)試Emacs Lisp代碼;因為Emacs Lisp是種“真正的”Lisp,它甚至可用來開發(fā)其它Lisp系統(tǒng)的代碼片斷。

基本Lisp實體

你需要熟悉Lisp基本元素包括函數(shù)、變量和atom(原子)。函數(shù)是Lisp的唯一程序單元(program unit),涵蓋了其它語言的過程、子程序、程序甚至操作符等標(biāo)記。

函 數(shù)被定義作上述實體的列表(list),通常是對其它現(xiàn)存函數(shù)調(diào)用的列表。所有函數(shù)都有返回值(return value)(類似Perl函數(shù)和non-void Java函數(shù));函數(shù)的返回值就是list里最后一項的值,一般是最后調(diào)用的函數(shù)返回的值。在其它函數(shù)里的函數(shù)調(diào)用等價于其它語言的語句 (statement),函數(shù)的語法如下:

(function-name argument1 argument2 ...)

等價于Java的:

method_name (argument1, argument2, ...);

這一語法用于所有函數(shù),包括那些等價于其它語言的算術(shù)或比較運算符。例如,在Java或Perl里2加4,你會用表達(dá)式2+4,而在Lisp里你會使用如下寫法:

(+ 2 4)

類似的,4 >= 2的Lisp方式:

(>= 4 2)

Lisp中的變量和其它語言的相似,不過沒有類型。Lisp變量能夠推測任何類型的值(值本身沒有類型,不過變量對其能存放的內(nèi)容不加任何限制)。

原子(atom)是個任意類型的值,包括整數(shù)、浮點(實)數(shù)、字符、字符串、布爾值、符號(symbol)和Emacs特殊類型如buffer、window和process。各種atom的語法如下:
  • 整數(shù):和你常用的一樣,有符號,范圍-2+27至2+27 - 1;
  • 浮點數(shù):可用十進(jìn)制和科學(xué)計數(shù)法表示的實數(shù)。例如5489可寫成5489、5.489e3、546.9e1等;
  • 字符:以問號開頭,如 ?a 。Esc、Newline和Tab可分別簡寫為\e、\n和\t;其它控制字符可以加\C-前綴來表示,例如C-a表示為?\C-a。整數(shù)也可用來表示字符,如ASCII表等。
  • 字符串:用雙引號包圍;字符串里的引號標(biāo)記和\需要加上\,"Jane said, \"See Dick run.\""是個合法字符串。字符串可以分割成多行,不需特殊語法。結(jié)束引號前的所有內(nèi)容包括所有斷行符都是字符串值的一部分。
  • 布爾值:大部分情況下真值為t,假值為nil,如果能預(yù)估到布爾值,則任何非nil值都被看作真值。nil也被用作null或nonvalue。

  • 符號:Lisp實體名,如變量或函數(shù)名。有時需要引用實體的名字而非其值,這時可以在名字前加上單引號(')。
setq用來賦值給變量,是個函數(shù),而不象其它語言里用來賦值的專門語法=或:=。setq接收兩個參數(shù):一個變量名和一個值。也可以進(jìn)行多次賦值,如:
(setq thisvar thisvalue
thatvar thatvalue
theothervar theothervalue)
也可用其它方法設(shè)置值或變量,不過setq是使用最廣的方法。

函數(shù)定義

首先熟悉一下Lisp語法的特殊表示。- 用作“割斷”字符用來分隔變量、函數(shù)等名稱里的字(word),這是Lisp編程慣用法,類似C和Ada里的“_”。

A more important issue has to do with all of the parentheses in Lisp code. Lisp is an old language that was designed before anyone gave much thought to language syntax (it was still considered amazing that you could use any language other than the native processor's binary instruction set), so its syntax is not exactly programmer-friendly. Yet Lisp's heavy use of lists?aand thus its heavy use of parentheses?ahas its advantages, as we'll see toward the end of this chapter.

讓我們從一個實例開始。
1 (defun count-words-buffer ( )
2 (let ((count 0))
3 (save-excursion
4 (goto-char (point-min))
5 (while (< (point) (point-max))
6 (forward-word 1)
7 (setq count (1+ count)))
8 (message "buffer contains %d words." count))))
defun: 指定函數(shù)名和參數(shù)來定義函數(shù)。注意defun本身是一個函數(shù)――被調(diào)用時,定義一個新函數(shù)。(defun返回把所定義的函數(shù)作為一個symbol返回。) 函數(shù)的參數(shù)顯示為在括號內(nèi)的一個名字list;本例,函數(shù)沒有參數(shù)。如果在參數(shù)前加關(guān)鍵字&optional就表示參數(shù)是optional(可選 的)。如果參數(shù)是optional的,在函數(shù)調(diào)用時未指定該參數(shù),則認(rèn)為其值為nil。
(let ((var1 value1) (var2 value2) ... )
statement-block)
let:1.定義(或聲明)一個變量list;2.變量設(shè)置初始值,同setq;3.創(chuàng)建一個語句塊(類似函數(shù)體),在此塊內(nèi)這些變量可用,let塊即這些變量的scope(作用域)。let里定義的變量可用setq改變其值,不過要小心使用setq。

save -excursion:Emacs內(nèi)建函數(shù),保存光標(biāo)原來的位置(因為 count-words-buffer函數(shù)要移動光標(biāo)以便計算字?jǐn)?shù))。調(diào)用 save-excursion就是要求Emacs記住實例函數(shù)開始執(zhí)行時的光標(biāo)位置,并在執(zhí)行完函數(shù)體內(nèi)的所有語句后返回至初始光標(biāo)位置。

goto -char:Emacs內(nèi)建函數(shù),其參數(shù)是個(內(nèi)嵌)函數(shù)調(diào)用,調(diào)用內(nèi)建函數(shù)point-min。point是Emacs內(nèi)部名稱,表示光標(biāo)的當(dāng)前位置。 point-min返回當(dāng)前buffer里第一個字符的位置值,幾乎總是1;這樣goto-char調(diào)用時其參數(shù)值為1,效果等同于把point移至 buffer起始處。

(while condition statement-block)

和let 及save-excursion一樣,while也建立了一個語句塊。condition是個值(atom、變量或返回一個值的函數(shù))。while對這個 值進(jìn)行測試,如果其值不是nil,則認(rèn)為條件(condition)為真,語句塊得以執(zhí)行,然后condition再次被測試,之后重復(fù)上述過程。當(dāng)然也 可以寫個無限循環(huán),如果你試圖執(zhí)行這樣的語句,Emacs會掛起,鍵入C-g終止。

在實例函數(shù)中,condition是函數(shù) < ,即帶兩個參數(shù)的小于函數(shù),類似Java或Perl里的<運算符。第一個參數(shù)是另一個函數(shù),它返回point的當(dāng)前字符位置;第二個參數(shù)返回 buffer里的最大(最后)字符位置,即buffer的長度。函數(shù)="">< (和其它關(guān)系函數(shù))返回一個布爾值,t 或 nil。

上 述循環(huán)的語句塊由兩條語句組成。第6行會把point往前移動一個字(word,即相當(dāng)于M-f)。第7行,循環(huán)計數(shù)器加一;函數(shù) 1+ 是(+ 1 variable-name)的簡寫方式。注意第三個右括號(第7行)和while前面的左括號匹配。這樣,在計算字?jǐn)?shù)時,while循環(huán)會讓Emacs 一次一個字(word)遍歷整個當(dāng)前buffer。

實例函數(shù)的最后一個語句使用內(nèi)建函數(shù)message在minibuffer里打印一行信息,提示buffer所含的字?jǐn)?shù)。message函數(shù)的格式類似C語言。

Message格式字符串
格式字符串 含義
%s 字符串或symbol
%c 字符
%d 整數(shù)
%e 科學(xué)計數(shù)法表示的浮點數(shù)
%f 十進(jìn)制表示的浮點數(shù)
%g 任意格式的浮點數(shù),產(chǎn)生最短的字符串

將Lisp函數(shù)變?yōu)镋macs命令

函 數(shù) count-words-buffer已編寫完成,接下來該如何運行?在交互模式中,可以把光標(biāo)移到函數(shù)的結(jié)束括號,然后鍵入C-j(或 Linefeed),讓Emacs執(zhí)行函數(shù)定義。你應(yīng)該看到該函數(shù)的名字會再次出現(xiàn)在buffer里;defun函數(shù)的返回值就是已定義的符號(即函數(shù)名 稱)。

函數(shù)定義之后,可以在Lisp交互窗口中輸入一行 (count-words-buffer) ,然后在結(jié)束括號后再次按下 C-j 。

如 果你象其它Emacs命令一樣用M-x來執(zhí)行上述函數(shù),M-x count-words-buffer Enter,會得到錯誤提示信息 [No match]。這是因為你并未在Emacs中“注冊”該函數(shù),使其可供交互(interactive)使用。實現(xiàn)這一功能的函數(shù)是 interactive ,形式如下:

(interactive "prompt-string")

上述語句必須出現(xiàn)在函數(shù)開始處,即緊隨defun和文檔說明字符串所在行之后。使用 interactive 會讓Emacs把函數(shù)注冊為一個命令,并提示用戶輸入defun語句中聲明的參數(shù)。提示字符串為可選。

提示字符串有一個特殊的格式:你要為想提示用戶輸入的每個參數(shù)都提供一段提示字符串,這些段用“\n”分隔。

用于interactive函數(shù)的參數(shù)代碼
代 碼
提示用戶輸入
b
現(xiàn)存buffer的名稱
e
事件(鼠標(biāo)動作或 function key press)
f
現(xiàn)存文件的名稱
n
數(shù)字(整數(shù))
s
字符串
上述代碼都有一個大寫的變種
B 可能不存在的buffer名稱
F 可能不存在的文件名稱
N
數(shù)字,unless command is invoked with a prefix argument, in which case use the prefix argument and skip this prompt
S 符號

示例:
(defun replace-string (from to)
(interactive "sReplace string: \nsReplace string %s with: ")
...)
回 到 count-words-buffer 命令:它不需參數(shù),因此 interactive 命令不需要提示字符串。另外可以再給我們的命令添加一個文檔說明字符串(doc string),它會顯示在describe-function(C-h f)之類的在線幫助工具中。Doc string是普通的Lisp字符串,可選,行數(shù)長度任意,不過一般來說,第一行是個簡要完整的句子,說明命令的功能。注意字符串里的任意雙引號前必須加 上 \ 。
(defun count-words-buffer ( )
"Count the number of words in the current buffer;
print a message in the minibuffer with the result."

(interactive)
(save-excursion
(let ((count 0))
(goto-char (point-min))
(while (< (point) (point-max))
(forward-word 1)
(setq count (1+ count)))
(message "buffer contains %d words." count))))

posted on 2006-07-19 11:04 王光平 閱讀(1732) 評論(2)  編輯 收藏 引用 所屬分類: linux世界

評論

# re: 初步認(rèn)識emacs的lisp編程 2011-12-12 22:43 chenshu

這行代碼看上去不對,(1 + count) => (+ count 1) 才對吧。
(setq count (1+ count)))  回復(fù)  更多評論   

# re: 初步認(rèn)識emacs的lisp編程[未登錄] 2012-02-03 09:40 123

@chenshu
是(1+ )
不是(1 + )  回復(fù)  更多評論   

<2006年8月>
303112345
6789101112
13141516171819
20212223242526
272829303112
3456789

導(dǎo)航

統(tǒng)計

留言簿(4)

隨筆分類

隨筆檔案

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久全球大尺度高清视频| 中文精品视频| 毛片av中文字幕一区二区| 先锋资源久久| 亚洲第一级黄色片| 亚洲国产免费看| 欧美日韩1080p| 亚洲免费一级电影| 欧美亚洲一区三区| 亚洲国产精品热久久| 亚洲精品在线免费观看视频| 国产精品99一区二区| 久久久777| 欧美激情精品久久久六区热门| 99re6热在线精品视频播放速度 | 亚洲三级影片| 日韩亚洲欧美在线观看| 国产欧美日韩在线| 亚洲第一主播视频| 欧美午夜激情小视频| 久久亚洲春色中文字幕| 欧美高清视频一二三区| 欧美一区二区在线播放| 美日韩精品视频| 亚洲一区影院| 麻豆成人在线播放| 欧美在线观看日本一区| 欧美激情精品久久久久久免费印度| 亚洲欧美在线一区| 嫩草影视亚洲| 久久久久成人精品免费播放动漫| 欧美国产一区在线| 久久久久久欧美| 国产精品成人一区二区网站软件 | 日韩一区二区免费高清| 国精品一区二区| 一本久久综合亚洲鲁鲁| 亚洲电影第三页| 亚洲在线观看| 亚洲视频axxx| 欧美激情二区三区| 另类激情亚洲| 国产三级欧美三级日产三级99| 亚洲精品乱码久久久久久蜜桃91| 国产一区二区三区日韩| 亚洲网站在线观看| 亚洲天天影视| 欧美日韩成人一区二区三区| 女女同性精品视频| 国产一区二区三区电影在线观看| 一区二区久久| 中日韩美女免费视频网址在线观看| 久久婷婷一区| 理论片一区二区在线| 国产视频观看一区| 亚洲欧美日韩区| 亚洲欧美日韩国产中文| 欧美日韩一区二区三区| 99re在线精品| a91a精品视频在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲欧美日韩一区二区三区在线观看| 农夫在线精品视频免费观看| 欧美.日韩.国产.一区.二区| 红桃av永久久久| 久久成人18免费观看| 久久婷婷丁香| 在线日韩欧美视频| 蜜臀久久99精品久久久画质超高清 | 国产精品久久91| 亚洲一区视频在线| 久久精品国产99| 韩国精品久久久999| 久久视频国产精品免费视频在线| 另类天堂视频在线观看| 狠狠色2019综合网| 美女成人午夜| 亚洲美女视频网| 香港久久久电影| 国产一区二区三区成人欧美日韩在线观看 | 欧美在线3区| 国产一区二区三区视频在线观看| 久久久久国产精品麻豆ai换脸| 老妇喷水一区二区三区| 亚洲激情视频在线| 欧美日韩国产首页在线观看| 亚洲深夜av| 乱人伦精品视频在线观看| 亚洲区欧美区| 国产精品免费在线| 久久一区二区三区四区| 亚洲精品一区二区三区婷婷月 | 亚洲激情在线播放| 欧美日韩午夜视频在线观看| 亚洲欧美日韩一区在线| 免费在线观看一区二区| 在线亚洲一区| 狠狠综合久久av一区二区小说| 欧美成人综合| 亚洲综合久久久久| 欧美激情亚洲视频| 亚欧成人在线| 亚洲三级视频在线观看| 国产日韩精品视频一区二区三区| 久久综合网hezyo| 亚洲伊人一本大道中文字幕| 蜜桃久久精品一区二区| 亚洲免费影视| 亚洲开发第一视频在线播放| 国产欧美一区二区白浆黑人| 欧美国产日韩一区二区| 欧美中文字幕在线播放| 日韩午夜电影在线观看| 男男成人高潮片免费网站| 亚洲一区二区三区四区中文| 亚洲二区在线视频| 国产亚洲一区二区精品| 欧美日韩一区自拍| 美女露胸一区二区三区| 欧美在线视频播放| 亚洲一区二区少妇| 99re这里只有精品6| 欧美国产精品劲爆| 另类国产ts人妖高潮视频| 性伦欧美刺激片在线观看| 野花国产精品入口| 亚洲精品久久嫩草网站秘色| 在线观看欧美日韩国产| 国产主播一区二区三区| 国产裸体写真av一区二区| 欧美午夜电影网| 欧美日韩中文字幕在线| 欧美日韩国产精品成人| 欧美二区在线播放| 欧美成人高清视频| 美女任你摸久久| 免费看亚洲片| 免费欧美电影| 欧美成人在线网站| 欧美成人亚洲| 欧美激情一区二区三区不卡| 欧美69wwwcom| 欧美激情一二三区| 欧美巨乳在线观看| 欧美日韩精品一本二本三本| 欧美激情第1页| 欧美另类一区| 国产精品久久久久久久久免费| 欧美视频一区| 国产精品三区www17con| 国产乱码精品一区二区三| 国产久一道中文一区| 国产麻豆精品在线观看| 国产一区二区三区高清在线观看| 国外成人在线视频网站| 在线日韩一区二区| 日韩视频永久免费| 亚洲小说春色综合另类电影| 欧美一二三视频| 免费日韩成人| 亚洲精品乱码久久久久久日本蜜臀| 亚洲精品资源美女情侣酒店| 亚洲午夜精品福利| 久久国产精品电影| 欧美—级在线免费片| 国产精品草草| 激情五月综合色婷婷一区二区| 亚洲大片av| 亚洲一区在线观看免费观看电影高清| 亚洲欧美高清| 免费日韩成人| 夜色激情一区二区| 欧美在线播放视频| 欧美另类久久久品| 国产精品自在线| 亚洲精品久久久久久久久久久久久| 亚洲午夜久久久久久久久电影院| 久久久久国产免费免费| 欧美激情成人在线| 亚洲一区国产视频| 欧美成人精精品一区二区频| 国产精品蜜臀在线观看| 在线播放一区| 午夜精品免费在线| 亚洲大片免费看| 午夜精品www| 欧美日韩黄视频| 在线看视频不卡| 欧美一级播放| 亚洲精品你懂的| 亚洲在线不卡| 欧美另类在线观看| 精品成人一区二区| 午夜一区不卡| 亚洲老司机av| 欧美xx69| 在线日韩中文字幕| 久久久噜噜噜久久中文字免| 一区二区三区 在线观看视| 免费黄网站欧美|