2011年12月14日 星期三

[設定] 在 Mac 上自訂 Windows 按鍵習慣 - Part II Emacs 及終端機設定

本文是承接自 Part I 的設定,介紹如何在 Mac 上,利用 PC 上的按鍵方式使用 Emacs 及 Terminal 內的命令列程式。

下面的設定比較複雜,如果你沒用過 Emacs,可以直接忽略本文。

在 PC 鍵盤上,能夠充當 Emacs 定義的 Meta 鍵的只有 Alt 鍵,不管是使用 Windows 上或是在 PC 上安裝 Linux/FreeBSD,當使用 Emacs 按鍵時,應該都會拿 Alt 鍵當做 Meta key。


PC 的 Alt 鍵,放到 Mac 鍵盤上會對應到 Command 鍵的位置。



雖然在 Mac OS 內,預設是拿 Option 鍵當做是 meta 鍵 (這在 Mac 的按鍵定義下有一些優點),但 GNU Emacs manual 也提到說,不論拿 Option 或 Command 鍵當 meta 鍵其實都是可行的,而且大部分人會喜歡用 Command 鍵當 meta 鍵,因為這樣可以留下 Option 鍵用來輸入一些歐洲語系的文字 (這在非英語系鍵盤上稱作 dead key)。

我個人認為拿 Command 鍵當做 meta 鍵還有一個好處,就是比較符合人體工學,比較好按。


1. Emacs 設定

在 Emacs 內使用上圖的按鍵設定很簡單,首先按照  Part I 去設定完成,然後在 .emacs 中加上下列設定即可:


