Elisp Notes
文章目录
example for number conversion expmple
教程
入门
xahlee
- http://xahlee.info/emacs/index.html
- Emacs Lisp Basics
- 注意: xahlee 会跳出付费页边,可以不用管,直接点击具体条目
- xahlee 美化的 elisp 官方文档
美化格式的 elisp 官方教程
xah lee elisp 教程
sequence 教程
教程
- 类型介绍: Emacs Lisp: Sequence Type
- seqence 操作函数 Emacs Lisp: Sequence Functions
- 遍历方法:Emacs Lisp: Sequence Iteration
list
- association list: Emacs Lisp: Association List
- property list: Emacs Lisp: Property List
array
- vector
- string
遍历
- dotimes
- dolist
- while
CheatSheet
参考
library
f
- file
s
- string
dash
- list
Cheat Sheet
字符串
创建 字符串
连接
string
- (string "a" "b", …)
char type
| escape character | comment |
|---|---|
| "\uNNNN" | 2Byte |
| "\U00NNNNNN" | 3Byte, less than U+10FFFF |
| "\xNN" | 1Byte, hex |
| \000 | octal |
| Control character | |
| ^I | |
| C-I | |
| Meta Charcter | |
| M-I | |
| Shift Character | |
| S- | |
| Alt | A- |
| super | s- 注:小写 s |
| hyper | H- |
Symbol
参考:
概述:
- Symbol
- keyword symbol + constant
关联的 cell
- 解释:即关联的数据
类型
print name
- 即 symbol 名称的字符串表示
- value
function cell
- 函数定义对象,用户函数,macro 等
property list(plist)
- 各种状态数据
相关函数
四种 cell 获取
value, 获取值
symbol-value
name, 获取 symbol 的 string 名称
symbol-name- 类似 python
__name__方法
function
symbol-function
plist
symbol-plist
string 名称转换成 symbol
internintern-safe- 如果 symbol 不存在,返回 nil
判断是否是 symbol
symbolp
检查 function cell 是否为空
fboundp
List Type
CAR, CDR, ATOM
- atom
- object that is not a cons cell.
- lists
- a series of cons cell.
- cons cell
- an object that consists of two slots, called the CAR slot and the CDR slot.
- dotted notation
- list notation
(1 . (2 . (3 . nil))) —-> (1 2 3)
(a . b) —-> (a b) —-> (a . (b))
(a . b . c) =====> 错误写法,cdr 已被 b 占用,c 就不能再成为 cdr
注:我的理解–> dotted notation —>逐层嵌套的 list
list
Predicates
listp
- is list?
nlistp
- not list?
proper-list-p?
1 2(proper-list-p '(a b . c)) ⇒ nilatom
- is atom?
null
- is null?
consp
- is a cons cell?
Access elements 访问元素
- car
- cdr
cdr-safe
- if the cdr part is a cons cell, return it, nil otherwise.
- 如果 输入 object 不是 list, 会报错
删除
pop
删除 list 中第一个元素
1(pop your-list)
访问 index 元素
nth
类似 arr[i]
1(nth 0 '(a b c)) --> a
切片
nthcdr
切片, 类似 python, arr[i:], 不包括 i
1(nthdr 0 '(a b c)) --> (b c)
last
最后的 N 个元素,特有功能
1(last '(a b c) 2) --> (b c)
butlast
去掉尾部 N 个元素,剩下的部份;特有功能
- 与 last 互补
注意
创建一个拷贝,而 last 关联的还是原来的 List
1(butlast '(a b c) 1) --> (a b)
nbutlast
类似 nbutlast
- 在原来 List 的基础上修改
注意
这样会破坏原有的 List
1(nbutlast '(a b c) 1)
长度
safe-length
- 统计不同的 (distinct) cons cell 的数量
创建 List 和 Cons Cells
连接创建
cons
cons cell 模式创建
1 2 3 4 5 6(cons 1 '(2)) ⇒ (1 2) (cons 1 '()) ⇒ (1) (cons 1 2) ⇒ (1 . 2)作用情况
- 元素 + list –> new_list
- 元素 + 元素 –> cons cell –> (A . B)
list + list –> 元素 + list –> (listA …)
- 相当于 python: [listA] + listB
注意
- 第一个被当成 car
- 第二个被当成 cdr
- list
枚举元素模式创建
(list &rest objects)把枚举的元素,转变成 list
1 2(list 1 2 3) --> (1 2 3) (list '(a b) 1 2 3) --> ((a b) 1 2 3)注意
- 每个对象都会被当成元素
make-list
- 重复元素模式创建
创建重复元素,新 list
1(make-list 3 'a) --> (a a a)
append
- 拼接模式创建
- 类似 python, list.extend, 即: listA + listB
(append a-list b-list)
1 2 3 4 5 6(setq trees '(pine oak)) ⇒ (pine oak) (setq more-trees (append '(maple birch) trees)) ⇒ (maple birch pine oak) (append) --> nil特性
相当于,连续使用 cons 函数拼接 car 与 cdr
1 2(apply 'append '((a b c) nil (x y z) nil)) ⇒ (a b c x y z)
copy-tree
- 创建拷贝模式
- 完全创建一个新的 list,所有的节点都被复制一遍
- (copy-tree tree)
flatten-tree
- 一维展开模式
把多种复合形式的嵌套 list,展开成一维
1 2(flatten-tree '(1 (2 . 3) nil (4 5 (6)) 7)) ⇒(1 2 3 4 5 6 7)
number-sequence
- 数字序列(迭代器)模式
- 类似 python range(start, stop, step)
(number-sequence from-number &optional to-number seperation-number)
1 2(number-sequence 1 10 2) ----> (1 3 5 7 9)
Modifying 修改 List
push
- <—> pop
- 添加元素
在头部添加元素
1 2 3 4 5 6(setq l '(a b)) ⇒ (a b) (push 'c l) ⇒ (c a b) l ⇒ (c a b)- (push element your-list)
add-to-list
- 判断式,尾部添加
- (add-to-list your-list element)
如果 element 不在 your-list 中
- 会通过 cons 的方法,被添加到 your-list 的尾部
add-to-ordered-list
- 按顺序插入
- 已经存在,则根据参数 Order 更新存放位置
| |
delete
- 删除给定元素,使用 equal 判断
- 只删除一个
delq
- 删除给定元素,使用 eq 判断
注
- 只删除一个相等的
- 有重复,删除后面的,而不是前面的
- 修改输入的 list
remq
- 删除所有的给定元素,使用 eq 判断
注
- 删除所有的
- 返回的是新的 list
- 不修改原来的 list
Association List (alist)
参考:
特点:
- 一个 (key . value) 对 pair 组成的 list
- 允许 key 重复
- 有序 key
注:类似 python 的字典 dictionary, 但是 key 可以重复
| |
In each element, the CAR is considered a “key”, and the CDR is considered an “associated value”.
值获取
alist-get
pair 获取 (类似 python dict item)
通过 key 获取
assoc: equal 比较assq: eq 比较
通过 value 获取
rassoc: equal 比较rassq: eq 比较
添加元素 pair
push- 开头添加
- 不检查是否已经存在 key
- eg:
(push '("cc" . 33) the-alist)
删除元素 pair
assoc-delete-all- 删除所有满足 key 的 pair
- 通过
equal判断 - eg:
(setq xx (assoc-delete-all "bb" demo-alist))
assq-delete-all- 删除所有满足 key 的 pair
- 通过
eq判断
rassoc-delete-all
- 删除所有满足 value 的 pair
Property List (plist)
参考:
特点:
- 相当于展开的 alist
- 禁止 key 重复
- key 必须是 elisp 语言的 Symbol 类型对象
- value 可以是其他任意类型对象
用途:
- elisp 中 symbol 的属性存储
Symbol Property List Text Properties- 不是通用类型,不适合大规模数据存储,元素数量 <= 100, 最好
创建
| |
值获取 get
plist-get- 通过
eq测试 key
1 2(plist-get '(x 1 y 2) 'y) ; 2 (plist-get '(x 1 y 2) 'b) ; nil- 通过
lax-plist-get- 通过
equal测试 key
- 通过
值修改 put
plist-puteq测试
lax-plist-putequal测试
key 存在判断
plist-membereq测试
Hash Table 哈稀表
参考:
特点:
无序
- 类似的结构 alist 是有序的
key 无重复
- 相反 alist 是允许重复 key 的
相关函数:
- make-hash-table
- gethash
- rmhash
- puthash
- clrhash
keys
hash-table-keys
values
hash-table-values
map
- maphash
重建
make-hash-table1 2;; create a hash table (setq xx (make-hash-table :test 'equal))手动创建
1 2 3 4 5 6 7 8 9 10 11(setq xx #s(hash-table size 30 test equal data ( "aa" 3 "bb" 9 "cc" 5 ))) ;; test (equal (gethash "aa" xx ) 3)
添加 element
puthash1 2 3(let ((xx (make-hash-table :test 'equal))) (puthash 'aa 9 xx) xx)
删除 element
rmhash1(remhash KEY TABLE)
删除所有元素
clrhash- clear hash
获取 element (get)
gethash1(gethash key table default)
长度 length
- hash-table-count
map 函数
maphash1 2 3 4 5 6 7 8 9 10 11 12(setq xx (make-hash-table :test 'equal)) (puthash "aa" 19 xx) (puthash "bb" 20 xx) (puthash "dd" 17 xx) (puthash "cc" 21 xx) (maphash (lambda (k v) (princ (format "%s , %s" k v)) (princ "\n")) xx )- 这里函数接收的是 (key, value) 键值对
Symbol Property List
概要:
- 这是一个 symbol 所关联的 plist
用途:
- 可以存储 function 关联的状态信息,而不用专门创建一个 global 变量
相关函数:
访问 symbol 的整个 plist
设置(赋值,类似 setq)
setplist
获取
symbol-plist
内部的单个 key / value 操作
修改
put
访问
get
Array Type
| 类型 | 备注 |
|---|---|
| strings | 字符串 |
| vectors | can hold any type of objects |
| bool-vectors | element –> t or nil |
| char-tables |
Vector
参考:
特点:
长短固定
- length is fixed
修改/访问时间固定
- accessing any element spend the same time –> different from list
固定索引 indexed
- zero-origin –> element index counting from zero
一维数据
- only one dimension
多维数据
- 通过嵌套 vector 实现
- multi-dimension —> nested one dimensional arrays
类型可变
- 元素的类型是任意的
创建
make-vector- 相同元素的 vecotr
eg:
1 2 3 4(equal (make-vector 5 0) [0 0 0 0 0] )
vector- 枚举元素法
- 参数被 eval
eg:
1 2 3 4(equal (make-vector 5 0) [0 0 0 0 0] )
手写法
- 参数不会被 eval
- 格式:
[a b c] eg:
1 2 3 4 5 6 7 8 9(let (aa xx) (setq aa 4) (setq xx [3 aa 5]) (equal xx [3 aa 5] )) ;; the aa remains a symbol- 这里 aa 没有被 eval, 所以还是 symbol aa, 而不是数值 4
填充相同元素
fillarray
长度
length
获取元素
aref
修改元素
aset
String
a string is a constant
new line is new line , escape new line is ignored by reading <==
'\ ' –> 转义换行,在 reading 中被忽略
"It is useful to include newlines
in documentation strings,
but the newline is \
ignored if escaped."
⇒ "It is useful to include newlines
in documentation strings,
but the newline is ignored if escaped."
Multibyte and unibyte
| 字符表示形式 | 备注 |
|---|---|
| \uNNNN, \U00NNNNNN | –> multibyte |
| \xN, \N | –> hexadecimal and octal escape sequence –> unibyte |
| –> use '\ ' (backslash + space) to terminate excape sequence | |
| –> 反斜杠 + 空格 终止有歧义的 转义字符 |
Nonprinting character
| 字符表示形式 | 备注 |
|---|---|
| ASCII control character | 不能分辨大小写 |
| ASCII meta character | 除 key binding 外,不能在 string 中识别 |
| super, alt, hyper character | string can not hold it |
Text properties in String
#("foo bar" 0 3 (face bold) 3 4 nil 4 7 (face italic))
Char table
printed representation –> start with #^
Bool-Vector
printed representation –> start with #& and followed by length
(make-bool-vector 3 t)
⇒ #&3"^G"
Hash Table
printed representation –> start with #s
macro
lisp macro <—> differnt from keyboard macro lisp macro —> a list start with element macro —> define with "defmacro" (itself is a lisp macro)
primitive function
| |
Equal Predicate
| 函数 | 备注 |
|---|---|
| eq | –> for integers, same value –> equal |
| –> same object | |
| equal | –> same elements recursively –> equal |
| equal-including-properties |
Numbers
Integer 整数
基数–>radix, 允许取 2-36 ‘#’ followed by a letter that specifies the radix: ‘b’ for binary, ‘o’ for octal, ‘x’ for hex, or ‘RADIXr’ to specify radix RADIX.
#b101100 ⇒ 44 #o54 ⇒ 44 #x2c ⇒ 44 #24r1k ⇒ 44
取值范围
variables
| most-positive-fixnum |
| most-negative-fixnum |
Float
special definition
infinity –>‘1.0e+INF’ and ‘-1.0e+INF’
not-a-number –>‘0.0e+NaN’ and ‘-0.0e+NaN’
functions for floating-point numbers
| 函数 | 备注 |
|---|---|
| isnan x | |
| frexp x | return cons (S . E) |
| S –> significand | |
| E –> exponant | |
| base –> 2 | |
| ldrexp s e | return s*2**e |
Predicates for Numbers
| 函数 | 备注 |
|---|---|
| floatp | |
| integerp | |
| numberp | |
| natnump | is a natural number? |
| zerop | is equal to ZERO |
Comparision for Numbers 数字的比较
| 函数 | 备注 |
|---|---|
| eq | 最严谨, is same object |
| equal | 先 is same type,后 is same value |
| eql | 类似 eq, 但 numbers, 类似 equal, |
| 即:先 is same type,后 is same value | |
| "=" | 只比较 is same value,且有 debug message |
| "/=" | is not equal 不等于号 |
| 参数,必需是 numbers or markers | |
| "<" | |
| ">" | |
| "<=" | |
| ">=" | |
| max | 参数,必需是 numbers or markers |
| min | |
| abs | 参数, numbers |
Number conversion
| 函数 | 备注 |
|---|---|
| (float num) | –> convert num to floating-point number |
| convert to Integer | output ====> arg 参数若为 floating-point, 报错 arith-error |
| (truncate number &optional divisor) | 取接近 0 的整数部份 |
| floor | |
| ceiling | |
| round | 取最近的整数,四舍五入 |
注:
—> for divisor args, both arguments may be integers or floating-point numbers. DIVISOR may also be ‘nil’. If DIVISOR is ‘nil’ or omitted, these functions convert NUMBER to an integer, or return it unchanged if it already is an integer. If DIVISOR is non-‘nil’, they divide NUMBER by DIVISOR and convert the result to an integer. If DIVISOR is zero (whether integer or floating point), Emacs signals an ‘arith-error’ error.
| |
Arithmetic Operations 算术运算
| 函数 | 备注 |
|---|---|
| '1+ | |
| '1- | |
| '- | (-) –> 0 |
| '+ | (+) –> 0 |
| '* | (*) –> 0 |
| '/ | divisor 为 0 –> 报错 arith-error |
| '% | args 参数必需是整数,不能是浮点数 |
| divisor 不能为 0 | |
| 'mod | 类似 % |
| 但是 args 可以是 floating-point |
| |
Rounding operation, 修剪函数==> 返回 foating-point Numbers
| 函数 | 备注 |
|---|---|
| (ffloor float) | 类似 floor 函数,但返回值,为浮点型 |
| fceiling | |
| fround | |
| ftruncate |
Bitwise Operation 位运算, 即:按位逻辑运算
| 函数 | |||
|---|---|---|---|
| (lsh Integer Step) | logical shift | 由名称可以看出 | |
| 移位运算, | 它适合 | ||
| 逻辑运算 | |||
| Step | –> 为正,左移 | , | |
| –> 为负,右移 | 因为最高位 | ||
| 补的是零 | |||
| 右移,Integer | 负数,最高位,补零 | ||
| 正数,最高位,补零 | |||
| (ash Integer Step) | arithmetic shift | 由名称可以看出 | |
| 移位运算 | 它适合 | ||
| 算术运算 | |||
| Step | –> 为正,左移 | , | |
| –> 为负,右移 | 因为最高位 | ||
| 补的是一 | |||
| 右移,Integer | 负数,最高位,补一 | ||
| 正数,最高位,补零 | |||
| (logand int1 int2) | 按位逻辑与 | ||
| logior | 按位逻辑或 | ||
| logxor | 按位逻辑异或 | ||
| lognot | 按位逻辑非 |
Standard Mathematical Functions 各种数学函数
| 函数 | 备注 |
|---|---|
| sin arg | 三角函数 |
| cos arg | |
| tan arg | |
| asin | 反三角函数 |
| acos | |
| atan | |
| (exp arg) | |
| (log arg &optional base) | 默认自然对数 |
| base ==> 基数 | |
| 如果,底-> arg | |
| 或,真数 -> base | |
| 为零,报错 ==> NaN | |
| (expt x y) | 相当于 x 的 y 次幂 |
| 即 x ^ y, | |
| x**y | |
| (sqrt arg) | 平方根 |
| squar root | |
| 特殊常量 | |
| mathematical constant | |
| float-e | e ==> 自然对数的底 |
| float-pi | 圆周律 PI |
Random Function 随机函数
pseudo random function, actually.
| 函数 | 备注 |
|---|---|
| (random &optonal LIMIT) | 若有 LIMIT, |
| 0<= random number < LIMIT | |
| 若无 LIMIT, | |
| random number, | |
| 在 | |
| most-positive number, | |
| most-negtive number | |
| 之间 | |
| (random "") | 参数为 空字符串 |
| 产生确定序列的,random numbers | |
| (在同一个 executable 内) | |
| (random string) |
Strings and Characters
string-width 字符串长度
函数:(string-width str)
String Predicate 字符串判断
| 函数 | 备注 |
|---|---|
| stringp | |
| string-or-null-p | string or nil |
| char-or-string-p |
Make String 创建 字符串
make-string
| 函数 | 备注 |
|---|---|
| (make-string COUNT CHAR) | 重复 CHAR,COUNT 次==> new string |
| |
substring
| 函数 | 备注 |
|---|---|
| (substring String &optional Start End) | 制造 子串 |
| |
| 符号 | |
|---|---|
| nil | –> 末尾,字符串结尾 |
| -1 | –> 负数,从右边计数 |
注:子串中包含了,text-properties
substring-no-properties
(substring-no-properties String &optional Start End)
concat
(concat &rest Sequences) : 连接字符串
split-string
| 函数 | 备注 |
|---|---|
| (split-string String &optional Seperator Omit-nulls Trim) | 太复杂,查看文档 |
| 特例: | |
| (split-string String) | 此时, |
| Seprator –> split-string-default-seperators | |
| 例: | Omit-nulls ->t |
| (split-string " two words ") | |
| ⇒ ("two" "words") | |
| 参数 args | |
| Seprator | 分割符 |
| 可为,正则表达式,regexp | |
| 注意, | |
| greedy wild card (*) <–> non greedy wild card (+) | |
| *,包含空串"" | |
| +,不包含空串"" | |
| Omit-nulls | 是否忽略 nil,即空串,"" |
| 默认值–> nil, 即不忽略"" | |
| Trim | 可为,正则表达式,regexp |
| 对上面产生的子串, | |
| 再次修剪, | |
| 删除,符合 Trim 的部份 | |
| 特殊常量 | |
| constant variable | |
| split-string-default-seperators | 默认值 |
| ‘"[ \f\t\n\r\v]+"’注意:第一个是空格 |
| |
Modify String 修改 字符串
| 函数 | |
|---|---|
| (aref Array Index) | |
| (aref String Index) | 按下标,获取 String 的第 Index 个字符 |
| (aset Array Index Object) | replace the element at Index with Object |
| and don't construct a new array. | |
| (aset String Index Char) | 元素取代 |
| (store-substring String Index Obj) | store Obj into String at Index |
| Mind the Length of Obj < String | |
| or error | |
| 插入子串,注意,字符串长度 | |
| (clear-string String) | zeroing String, 清零 String |
Comparison of Characters and Strings 字符 与 字符串 比较
| 函数 | |
|---|---|
| char-equal | 大小写字母,敏感性 |
| 由 variable | |
| case-fold-search | |
| 决定 | |
| 注:case-fold-search –>buffer-local variable | |
| string= | 在比较字符串值时 |
| string-equal | 它们效果相同 |
| equal | case-fold-search |
| 对它无效 | |
| string< | |
| string-lessp | |
| string> | |
| string-greaterp | |
| (string-collate-equalp String1 String2 | 与 设置 Locale 相关 |
| &optional locale ignore-case) | |
| string-collate-lessp | |
| string-version-lessp | 把字符串中的数字, |
| 当成一个整体数字 | |
| 来参与比较 | |
| (string-prefix-p Prefix String &optional ignore-case) | 判断,Prefix 是否是 |
| String 的前缀 | |
| string-suffix-p | |
| (compare-strings string1 start1 end1 string2 start2 end2 | 比较特定序列 |
| &optional ignore-case) | |
| (assoc-string key alist &optional case-fold) | 比较 key 与 alist 的 |
| car 部份是否相等, | |
| key 必需是 string | |
| 使用 compare-strings | |
| 比较 | |
| (compare-strings Str1 Start End Str2 Start End | The value is t if the strings (or specified portions) match. |
| &optional Ignore-case) | If string STR1 is less, the value is a negative number N; |
| - 1 - N is the number of characters that match at the beginning. | |
| If string STR1 is greater, the value is a positive number N; | |
| N - 1 is the number of characters that match at the beginning. | |
| 即: | |
| 相同 –> 返回 t | |
| 大于 –> 返回正数 N,相同部份 Index 下标,abs(N) | |
| 小于 –> 返回负数 N,相同部份 Index 下标,abs(N) |
注:case-fold <–> ignore-case 都是 忽略大小写 的意思。
Conversion of Chars and Strings 字符串,字符,数字 –> 转换
| 函数 | |
|---|---|
| number-to-string Number | Number ==> String |
| string-to-number String &optional Base | String ==> Number |
| 无法转换的 String | |
| output ==> 输出 0 | |
| string-to-char | 取出 String 的第一个 字符 |
| 空串 –> 0 | |
| char-to-string | |
| List <===> String | |
| concat &rest Sequences | Vector or List ===> String |
| vconcat &rest Sequences | String or Something ===> Vector |
| append &rest Sequences | String or Something –> List |
| byte-to-string Byte | a byte char ==> a unibyte String |
| (byte-to-string ?a) –> "a" |
Formatting Strings 格式化创建字符串
| 函数或格式 | |
|---|---|
| format String &rest args | |
| format-massage String &rest args | 与 format 区别 |
| 把 apostrophe( ' )单引号 | |
| 和 grave accent ( ` ),即 back quote | |
| 分别转换成 | |
| 汉语的标点符号 | |
| 左单引号(‘) 和 右单引号( ’) | |
| 格式化方法 | 类似 C 语言的 printf 函数 |
| a format specification | |
| 百分号 | |
| %% ==> % | |
| 字符串与字符 | |
| %s | |
| %c | |
| 浮点数 | |
| %e | |
| %f | |
| %g | 如果 if,该数的指数部份,小于-4 |
| 或,该数大于等于 >= 显示精度 precision(默认为 6) | |
| { 使用指数形式输出 } | |
| 否则 else, | |
| { 使用小数形式输出 } | |
| 整数 | |
| %d | |
| %o | 八进制 |
| %x | |
| %X | |
| %S 注意大 S |
| 函数或格式 | |
|---|---|
| %-sequence 特别化格式 | |
| %<field><flags><width><precision>characters | |
| <field> | 指定具体引用,后面哪一个参数 |
| 形式==> number$ | |
| (format "%2$s, %3$s, %%, %1$s" "x" "y" "z") | output ==> "y, z, %, x" |
| <flags> | |
| 形式==> [+ #-0] | +,空格,#,-,0 |
| 这三个,用于占位 | |
| + | +,只能占一个位置,即显示正负号的地方 |
| 空格 | 以空格占位 |
| 0 | 以 0 占位 |
| - | 左对齐,默认右对齐 |
| # | 特别: |
| 相对 %o, %x, %X | |
| 分别以 0, 0x,0X 为前缀显示,输出数字 | |
| 例:%8.5d | 类似 C 语言,占位 8 个,小数点后显示 5 位 |
| <width> | |
| <precision> | 特例: |
| %f, %e, %g | |
| 小数形式,precision ==> 小数点后的位数 | |
| 指数形式,precision ==> 有效数字的位数 | |
| significant -> 有效数字 | |
| %s | |
| precision ==> 截取 String 的前 pricison 个字符 |
注意:
列表,参与运算需要,添加(')号
- dolist, mapcar
- 不加撇号,列表会被当成函数调用,被执行
- '(a b c) 等价于 (quote (a b c))
nth <—> elt
- nth, 只用于 list
- elt,即 element,用于序列 sequence
- 都是 index,从 0 开始计算的
vector
- (vector a b c)每个元素都会被执行
- [a b c],其中的元素不会被执行
(add-to-list 'list-var 'element)
- 其中的 list-var 变量必须加(')号
dolist
- (dolist (var your-list [RESULT]) Body…)
- 其中,var 变量用于接收 your-list 中的元素
- 而,RESULT 用于存放返回值(return value)
Sequence 类型转换
List –> Vector
- (vconcate seqence1 sequence2)
Vector –> List
- (append sequence1 sequence2)
association list 关联表
- cons pair —> (a . b) —> (key . value)
- list of cons pair ==> association list
- ((a . b) (c . d))
key <—> value, 关联表是,有 car 和 cdr 的列表的列表
- car –> key
- cdr –> value
eg:
1 2 3 4 5 6 7((pine . cones) (oak . acorns) (maple . seeds)) ((a . 1) ("b" 2 3)) ((rose red) (lily white) (buttercup yellow))
(assoc key a-list)
- 通过 key 查找 cons pair 对
(rassq value a-list)
- 通过 value 查找 cons pair 对, 通过 eq 判断
- (rassoc value a-list)
如何向 lambda 函数传递参数
方法: 使用 backquote expression
参考:
Backquote Reader Macro
参考:
- xah lee: Emacs Lisp: Backquote Reader Macro
用法解释:
- backquote 符号即(`),类似与单引号的用法,也是为了阻止变量被 eval, 不同之处在于反引号对一个 list 使用时, 里面的元素可以在前面加上一个逗号, (,)逗号表示"unquoted",即要使用它的值而不是表达式本身
`: backquote, 开始一个 backquote list,: unquoted, 用来表示哪些 element 会被执行1 2 3 4 5 6 7(setf name 'fred) `(this is ,name) (this is fred) `(i give ,name ,(* 10 10) dollars) (i give fred 100 dollars) ex 14.5- 参考 function (\'), 获取详细解释
,@: comma at, 展开 element(子 list)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16;; example of turning a list into elements, inside a list (setq x1 (list 1 2)) (setq x2 (list 3 4)) ;; we want the elements of x1 and x2 inside a list, but not as sublist (setq x3 `(0 ,@x1 ,@ x2)) ;; 这样写也可以: (setq x3 `(0 ,@ x1 ,@ x2)) (equal x3 '(0 1 2 3 4)) ;; true (proper-list-p x3) ;; true
特殊用法:
用来展开 list 用作函数的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17;; our test function (defun ff (x y z) "return args as one string" (format "%s %s %s" x y z)) ;; normal usage (equal (ff 2 3 4) "2 3 4") ;; define a list (setq xx '(2 3 4)) ;; use backquote reader macro, to turn a list into elements, then use eval (equal (eval `(ff ,@ xx)) "2 3 4")
function quote #'
interactive elisp mode
command –> ielm
function
interactive
参数类型:
"P":
- 使用 Ctrl-u –> 1
没有 Ctrl-u –> nil
1 2(defun my/fun (&optional arg) (message "arg: %s" arg))
"p":
- 使用 Ctrl-u –> 4
- 没有 Ctrl-u –> 1
Buffer
创建 Buffer
简单创建
1 2 3 4 5 6(setq bufferName "myBuffer") ;; create buffer (generate-new-buffer bufferName) (setq newBuff (generate-new-buffer bufferName))注意
如果给定名称“myBuffer” 已经被使用,背后的实现
1(generate-new-buffer (generate-new-buffer "myBuffer"))- 实际是使用 generate-new-buffer-name 创建的新名称
重复使用已有 Buffer
1 2 3 4 5 6(setq bufferName "myBuffer") # create or get existed buffer (get-buffer-create bufferName) (setq xbuff (get-buffer-create bufferName))临时创建 Buffer, 用于不保存内容的代码 默认情况下是输出内容的。
1 2 3(with-temp-buffer (print "hello") )
用于输出
- 临时 Buffer with-temp-buffer
使用给定 Buffer 输出内容
1 2 3(with-current-buffer yourBuffer (print "hello") )注意
- 会清空之前的所有内容,带 with-** 的命令都是如此
- 自动取消 message, print, 等自带的双引号(“”)
获取 Buffer 信息
Buffer 本身名称
1(buffer-name) ;;--> "elisp-note.org"关联文件
1(buffer-file-name) ;; --> "/home/sawyer/note/elisp-note.org"获取当前 Buffer 对象
1(current-buffer)
切换 Buffer
切换到当前窗口
1(switch-to-buffer yourBuffer)在后台切换,不弹出
1(set-buffer yourBuffer)临时切换
1 2(with-current-buffer yourBuffer (print "hello"))- 结果会输出到 yourBuffer
当成 stdout
1 2(with-output-to-temp-buffer yourBuffer (print "good"))
关闭 Buffer
| |
输出打印
message: 类似 C 语言的 printf
1(message "count is %d" 32)- 结果带双引号(""),自动换行
- insert
- print1
- princ
输出位置
标准输出 stdout
- prin1
- princ
使用方式
- 指定输出 Buffer
使用
1 2(with-output-to-temp-buffer yourBuffer (print "hello"))
当前 Buffer
- insert
使用方式
- 直接使用,在 elisp mode 中
切换到需要的 Buffer
使用 swich-to-buffer
1 2 3 4 5(progn (switch-to-buffer (get-buffer-create "*yourBuffer*")) (insert my/str) (switch-to-buffer "*Previous Buffer*") )使用 set-buffer
1 2 3 4 5(progn (set-buffer (get-buffer-create "*yourBuffer*")) (insert my/str) (set-buffer "*Previous Buffer*") )
能输出到给定 Buffer 的函数
print
- 带双引号
自动换行
- 行尾,自动加\n
- 行首
- 不带\n,添加\n
- 已有\n,不添加\n
- prin1
princ
- 不带双引号
只能输出到当前 Buffer 的函数
insert
- 不换行
- 不带双引号
- 返回 nil, 在 Echo Area
不带双引号的函数
insert
- 在 Echo Area 显示 nil
- 不换行
princ
- 在 Echo Area 不显示内容
- 不换行
不换行的函数
insert
- 不带双引号
princ
- 不带双引号
prin1
- 带双引号
换行的函数
能格式化的函数
message
- 用于输出警告与错误
- 输出结果到 Echo Area 与
"*Message*"Buffer - 注: 含 message 的函数都与警告和错误相关
format
- 不输出结果
- 返回格式化的字符串
shell
进程 Process
类型
按同步异步
- 同步 synchronous
- 异步 asynchronous
按来源
- 系统进程 System process
- Emacs 子进程 Subprocess
- 远程进程,与远程通信
创建方法
异步进程
使用 make-process
同步进程
- call-process
- call-process-region
相关变量
环境变量,environment
- 从 Emacs 继承,Emacs 从系统继承
- 通过自定义 process-environment 变量 override 默认环境变量
工作目录
- 从变量 default-directory 获取
正确用法
1 2(let* ((default-directory "my-path")) (compile "my-command args"))
exec-path
- 一个可能包含 shell 命令(program)的目录列表
其中包含 nil, 表示 default-directory, 即当前目录
- 用于查找 shell 命令的路径,
exec-directory
- shell 命令所在的具体目录
exec-suffixes
- 变量的后缀名
包含空串"",用于表示 program 不需要后缀
- 用于查找补全 shell 命令的全名
参数
PROGRAM 参数
- 即 shell 命令本身,不包含目录
包不包含后缀名,无所谓
由变量 exec-suffixes 处理
- 必须不能包含命令的参数
ARGS 参数
- 即命令的参数
- 必须是字符串
相关函数
预处理函数
处理参数
shell-quote-arguments
1 2(selll-quote-arguments "foo > bar") # output on linux: "foo\\ \\>\\ bar"作用
- 把参数中的特殊字符,根据系统与 shell 转义成 shell 能识别的字 符串。
(split-string-and-unquote string &optional separators)
作用
切割参数,并且去掉引号
1 2(split-string-and-unquote "foo > \"bar\"") # output: ("foo" ">" "bar")
(combine-and-quote-strings list-of-strings &optional separator)
作用
拼接字符串 lisp
1 2(combine-and-quote-strings '("good" "or" "not")) # output: "good or not"注意
- 字符串 list 中不能由空格
具体实现
创建同步进程 synchronous process
- 只能等进程结束,才能继续进行 Emacs
call-process
| |
call-process-region
作用把 current-buffer start ~ end 位置的内容,作为参数传给 program
| |
创建异步进程 asynchronous process
可以与这个异步进程通信
make-process
| |
- 参数复杂,见 elisp 详细说明 http://ergoemacs.org/emacs_manual/elisp/Asynchronous-Processes.html
- 低层命令
start-process
对 make-process 封装后的高级命令
1(start-process name buffer-or-name program &rest args)参数
- name: 进程名
- buffer-or-name: 输出存储位置
- program
- &rest args: program 的参数
start-process-shell-command
- 在一个 shell 中执行
智能判断类型
shell-command
- 使用内部子 shell 执行命令
- 如果命令不带“&”那么是 synchronous process
如果带“&”, 那么是 Asynchronous process
1 2 3(shell-command COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER) (shell-command "ls -al" myBuffer)
局部变量
let
| |
与 let* 的区别
- 以上述例子为例
let 是平行创建的变量
- 即 a, b, c, d, e 创建时间没有先后
- 你不能使用 a 来初始化 b
let* 是有时间顺序的创建变量
- 即 a, b, c, d, e 是依次创建的
- 可以使用 a 来初始化 b
String
查找
string-match-p, Regex 完全匹配
| |
cl-search, 查找子串
| |
- 找到,返回 index
- 没找到,返回 nil
函数调用
https://stackoverflow.com/a/3862485 apply Vs funcall
apply
把参数作为一个 list 传送给 给定函数
| |
funcall
把剩余的参数原样转发给 给定函数
| |
判断变量,函数,包(feature)是否存在
http://ergoemacs.org/emacs/elisp_check_defined.html
- boundp –> variable
- fboudp –> function
featurep –> feature
1(featurep 'elpy)
Directory local variable 文件夹 局部变量
格式
list of cons cell
1 2 3 4 5 6 7 8 9 10 11 12((nil . ((indent-tabs-mode . t) (fill-column . 80) (mode . auto-fill))) (c-mode . ((c-file-style . "BSD") ;; 忽略子文件夹 (subdirs . nil))) ;; 子文件夹 中的设置 ("src/imported" . ((nil . ((change-log-default-name . "ChangeLog.local"))))) ;; 执行函数 (nil . ((eval . (pyvenv-activate "d:/soft/miniconda3/envs/extractor/")))))- 执行函数 使用 (eval . (function &rest args))
载入函数
(hack-local-variables)
在 mode hook 中使用
笨方法
在 hook 函数中 调用 (hack-local-variables)
- 缺点,每次都要提醒载入确认
参考
方法一:使用 your-major-mode-"local-vars-hook"
| |
定义 run-local-vars-mode-hook 函数
- 作用:用来制作 python-mode"-local-vars-hook"
- 在 hack-local-variables-hook 中调用
- 把 run-local-vars-mode-hook 添加到 hack-local-variables
- 把我们的真正自定的函数,添加到 python-mode"-local-vars-hook" 中
方法二:内部嵌套 add-hook
| |
原理
- hack-local-variables 是 在 python-mode-hook 后运行的
- 因此,把自定义代码 放到 hack-local-variables-hook 中运行即可
文件路径 file path
- info 路径: Files > File Names
- cheat sheet
| 功能 | 函数 |
| dirname | file-name-directory |
| basename | file-name-non-directory |
| extension 扩展名 | file-name-extension |
| 名称主体 | file-name-base |
| 判断 abspath | file-name-absolute-p |
| relative path 制作相对路径 | file-relative-name |
| 文件夹 directory | |
| 文件转成路径(folder 结尾添加斜线) | file-name-as-directory |
| 路径判断 | directory-name-p |
| folder 转成文件 (去掉 folder 结尾斜线) | director-file-name |
| ~ 替换 | abbreviate-file-name |
| eg: /home/sawyer/hello –> ~/hello | |
| 相对路径展开 | |
| 展开(变成绝对路径,a. 当前变绝对 b.相对变绝对) | expand-file-name |
| 软链接 展开 | |
| file-truename | |
| 路径中环境变量替换 | substitute-in-file-name |
| 临时文件 | |
| make-temp-file | |
| make-temp-name |
| 功能 | 变量 |
|---|---|
| 当前路径(工作目录) | default-directory |
| 注意:只能是绝对路径 |
create directory
mkdir
- (make-directory "dirname")
mkdir -p
- (make-directory "dirname" t)
- (f-mkdir-full-path "dirname")
文件查找
递归文件查找
使用 directory-files-recursively, 实现递归查找,和正则过滤
语法: directory-files-recursively directory regexp &optional include-directories predicate follow-symlinks
参考:
替代工具
find-name-dired- 语法:
(find-name-dired DIR PATTERN) 特点:
- 使用通配符等
- 底层调用 linux find 命令
返回结果到 dired buffer 展示
- 便于可视化展示
- 语法:
修改 buffer-local 变量
| |
- 创建 local-variable
- 设置默认值
set-default
分支语句
- if
when
1 2(when condition (todo-sexp))cond
解说
- 多个条件语句
- 只执行第一个成立的条件语句,其他的直接跳过
类似 cpp switch 语句,但不完全一样
1 2 3 4 5 6 7 8(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)) (t "default") ;; default 语句 )单个条件
- ((条件) 执行语句)
keymap 快捷键
Key Sequence
- 函数: (kbd "C-x")
- 注意:C-x + l –> (kbd "C-x l") 不能是 "C-xl"
文本 按键 映射关系
按键 文本 特殊 空格键 SPC F1 <f1> * Win 键 s Shift 键 S enter 键 RET down 向上箭头 <down> up 向下箭头 <up> left <left> ritht <right> page down <next> * page up <prior> * insert <insert> del <delete>
prefix sequence
- 前缀快捷键
- eg: M-x; C-x; …
keymap 优先级关系
- minor-mode-map > local-keymap > global-keymap
参考
函数
current-active-maps
- 查询 keymap
key-binding
- 查询绑定函数 binding-function
Active keymaps 操控
- 参考:Ctrolling the Active Keymaps
变量
- global-map
- minor-mode-map-alist
函数
- current-global-map
返回值一般 与 global-map 变量相同
- current-minor-mode-maps
- use-global-map
很少用
- minor-mode-overriding-map-alist
keymap 格式
- 参考:elisp keymap format
单个 keymap
1 2(keymap (key-sequence . bind-function))嵌套 keymap –> 前缀快捷键
1 2 3(keymap (prefix-key-sequence keymap (key-sequence . binding-function)))
keymap 操作
判断
- keymapp
赋值
- fset
例子
1 2 3 4 5 6 7(keymapp '(keymap)) ⇒ t (fset 'foo '(keymap)) (keymapp 'foo) ⇒ t (keymapp (current-global-map)) ⇒ t创建
- make-sparse-keymap
- make-keymap
copy-keymap
- 很少使用到
- 应该用继承
set-keymap-parent
make-composed-keymap
- 使用多个已有 keymap 生成一个新 keymap
获取
- current-local-map
设置
继承
- set-keymap-parent
获取父 keymap
- keymap-parent
多继承实现
- make-composed-keymap
例子
1 2 3 4 5(defvar help-mode-map (let ((map (make-sparse-keymap))) (set-keymap-parent map (make-composed-keymap button-buffer-map special-mode-map)) ... map) ... )
prefix keys
解释
- prefix key 的 binding-function 是另一个 keymap
- 参考
设置 prefix key
1 2 3 4 5 6;; * 设置到给定 map 上 (define-key map-name (kbd "prefix-key-sequence") given-keymap) ;; * 直接 绑定 prefix key (local-set-key (kbd "key-sequence") given-keymap) (global-set-key (kbd "key-sequence") given-keymap)
添加绑定
解释
- 给已有 map 设置新 short — binding-function
函数
define-key
eg:
1(define-key given-map (kbd sequence-str) binding-function)
获取绑定函数 –> get binding-function
解释
- 获取绑定到给定 key-sequence 上的 binding-function
函数
key-binding
eg:
1(key-binding (kbd "M-f"))
修改绑定函数本身
解释
- 维持 key-sequence 快捷键不变,修改 binding-function 定义
操纵函数
substitute-key-definition
eg:
1(substitute-key-definition olddef newdef keymap &optional oldmap)
编码和国际化 Encoding and Internationalization
参考
- emacs list manual -> International -> Language Environments
插入特殊字符
C-x 8
- 快捷符号
C-x 8 <RET>
- 所有符号
展示当前 编码信息
- C-h h
编码命令快捷键
快捷键前缀 prefix
- C-x <RET>
解释当前 char 字符
- C-x =
language-environment 作用
- 设置语言偏好,默认编码文件 encoding system,默认 input method
配置
函数
set-language-environment
变量
current-language-environment
相关系统
环境变量- LC_ALL
- LC_CTYPE
- LANG
机理
- 通过 emacs 内部设置的别名列表,查询到系统的 默认 language-environment
注意:
- 在 emacs 内部设置这些变量 对 language-environment 无效
- 要生效需要调用
set-locale-environment
encoding system
- 解说:emacs 读写外部 信息的编码格式
修改 编码优先级
命令
- prefer-coding-system
影响编码的 emacs 配置
- language-environment
指定文件类型的编码
函数
modify-coding-system-alist1 2;; "\\.txt\\'" --> 正则表达式 (modify-coding-system-alist 'file "\\.txt\\'" 'chinese-iso-8bit)
Symbol 和 String 转换
参考
symbol –> String
symbol-name(symbol)
String –> Symbol
intern("symbol_string")
字体 – font – face 设置
参见:
实用函数:
直接设置 face
1(set-face-attribute 'default nil :family "Cascadia Mono" :foundry "outline" :slant 'normal :weight 'normal :height 128 :width 'normal)通过其他 face-1 设置给定 face-2 属性
1(set-face-font 'mode-line (face-attribute 'default :font))
org faces
debug hook
如何 debug 得知,给定函数在哪个 hook 中被调用
参考: eldoc - How to find in which hook(s) a certain function is called? - Emacs St…
方法:
启用 debug:
M-x debug-on-entry <company-mode>- 说明:判断
company-mode被什么时候调用,调用 company-mode 会触发中断
- 说明:判断
- 停用 debug:
M-x cancel-debug-on-entry <company-mode>
Advising Functions (advice-add)
参考:
Combinators 添加位置
:before:after:around:override
功能说明:
- override 完全覆盖, 通过
remove-function恢复原函数 around 覆盖
- 但是,接收原函数作为参数
函数接口:
与原函数一致
- before
- after
- override
例子
| |
把按键字符串当做命令执行
参考:
| |
这样就把 C-g 当做命令执行了(像手动输入的按键一样)
character
特殊字符输入
- 空格:
?\s - tab 键:
?\t
文章作者
上次更新 2024-01-05 (5c92d1c)