diff options
| author | Ben Beltran <ben@nsovocal.com> | 2015-07-10 11:12:25 -0500 |
|---|---|---|
| committer | Ben Beltran <ben@nsovocal.com> | 2015-07-10 11:12:25 -0500 |
| commit | 24c7594d62d8d7fbbcdb64b11ce4adc5d8e6991a (patch) | |
| tree | ded312222bb108923da1820ba40b04d710d20e5b /atom/packages/vim-mode-visual-block/lib | |
| parent | eb786e82d170e2abc351a432ade616d6ecdeeb6b (diff) | |
Adds atom
Diffstat (limited to 'atom/packages/vim-mode-visual-block/lib')
| -rw-r--r-- | atom/packages/vim-mode-visual-block/lib/main.coffee | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/atom/packages/vim-mode-visual-block/lib/main.coffee b/atom/packages/vim-mode-visual-block/lib/main.coffee new file mode 100644 index 0000000..61cfe76 --- /dev/null +++ b/atom/packages/vim-mode-visual-block/lib/main.coffee @@ -0,0 +1,158 @@ +_ = require 'underscore-plus' +{CompositeDisposable} = require 'atom' + +Config = + debug: + type: 'boolean' + default: false + +module.exports = + disposables: null + active: false + prefix: 'vim-mode-visual-block' + + activate: (state) -> + @disposables = new CompositeDisposable + blockwiseCommands = {} + # [TODO] remove 'h', 'l' after some period. + commands = 'jkhloDCIA'.split('') + commands.push 'escape', 'ctrl-v' + for command in commands + do (command) => + name = "#{@prefix}:#{command}" + blockwiseCommands[name] = (event) => @blockOperation(event, command) + + blockwiseCommands["#{@prefix}:toggle-debug"] = => @toggleDebug() + @disposables.add atom.commands.add('atom-text-editor', blockwiseCommands) + @reset() + + deactivate: -> + @disposables.dispose() + + consumeVimMode: (@vimModeService) -> + + reset: -> + @startRow = null + + getEditor: -> + atom.workspace.getActiveTextEditor() + + isVisualBlockMode: (vimState) -> + (vimState.mode is 'visual') and (vimState.submode is 'blockwise') + + getVimEditorState: (editor) -> + @vimModeService.getEditorState editor + + adjustSelections: (editor, options) -> + for selection in editor.getSelections() + range = selection.getBufferRange() + selection.setBufferRange range, options + + blockOperation: (event, command) -> + editor = @getEditor() + vimState = @getVimEditorState editor + + unless @isVisualBlockMode vimState + event.abortKeyBinding() + @reset() + return + + # May be non-continuous execution. + if editor.getCursors().length is 1 + @reset() + + currentRow = editor.getLastCursor()?.getBufferRow() + @startRow ?= currentRow + # @debug "@startRow = #{@startRow}" + + switch command + when 'o' + @startRow = currentRow + when 'D', 'C' + vimState.activateCommandMode() + event.abortKeyBinding() + when 'escape', 'ctrl-v' + vimState.activateCommandMode() + editor.clearSelections() + when 'j', 'k' + cursorPositions = editor.getCursorsOrderedByBufferPosition() + cursorTop = _.first cursorPositions + cursorBottom = _.last cursorPositions + + if (command is 'j' and cursorTop.getBufferRow() >= @startRow) or + (command is 'k' and cursorBottom.getBufferRow() <= @startRow) + lastSelection = editor.getLastSelection() + + if command is 'j' + editor.addSelectionBelow() + else + editor.addSelectionAbove() + + # [FIXME] + # When addSelectionAbove(), addSelectionBelow() doesn't respect + # reversed stated, need improved. + # + # and one more.. + # + # When selection is NOT empty and add selection by addSelectionAbove() + # and then move right, selection range got wrong, maybe this is bug.. + @adjustSelections editor, reversed: lastSelection.isReversed() + else + # [FIXME] + # Guard to not destroying last cursor + # This guard is no longer needed + # Remove unnecessary code after re-think. + if (editor.getCursors().length < 2) + @reset() + return + + if command is 'j' + cursorTop.destroy() + else + cursorBottom.destroy() + when 'I', 'A' + cursorsAdjusted = [] + + adjustCursor = (selection) -> + {start, end} = selection.getBufferRange() + pointEndOfLine = editor.bufferRangeForBufferRow(start.row).end + pointTarget = {'I': start, 'A': end}[command] + {cursor} = selection + + if pointTarget.isGreaterThanOrEqual(pointEndOfLine) + pointTarget = pointEndOfLine + cursorsAdjusted.push cursor + cursor.setBufferPosition(pointTarget) + + adjustCursor(selection) for selection in editor.getSelections() + vimState.activateCommandMode() + vimState.activateInsertMode() + + if command is 'A' and cursorsAdjusted.length + cursor.moveRight() for cursor in cursorsAdjusted + + else + event.abortKeyBinding() + content = """ + *#{@prefix}* + * From version 0.2.5, `#{@prefix}` provide default keymap. + * And `h`, `l` command become obsolete. + * Remove all explicit keymap from `keymap.cson`. + """ + atom.notifications.addWarning content, dismissable: true + + unless @isVisualBlockMode vimState + @reset() + + toggleDebug: -> + oldState = atom.config.get("#{@prefix}.debug") + atom.config.set("#{@prefix}.debug", not oldState) + state = atom.config.get("#{@prefix}.debug") and "enabled" or "disabled" + console.log "#{@prefix}: debug #{state}" + + debug: (msg) -> + return unless atom.config.get("#{@prefix}.debug") + console.log msg + + # dump: -> + # @debug "@startRow = #{@startRow}" |