Elisp 编程 之一

Printed Representation and Read Syntax

Elisp 中的 object

在 Elisp 中的所有的数据都是 object , 例如一个 integer, 一个 string, 一个 hash table , 一个 list, 一个 array. 一个buffer, 一个 window 等等。

Elisp 中 type

Elisp 中的每一个 object 都属于一种或几种 type . 一 个 type 就是一个 object 的集合。

Elisp 中的数值类型

integer 和 floating point 是两种 Elisp 的数值类型。看起来像数值的数都可以凭直 觉把他们分类。例如: 1, 2, 3 当然就是integer ,1.2, 1.5e10, 3.14 当然就是 floating point 类型的。

Elisp 中的 character 类型

character 类型和 integer 类型本质上是一样的,例如 'A' 和67 是一个东西。而 character 有更多的 read syntax 。通常,一个 character的 read syntax 是一个问号后 面跟一个字符。character 的 Printed Representation 和 integer 的是一样的。例如:

?A  => 67

这里 `>' 表示“求值”得到的意思。也就是说 (prin1 ?A) 会打印 67 。

还可以用斜杠表示一些特殊字符,叫做 escape sequences 。例如: <pre class"example"> ?\a => 7 ; `C-g' ?\b => 8 ; backspace, &lt;BS&gt;, `C-h' ?\t => 9 ; tab, &lt;TAB&gt;, `C-i' ?\n => 10 ; newline, `C-j' ?\v => 11 ; vertical tab, `C-k' ?\f => 12 ; formfeed character, `C-l' ?\r => 13 ; carriage return, &lt;RET&gt;, `C-m' ?\e => 27 ; escape character, &lt;ESC&gt;, `C-[' ?\\ => 92 ; backslash character, `\' ?\d => 127 ; delete character, &lt;DEL&gt;

如果 escape sequence 中后面的字符没有特殊意义,那么就表示字符本身。例如 ?\( 和 ?( , ?\+ 和 ?+ 就是一个意思。

还可以 "?\^" 后面跟一个字母来表示一个ASCII 的控制字符,例如:

?\^a   => 1
?\^b   => 2
?\^c   => 3
?\^d   => 4
?\^e   => 5
?\^f   => 6
?\^g   => 7
?\^h   => 8
?\^i   => 9
?\^j   => 10
?\^k   => 11
?\^l   => 12
?\^m   => 13
?\^n   => 14
?\^o   => 15
?\^p   => 16
?\^q   => 17
?\^r   => 18
?\^s   => 19
?\^t   => 20
?\^u   => 21
?\^v   => 22
?\^w   => 23
?\^x   => 24
?\^y   => 25
?\^z   => 26
?\^?   => 127

这里是不分大小写的,?\^i ?\^I 都是一样的。

还可以用 `C-' 来代替 `^',例如?\C-i 和 ?\^i, \?^I 都是表示 TAB 字符,ASCII 9。

可以用 8 进制数表示一个字符,例如

 ?\012 => 10         ?\n => 10         ?\C-j => 10

一个 integer 和一个 character 是一样。但是一个 character 的范围是用 19 个bit 来表示的。但是如果表示键盘输入的话,character 的范围会更大,用其它的 bit 表示 Meta , Control 和Shift 键的组合键。

在表示键盘输入的时候,一个 character 的第26位,第27位和第25位,分别表示 Meta 键, Control 键, Shift 键。注意,只有在 X Windows 的条件下,或者一些特殊终端, 才能够产生这样的组合按键的。这些键分别可以用 `M-' `C-' 和 `S-' 和上面的表示方法 组合类表示。例如: ?\M-

 \C-b ;; 表示在按下 Control 和 Meta 的 同时按下 b
键。?\M-\S-C-b ;; 表示在按下 Control, Shift 和 Meta 的 同时按下 b 键。

如果不是 X Windows 下,那么是没有办法区分键盘输入 C-M-S-b 和 C-M-b 的。

同样在 X Windows 下还定义了一些其它的辅助按键,例如: "hyper", "super" 和 "alt" ,在用来表示不同键盘上特殊按键。分别用 `H-', `s-' 和 `A-' 来表示,例如 `?\H-\M-\A-x' 表示 `Alt-Hyper-Meta-x' 。

在 MS Windows 的键盘布局上,Win 键是 super , Alt 键是Meta, Ctrl键是 Control 。

关于字符串的函数

关于上一次事件的变量

last-command-event last-command-char , last-command-char 是过时的东西了。

last-input-event last-input-char, last-input-char 是过时的版本的东西了。 返回 read-char 的东西, last-command-event 返回输入的命令字符。

如果按了 C-x C-e ,那么 last-command-event 只返回 C-e

(progn (print (read-char))
       (print last-command-event)
       last-input-event)

要的到上一次输入的命令序列,可以先的到上一次的命令last-command ,然后用 where-is-internal 查找命令对应的快捷键,

key-binding 可以返回一个快捷键对应的函数。substitute-key-definition 可以用来 一个函数对应的快捷键和另外一个函数绑定。参考 global-key-binding , local-key-binding, lookup-key 。

self-insert-command 读取 last-command-event

(let ((last-command-event ?a))
   (self-insert-command 10))

interactive 用于创建一个命令。如果一个函数的内的调用了interactive 那么这个函 数就会变成一个命令。

interactive 接收一些参数,用于指明如何初始化成为命令的函数的参数。例如

(defun test-cmd (arg)
  (interactive "p")
  (print arg))

在没有用 C-u 指定命令的参数的时候, arg == 1 ,否则 arg 就是C-u 指定的参数。