如下内容均在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"调用该函数.