example for number conversion expmple

教程

xah lee elisp 教程

参考

library

  • f

    • file
  • s

    • string
  • dash

    • list

Cheat Sheet

字符串

创建 字符串

连接
  • string

    • (string "a" "b", …)

char type

escape charactercomment
"\uNNNN"2Byte
"\U00NNNNNN"3Byte, less than U+10FFFF
"\xNN"1Byte, hex
\000octal
Control character
^I
C-I
Meta Charcter
M-I
Shift Character
S-
AltA-
supers- 注:小写 s
hyperH-

Symbol

参考:

概述:

Symbol
keyword symbol + constant

关联的 cell

  • 解释:即关联的数据
  • 类型

    1. print name

      • 即 symbol 名称的字符串表示
    2. value
    3. function cell

      • 函数定义对象,用户函数,macro 等
    4. property list(plist)

      • 各种状态数据

相关函数

  1. 四种 cell 获取

    • value, 获取值

      • symbol-value
    • name, 获取 symbol 的 string 名称

      • symbol-name
      • 类似 python __name__ 方法
    • function

      • symbol-function
    • plist

      • symbol-plist
  2. string 名称转换成 symbol

    • intern
    • intern-safe

      • 如果 symbol 不存在,返回 nil
  3. 判断是否是 symbol

    • symbolp
  4. 检查 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))
     nil
  • atom

    • 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 更新存放位置
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(setq foo '())
 nil

(add-to-ordered-list 'foo 'a 1)     ;; Add ‘a’.
 (a)

(add-to-ordered-list 'foo 'c 3)     ;; Add ‘c’.
 (a c)

(add-to-ordered-list 'foo 'b 2)     ;; Add ‘b’.
 (a b c)

(add-to-ordered-list 'foo 'b 4)     ;; Move ‘b’.
 (a c b)

(add-to-ordered-list 'foo 'd)       ;; Append ‘d’.
 (a c b d)

(add-to-ordered-list 'foo 'e)       ;; Add ‘e’.
 (a c b e d)

foo                       ;; ‘foo’ was changed.
 (a c b e d)
delete
  • 删除给定元素,使用 equal 判断
  • 只删除一个
delq
  • 删除给定元素,使用 eq 判断
    • 只删除一个相等的
    • 有重复,删除后面的,而不是前面的
    • 修改输入的 list
remq
  • 删除所有的给定元素,使用 eq 判断
    • 删除所有的
    • 返回的是新的 list
    • 不修改原来的 list

Association List (alist)

参考:

特点:

  • 一个 (key . value) 对 pair 组成的 list
  • 允许 key 重复
  • 有序 key

注:类似 python 的字典 dictionary, 但是 key 可以重复

1
2
(setq alist-of-colors
  '((rose . red) (lily . white) (buttercup . yellow)))

In each element, the CAR is considered a “key”, and the CDR is considered an “associated value”.

值获取

alist-get

pair 获取 (类似 python dict item)

  1. 通过 key 获取

    • assoc : equal 比较
    • assq : eq 比较
  2. 通过 value 获取

    • rassoc : equal 比较
    • rassq : eq 比较

添加元素 pair

  1. push

    • 开头添加
    • 不检查是否已经存在 key
    • eg: (push '("cc" . 33) the-alist)

删除元素 pair

  1. assoc-delete-all

    • 删除所有满足 key 的 pair
    • 通过 equal 判断
    • eg: (setq xx (assoc-delete-all "bb" demo-alist))
  2. assq-delete-all

    • 删除所有满足 key 的 pair
    • 通过 eq 判断
  3. rassoc-delete-all

    • 删除所有满足 value 的 pair

Property List (plist)

参考:

特点:

  • 相当于展开的 alist
  • 禁止 key 重复
  • key 必须是 elisp 语言的 Symbol 类型对象
  • value 可以是其他任意类型对象

用途:

  • elisp 中 symbol 的属性存储 Symbol Property List
  • Text Properties
  • 不是通用类型,不适合大规模数据存储,元素数量 <= 100, 最好

创建

1
(setq my-plist '(x 1 y 2))

值获取 get

  1. plist-get

    • 通过 eq 测试 key
    1
    2
    
    (plist-get '(x 1 y 2) 'y) ; 2
    (plist-get '(x 1 y 2) 'b) ; nil
  2. lax-plist-get

    • 通过 equal 测试 key

值修改 put

  1. plist-put

    • eq 测试
  2. lax-plist-put

    • equal 测试

key 存在判断

  1. plist-member

    • eq 测试

Hash Table 哈稀表

参考:

特点:

  • 无序

    • 类似的结构 alist 是有序的
  • key 无重复

    • 相反 alist 是允许重复 key 的

相关函数:

  1. make-hash-table
  2. gethash
  3. rmhash
  4. puthash
  5. clrhash
  6. keys

    • hash-table-keys
  7. values

    • hash-table-values
  8. map

    • maphash

重建

  1. make-hash-table

    1
    2
    
    ;; create a hash table
    (setq xx (make-hash-table :test 'equal))
  2. 手动创建

     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

  1. puthash

    1
    2
    3
    
    (let ((xx (make-hash-table :test 'equal)))
      (puthash 'aa 9 xx)
      xx)

删除 element

  1. rmhash

    1
    
    (remhash KEY TABLE)

删除所有元素

  1. clrhash

    • clear hash

获取 element (get)

  1. gethash

    1
    
    (gethash key table default)

长度 length

  1. hash-table-count

map 函数

  1. maphash

     1
     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 变量

相关函数:

  1. 访问 symbol 的整个 plist

    • 设置(赋值,类似 setq)

      • setplist
    • 获取

      • symbol-plist
  2. 内部的单个 key / value 操作

    • 修改

      • put
    • 访问

      • get

Array Type

类型备注
strings字符串
vectorscan hold any type of objects
bool-vectorselement –> 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
  • 类型可变

    • 元素的类型是任意的

创建

  1. make-vector

    • 相同元素的 vecotr
    • eg:

      1
      2
      3
      4
      
      (equal
       (make-vector 5 0)
       [0 0 0 0 0]
       )
  2. vector

    • 枚举元素法
    • 参数被 eval
    • eg:

      1
      2
      3
      4
      
      (equal
       (make-vector 5 0)
       [0 0 0 0 0]
       )
  3. 手写法

    • 参数不会被 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 characterstring 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

1
2
3
4
5
(symbol-function 'car)          ; Access the function cell
  			     ;   of the symbol.
     #<subr car>             ;The word “subr” is derived from “subroutine”.
(subrp (symbol-function 'car))  ; Is this a primitive function?
      t                       ; Yes.

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 xreturn cons (S . E)
S –> significand
E –> exponant
base –> 2
ldrexp s ereturn s*2**e

Predicates for Numbers

函数备注
floatp
integerp
numberp
natnumpis a natural number?
zeropis 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 Integeroutput ====> 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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
;;============= truncate
(truncate 1.7)
 1
(truncate -1.2)
 -1
;;============= floor
(floor 1.7)
 1
(floor -1.2)
 -2
;;============ ceiling
(ceiling 1.7)
 2
(ceiling -1.2)
 -1
;;============ round
(round 1.7)
 2
(round -1.2)
 -1
(round 1.5)
 2

Arithmetic Operations 算术运算

函数备注
'1+
'1-
'-(-) –> 0
'+(+) –> 0
'*(*) –> 0
'/divisor 为 0 –> 报错 arith-error
'%args 参数必需是整数,不能是浮点数
divisor 不能为 0
'mod类似 %
但是 args 可以是 floating-point
1
2
3
4
5
6
7
8
9
;;For any two numbers DIVIDEND and DIVISOR,

(+ (mod DIVIDEND DIVISOR)
   (* (floor DIVIDEND DIVISOR) DIVISOR))

;;For any two integers DIVIDEND and DIVISOR,

(+ (% DIVIDEND DIVISOR)
   (* (/ DIVIDEND DIVISOR) DIVISOR))

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-ee ==> 自然对数的底
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-pstring or nil
char-or-string-p

Make String 创建 字符串

make-string

函数备注
(make-string COUNT CHAR)重复 CHAR,COUNT 次==> new string
1
2
3
4
 (make-string 5 ?x)
 "xxxxx"
 (make-string 0 ?x)
 ""

substring

函数备注
(substring String &optional Start End)制造 子串
1
2
3
4
5
6
7
8
(substring "abcdefg" 0 3)
 "abc"

(substring "abcdefg" -3 nil)
 "efg"

(substring [a b (c) "d"] 1 3)
 [b (c)]
符号
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]+"’注意:第一个是空格
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
(split-string "ooo" "o*" t)
  nil
(split-string "ooo" "\\|o+" t)
  ("o" "o" "o")

(split-string "Soup is good food" "o")
  ("S" "up is g" "" "d f" "" "d")
(split-string "Soup is good food" "o" t)
  ("S" "up is g" "d f" "d")
(split-string "Soup is good food" "o+")
  ("S" "up is g" "d f" "d")

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它们效果相同
equalcase-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 EndThe 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 NumberNumber ==> String
string-to-number String &optional BaseString ==> Number
无法转换的 String
output ==> 输出 0
string-to-char取出 String 的第一个 字符
空串 –> 0
char-to-string
List <===> String
concat &rest SequencesVector or List ===> String
vconcat &rest SequencesString or Something ===> Vector
append &rest SequencesString or Something –> List
byte-to-string Bytea 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 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

1
(kill-buffer yourBuffer)

输出打印

  • message: 类似 C 语言的 printf

    1
    
    (message "count is %d" 32)
    • 结果带双引号(""),自动换行
  • insert
  • print
  • print1
  • princ

输出位置

标准输出 stdout

  • print
  • 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

    • 带双引号

换行的函数

  • print

能格式化的函数

  • 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
1
2
(call-process program &optional infile destination display  &rest args)
(call-process "ls" nil mybuff "")
call-process-region

作用把 current-buffer start ~ end 位置的内容,作为参数传给 program

1
(call-process-region start end program &optional delete destination display &rest args)

创建异步进程 asynchronous process

可以与这个异步进程通信

make-process
1
(make-process &rest)
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
(defun my/fun ()
  "description"
  (let (a "value1")
    (b "value2")
    c
    d
    (e "value3"))

  (print "hello")
  (print d)
  )

与 let* 的区别

  • 以上述例子为例
  • let 是平行创建的变量

    • 即 a, b, c, d, e 创建时间没有先后
    • 你不能使用 a 来初始化 b
  • let* 是有时间顺序的创建变量

    • 即 a, b, c, d, e 是依次创建的
    • 可以使用 a 来初始化 b

String

查找

string-match-p, Regex 完全匹配

1
(string-match-p (regexp-quote needle) haystack)

cl-search, 查找子串

1
2
3
4
  ELISP> (cl-search "f t" "df tj")
  1 (#o1, #x1, ?\C-a)
  ELISP> (cl-search "ft" "df tj")
  nil
  • 找到,返回 index
  • 没找到,返回 nil

函数调用

https://stackoverflow.com/a/3862485 apply Vs funcall

apply

把参数作为一个 list 传送给 给定函数

1
2
3
(apply '+ '(1 2))

(defun passargs (&rest args) (apply #'myfun args))

funcall

把剩余的参数原样转发给 给定函数

1
2
3
(funcall '+ 1 2)

(defun passargs (a b) (funcall #'myfun a b))

判断变量,函数,包(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 中使用

方法一:使用 your-major-mode-"local-vars-hook"

1
2
3
4
5
6
(defun run-local-vars-mode-hook ()
  "Run a hook for the major-mode after the local variables have been processed."
  (run-hooks (intern (concat (symbol-name major-mode) "-local-vars-hook"))))

(add-hook 'hack-local-variables-hook 'run-local-vars-mode-hook)
(add-hook 'python-mode-local-vars-hook 'Our-self-defined-function)
  1. 定义 run-local-vars-mode-hook 函数

    • 作用:用来制作 python-mode"-local-vars-hook"
    • 在 hack-local-variables-hook 中调用
  2. 把 run-local-vars-mode-hook 添加到 hack-local-variables
  3. 把我们的真正自定的函数,添加到 python-mode"-local-vars-hook" 中

方法二:内部嵌套 add-hook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
(add-hook 'python-mode-hook 'cr/python-mode-shell-setup)

(defun cr/python-mode-shell-setup ()
  (add-hook 'hack-local-variables-hook
        (lambda () (message "virtualenv-name is %s" cr/virtualenv-name)
          (let ((python-base (cr/virtualenv)))
        (cond ((and (fboundp 'ipython-shell-hook) (file-executable-p (concat python-base "/bin/ipython")))
               (setq python-python-command (concat python-base "/bin/ipython"))
               (setq py-python-command (concat python-base "/bin/ipython"))
               (setq py-python-command-args '( "-colors" "NoColor")))
              (t
               (setq python-python-command (concat python-base "/bin/python"))
               (setq py-python-command (concat python-base "/bin/python"))
               (setq py-python-command-args nil)))))
        nil t)) ; buffer-local hack-local-variables-hook
  • 原理

    • hack-local-variables 是 在 python-mode-hook 后运行的
    • 因此,把自定义代码 放到 hack-local-variables-hook 中运行即可

文件路径 file path

  • info 路径: Files > File Names
  • cheat sheet
功能函数
dirnamefile-name-directory
basenamefile-name-non-directory
extension 扩展名file-name-extension
名称主体file-name-base
判断 abspathfile-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)
    • 特点:

      1. 使用通配符等
      2. 底层调用 linux find 命令
      3. 返回结果到 dired buffer 展示

        • 便于可视化展示

修改 buffer-local 变量

1
2
(make-local-variable 'imp-user-filter)
(setq-default imp-user-filter 'markdown-html)
  1. 创建 local-variable
  2. 设置默认值 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-alist

        1
        2
        
        ;; "\\.txt\\'" --> 正则表达式
        (modify-coding-system-alist 'file "\\.txt\\'" 'chinese-iso-8bit)

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))

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 添加位置

参考: elisp#Advice Combinators

  • :before
  • :after
  • :around
  • :override

功能说明:

  • override 完全覆盖, 通过 remove-function 恢复原函数
  • around 覆盖

    • 但是,接收原函数作为参数

函数接口:

  • 与原函数一致

    • before
    • after
    • override

例子

1
2
3
4
5
6
;; advice for `conda-env-activate'
(defun my/lsp-bridge-restart-conda-advice (&rest args)
  (when lsp-bridge-epc-process
    (lsp-bridge-restart-process)))

(advice-add 'conda-env-activate :after #'my/lsp-bridge-restart-conda-advice)

把按键字符串当做命令执行

参考:

1
(execute-kbd-macro (read-kbd-macro "C-g"))

这样就把 C-g 当做命令执行了(像手动输入的按键一样)

character

特殊字符输入

  • 空格: ?\s
  • tab 键: ?\t