Atom 深入鍵表(keymap)

2018-08-12 21:50 更新

深入鍵表(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!'

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

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

重載快捷鍵

一些情況下需要把多個(gè)動作依次放到同一個(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來處理。
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號