(setq mac-option-modifier 'none)
(setq mac-control-modifier 'meta)
(setq mac-command-modifier 'control)

另外 Apple 全尺寸鍵盤上也有 Home/End 鍵,在 Mac 上預設是移到整個 buffer 的首尾,可以仿照 Windows 改成移至行首及行尾

(global-set-key (kbd "<home>") 'move-beginning-of-line)
(global-set-key (kbd "<end>") 'move-end-of-line)

另外由於  Part I  把 Command & Control 鍵對調,所以實體按鍵 Control+Space 會跟 Windows 一樣用來切換輸入法,我個人習慣把 Control+Enter 設定成 Emacs 中的 set mark。

(global-set-key (quote [C-return]) 'set-mark-command)

有些模式會用到 C-Enter,比如 nxml-mode 會把 Control-Enter 改成另一個指令,這時候就要在 .emacs 中手動換回來,以 nxml-mode 為例

(add-hook 'nxml-mode-hook
 '(lambda ()
    ; we need to reserve C-return for set-mark-command
    (define-key nxml-mode-map (quote [C-return]) 'set-mark-command)
    (define-key nxml-mode-map (quote [M-return]) 'nxml-complete)))


--------------------------------------------------------

順帶一提,Mac 上的 Emacs 只要語系有設定正確,可以用 Yahoo 輸入法輸入中文,但可惜無法左右選字,也無法輸入部分標點符號,我的暫解是重新定義 Ctrl+, 等按鍵來輸入標點符號:


(define-key global-map [(control \,)]  (lambda () (interactive)
(insert-string ",")))
(define-key global-map [(control \.)]  (lambda () (interactive)
(insert-string "。")))
(define-key global-map [(control \:)]  (lambda () (interactive)
(insert-string ":")))
(define-key global-map [(control \")]  (lambda () (interactive)
(insert-string ";")))
(define-key global-map [(control \?)]  (lambda () (interactive)
(insert-string "?")))
(define-key global-map [(control \!)]  (lambda () (interactive)
(insert-string "!")))
(define-key global-map [(control \{)]  (lambda () (interactive)
(insert-string "『")))
(define-key global-map [(control \})]  (lambda () (interactive)
(insert-string "』")))


2. Terminal 設定

Terminal 比較尷尬,因為 Mac 鍵盤原本的設計是最方便的:Command 鍵跟 Control 及 Meta 鍵 (預設 Option 鍵) 是分開的,即使在 Terminal 內仍然可以很方便地使用 Command 鍵有關的熱鍵 (比如用 Command+T 開新分頁)。

但如果你跟我一樣曾在 PC 上用了太多年的 Emacs,一時習慣改不過來,還是想硬把 Command 鍵設定為 Meta 鍵的話:

2.1 先在 Terminal 的設定中勾選「使用 option 鍵作為 meta 鍵」


2.2 接下來使用 KeyRemap4MacBook 去把 Command 鍵對應到 Option 鍵

你可以直接把下面的 XML code 貼到上一篇文章的 private.xml 中


  <!-- Use physical Command_L as meta key for Emacs key binding in Terminal. 
       KNOWN BUG: it will block us from using Command key to access menu in Terminal app. -->
  <item>
    <name>Setup Control and Meta keys in Terminal as PC keyboard layout</name>
    <appendix>(Command and Control modifiers should be swapped in system preference before enabling this option)</appendix>
    <appendix>(Keep Option+Tab to Command+Tab)</appendix>
    <appendix>(Keep Option+Backquote to Command+Backquote)</appendix>
    <appendix>(Keep Option+Arrow to Control+Arrow)</appendix>
    <identifier>private.app_term_controlL2optionL_except_tab</identifier>
    <only>TERMINAL</only>
    <autogen>--KeyToKey-- KeyCode::CONTROL_L, KeyCode::OPTION_L</autogen>
    <autogen>--KeyToKey-- KeyCode::CONTROL_R, KeyCode::OPTION_R</autogen>    
    <autogen>--KeyToKey-- KeyCode::COMMAND_L, KeyCode::CONTROL_L</autogen>
    <autogen>--KeyToKey-- KeyCode::COMMAND_R, KeyCode::CONTROL_R</autogen>        
    <autogen>--KeyToKey-- KeyCode::TAB, VK_OPTION, KeyCode::TAB, ModifierFlag::COMMAND_L</autogen>
    <autogen>--KeyToKey-- KeyCode::BACKQUOTE, VK_OPTION, KeyCode::BACKQUOTE, ModifierFlag::COMMAND_L</autogen>
    <autogen>--KeyToKey-- KeyCode::CURSOR_LEFT, VK_OPTION, KeyCode::CURSOR_LEFT, ModifierFlag::CONTROL_L</autogen>
    <autogen>--KeyToKey-- KeyCode::CURSOR_RIGHT, VK_OPTION, KeyCode::CURSOR_RIGHT, ModifierFlag::CONTROL_L</autogen>    
    <autogen>--KeyToKey-- KeyCode::CURSOR_UP, VK_OPTION, KeyCode::CURSOR_UP, ModifierFlag::CONTROL_L</autogen>    
    <autogen>--KeyToKey-- KeyCode::CURSOR_DOWN, VK_OPTION, KeyCode::CURSOR_DOWN, ModifierFlag::CONTROL_L</autogen>
  </item>


這一段 XML 比較複雜,因為得將實體的Command 鍵+方向鍵 (用於 Mission Control) 以及實體的Command 鍵+Tab (用於切換程式) 當做特例處理。

另外由於 Terminal 中主要會用到的 Emacs 按鍵主要是 C-k, M-d, M-Del, M-f 等,其他一些按鍵如 C-n, C-w, C-t 雖然跟 Emacs 按鍵衝突,但為了符合 Mac 下的操作習慣,也可以把他們還原回原本的功能,比如:
  • Command++ 放大字體
  • Command+- 縮小字體
  • Command+w 關閉分頁
  • Command+t 新增分頁
  • Command+q 結束程式

    <autogen>--KeyToKey-- KeyCode::EQUAL, VK_CONTROL | VK_SHIFT, 

    KeyCode::EQUAL, ModifierFlag::COMMAND_L | ModifierFlag::SHIFT_L</autogen>

    <autogen>--KeyToKey-- KeyCode::MINUS, VK_CONTROL | ModifierFlag::NONE, 
    KeyCode::MINUS, ModifierFlag::COMMAND_L</autogen>

    <autogen>--KeyToKey-- KeyCode::Q, VK_CONTROL, KeyCode::Q, ModifierFlag::COMMAND_L</autogen>
    <autogen>--KeyToKey-- KeyCode::W, VK_CONTROL, KeyCode::W, ModifierFlag::COMMAND_L</autogen>    
    <autogen>--KeyToKey-- KeyCode::T, VK_CONTROL, KeyCode::T, ModifierFlag::COMMAND_L</autogen>


由於 KeyRemap4MacBook 的功能強大,非常有彈性。我們也可以調整其他按鍵設定,比如 Terminal 中 Apple 預設是以 Command+{} 來左右切換分頁,我習慣用 Windows 上 Firefox 所定義的 Control+PageUp/PageDown 來切換分頁,只要加上下述 XML 就可以用在 Terminal 上。

    <autogen>--KeyToKey-- KeyCode::PAGEDOWN, VK_CONTROL, KeyCode::BRACKET_RIGHT, ModifierFlag::SHIFT_L | ModifierFlag::COMMAND_L </autogen>
    <autogen>--KeyToKey-- KeyCode::PAGEUP, VK_CONTROL, KeyCode::BRACKET_LEFT, ModifierFlag::SHIFT_L | ModifierFlag::COMMAND_L</autogen>       

沒有留言:

張貼留言