2020-03-01emacs 中使用LISP

Elisp 基礎

X分鐘速成elisp

Common Lisp 里的一些基本概念

C-j

計算當前光標到行首之間函數(shù)式結果,插入正文內容,結果內容最多只顯示2行,后面用省略號,What!!

使用C-0 C-j能把結果內容顯示全。

eval-expression-print-levelandeval-expression-print-length用來控制內容顯示的長度。

C-x C-e

計算當前光標到行首之間函數(shù)式結果,顯示在mini-buffer里。

Emacs Lisp 是一個函數(shù)式的語言。

*scratch*buffer

C-x 方向鍵切換到*scratch*buffer , 可以在其中測試 elisp 語句。

這個buffer是lisp-interaction-mode

光標移動到函數(shù)式后,按下C-j或者C-x C-e,就可以執(zhí)行函數(shù)式計算。

基本寫法,如何測試

(+ 3 (+ 1 2))

;;? ? ? ? ? ^ 光標放到這里

;; 按下`C-j' 就會輸出 6

;; `C-j' 會在buffer中插入當前運算的結果

;; 而`C-xC-e' 則會在emacs最底部顯示結果,也就是被稱作"minibuffer"的區(qū)域

;; 為了避免把我們的buffer填滿無用的結果,我們以后會一直用`C-x C-e'

變量

setq設置當前緩沖區(qū)(Buffer)中的變量值

setq-default設 置的為全局的變量的值

;; `setq' 可以將一個值賦給一個變量

(setq my-name "Bastien")

;; `C-x C-e' 輸出 "Bastien" (在 mini-buffer 中顯示)

;; 定義變量

(setq name "username")

(message name) ; -> "username"

1

2

;; 設置光標樣式

