学习Elisp基础,https://learnxinyminutes.com/docs/elisp/
Emacs Lisp 为一个函数式的语言,所以它全部 功能都是由函数来实现的。
Learn X in Y minutes, Where X=elisp
15分钟学会Emacs Lisp (v0.2a)
;;(作者:bzg,https://github.com/bzg
;; 译者:lichenbo,http://douban.com/people/lichenbo)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
打开emacs
;;
;; 按'q'消除欢迎界面
;;
;; 现在请注意窗口底部的那一个灰色长条,"*scratch*" 是你现在编辑界面的名字。
;; 这个编辑界面叫做一个"buffer"。
;;
;; 每当你打开Emacs时,都会默认打开这个scratch buffer,此时你并没有在编辑任何文件,
;;而是在编辑一个buffer,之后你可以将这个buffer保存到一个文件中。
;; 之后的"Lisp interaction" 则是表明我们可以用的某组命令
;;
;; Emacs在每个buffer中都有一组内置的命令,而当你激活某种特定的模式时,就可以使用相应的命令
;; 这里我们使用`lisp-interaction-mode',这样我们就可以使用内置的Emacs Lisp命令了。
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 分号是注释开始的标志
;;
;; Elisp 是由符号表达式构成的 (即"s-表达式"或"s式"):
(+ 2 2)
;; 这个s式的意思是 "对2进行加2操作".
;; s式周围有括号,而且也可以嵌套:
(+ 2 (+ 1 1))
;; 一个s式可以包含原子符号或者其他s式
;; 在上面的例子中,1和2是原子符号
;; (+ 2 (+ 1 1)) 和 (+ 1 1) 是s式.
;; 在 `lisp-interaction-mode' 中你可以计算s式.
;; 把光标移到闭括号后,之后按下ctrl+j(以后简写为'C-j')
(+ 3 (+ 1 2))
;; ^ 光标放到这里
;; 按下`C-j' 就会输出 6
;; `C-j' 会在buffer中插入当前运算的结果
;; 而`C-xC-e' 则会在emacs最底部显示结果,也就是被称作"minibuffer"的区域
;; 为了避免把我们的buffer填满无用的结果,我们以后会一直用`C-xC-e'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; `setq' 可以将一个值赋给一个变量
(setq my-name "Bastien")
;; `C-xC-e' 输出 "Bastien" (在 mini-buffer 中显示)
;; `insert' 会在光标处插入字符串:
(insert "Hello!")
;; `C-xC-e' 输出 "Hello!"
;; 在这里我们只传给了insert一个参数"Hello!", 但是我们也可以传给它更多的参数,比如2个:
(insert "Hello" " world!")
;; `C-xC-e' 输出 "Hello world!"
;; 你也可以用变量名来代替字符串
(insert "Hello, I am " my-name)
;; `C-xC-e' 输出 "Hello, I am Bastien"
;; 你可以把s式嵌入函数中
(defun hello () (insert "Hello, I am " my-name))
;; `C-xC-e' 输出 hello
;; 现在执行这个函数
(hello)
;; `C-xC-e' 输出 Hello, I am Bastien
;; 函数中空括号的意思是我们不需要接受任何参数,但是我们不能一直总是用my-name这个变量
;; 所以我们现在使我们的函数接受一个叫做"name"的参数
(defun hello (name) (insert "Hello " name))
;; `C-xC-e' 输出 hello
;; 现在我们调用这个函数,并且将"you"作为参数传递
(hello "you")
;; `C-xC-e' 输出 "Hello you"
;; 成功!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 下面我们在新的窗口中新建一个名为 "*test*" 的buffer:
(switch-to-buffer-other-window "*test*")
;; `C-xC-e' 这时屏幕上会显示两个窗口,而光标此时位于*test* buffer内
;; 用鼠标单击上面的buffer就会使光标移回。或者你可以使用 `C-xo' 使得光标跳到另一个窗口中
;; 你可以用 `progn'命令将s式结合起来:
(progn
(switch-to-buffer-other-window "*test*")
(hello "you"))
;; `C-xC-e' 此时屏幕分为两个窗口,并且在*test* buffer中显示"Hello you"
;; 现在为了简洁,我们需要在每个s式后面都使用`C-xC-e'来执行,后面就不再说明了
;; 记得可以用过鼠标或者`C-xo'回到*scratch*这个buffer。
;; 清除当前buffer也是常用操作之一:
(progn
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello "there"))
;; 也可以回到其他的窗口中
(progn
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello "you")
(other-window 1))
;; 你可以用 `let' 将一个值和一个局部变量绑定:
(let ((local-name "you"))
(switch-to-buffer-other-window "*test*")
(erase-buffer)
(hello local-name)
(other-window 1))
;; 这里我们就不需要使用 `progn' 了, 因为 `let' 也可以将很多s式组合起来。
;; 格式化字符串的方法:
(format "Hello %s!
" "visitor")
;; %s 是字符串占位符,这里被"visitor"替代。
是换行符。
;; 现在我们用格式化的方法再重写一下我们的函数:
(defun hello (name)
(insert (format "Hello %s!
" name)))
(hello "you")
;; 我们再用`let'新建另一个函数:
(defun greeting (name)
(let ((your-name "Bastien"))
(insert (format "Hello %s!
I am %s."
name ; the argument of the function
your-name ; the let-bound variable "Bastien"
))))