2022-04-07 Thu
- 默认会对任何表进行求值,如表达式
(hello world)
会将 hello 作为指令 world 作为参数执行 - 特殊情况:
(quote a b c)
会将参数作为列表返回而不执行,等同于'(a b c)
`(a ,b c)
类似于 quote 但是会对 b 进行求值
2022-04-08 Fri
对 emacs 的任意操作都是执行表达式,比如 self-insert-command
绑定到任意输入键,执行插入对应字符。
- 基本函数( Primitive Functions ):: 由 c 实现的函数
defun
宏:
(defun
function-name
(args1 args2)
"可选的文档"
(interactive ARGUMENT-PASSING-INFO) ; 可选的标记函数是否可交互(通过 M-x 调用)
;; BODY...
(message args1)
(message args2)
)
2022-04-09 Sat
(interactive "p")
p
表示接收 prefix argument 作为函数参数。默认会设置为 1- prefix argument,通过
C-u <NUM>
或M-<NUM>
传递的参数 - elisp#Interactive Codes
2022-04-12 Tue
let
局部变量(let ((name value);;VARLIST unbound-var ;; nil ;;... ) BODY... ;;返回最后一个表达式的值 )
if
(if TEST THAN) (if TEST (THAN) (ELSE))
- 布尔值
false
nil
也是空列表()
的意思true
- 其他值
save-excursion
(save-excursion FIRST-EXPRESSION-IN-BODY SECOND-EXPRESSION-IN-BODY THIRD-EXPRESSION-IN-BODY ... LAST-EXPRESSION-IN-BODY)
保存当前 Point ,执行 BODY 后恢复到保存的 Point
- Point
- 当前指针的位置,整型,在文档开头值为 1
- mark
- 通过
C-<SPC>
设置的标记, - region
- mark 与 point 构成一个范围(region)
2022-04-13 Wed
mark-whole-buffer
transient-mark-mode
push-mark
append-to-buffer
let
与let*
的区别在赋值列表的行为(setq y 2) ;; 同步求值? (let ((y 1) ;; 1 (z y));; 2 (list y z)) (let ((x 1) (x 2)) ;; 赋值顺序不确定 (print x)) ;; 1 or 2 ;;一个接一个求值 (let* ((y 1) (z y)) (list y z)) ;; 1 1
2022-04-14 Thu
- windows
- A “window” is an area of the screen that is used to display a buffer.
- frames
- 包含 1 或多个 windows 的容器,表现为操作系统级的窗口
point
与window-point
不一致。interactive
if the string begins with*
, an error is signaled if the buffer(当前的) is read-only.let
可以用于临时隐藏外部 Symbol, 使setq
的作用域限定于let
的 scope(setq x (1+ 2)) ;; 3 (let (x) (setq x 1) (print x) ;; 1 ) (print x) ;; 3
2022-04-15 Fri
- 可选参数
&optional
\\[universal-argument]
函数文档中,这种形象的表达式会被解析为绑定的按键,见 help:beginning-of-buffer
2022-04-18 Mon
- narrow
C-x n n
, widenC-x n w
- lisp 对 buffer 的处理会会被限制于 narrow 的区域,比如
point-min
会返回 narrow 后的首字符位置 save-restriction
保存当前 narrow 的状态,完成后恢复car
, Contents of the Address part of the Register, 返回的是原子(first)cdr
, Contents of the Decrement part of the Register, 返回的是表(rest)cons
, construct lists not arrays.(cons CAR CDR)
(cons 'pine '(fir oak maple)) ;; (pine fir oak maple)
car
andcdr
,cons
is non-destructive(immutable).(nthcdr 2 '(pine fir oak maple))
相当于调用 n 次cdr
- 0 返回原列表
- >len 返回空列表
nil
(nth 2 '(pine fir oak maple))
相当于调用 n 次cdr
再调用car
setcar
andsetcdr
mutable 版本(setq animals (list 'antelope 'giraffe 'lion 'tiger)) (setcar animals 'hippopotamus) ;; animals => hippopotamus giraffe lion tiger (setcdr animals '(cat dog)) ;; animals => hippopotamus cat dog
2022-04-19 Tue
- 隐式
progn
,文档中以...
表示,比如BODY...
kill-ring
`引用'
相当于'引用'
。历史遗留问题,info 里面用的是弯引号kill-region
kill 理解为 clipcondition-case
相当于 try-catch
2022-04-25 Mon
- emacs 中的异常叫 “signaling an error”
- macro
when
2022-05-31 Tue
after-change-functions
注册的函数接收三个函数, region 、变更前的文本长度;; 通过这三个参数判断是不是另起一行 ;; beg 是上一行最后一个位置 ;; end 是新行第一个位置 (and (eq len 0) (not (eq beg end)) (eq (char-after beg) 10)))
- Association List(alist),关联列表
car 部分作为 key. cdr 部分作为 value.
常用如下语法构建 alist :
((pine . cones) (oak . acorns) (maple . seeds))
如果是
(pine connes)
等价于(pine . (connes))
assoc
通过 key 获取 pairrassq
则是通过 value
2022-06-02 Thu
正则表达式
- 要输入
\
的字面量是\\
,因为\
也是 elisp 字符串的转义符号,字符串先被 elisp 转义后再输入给 regex 引擎。 (){}|
不转义的话会匹配原意,这与其他正则相反。
还有反习惯的点:\
在 []
(character alternatives)里只是普通字符,不能起转义作用。
- 要匹配
]
需要在第一个有效字符声明[]]
或[^]]
-
需要在最后一个有效字符[abcde-]
^
不能在第一个字符
所以 []
(character alternatives)不能放入 syntax(\sCode) 和 category(\cCode),这也在 rx[fn:1] 的文档得到验证。
Each SET is a character, a string representing the set of its characters, a range or a character class…
正则表达式相关的字符集合:
- elisp#Char Classes
\sCode
elisp#Syntax Class Table elisp 的概念,每个 buffer 或者 main mode 都有自己的定义\cC
,C
指 elisp#Categories. 可以实现类似于\p{Han}
的效果describe-categories
可以获取当前 categories table
Footnotes
[fn:1] rx 是 emacs 一套用 S-表达式表示正则表达式的工具,见 elisp#Rx Constructs