Emacs = Esc + Meta + Alt + Ctrl + Super
這是一個玩笑話,不過 Emacs 確實有著多到令人咋舌的 key-binding。記不完怎麼辦?沒怎麼辦,就跟英文單字一樣,你也不需要把整本牛津字典背完才能開始說英文。只要先記住一些基本 key-binding 就可以了,熟悉以後能夠有效增加你的編輯效率。以下做一些整理。
C-x C-f
開檔。C-x C-s
存檔。C-x C-w
另存新檔。C-x C-c
離開 Emacs。
C-x k
關掉目前 buffer。C-x C-←
切換到上一個 buffer。C-x C-→
切換到下一個 buffer。C-x b
切換到/開啟一個名為 xxx 的 buffer。C-x C-b
開啟 buffer 管理員(不推薦使用,預設的管理員難用到爆)
這裡一定要特別提一下,按下
C-x C-b
會跳出 Emacs 預設的 buffer 管理員…這玩意簡直垃圾一般的存在,非常之難用,實在不懂為何到了 2015 年還是預設用這鬼東西(我猜可能是 RMS 愛用)。強烈建議改用 Emacs 內建的ibuffer
來代替預設的 buffer 管理員:(require 'ibuffer) (global-set-key (kbd "C-x C-b") 'ibuffer)試試看,這樣就已經比預設的好用了。除此之外
ibuffer
還有包含給 buffer 分類的功能。例如如下設定可以將正在使用 Python、Ruby、Dired 跟 Markdown 的 buffers 分開:(setq ibuffer-saved-filter-groups (quote (("default" ("Dired" (mode . dired-mode)) ("Markdown" (or (name . "^diary$") (mode . markdown-mode))) ("ReStructText" (mode . rst-mode)) ("Python" (or (mode . python-mode) (mode . ipython-mode) (mode . inferior-python-mode))) ("Ruby" (or (mode . ruby-mode) (mode . enh-ruby-mode) (mode . inf-ruby-mode)))))))可以再根據自己的需要修改。如果看不懂這在幹麻請先耐下性子,後續章節會提到要怎麼看懂並修改這類玩意。
– ono hiroko
C-x 0
關掉目前 WindowC-x 1
將目前 Window 以外的所有 Window 關掉。C-x 2
水平分割 WindowC-x 3
垂直分割 WindowC-x o
切換到下一個 Window(不推薦使用,不知道誰想出來的爛設計)
是的不才在下我今天又要來靠北一下 Emacs 的預設操作方式了。
C-x o
這個設計真是難按斃了,尤其當螢幕上你切割了一大堆 window 時,得按好幾次C-x o
才能切換到你要的,不過 Emacs 其實有內建一個套件叫windmove
,我自己是加入這樣的設定到設定檔中:(global-set-key (kbd "M-S") 'windmove-up) (global-set-key (kbd "M-X") 'windmove-down) (global-set-key (kbd "M-C") 'windmove-right) (global-set-key (kbd "M-Z") 'windmove-left)這樣就可以用
Alt+Shift+s/z/x/c
來向上/下/左/右切換 window,而且在標準 qwerty 鍵盤上可以單手操作。如果你有其他更偏好的 key-binding 請自行修改。– ono hiroko
C-x 5 0
關掉目前 FrameC-x 5 1
將目前以外的 Frame 關掉C-x 5 2
新增 FrameC-x 5 o
切換到不同的 Frame
我用了快五年 Emacs 才發現這幾個 Frame 相關命令有多麼實用(不知道這啥的話請重看第二章,詳細解釋Buffer/Window/Frame的差異)!我現在甚至讓 F11, F12 專門拿來切換 Frame:
(global-set-key (kbd "<f11>") (lambda () (interactive) (other-frame 1))) (global-set-key (kbd "<f12>") (lambda () (interactive) (other-frame -1)))
C-a
跳到行首C-e
跳到行尾M-f
跳到下一個英文單字(f 表示 forward)M-b
跳到前一個英文單字(b 表示 backward)
與 Vim 一樣,這種針對「單字」的操作指的都是歐洲語系國家的單字,因為他們有空白來分割每個單字。
然而對中文來說,Emacs 並沒有辦法針對中文斷詞,所以
M-f
會 直接跳到下一句話 ,因為每句話之間有標點符號分隔著。同理,編輯日文時,Emacs 只會按照平假名/片假名/漢字來「斷詞」。
– ono hiroko
M-g M-g
跳到第 N 行。M-<
跳到文件最頂端。M->
跳到文件最尾端。
這兩個比較特殊的游標移動,你可以自己試試看不同程式語言的 mode 中這些代表什麼意思,蠻常用到的。
C-M-b
跳到上一個 S-expression / 上一個 tokenC-M-f
跳到下一個 S-expression / 下一個 token
C-v
向下捲動一頁M-v
向上捲動一頁M-Page Down
隔壁的 window 向下捲動一頁M-Page Up
隔壁的 window 向上捲動一頁C-l
畫面與游標位置對齊(重複按可對齊三種位置)
C-s
普通字串搜尋(繼續按C-s
搜尋下一個)C-M-s
Regexp 搜尋 (一樣,也是繼續按C-s
搜尋下一個)M-%
字串搜尋並取代
注意,目前 buffer 的工作目錄就是指令執行時的 pwd
位置。
M-!
執行外部指令(synchronously)M-&
執行外部指令(asynchronously)M-|
將選取起來的區域(使用C-@
)透過 pipe 傳送給外部命令
這幾個玩意在臨時需要下指令時非常方便,其中最常用的應該是
M-!
,我常常拿它來下諸如git init
,git clone
,mkdir
等指令,而不用另外開個 console。– ono hiroko
C-k
從目前游標 kill 到行尾(並將被 kill 掉的部份丟入 kill-ring)M-k
從目前游標 kill 到一句話的尾端。C-d
kill 目前游標下的字元M-d
從目前游標 kill 到下一個 空格 or 標點符號 or 行尾
C-@
標記選取範圍。C-x C-x
跳到選取範圍的開頭/尾端。M-w
複製目前選取區域。C-w
剪下目前選取區域。
- 按
C-y
可以把最近一次被 Kill 掉的文字從 Kill-ring 給「拉 (Yank) 」出來。 - 再按 N 下
M-y
可以把前 N 次被 Kill 掉的文字從 Kill-ring 中「拉」出來。
前面提過,學 Emacs 的優勢之一,就是「FLOSS 界中,很多軟體都會用 Emacs-flavored key-binding 的」。
我個人覺得最神奇的,就是在我用 Emacs 一段時間後,赫然發現 「Bash 和 Zsh 中是可以使用 kill-ring 的!」 試試看就知道我在說什麼了,真的非常方便。尤其如果你已經很熟悉 Emacs 的操作,那往後在使用 Bash/Zsh 時你會發現比以往更如魚得水。
– ono hiroko
C-/
或C-_
: 復原(Undo)。- 先按
C-g
再按 undo:Redo。
這是每個 Emacs 初學者一開始都會被搞混的概念。但 Emacs 的 Undo/Redo 非常強大,但邏輯很難懂。在這裡簡單的說,就是 在 Emacs 中,包含 undo 這個動作本身都是可以 undo 的 ,也就是 undo 本身也會被紀錄在整個編輯歷史中,而不會被其他 undo/redo 動作給消除(直到你關閉這個檔案為止)。「一切你的編輯行為都是可以undo的」,而「編輯行為」也包含undo自己。
其實我自己也解釋不太清楚這個概念,雖然很常用但解釋真的不太容易…
希望我沒解釋錯(請各位大大指正)例如開一個全新的buffer 後:
0.[空白buffer狀態] 1.輸入一串字(A) 2.按undo把(A)消乾淨[回到0.的空白buffer狀態,無法再undo] 3.再輸入另一串字(B) 4.按undo把(B)消乾淨 5.再按一次undo,會發現(A)跑回來了,因為他undo了你在2.時所作的undo 6.再按一次undo,又回到最一開始的0.[空白buffer無法再undo]重點在步驟
5.
Vim 聽說也是這樣,所以 Vimmer 應該能了解。
我個人推薦使用
undo-tree.el
這個外掛,可以視覺化整個 undo/redo 歷史樹。我個人還蠻常用undo-tree
,但也聽過別人說他們覺得這玩意沒什麼使用時機。各人喜好吧。順帶一提,
undo-tree.el
中有提供一個 command 叫做undo-tree-redo
,它的功能就是你想要的那個 redo,你可以把這 command 給綁到你要的 key-binding 上。我自己平常就是用這個來做 redo 的,這樣就不用先按C-g
就能 Redo 了。– ono hiroko
M-^
把目前行的縮排拿掉後,接到上一行。
M-;
插入目前語言的註解(如 Python 就是# comment
,Haskell 就是-- comment
)注意,你可以用
C-@
選取一段文字後,再按下M-;
,這樣就可以將整個選取的範圍給註解掉。試試看就知道我在說什麼了。– ono hiroko
C-M-\
立刻自動縮排M-q
將目前整個段落每 70 字元換行。
M-l
單字轉成全小寫。M-u
單字轉成全大寫。M-c
單字轉首字大寫。
這個功能看似雞肋,不過我還蠻常用的。
因為這個大小寫轉換是從目前游標開始算起,所以請搭配前面提到過的
M-b
來使用。例如M-b M-u
就可以把目前單字轉成全大寫。– ono hiroko
C-t
前後字元交換。M-t
前後單字交換。
規則很難解釋,自己多試用幾次看看就會懂了。熟悉後我發現這個功能出乎意料的實用。
– ono hiroko