aboutsummaryrefslogtreecommitdiff
path: root/atom/packages/vim-surround/lib/command/change.coffee
blob: 7bdf623e1df1b28dde3990b9c4e99de6f6722156 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
{CompositeDisposable} = require 'atom'

Base = require './base'
Selector = require './selector'

module.exports = class Change
  constructor: (config) ->
    @command = config.changeSurroundCommand
    @context = "atom-text-editor.vim-mode.normal-mode"
    @disposables = new CompositeDisposable
    @curPairs = []
    @curPairsWithTarget = []
    @registerPairs config.pairs

  getName: (key, targetKey) -> "change-#{key}-to-#{targetKey}"

  registerPairs: (pairs) ->
    pairs = (x for x in pairs when x.length > 0 and x.length %2 == 0)

    for pair in pairs
      for target in pairs
        if "#{pair}#{target}" not in @curPairs
          @registerPair pair, target
          @curPairs.push("#{pair}#{target}")

  registerPair: (pair, target) ->
    [left, right] = @splitPair(pair)
    [target_left, target_right] = @splitPair(target)

    for key in [left, right]
      for targetKey in [target_left, target_right]
        if "#{key}#{targetKey}" not in @curPairsWithTarget
          name = "vim-surround:#{@getName(key, targetKey)}"

          unless pair == target
            @disposables.add atom.commands.add @context, name, @getRunner pair, target

          keymapArg = {}
          fullCommand = "#{@command} #{key} #{targetKey}"
          keymapArg[fullCommand] = name

          contextArg = {}
          contextArg[@context] = keymapArg

          # Capture the disposable heretom test!
          unless pair == target
            @disposables.add atom.keymaps.add name, contextArg
          @curPairsWithTarget.push("#{key}#{targetKey}")

  splitPair: (pair) ->
    return [pair[..(pair.length/2)-1], pair[pair.length/2..]]

  getRunner: (from, to) -> ->
    [left, right] = [from[0], from[1]]
    [target_left, target_right] = [to[0], to[1]]
    editor = atom.workspace.getActiveTextEditor()
    selector = new Selector(editor, left, right)

    editor.transact ->
      cursorPos = editor.getCursorBufferPosition()

      selector.inside().select()
      editor.selections.forEach (selection) ->
        text = selection.getText()

        # restore cursore and select text with surrounding keys
        editor.setCursorBufferPosition(cursorPos)
        selector.outside().select()

        editor.selections.forEach (selection) ->
          selection.insertText "#{target_left}#{text}#{target_right}"

      # restore cursore
      editor.setCursorBufferPosition(cursorPos)