在說基本編輯指令之前,我們先加一個小tip,說說如何将函數和鍵綁定在一起。
define-key函數需要三個參數,第一個是綁定表的名稱,不同的模式下的描述表是不同的。第二個參數是鍵名,第三個參數是鍵要綁定的函數名。
emacs是一種無模式的編輯器,這也是除了vi之外大部分編輯器的标準做法。每個輸入的字元都會直接輸入到緩沖區裡。編輯要用到的功能函數,就隻好綁定到組合鍵上,主要是ctrl鍵,esc或alt鍵的組合鍵。
比如,最基本的光标移動。如果有上下左右鍵,就用上下左右鍵。沒有的話,emacs會用c-f向右,c-b向左,c-n向下一行,c-p向上一行。c-a移動到行首,c-e移動到行尾。
大量使用ctrl和alt,esc鍵,使得手需要經常移動,小指被過度使用。
而vi的采用正常模式和編輯模式分離來解決這個問題,在正常模式下,不能輸入字元,所有的字元都被當成指令來執行。此時,j是下一行,k是上一行,h是向左,l向右。效率要比c-n,c-p,c-b,c-f要高。0到行首,$到行尾。
但是vi的問題就是,需要經常在正常模式和編輯模式來回切換。
spacemacs使用evil來模拟vi的這種模式,而且有些鍵的綁定與标準emacs有所不同。
移動光标是最基本的指令了,這其中最基本的是光标左右移動,和上下移動。
我們先學習emacs的标準方式:
向右一個字元: c-f (forward-char)
向左一個字元: c-b (backward-char)
這兩個函數都是用c語言實作的,是以沒有lisp源碼,目前我們暫時先關注lisp部分。
但是,在spacemacs的預設情況下,這兩個綁定已經被取消了。因為spacemacs預設是用vi的模式方案,在正常模式下,使用h鍵左移,l鍵右移。
l鍵和右箭頭鍵,綁定到evil-forward-char函數上. 最終,evil-forward-char還是會調用到forward-char來實作移動的功能的:
而左箭頭和h鍵,則是調用的evil-backward-char函數:
就是行間移動,标準emacs的方式是:
向下一行:c-n (next-line)
向上一行:c-p (previous-line)
這兩種方式在spacemacs中,在編輯模式下仍然可以使用。但是正常模式下已經被綁定到其他函數上了,因為有更友善的j和k可以用。
spacemacs支援在普通模式下使用j來移動到下一行,k來移動到上一行。j綁定的是evil-next-line函數,k綁定的是evil-previous-line函數。
上面兩個函數都是對evil-line-move的封裝,evil-next-line的參數是正的,evil-previous-line是負的。
很多時候,我們需要移動到行首或行尾,而不是向左或向右一點一點移動。
我們還是先看emacs的标準實作方式:
到行首:c-a (move-beginning-of-line) spacemacs支援
到行尾:c-e (move-end-of-line) spacemacs不支援
move-beginning-of-line的實作如下:
最終會調用到我們後面要學的goto-char函數,通過goto-char跳到真正的位置上。
spacemacs支援vi的方式,在普通模式下,0移動到行首,$移動到行尾
0 (evil-digit-argument-or-evil-beginning-of-line)
$ (evil-end-of-line)
evil-end-of-line其實還是要調用move-end-of-line函數來實作功能的。
emacs的标準方式:
到緩沖區頭 a-< (beginning-of-buffer)
到緩沖區尾 a-> (end-of-buffer)
spacemacs支援這兩種方式,在正常模式下,還支援"<"鍵綁定beginning-of-buffer,">"綁定end-of-buffer的方式。
我們先看下beginning-of-buffer,雖然也是goto-char的封裝,但是确實不隻是(goto-char 0)這麼簡單:
end-of-buffer的話,除了goto-char之外,還得考慮recenter的問題
emacs提供了兩個函數,可以跳到任意一行,或者是任意一個字元。
a-g g 或 a-g a-g (goto-line n) :跳轉到第n行
a-g c (goto-char n): 跳轉到第n個字元
spacemacs還支援vi的方式來跳轉行
行号 g (evil-goto-line),如果沒有行号,則跳到緩沖區末尾
goto-char不出意料的,是用c實作的。
我們先來看看goto-line:
evil-goto-line寫得簡短一些:
如果一行一行的移動,實在是太慢了,我們可以使用重複指令,給函數傳遞一個參數。
标準emacs的做法是esc + 數字和c-u加數字兩種方式:
esc n + 指令:執行n次指令。如果無法執行完n次,就盡最大的努力。比如向下移動n行,到是沒到n行就到檔案末尾了。那麼就停在檔案末尾。
例:
esc 10 c-n,向下移動10行
(universal-argument)函數,它綁定在c-u鍵上。
universal-argument如果不指定參數的話,預設執行4次。
但是在spacemacs上,universal-argument函數綁定在"空格 u"和"alt-m u"兩個鍵上。
c-u在spacemacs中被移做綁定到evil-scroll-up上,用于翻屏。
有的時候,需要重新繪制一下螢幕,讓我們移動到的那行變為中心:
c-l (recenter-top-bottom)
做錯了,撤銷是很關鍵的操作。
在标準emacs中,使用undo函數來進行這個操作。它綁定到c-_或c-/或c-x u三個鍵上。
在spacemacs中,c-x u被綁定到undo-tree-visualize函數上。 還可以用"空格 a u"來通路它。
而c-_,c-/,在spacemacs中,被綁定在undo-tree-undo上。
功能
函數名
快捷鍵
leader鍵
光标右移
forward-char
無
evil-forward-char
l
光标左移
backward-char
evil-backward-char
h
下移一行
next-line
正常模式c-n無效
evil-next-line
j
上移一行
previous-line
正常模式c-p無效
evil-previous-line
k
光标移至行首
move-beginning-of-line
c-a
evil-digit-argument-or-evil-beginning-of-line
光标移至行尾
move-end-of-line
evil-end-of-line
$
跳轉到某一行
goto-line
a-g g或a-g a-g
evil-goto-line
g
跳到某一字元
goto-char
a-g c
跳到緩沖區頭
beginning-of-buffer
a-<或>
跳到緩沖區尾
end-of-buffer
a->或>
重複執行
universal-argument
a-m u
空格 u
居中重繪螢幕
recenter-top-bottom
c-l
撤銷上一次的操作
undo
undo-tree-visualize
c-x u
undo-tree-undo
c-_或c-/