如下內容均在emacs *scratch*中測試html
格式爲西文分號加空格,即";; ",可在任意一行的任何位置開始註釋。express
;; test code (+ 3 4) ;; test code
(+ 4 5 1) ;; 10 (- 9 2 3) ;; 4 (* 2 3 3) ;; 18 (/ 7 2) ;; 3,取整 (/ 7 2.0) ;; 3.5,除法 (% 7 4) ;; 3,取餘 (expt 2 3) ;; 8
(integerp 3.) ;; t,3.表示整數,3.0表示小數 (floatp 3.) ;; nil (floatp 3.0) ;; t
注 :函數名字以p結尾表示測試,返回對(t)或錯(nil)數組
(float 3) ;; 3.0 (truncate 3.3) ;; 3,捨棄小數部分 (floor 3.3) ;; 3,向下取整 (ceiling 3.3) ;; 4,向上取整 (round 3.4) ;; 3,四捨五入
(string-to-number "3") (number-to-string 3)
elisp中 沒有布爾類型
只有 nil 和 空列表 () 表示 FALSE 外
其它全部都爲 TRUE ,即 t 。app
與或非less
(and t nil) ;; nil 與運算 (or t nil) ;; t 或運算 (not t) ;; nil 非運算
(< 3 4) ;; 小於 (> 3 4) (<= 3 4) (>= 3 4) (= 3 3) ;; t,比較兩數是否相等 (= 3 3.000000000000000000001) ;; t,可見elisp將超過精度小數部分捨棄 (/= 3 4) ;; t, 比較兩數是否不相等
(equal "abc" "abc") ;; t ;; string-equal比較字符串專用函數 (string-equal "abc" "abc") ;; t (string-equal "abc" "Abc") ;; nil,大小寫問題 (string-equal "abc" 'abc) ;; t,可用於比較字符串和符號
一般使用equal進行等價測試,它比較兩個測試對象是否具備相同類型和值。ide
(equal "abc" 'abc) ;; nil
不等價測試,運算"/="只針對數值,對於字符串和其它數據類型無效,可以使用not來否認equal達到目標。函數
not (equal "abc" 'abc) ;; t
setq用於設置全局變量,且變量無需聲明。oop
(setq x 1) ;; x = 1 (setq a 3 b 2 c 7) ;; a = 3, b = 2, c = 7,批量賦值
let用於設置局部變量。測試
形式一this
(let (var1 var2 ...) body)
body由elisp表達式組成,且其最後一條表達式的返回值做爲let的返回值。
(let (a b) (setq a 3) (setq b 4) (+ a b)) ;; 7
形式二
(let ((var1 val1) (var2 val2) ...) body)
此方法無需在body中使用setq爲變量賦值,更方便。
(let ((a 3) (b 4)) (+ a b)) ;; 7
(message FORMAT-STRING &rest ARGS)
打印格式化字符串到 Message ,可經過"M-x view-echo-area-message" 或 "C-h e" 查看
(message "age is: %d " 16)
FORMAT-STRING字符串格式化:
format | explanation |
---|---|
%s | 表示字符串,相似princ(後面介紹) |
%d | 十進制數值(%o 八進制, %x 十六進制) |
%X | 大寫的十六進制 |
%e | 指數表示的數值 |
%f | 小數點表示的數值 |
%g | 使用指數或小數點表示數值,以字符較少爲準 |
%c | 以字符方式打印數值 |
%S | 打印任何對象的S-表達式,相似prin1(後面介紹) |
(insert &rest ARGS)
在當前buffer的光標位置插入字符串。
(insert "xyz")
(print OBJECT &optional PRINTCHARFUN)
打印lisp OBJECT(整數、浮點、字符、字符串、列表、符號等),輸出能夠被read函數讀回,
Optional參數能夠是一個buffer或函數。
setq xbuff (generate-new-buffer "*my output*")) (print "something" xbuff) (switch-to-buffer xbuff )
with-output-to-temp-buffer
(with-output-to-temp-buffer BUFNAME &rest BODY)
將標準輸出綁定到緩衝區BUFNAME,執行BODY,則首先會清空BUFNAME,而後在BUFNAME中顯示結果,
不會將結果顯示在當前緩衝區。
(setq xbuff (generate-new-buffer "*my output*")) (with-output-to-temp-buffer xbuff ;; this is inserted in current buffer (insert "xyz") ;; this is printed in buffer xbuff (print "abc")) (switch-to-buffer xbuff )
(prin1 OBJECT &optional PRINTCHARFUN)
相似print,可是不會換行。
(prin1 '("x" "y")) ;; ("x" "y")
(princ OBJECT &optional PRINTCHARFUN)
既不換行也不打印字符串中的分隔符。
(princ '("x" "y")) ;; (x y),未打印」引號「分割符
with-temp-buffer
(with-temp-buffer &rest BODY)
建立臨時buffer並像progn(後面介紹)執行BODY。
(setq myStr "big text") (with-temp-buffer (insert myStr) ;; manipulate the string here ;; print whole buffer content (message "%s" (buffer-string)))注 :大多數時候應該使用該函數建立新buffer,能夠節省建立buffer的代碼、切換到它作些事,
generate-new-buffer
建立新buffer並返回。
;; 設置新buffer名字,若是名字以空格開始,則撤銷會被禁止 (setq newBufName " xyz") ;; 建立一個新buffer並保存在一個變量中,以便後續切換或關閉 (setq newBuf (generate-new-buffer newBufName)) ;; 把新buffer設置爲當前buffer且不可見,全部的插入等操做都適用於它 (set-buffer newBuf)
get-buffer-create
(get-buffer-create BUFFER-OR-NAME)
若是字符串以空格開頭,則撤銷操做被禁止
;; 確保字符串是惟一的且以空格開頭 (setq newBuf (get-buffer-create " xyz")) (set-buffer newBuf)
buffer-name
;; 獲取當前buffer名字 (buffer-name)
buffer-file-name
;; 獲取buffer文件的完整路徑,若無文件返回nil (buffer-file-name)
with-current-buffer
建立臨時buffer,在函數執行完後會自動返回原buffer。
(witch-curent-buffer myBuf ;; insert or delete text here )
set-buffer
切換到指定buffer,但緩衝區不可見。
(save-current-buffer ;; switch to myBuf (set-buffer myBuf) ;; do stuff, such as insert/delete text )
switch-to-buffer
切換到指定buffer,但不用在Lisp代碼中,通常用於切換到可見緩衝區。
kill-buffer ;; 關閉指定buffer (kill-buffer myBuffer)
find-file
;; 打開文件,返回一個buffer (find-file "~/test.txt")
save-buffer
;; 保存當前buffer,保存buffer關聯文件 (save-buffer)
write-file
;; 至關於「另存爲」 (write-file "~/new.txt")
append-to-file
;; 在指定位置追加文本 (append-to-file 100 200 "~/test.txt") ;; 在位置100~200追加內容
(if test body) 或 (if test true_body false_body) (if (< 3 2) 7 8) ;; 8 ;; 若沒有false_body則返回nil (if (< 3 2) (message "yes")) ;; nil
若是if語句中不須要else部分,則可以使用when語句,形如:
(when condition expr1 expr2 ...) ;;等價於 (if condition (progn expr1 expr2 ...) nil)
若是if語句中不須要then部分,則可以使用unless語句,形如
(unless condition expr1 expr2 ...) ;;等價於 (if condition nil expr1 expr2 ...)
相似於C語言中的switch語句。
cond每一個clause必須是list,且list的car值是condition,剩餘部分是body-forms
(condition body-forms...)
若全部的condition爲nil,則表示全部的clause fail,cond返回nil。
(cond ((numberp x) x) ((stringp x) x) ((bufferp x) (setq temporary-hack x) ;; multiple body-forms (buffer-name x)) ;; in one clause ((symbolp x) (symbol-value x)))
可能cond語句的全部條件都測試爲nil,但咱們不但願cond返回nil,能夠用t做爲cond最後一個
clasue,如(t "default")。
(setq a 5) (cond ((eq a 'hack) 'foo) (t "default"))
注 :任何條件結構均可以由if或cond表示,區別在於風格,例
(if a b c) ≡ (cond (a b) (t c))
有時候咱們須要將多個表達式放在一個塊中做爲一個表達式,相似C中的塊`{…}`,在elisp中由函數progn實現。
(progn body...)
通常在if語句中使用
(if something (progn ;; true ... ) (progn ;; else ... ) )
progn返回其body最後一個表達式的返回值。
(progn 3 4) ;; 4
(while test body)
body由至少一個lisp表達式組成。
(setq x 0) (while (< x 4) (message (format "number is %d" x)) (setq x (1+ x))) ;; number is 3 (let ((mylist '(a b c))) (while mylist (message "%s" (pop mylist) (sleep-for 1))) ;; pop用於減小list
(mapcar FUNCTION SEQUENCE)
應用 FUNCTION,遍歷 SEQUENCE 元素,返回一個list。輸入 SEQUENCE 多是一個list、vector、
bool-vector或字符串,但輸出爲 list,且該 list 長度和 SEQUENCE 同樣。
(mapcar '1+ [3 4 5]) ;; (4 5 6),將1加在每一個vector元素並返回一個list (mapcar '1+ '(3 4 5)) ;; (4 5 6),將1加在每一個list元素並返回一個list
1+ 是一個lisp函數,它將參數加一併返回,如`(1+ 2)`返回3
在mapcar函數中使用,必須在函數名前加引用
1+ 是一個函數,因此須要加引用,即 `'1+` 或 `(quote 1+)`
(mapcar 'car '((1 2) (3 4) (5 6))) ;; (1 3 5),取出每一個元素list的第一個元素
mapcar 一般結合 lambda 使用,例如
(mapcar (lambda (x) (elt x 0)) [[1 2] [3 4]]) ;; (1 3),獲取每一個元素vector的第一個元素
lambda 定義一個「匿名函數「,可使你在代碼中定義一個函數,形如
(lambda (args) body) (lambda (x y) (+ x y)) ;; 取兩個參數相加,返回他們的和 (mapcar (lambda (x) (+ x 1)) (list 1 2 3 4)) ;; (2 3 4 5),每一個list元素加一
mapc相似mapcar,可是返回nil。
(mapc 'my-update-html-footer (list "~/file1.html" "~/file2.html" "~/file3.html" )) ;; 使用函數遍歷list中每一個文件
(dolist (VAR LIST) BODY) ;; 遍歷list返回nil (dolist (VAR LIST RESULT) BODY) ;; 返回 RESULT (let ( (xlist (number-sequence 97 122)) ;; list 97 to 122 ) (dolist (n xlist) (insert n)))
dolist和mapc主要區別
(dotimes (VAR COUNT) BODY ...) ;; 循環指定次數,從0開始計數,不包括COUNT,返回nil (dotimes (VAR COUNT RESULT) BODY ...) ;; 返回 RESULT
dotimes在使用升序計數的循環遍歷中很是有用
(dotimes (i 4) (insert (number-to-string i)))
退出函數:map,loop.
(catch 'tagname body)
catch執行body,返回body最後一個表達式的返回值。若body中包含(throw …),且被調用,則返回throw傳遞的值。
(throw 'tagname value)
退出函數或跳出相應tagname的map或loop
(defun test-exit-f () "example. using catch/throw to exit function" (interactive) (catch 'aaa (if (y-or-n-p "exit?") (progn (message "existing") (throw 'aaa 3) ;; 若是yes,馬上退出,並返回3 ) (progn (message "went on") 4 ;; return 4 )))))
可調用error或user-error
(defun test-exit-f "example" (interactive) (if (y-or-n-p "invoke user-error to exit?") (user-error "Error, because: %s" "you said so!") (progn (message "went on") )))
sequence和Array實際上不是elisp數據類型
list和vector區別
vector的長度不能改變
list的長度能夠改變,經過增刪list第一個元素實現
相似Java中的數組對象
讀寫元素隨機訪問時間相同
make-vector
(make-vector 5 0) ;; [0 0 0 0 0],建立一個長度爲5個元素的向量,且每一個元素初始化爲0
vector
(vector a b ...) ;; 建立一個包含元素a,b,...的向量
填充Vector
(fillarray array val) ;; 使array中的全部值爲val,相似從新賦值 (setq aa [3 4 5]) (fillarray aa nil) ;; [nil nil nil]
獲取Vector長度
(length (Vector 7 4 5)) ;; 3
獲取元素
(aref array n) ;; 返回array索引爲n的元素 (elt sequence n) ;; 返回sequence索引爲n的元素強調 :emacs文檔說起「array",你能夠認爲是"vector"或"string"
修改元素
;; 將 ARRAY索引爲IDX的元素值替換爲NEWELT,返回NEWELT (aset ARRAY IDX NEWELT)
嵌套Vector
;; Vector能夠以任何方式嵌套 [[1 2] [3 4]] ;; 2 by 2 matrix
鏈接Vectors,轉換list爲Vector
;; 鏈接任何sequence類型,返回一個vector (vconcat sequence1 sequence2 ...) (vconcat [3 4] '("a" "b")) ;; [3 4 "a" "b"]
轉換Vector爲list
;; 鏈接任何sequence類型,返回一個list (append sequence1 sequence2 ...)
注 :若想返回一個proper list,最後一個元素必須是list或nil.
(append [1 2 3] [4 5]) ;; (1 2 3 . [4 5]),improper list (append [1 2 3] [4 5] nil) ;; (1 2 3 4 5),proper list
建立list
(list a b ...)
若不想元素被執行,可寫做
'(a b ...) ;;等價於 (quote (list a b ...)) (setq mylist '(a b c)) (message "%S" mylist) (make-list LENGTH INIT) ;;建立長度爲LENGTH的list,全部元素初始化爲INIT
空list
在elisp中,空list等價於nil
'() ≡ (list) ≡ nil
list of number
(number-sequence n m step) ;; 返回從n到m,步長爲step的list (number-sequence n m) ;; 默認step爲1 (number-sequence n) ;; 返回只有一個元素n的list (number-sequence 0 9 3) ;; (0 3 6 9)
length
(length list)
獲取一個元素
(car list) ;; 獲取第一個元素 (nth n list) ;; 獲取第n個元素 (car (last list)) ;; 獲取最後一個元素 ;;list索引(下標)從0開始
獲取子list
(cdr list) ;; 獲取第二個元素到最後一個元素 (nthcdr n list) ;; 獲取第n個元素到最後一個元素 (butlast list n) ;; 獲取除最後n個元素的元素
前置鏈接list(prepend to list)
(cons x list) ;; 將x加到list前面,返回一個新list (cons "a" (list "c" "d")) ;; ("a" "c" "d")
鏈接list
(append sequence1 sequence2 ...) ;; 鏈接任何類型sequence,返回list
修改元素
(push list) ;; 在變量前加一個元素,返回新list (pop list) ;; 移除變量第一個元素,返回移除元素 (nbutlast list n) ;; 移除變量最後n個元素,返回變量新值 (setcar list x) ;; 用x替換list的第一個元素,返回x (setcdr list x) ;; 用x替換list除第一個元素外剩餘元素,返回x
list轉換爲string
(mapconcat 'number-to-string '(1 2 3) ",") ;; "1,2,3" (format "%s" '(1 "two" 3)) ;; "(1 two 3) (substring (format "%s" '(1 "two" 3)) 1 -1) ;; "1 two 3"
(defun function_name (param1 param2 ...) "doc_string" body)
函數返回值爲 body 中最後一個表達式的返回值.
(defun myFunction () "testing" (message "Yay!"))
可選參數(&optional)
若是你的函數須要可選擇的參數,只需在參數列表中加&optional選項,在該選項後的剩餘參數均是可選的.
;; 定義一個有兩個可選參數的函數,可選參數爲cc和dd (defun myfun (aa bb &optional cc dd) "test optional arguments" (insert aa bb cc dd)) (myfun "1" "2" "3" "4") ;; 當optional parameter 沒有給出,則它的值爲nil (myfun "myaa" "mybb" nil "mydd") ;; 若你不關心某個可選參數,可將其置爲nil
不定量參數(&rest)
要指定未指定數量的參數,可在最後一個參數添加&rest name;name的值能夠是一個list,若沒有給出,則是nil
(defun ff (aa bb &rest cc) "test rest arguments" (message "%s" cc)) ;; cc is a list (ff "1" "2" "3" "4") ;; ("3" "4")
若使一個函數可交互,在函數的doc string後面增長代碼(interactive)
(defun yay () "Insert 「Yay!」 at cursor position." (interactive) (insert "yay!"))
執行以上代碼,而後可使用"M-x yay"調用該函數.