從 Vim 遷移到 spacemacs
從 Vim 遷移到 spacemacs
-
從 vim 遷移到 spacemacs
-
本文檔的目的
-
哲學
-
基本使用
-
緩沖區
-
窗戶
-
模式和狀態
-
層
-
微觀狀態
-
條款
-
方便快捷的按鍵綁定
-
執行命令
-
緩沖區和窗口管理
-
文件
-
幫助系統
-
探索
-
定制
-
改變 escape 鍵
-
改變代碼高亮主題
-
非高亮查找
-
會話
-
使用虛線作為導航
-
變量
-
快捷鍵
-
函數
-
.spacemacs 配置文件
-
Emacs Lisp
-
激活一層
-
創建一個層
-
安裝一個包
-
加載一個包
-
卸載一個包
-
常見的調整
-
其他有用的鏈接
本文檔的目的
本文旨在通過跨越 vim 和 Spacemacs 之間的差距,以補充 Spacemacs 文檔。雖然有些信息可能被復制,但這并不能代替 Spacemacs 文檔。建議您閱讀這兩個文件,充分認識 Spacemacs。
哲學
很多 vim 都有的誤解是,Spacemacs 是 vim 的 Emacs 克隆。Spacemacs 沒有完全模仿 vim 的行為,它只有在編輯的時候才這樣。你不能指望每個 vim 指令都可用,盡管很多都是可用的。你不能用 Vimscript 配置 Spacemacs,反正沒人喜歡 Vimscript。重要的是,Spacemacs 旨在使用 vim 高級編輯模式以及 Emacs 更好的配置語言來改善 vim 和 Emacs 兩者。
基本介紹
術語
Spacemacs 使用與 vim 不同的術語,可能會使新用戶感到困惑。本節試圖厘清這些困惑。
模式和狀態
在 vim 中,你具有多種編輯模式如插入模式和可視模式來處理文本。在 Emacs 中,我們使用的是狀態。它們等同于 vim 的模式。例如 evil-insert-state 與 vim中的insert-mode相同。
Emacs 中的 minor-mode 就像是激活一項功能。例如:aggressive-indent-mode 就是一個 minor-mode,它可以在你輸入的同時自動縮進代碼。需要知道的是,在一個緩沖區中可以激活多個 minor-modes。許多 Emacs 包通過提供一個 minor-mode 進行工作。Major-mode 確定 Emacs 在當前緩沖區的行為。通常每個文件類型對應一個 major-mode。一個 major-mode 的例子如 python-mode,它對 python 文件提供針對 python 的設置。每個緩沖區只有一個 major-mode。
層
Spacemacs 具有層的概念。層類似于 vim 中的插件。它們提供可以在 Spacemacs 中使用的新功能。但是層通常是由數個相互整合良好的包組成。例如,python 層包括自動補齊支持,文檔查找,測試和其它由不同的包提供的功能。這使你不需要考慮安裝什么包,只需要考慮你想要什么功能。關于層的更多內容可以參考自定義章節和官方文檔。同時還有一個關于編寫層的更深入的指南。
微狀態
Spacemacs 提供一個稱為微狀態的特殊功能。微狀態允許相似的命令連續執行,不需要重復按鍵。微狀態通常由使用如下模式的鍵位綁定觸發:<Leader> <group>這里的 group 是微狀態從屬的目錄。當處于一個微狀態時,你將會在窗口的底部看到說明文檔。要退出微狀態,按 q 鍵。
鍵位綁定約定
Spacemacs 使用 SPC 作為它的 <Leader> 鍵。本文檔也使用 SPC 作為 <Leader> 鍵。所有的鍵位綁定都采用助記方式,并由 <Leader> 鍵組織。例如,語言指定命令的鍵位綁定通常使用 SPC m前綴。Spacemacs 使用的約定如下 表. 注意所有的鍵位綁定都可以更改。
Spacemacs 在一個延遲之后使用 which-key 來顯示可用的鍵位綁定:
運行命令
可以使用 SPC:運行 Emacs 命令。這將會彈出一個使用 Helm 的緩沖區。這個緩沖區中可以運行任意的 Emacs 命令。你同樣可以使用:運行許多外部命令,就跟 vim 中一樣。
注意:你可以使用: 運行 Emacs 交互命令,但是不能使用 SPC : 運行外部命令。
緩沖區和窗口管理
緩沖區
在 Emacs 和 vim 中緩沖區本質上是相同的。緩沖區的快捷鍵都具有 SPC b 前綴。
快捷鍵 | 功能 |
---|---|
SPC b b <buffer-name> | 創建一個名為<buffer-name>的緩沖區。 |
SPC b b | 通過打開緩沖區和最近的文件搜索。 |
SPC b n 或 :bnext | 切換到下一個緩沖區。(參見特殊緩沖區) |
SPC b p 或 :bprevious | 切換到前一個緩沖區。 (參見特殊緩沖區) |
SPC b d 或 :bdelete | 結束當前緩沖區。 |
SPC b k | 查找并結束一個緩沖區。 |
SPC b K | 結束除當前緩沖區的所有其他緩沖區。 |
SPC b . | 緩沖區微狀態。 |
特殊緩沖區
Emacs 默認會創建大量緩沖區,這些緩沖區很多人從來都不會使用到,就像 *Messages*。Spacemacs 會在使用這些快捷鍵時自動忽略這些緩沖區。可以在這里找到更多相關信息。
窗口
窗口就像 vim 中的分割。它們在一次編輯多個文件時相當有用。所有的快捷鍵都有 SPC w 前綴。
快捷鍵 | 功能 |
---|---|
SPC w v 或 :vsplit | 在右側打開一個垂直分割。 |
SPC w s 或 :split | 在下部打開一個水平分割。 |
SPC w h/j/k/l | 在窗口間導航。 |
SPC w H/J/K/L | 移動當前窗口。 |
SPC w . | 窗口微狀態。 |
文件
Spacemacs 中所有文件命令都有 SPC f 前綴。
快捷鍵 | 功能 |
---|---|
SPC f f | 打開一個緩沖區搜索當前目錄中的文件。 |
SPC f r | 打開一個緩沖區在最近打開的文件中搜索。 |
SPC f s 或 :w | 保存當前文件。 |
:x | 保存當前文件并退出。 |
:e <file> | 打開<file> |
幫助系統
Emacs 具有一個可擴展的幫助系統。所有的快捷鍵都有SPC h d 前綴,以允許便捷地訪問幫助系統。最重要的快捷鍵是 SPC h d f, SPC h d k, 和 SPC h d v。同樣還有 SPC <f1> 允許用戶搜索文檔。
快捷鍵 | 功能 |
---|---|
SPC h d f | 對一個功能提示并顯示其文檔。 |
SPC h d k | 對一個快捷鍵提示并顯示其綁定的內容。 |
SPC h d v | 對一個變量提示并顯示其文檔和當前值。 |
SPC <f1> | 搜索一個命令,功能,變量或接口,并顯示其文檔 |
不論何時,你遇到怪異的行為或想知道是什么東西做的,這些功能是你應該首先查閱的。
探索
有幾種方式可以探索 Spacemacs 的功能。一個是閱讀 Github 上的源代碼。你可以開始了解 Emacs Lisp,并能知道 Spacemacs 是怎樣工作的。你還能通過如下快捷鍵來探索:
快捷鍵 | 功能 |
---|---|
SPC f e h | 列出所有層并允許你瀏覽層上的文件。 |
SPC ? | 列出所有快捷鍵。 |
自定義
.spacemacs 文件
首次啟動 spacemacs 時,會提示你選擇編輯樣式。如果你現在正讀到這里,你可能會選擇 vim 樣式。這樣將會使用選擇的相應樣式創建一個 .spacemacs 文件。大多數瑣碎的配置都在這個文件中。
在這個文件中有四個頂級函數:dotspacemacs/layers, dotspacemacs/init,dotspacemacs/user-init 和 dotspacemacs/user-config。
Dotspacemacs/layers 函數僅用于啟用和禁用層和包。Dotspacemacs/init 函數是在啟動過程中,在其他東西運行前運行,并且包含 Spacemacs 設置。 除非你需要更改默認 Spacemacs 設置,否則你不用動這個函數。Dotspacemacs/user-init 函數也是在其他程序運行前運行,并包含用戶特定配置。Dotspacemacs/user-config 函數是你用到最多的函數。 在這里,你可以定義任何用戶配置。
快捷鍵 |
功能 |
---|---|
SPC f e d | 打開你的 .spacemacs |
SPC f e D | 使用diff 通過默認模版手動更新你的 .spacemacs |
Emacs Lisp
這個部分介紹幾個 配置 Spacemacs 需要的 Emacs Lisp 函數。如需詳細了解這個語言,請查看次鏈接。如果你很想了解 emacs lisp 的一切,請使用 SPC h i elisp RET 上的信息頁面
變量
設置變量是定制 Spacemacs 行為最常見的方式。語法很簡單:
(setq variable value) ; Syntax ;; Setting variables example (setq variable1 t ; True variable2 nil ; False variable3 '("A" "list" "of" "things"))
快捷鍵
定義快捷鍵是幾乎每個人都想做的事情,最好的方式就是使用內置的 define-key 函數。
(define-key map new-keybinding function) ; Syntax ;; Map H to go to the previous buffer in normal mode (define-key evil-normal-state-map (kbd "H") 'spacemacs/previous-useful-buffer) ;; Mapping keybinding to another keybinding (define-key evil-normal-state-map (kbd "H") (kbd "^")) ; H goes to beginning of the line
map 是你想要綁定鍵位到的 keymap。大多數情況下你會使用 evil-<state-name>-state-map。其對應不同的 evil-mode 狀態。例如,使用 evil-insert-state-map 映射用于插入模式的快捷鍵。
使用 evil-leader/set-key 函數來映射 <Leader> 快捷鍵。
(evil-leader/set-key key function) ; Syntax ;; Map killing a buffer to <Leader> b c (evil-leader/set-key "bc" 'kill-this-buffer) ;; Map opening a link to <Leader> o l only in org-mode (evil-leader/set-key-for-mode 'org-mode "ol" 'org-open-at-point)
函數
你可能偶爾想要定義一個函數做更復雜的定制,語法很簡單:
(defun func-name (arg1 arg2) "docstring" ;; Body ) ;; Calling a function (func-name arg1 arg1)
這里有個現實可用的示例函數:
;; This snippet allows you to run clang-format before saving ;; given the current file as the correct filetype. ;; This relies on the c-c++ layer being enabled. (defun clang-format-for-filetype () "Run clang-format if the current file has a file extensions in the filetypes list." (let ((filetypes '("c" "cpp"))) (when (member (file-name-extension (buffer-file-name)) filetypes) (clang-format-buffer)))) ;; See http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html for ;; what this line means (add-hook 'before-save-hook 'clang-format-for-filetype)
激活一個層
正如上文術語那段所說,層提供一個簡單的方式來添加特性。可在 .spacemacs 文件中激活一個層。在文件中找到 dotspacemacs-configuration-layers 變量,默認情況下,它看起來應該是這樣的:
(defun dotspacemacs/layers () (setq-default ;; ... dotspacemacs-configuration-layers '(;; auto-completion ;; better-defaults emacs-lisp ;; (git :variables ;; git-gutter-use-fringe t) ;; markdown ;; org ;; syntax-checking )))
你可以通過刪除分號來取消注釋這些建議的層,開箱即用。要添加一個層,就把它的名字添加到列表中并重啟 Emacs 或按 SPC f e R。使用 SPC f e h 來顯示所有的層和他們的文檔。
創建一個層
為了將配置分組或當配置與你的 .spacemacs 文件之間不匹配時,你可以創建一個配置層。Spacemacs 提供了一個內建命令用于生成層的樣板文件:SPC :configuration-layer/create-layer。這條命令將會生成一個如下的文件夾:
[layer-name] |__ [local]* | |__ [example-mode-1] | | ... | |__ [example-mode-n] |__ config.el* |__ funcs.el* |__ keybindings.el* |__ packages.el [] = 文件夾 * = 不是命令生成的文件
Packages.el 文件包含你可以在 <layer-name>-packages 變量中安裝的包的列表。所有 MELPA 倉庫中的包都可以添加到這個列表中。還可以使用 :excludedt 特性將包包含在列表中。每個包都需要一個函數來初始化。這個函數必須以這種模式命名:<layer-name>/init-<package-name>。這個函數包含了包的配置。同時還有一個 pre/post-init 函數來在包加載之前或之后運行代碼。它看起來想這個樣子:
(setq layer-name-packages '(example-package ;;這個層通過設置:excluded 屬性 ;;為真(t)來卸載example-package-2 (example-package-2 :excluded t))) (defun layer-name/post-init-package () ;;在這里添加另一個層的包的配置 ) (defun layer-name/init-example-package () ;;在這里配置example-package )
**注意**:只有一個層可以具有一個對于包的 init 函數。如果你想覆蓋另一個層對一個包的配置,請使用 use-package hooks 中的 <layer-name>/pre-init 函數。
如果 MELPA 中沒有你想要的包,你必須是由一個本地包或一個包源。關于此的更多信息可以從層的剖析處獲得。
確保你添加了你的層到你的 .spacemacs 文件中,并重啟 spacemacs 以激活。
關于層的加載過程和層的工作原理的詳細描述可以參考LAYERS.org。
安裝一個單獨的包
有時創建一個層會有點大材小用了,也許你僅僅想要一個包而不想維持整個層。Spacemacs 在 .spacemacs 文件中的 dotspacemacs/layers 函數里提供了一個叫做 dotspacemacs-additional-packages 的變量,只要在列表中添加一個包名,它就會在你重啟的時候被安裝。下一段來說明如何加載這個包。
加載包
有沒有想過 Spacemacs 如何可以在僅僅幾秒鐘之內加載超過 100 個包呢?如此低的加載時間必須需要某種難以理解的黑魔法吧。還好這不是真的,多虧有了 use-package。它是一個可以輕松實現對包進行延遲加載和配置的包。以下是它的基礎用法:
;; Basic form of use-package declaration. The :defer t tells use-package to ;; try to lazy load the package. (use-package package-name :defer t) ;; The :init section is run before the package loads The :config section is ;; run after the package loads (use-package package-name :defer t :init (progn ;; Change some variables (setq variable1 t variable2 nil) ;; Define a function (defun foo () (message "%s" "Hello, World!"))) :config (progn ;; Calling a function that is defined when the package loads (function-defined-when-package-loads)))
這只是 use-package 的一個非常基本的概述。它還有許多其他的方式來控制包的加載,就不在這里介紹了。
卸載一個包
Spacemacs 在 .spacemacs 文件中的 dotspacemacs/init 函數里提供了一個叫做 dotspacemacs-excluded-packages 的變量。只要在列表中添加一個包名,它就會在你重啟的時候被卸載。
常見調整
本段是為了想要做更多調整的人所寫的。除非另有說明,所有這些設置都去你的 .spacemacs 文件中的 dotspacemacs/user-config 函數里完成。
變更 escape 鍵
Spacemacs 使用 [[https://github.com/syl20bnr/evil-escape][evil-escape]] 來允許從許多擁有一個快捷鍵的 major-modes 中跳出。你可以在你的 dotspacemacs/user-config 函數中像這樣定制變量:
(defun dotspacemacs/user-config () ;; ... ;; Set escape keybinding to "jk" (setq-default evil-escape-key-sequence "jk"))
更多的文檔可以在 evil-escape README 中找到。
變更配色方案
.spacemacs 文件的 dotspacemacs/init 函數中有一個 dotspacemacs-themes 變量。這是一個可以用 SPC T n 鍵循環的主題的列表。列表中的第一個主題是在啟動時加載的主題。以下為示例:
(defun dotspacemacs/init ;; Darktooth theme is the default theme ;; Each theme is automatically installed. ;; Note that we drop the -theme from the package name. ;; Ex. darktooth-theme -> darktooth (setq-default dotspacemacs-themes '(darktooth soothe gotham)))
可以使用 SPC T h 鍵列出和選擇所有已安裝的主題。
非高亮搜索
Spacemacs 模仿了默認的 vim 行為,會高亮顯示搜索結果,盡管你不在它們之間進行導航。你可以使用 SPC s c 或 :nohlsearch 來關閉搜索結果高亮。
若再也不需要自動高亮結果,你可以卸載 evil-search-highlight-persist 包。
會話
當你打開 Spacemacs 時,它不會自動恢復窗口和緩沖區。如果你常使用 vim 會話,你可能要在你的 .spacemacs 文件中的 dotspacemacs/user-config 里添加 (desktop-save-mode t),然后你就可以使用 SPC : desktop-read 加載已被保存的會話。桌面文件的位置可以使用 desktop-dirname 變量設置。要自動加載一個會話,就在你的 .spacemacs 文件中添加 (desktop-read)。
使用 visual lines 導航
Spacemacs 使用 vim 默認 actual lines 導航,即使它們被包裝了。如果你想要讓 j 和 k 的行為如 g j 和 g k 一般,將一下代碼添加到你的 .spacemacs 文件:
(define-key evil-normal-state-map (kbd "j") 'evil-next-visual-line) (define-key evil-normal-state-map (kbd "k") 'evil-previous-visual-line)
其他有用的連接
-
注意:文中提到使用 SPC b s 切換緩沖區,應該是 SPC b b。
本文地址:http://www.oschina.net/translate/migrating-from-vim
原文地址:https://github.com/syl20bnr/spacemacs/blob/master/doc/VIMUSERS.org