]>
Commit | Line | Data |
---|---|---|
1 | _ = require 'underscore-plus' | |
2 | {CompositeDisposable} = require 'atom' | |
3 | ||
4 | Config = | |
5 | debug: | |
6 | type: 'boolean' | |
7 | default: false | |
8 | ||
9 | module.exports = | |
10 | disposables: null | |
11 | active: false | |
12 | prefix: 'vim-mode-visual-block' | |
13 | ||
14 | activate: (state) -> | |
15 | @disposables = new CompositeDisposable | |
16 | blockwiseCommands = {} | |
17 | commands = 'jkoDCIA'.split('') | |
18 | commands.push 'escape', 'ctrl-v' | |
19 | for command in commands | |
20 | do (command) => | |
21 | name = "#{@prefix}:#{command}" | |
22 | blockwiseCommands[name] = (event) => @blockOperation(event, command) | |
23 | ||
24 | # blockwiseCommands["#{@prefix}:toggle-debug"] = => @toggleDebug() | |
25 | @disposables.add atom.commands.add('atom-text-editor', blockwiseCommands) | |
26 | @reset() | |
27 | ||
28 | deactivate: -> | |
29 | @disposables.dispose() | |
30 | ||
31 | consumeVimMode: (@vimModeService) -> | |
32 | ||
33 | reset: -> | |
34 | @startRow = null | |
35 | ||
36 | getEditor: -> | |
37 | atom.workspace.getActiveTextEditor() | |
38 | ||
39 | isVisualBlockMode: (vimState) -> | |
40 | (vimState.mode is 'visual') and (vimState.submode is 'blockwise') | |
41 | ||
42 | getVimEditorState: (editor) -> | |
43 | @vimModeService.getEditorState editor | |
44 | ||
45 | adjustSelections: (editor, options) -> | |
46 | for selection in editor.getSelections() | |
47 | range = selection.getBufferRange() | |
48 | selection.setBufferRange range, options | |
49 | ||
50 | blockOperation: (event, command) -> | |
51 | editor = @getEditor() | |
52 | vimState = @getVimEditorState editor | |
53 | ||
54 | unless @isVisualBlockMode vimState | |
55 | event.abortKeyBinding() | |
56 | @reset() | |
57 | return | |
58 | ||
59 | # May be non-continuous execution. | |
60 | if editor.getCursors().length is 1 | |
61 | @reset() | |
62 | ||
63 | currentRow = editor.getLastCursor()?.getBufferRow() | |
64 | @startRow ?= currentRow | |
65 | ||
66 | switch command | |
67 | when 'o' | |
68 | @startRow = currentRow | |
69 | when 'D', 'C' | |
70 | vimState.activateNormalMode() | |
71 | event.abortKeyBinding() | |
72 | when 'escape', 'ctrl-v' | |
73 | vimState.activateNormalMode() | |
74 | editor.clearSelections() | |
75 | when 'j', 'k' | |
76 | cursors = editor.getCursorsOrderedByBufferPosition() | |
77 | cursorTop = _.first cursors | |
78 | cursorBottom = _.last cursors | |
79 | ||
80 | if (command is 'j' and cursorTop.getBufferRow() >= @startRow) or | |
81 | (command is 'k' and cursorBottom.getBufferRow() <= @startRow) | |
82 | lastSelection = editor.getLastSelection() | |
83 | ||
84 | if command is 'j' | |
85 | editor.addSelectionBelow() | |
86 | else | |
87 | editor.addSelectionAbove() | |
88 | ||
89 | # [FIXME] | |
90 | # When addSelectionAbove(), addSelectionBelow() doesn't respect | |
91 | # reversed stated, need improved. | |
92 | # | |
93 | # and one more.. | |
94 | # | |
95 | # When selection is NOT empty and add selection by addSelectionAbove() | |
96 | # and then move right, selection range got wrong, maybe this is bug.. | |
97 | @adjustSelections editor, reversed: lastSelection.isReversed() | |
98 | else | |
99 | # [FIXME] | |
100 | # Guard to not destroying last cursor | |
101 | # This guard is no longer needed | |
102 | # Remove unnecessary code after re-think. | |
103 | if (editor.getCursors().length < 2) | |
104 | @reset() | |
105 | return | |
106 | ||
107 | if command is 'j' | |
108 | cursorTop.destroy() | |
109 | else | |
110 | cursorBottom.destroy() | |
111 | when 'I', 'A' | |
112 | cursorsAdjusted = [] | |
113 | ||
114 | adjustCursor = (selection) -> | |
115 | {start, end} = selection.getBufferRange() | |
116 | pointEndOfLine = editor.bufferRangeForBufferRow(start.row).end | |
117 | pointTarget = {'I': start, 'A': end}[command] | |
118 | {cursor} = selection | |
119 | ||
120 | if pointTarget.isGreaterThanOrEqual(pointEndOfLine) | |
121 | pointTarget = pointEndOfLine | |
122 | cursorsAdjusted.push cursor | |
123 | cursor.setBufferPosition(pointTarget) | |
124 | ||
125 | adjustCursor(selection) for selection in editor.getSelections() | |
126 | vimState.activateNormalMode() | |
127 | vimState.activateInsertMode() | |
128 | ||
129 | if command is 'A' and cursorsAdjusted.length | |
130 | cursor.moveRight() for cursor in cursorsAdjusted | |
131 | ||
132 | unless @isVisualBlockMode vimState | |
133 | @reset() | |
134 | ||
135 | toggleDebug: -> | |
136 | oldState = atom.config.get("#{@prefix}.debug") | |
137 | atom.config.set("#{@prefix}.debug", not oldState) | |
138 | state = atom.config.get("#{@prefix}.debug") and "enabled" or "disabled" | |
139 | console.log "#{@prefix}: debug #{state}" | |
140 | ||
141 | debug: (msg) -> | |
142 | return unless atom.config.get("#{@prefix}.debug") | |
143 | console.log msg | |
144 | ||
145 | # dump: -> | |
146 | # @debug "@startRow = #{@startRow}" |