鍍金池/ 教程/ C++/ 深入鍵表(keymap)
調(diào)試
初始文件
作用域設(shè)置、作用域和作用域描述符
在Atom中移動(dòng)
在Atom背后
Atom中的包
為什么選擇Atom?
從Textmate中轉(zhuǎn)換
小結(jié)
新手入門
折疊
代碼段
Hacking Atom
基本的自定義
Atom中的序列化
文本處理包
字?jǐn)?shù)統(tǒng)計(jì)包
所需工具
維護(hù)你的包
Atom基礎(chǔ)
深入鍵表(keymap)
配置API
使用Atom
自動(dòng)補(bǔ)全
面板
在Atom中寫作
文本選擇
創(chuàng)建主題
圖標(biāo)
小結(jié)
開發(fā)Node模塊
編輯和刪除文本
安裝Atom
通過服務(wù)和其它包交互
小結(jié)
編寫 spec
語法
Atom中的版本控制
查找和替換

深入鍵表(keymap)

鍵表文件是以JSON或者CSON編碼的文件,其中含有嵌套的哈希表。它們的工作方式像是樣式表,但是它們指定匹配選擇器的元素的快捷鍵的作用,而不是應(yīng)用樣式屬性。下面是一些快捷鍵的例子,它們在atom-text-editor元素上按下時(shí)生效:

'atom-text-editor':
  'cmd-delete': 'editor:delete-to-beginning-of-line'
  'alt-backspace': 'editor:delete-to-beginning-of-word'
  'ctrl-A': 'editor:select-to-first-character-of-line'
  'ctrl-shift-e': 'editor:select-to-end-of-line'
  'cmd-left': 'editor:move-to-first-character-of-line'

'atom-text-editor:not([mini])':
  'cmd-alt-[': 'editor:fold-current-row'
  'cmd-alt-]': 'editor:unfold-current-row'

在第一個(gè)選擇器底下綁定了一些快捷鍵,將特定的鍵位通配符映射到命令上面。當(dāng)一個(gè)atom-text-editor元素獲得焦點(diǎn),并且cmd-delete被按下,一個(gè)叫做editor:delete-to-beginning-of-line的自定義DOM事件會在atom-text-editor元素上面觸發(fā)。

第二個(gè)選擇器分組也指向了編輯器,但是只是沒有mini屬性的編輯器。在這個(gè)例子中,代碼折疊的命令在迷你編輯器中毫無意義,所以選擇器將它們限制于普通的編輯器中。

鍵位通配符(keystroke pattern)

鍵位通配符表示一個(gè)或者多個(gè)鍵位,帶有可選的輔助鍵(modifier key)。例如ctrl-w vcmd-shift-up。鍵位由下面的符號組成,以-分隔。一個(gè)多種鍵位的通配符可以表示為以空格分割的鍵位通配符。

類型 例子
字符的字面值 a 4 $
輔助鍵 cmd ctrl alt shift
特殊鍵 enter escape backspace delete tab home end pageup pagedown left right up down

命令

命令是自定義的DOM事件,當(dāng)一個(gè)鍵位匹配到綁定的快捷鍵時(shí)觸發(fā)。這可以讓UI代碼來監(jiān)聽具名的命令,而不需要指定觸發(fā)它的特定的快捷鍵。例如,下面的代碼創(chuàng)建了一個(gè)命令來向編輯器插入當(dāng)前日期:

atom.commands.add 'atom-text-editor',
  'user:insert-date': (event) ->
    editor = @getModel()
    editor.insertText(new Date().toLocaleString())

atom.commands指向全局{CommandRegistry}的實(shí)例,所有命令在它里面設(shè)置,并且可以通過命令面板來獲取。

當(dāng)你想要綁定新的快捷鍵時(shí),使用命令面板(ctrl-shift-p)來看一看在一個(gè)具有焦點(diǎn)的上下文中,什么命令正在被監(jiān)聽,是十分有用的。遵循一個(gè)簡單的算法使得命令會很“人性化”,所以editor:fold-current-row命令會顯示為“Editor: Fold Current Row”。

“組合”命令

一個(gè)很常見的問題是,“我如何使用一個(gè)快捷鍵來執(zhí)行兩個(gè)或者更多命令?”Atom并不直接支持這一需求,但是我們可以通過創(chuàng)建一個(gè)自定義命令,它執(zhí)行你想要的多個(gè)操作,并且為這個(gè)命令創(chuàng)建一個(gè)快捷鍵來解決。例如,假設(shè)我想創(chuàng)建一個(gè)“組合”命令,選取并剪切一行。你可以在init.coffee中添加一下代碼:

