t

メモ

mark-word for Atom

Emacsmark-sexp のようなのものが Atom に欲しい、と思ったのですが AtomCoffeeScript もよく知らないし面倒なので mark-word のようなもので我慢することにしました。

具体的には次のようなスクリプト(2014-08-04: Atom 0.120.0 で動くように修正)を ~/.atom/init.coffee に書けば使えます。なお atomic-emacs が必要です。

AtomicEmacs = require './packages/atomic-emacs/lib/atomic-emacs'

class MyAtomicEmacs
  constructor: (@editor) ->
    nonWordCharacters = atom.config.get('editor.nonWordCharacters')
    cs = nonWordCharacters.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
    @wordPattern = new RegExp('[\\s' + cs + ']*[^\\s ' + cs + ']*')

  markWord: (event) ->
    eof = @editor.getEofBufferPosition()
    for selection in @editor.getSelections()
      cursor = selection.cursor
      mark = AtomicEmacs.Mark.for(cursor)
      if selection.isEmpty()
        mark.set().activate()
      cp = cursor.getBufferPosition()
      mp = mark.getBufferPosition()
      selection.modifySelection =>
        if cp.isLessThanOrEqual(mp)
          @editor.scanInBufferRange @wordPattern, [mp, eof], (hit) ->
            cursor.selection.setBufferRange([cp, hit.range.end], isReversed: true)
            mark.marker.setHeadBufferPosition(hit.range.end)
        else
          @editor.backwardsScanInBufferRange @wordPattern, [mp, [0, 0]], (hit) ->
            cursor.selection.setBufferRange([hit.range.start, cp])
            mark.marker.setHeadBufferPosition(hit.range.start)

atom.workspaceView.eachEditorView (editorView) ->
  myAtomicEmacs = new MyAtomicEmacs(editorView.getEditor())
  editorView.command "my-emacs:mark-word", (event) => myAtomicEmacs.markWord(event)

私は ~/.atom/keymap.cson に次のような設定を書いて使っています。

'.editor':
  'ctrl-[ ctrl-space': 'my-emacs:mark-word'

そしてこの設定は KeyRemap4MacBook の Space to Shift_L と相性が悪いので、次のような ~/Library/Application Support/KeyRemap4MacBook/private.xml を書いてごまかしました。

<?xml version="1.0"?>
<root>
  <item>
    <name>Space to Shift_L</name>
    <appendix>(+ When you type Ctrl_L-Space, send Ctrl_L-Space)</appendix>
    <appendix>Ctrl_L+Space to Ctrl_L+Space</appendix>
    <identifier>remap.space2shiftL_ctrlspace_ctrlspace</identifier>
    <autogen>__KeyToKey__ KeyCode::SPACE, ModifierFlag::CONTROL_L, KeyCode::SPACE, ModifierFlag::CONTROL_L</autogen>
    <autogen>__KeyOverlaidModifier__ KeyCode::SPACE, KeyCode::SHIFT_L, KeyCode::SPACE</autogen>
  </item>
</root>