(setq-default cursor-type 'bar)

quote 單引號

https://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html

http://stackoverflow.com/questions/134887/when-to-use-quote-in-lisp

1

2

3

;; 下面兩行的效果完全相同的

(quote foo)

'foo

quote 的意思是不要執(zhí)行后面的內容,返回它原本的內容

1

2

(print '(+ 1 1)) ;; -> (+ 1 1)

(print (+ 1 1))? ;; -> 2

列表

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

;; 我們將一些名字存到列表中:

(setq list-of-names '("Sarah" "Chloe" "Mathilde"))

;; 用 `car'來取得第一個名字:

(car list-of-names)

;; 用 `cdr'取得剩下的名字:

(cdr list-of-names)

;; 用 `push'把名字添加到列表的開頭:

(push "Stephanie" list-of-names)

;; 注意: `car' 和 `cdr' 并不修改列表本身, 但是 `push' 卻會對列表本身進行操作.

;; 這個區(qū)別是很重要的: 有些函數(shù)沒有任何副作用(比如`car')

;; 但還有一些卻是有的 (比如 `push').

循環(huán)

http://www.gnu.org/software/emacs/manual/html_mono/cl.html#Loop-Facility

loop for ... in來自 cl 即 Common Lisp 擴展。

1

2

;; cl - Common Lisp Extension

(require 'cl)

for , in, collect 均為 cl-loop 中的 保留關鍵字。下面是一些簡單的 cl-loop 的使用示例:

1

2

3

4

5

6

7

8

9

;; 遍歷每一個緩沖區(qū)(Buffer)

(cl-loop for buf in (buffer-list)

? collect (buffer-file-name buf))

;; 尋找 729 的平方根(設置最大為 100 為了防止無限循環(huán))

(cl-loop for x from 1 to 100

? for y = (* x x)

? until (>= y 729)

? finally return (list x (= y 729)))

mapcar

1

2

3

4

5

6

7

8

9

10

11

;; 我們來對`list-of-names'列表中的每一個元素都使用hello函數(shù):

(mapcar 'hello list-of-names)

;; 將 `greeting' 改進,使的我們能夠對`list-of-names'中的所有名字執(zhí)行:

(defun greeting ()

? ? (switch-to-buffer-other-window "*test*")

? ? (erase-buffer)

? ? (mapcar 'hello list-of-names)

? ? (other-window 1))

(greeting)

while 循環(huán)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

(defun replace-hello-by-bonjour ()

? ? (switch-to-buffer-other-window "*test*")

? ? (goto-char (point-min))

? ? (while (search-forward "Hello")

? ? ? (replace-match "Bonjour"))

? ? (other-window 1))

;; (goto-char (point-min)) 將光標移到buffer的開始

;; (search-forward "Hello") 查找字符串"Hello"

;; (while x y) 當x返回某個值時執(zhí)行y這個s式

;; 當x返回`nil' (空), 退出循環(huán)

(replace-hello-by-bonjour)

;; 你會看到所有在*test* buffer中出現(xiàn)的"Hello"字樣都被換成了"Bonjour"

;; 你也會得到以下錯誤提示: "Search failed: Hello".

;;

;; 如果要避免這個錯誤, 你需要告訴 `search-forward' 這個命令是否在

;; buffer的某個地方停止查找, 并且在什么都沒找到時是否應該不給出錯誤提示

;; (search-forward "Hello" nil t) 可以達到這個要求:

;; `nil' 參數(shù)的意思是 : 查找并不限于某個范圍內

;; `t' 參數(shù)的意思是: 當什么都沒找到時,不給出錯誤提示

defun

1

2

3

4

5

6

7

8

9

10

11

12

13

;; 你可以把s式嵌入函數(shù)中

(defun hello () (insert "Hello, I am " my-name))

;; `C-xC-e' 輸出 hello

;; 現(xiàn)在執(zhí)行這個函數(shù)

(hello)

;; `C-xC-e' 輸出 Hello, I am Bastien

;; 帶參數(shù)的函數(shù)定義

(defun hello (name) (insert "Hello " name))

;; `C-xC-e' 輸出 hello

(hello "you")

;; `C-xC-e' 輸出 "Hello you"

progn

1

2

3

4

5

;; 你可以用 `progn'命令將s式結合起來:

(progn

? (switch-to-buffer-other-window "*test*")

? (hello "you"))

;; `C-xC-e' 此時屏幕分為兩個窗口,并且在*test* buffer中顯示"Hello you"

let

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

;; 你可以用 `let' 將一個值和一個局部變量綁定:

(let ((local-name "you"))

? (switch-to-buffer-other-window "*test*")

? (erase-buffer)

? (hello local-name)

? (other-window 1))

;; 我們再用`let'新建另一個函數(shù):

(defun greeting (name)

? (let ((your-name "Bastien"))

? ? (insert (format "Hello %s!nnI am %s."

? ? ? ? ? ? ? ? ? ? name? ? ? ; the argument of the function

? ? ? ? ? ? ? ? ? ? your-name? ; the let-bound variable "Bastien"

? ? ? ? ? ? ? ? ? ? ))))

;; 之后執(zhí)行:

(greeting "you")

交互命令 read-from-minibuffer

1

2

3

4

5

6

7

8

9

10

11

12

13

14

;; 有些函數(shù)可以和用戶交互:

(read-from-minibuffer "Enter your name: ")

;; 這個函數(shù)會返回在執(zhí)行時用戶輸入的信息

;; 現(xiàn)在我們讓`greeting'函數(shù)顯示你的名字:

(defun greeting (from-name)

? (let ((your-name (read-from-minibuffer "Enter your name: ")))

? ? (insert (format "Hello!nnI am %s and you are %s."

? ? ? ? ? ? ? ? ? ? from-name ; the argument of the function

? ? ? ? ? ? ? ? ? ? your-name ; the let-bound var, entered at prompt

? ? ? ? ? ? ? ? ? ? ))))

(greeting "Bastien")

lisp 操作 emacs

switch-to-buffer-other-window

1

2

3

4

5

6

7

;; 下面我們在新的窗口中新建一個名為 "*test*" 的buffer:

(switch-to-buffer-other-window "*test*")

;; `C-xC-e' 這時屏幕上會顯示兩個窗口,而光標此時位于*test* buffer內

;; 用鼠標單擊上面的buffer就會使光標移回。

;; 或者你可以使用 `C-xo' 使得光標跳到另一個窗口中

(goto-char (point-min)) 將光標移到buffer的開始

(search-forward “Hello”) 查找字符串”Hello”

global-set-key 設置快捷鍵

1

2

;; 設置快捷鍵

(global-set-key (kbd "<f1>") 'func-name)

其他lisp語法

insert

1

2

3

4

5

6

7

8

9

10

;; `insert' 會在光標處插入字符串:

(insert "Hello!")

;; `C-xC-e' 輸出 "Hello!"

(insert "Hello" " world!")

;; `C-xC-e' 輸出 "Hello world!"

;; 你也可以用變量名來代替字符串

(insert "Hello, I am " my-name)

;; `C-xC-e' 輸出 "Hello, I am Bastien"

format

1

2

3

4

5

;; 格式化字符串的方法:

(format "Hello %s!n" "visitor")

(defun hello (name)

? (insert (format "Hello %s!n" name)))

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容