atom.commands.add 'atom-text-editor', 'custom:cut-line', ->
  editor = atom.workspace.getActiveTextEditor()
  editor.selectLinesContainingCursors()
  editor.cutSelectedText()

然后我們想要把這個(gè)命令關(guān)聯(lián)到alt-ctrl-z上去,你應(yīng)該添加以下內(nèi)容到鍵表中:

'atom-text-editor':
  'alt-ctrl-z': 'custom:cut-line'

特異性(優(yōu)先級)和層級順序

就像這個(gè)應(yīng)用了CSS樣式的例子,當(dāng)很多快捷鍵的綁定匹配到一個(gè)元素的時(shí)候,沖突通過選擇最特別的選擇器來解決。如果兩個(gè)匹配到的選擇器具有相同的特異性,在層級中出現(xiàn)順序靠后的選擇器的快捷鍵會優(yōu)先執(zhí)行。

當(dāng)前,沒有任何方法在一個(gè)單獨(dú)的鍵表中指定快捷鍵的順序,因?yàn)镴SON的對象是無序的。我們最終打算為鍵表引入一個(gè)自定義類似CSS的文件格式來允許在單個(gè)文件中排序。到目前為止,我們可以選擇性解決一些情況,其中選擇器的順序由把鍵表分開放到兩個(gè)文件中來嚴(yán)格規(guī)定。就像snippets-1.csonsnippets-2.cson。

移除快捷鍵

當(dāng)鍵表系統(tǒng)遇到了以unset!作為快捷鍵的命令,它就會像沒有綁定匹配到當(dāng)前鍵位序列一樣,繼續(xù)從它的父節(jié)點(diǎn)中尋找。如果你想移除一個(gè)你不再用到的快捷鍵,例如Atom核心中的或者包中的快捷鍵,應(yīng)該直接使用unset!

例如,下面的代碼移除了樹視圖上a的快捷鍵,它一般會觸發(fā)tree-view:add-file命令:

'.tree-view':
  'a': 'unset!'

http://wiki.jikexueyuan.com/project/atom-flight-manual-zh-cn/images/keybinding.png" alt="" />

強(qiáng)制Chrome處理本地快捷鍵

如果你想要在一個(gè)提供的快捷鍵上強(qiáng)制執(zhí)行本地瀏覽器的行為,直接使用native!作為綁定的命令。這會在啟動(dòng)本地輸入元素的正確行為時(shí)比較有用。例如,如果你在一個(gè)元素上面應(yīng)用了.native-key-bindings class,所有由瀏覽器處理的快捷鍵都會綁定為native!。

重載快捷鍵

一些情況下需要把多個(gè)動(dòng)作依次放到同一個(gè)快捷鍵下面。一個(gè)例子就是代碼段的包,代碼段由輸入一個(gè)類似for的前綴之后按下tab來插入。每次tab按下的時(shí)候,如果光標(biāo)前面的文字存在對應(yīng)的代碼段,我們想要執(zhí)行代碼來展開代碼段。如果代碼段并不存在,我們希望tab插入空白字符。

要實(shí)現(xiàn)成這樣,代碼段的包利用了代表snippets:expand命令的事件對象的.abortKeyBinding()方法。

# pseudo-code
editor.command 'snippets:expand', (e) =>
  if @cursorFollowsValidPrefix()
    @expandSnippet()
  else
    e.abortKeyBinding()

當(dāng)事件處理器觀察到光標(biāo)前面并沒有一個(gè)有效的前綴時(shí),會調(diào)用`e.abortKeyBinding()來告訴鍵表系統(tǒng)繼續(xù)尋找另一個(gè)匹配到的綁定。

詳細(xì)步驟:按鍵事件如何映射到命令

  • 按鍵事件出現(xiàn)在獲得焦點(diǎn)的元素上面。
  • 由獲取焦點(diǎn)的元素開始,鍵表會向上搜索,直到文檔的根元素,尋找最具特異性的CSS選擇器,它匹配當(dāng)前DOM元素并且含有匹配按鍵事件的快捷鍵通配符。
  • 找到匹配的快捷鍵通配符之后,搜索就結(jié)束了,并且與通配符綁定的命令會在當(dāng)前元素上觸發(fā)。
  • 如果在觸發(fā)的事件對象上調(diào)用了.abortKeyBinding(),會恢復(fù)搜索,在相同元素上觸發(fā)下一個(gè)最具特異性的CSS選擇器上綁定的事件,或者繼續(xù)向上搜索。
  • 如果找不到任何快捷鍵,事件通常就會由Chrome來處理。