-
Notifications
You must be signed in to change notification settings - Fork 108
ExtendVimModePlusInInitFile
You can extends vim-mode-plus by adding your original Motion/Operator/TextObject.
You don't even create Atom package, just adding small code in your init.coffee
is enough.
I'll explain here HOW-TO.
First define following function in your init.coffee
# init.coffee
# -------------------------
# General service consumer function
consumeService = (packageName, providerName, fn) ->
disposable = atom.packages.onDidActivatePackage (pack) ->
if pack.name is packageName
service = pack.mainModule[providerName]()
fn(service)
disposable.dispose()
All vim-mode-plus's commands must inherit Base
class directly or indirectly.
Above registerCommand()
function is Base class's function.
When you call registerCommand
your class name(MoveUp
or MoveDown
here) is transformed to dash-case string by prefixing @commandPrefix
.
So you get vim-mode-plus-user:move-up
and vim-mode-plus-user:move-down
commands here.
All the rest you have to do is set keymap for those commands.
- keymap.cson
'atom-text-editor.vim-mode-plus:not(.insert-mode)':
'j': 'vim-mode-plus-user:move-down'
'k': 'vim-mode-plus-user:move-up'
- init.coffee
consumeService 'vim-mode-plus', 'provideVimModePlus', ({Base}) ->
Motion = Base.getClass('Motion')
class MoveUp extends Motion
@commandPrefix: 'vim-mode-plus-user'
moveCursor: (cursor) ->
cursor.moveUp()
class MoveDown extends Motion
@commandPrefix: 'vim-mode-plus-user'
moveCursor: (cursor) ->
cursor.moveDown()
MoveUp.registerCommand() # `vim-mode-plus-user:move-up`
MoveDown.registerCommand() # `vim-mode-plus-user:move-up`
class InsertSpaces extends Base.getClass('Operator')
@commandPrefix: 'vim-mode-plus-user'
@registerCommand()
requireTarget: false
execute: ->
@editor.insertText(" ".repeat(@getCount()))
# keymap.cson
# 'atom-text-editor.vim-mode-plus.normal-mode':
# 'g space': 'vim-mode-plus-user:insert-spaces'
#
# Description
# keystroke '3 g space' insert three spaces at cursor position
# multi-selection support, can repeat by `.`
MoveUp/MoveDown to row which have same level of indentation.
- keymap.cson
'atom-text-editor.vim-mode-plus:not(.insert-mode)':
'(': 'vim-mode-plus-user:move-up-to-same-indent'
')': 'vim-mode-plus-user:move-down-to-same-indent'
- init.coffee
consumeVimModePlus = getConsumer 'vim-mode-plus', 'provideVimModePlus'
requireVimModePlus = (path) ->
packPath = atom.packages.resolvePackagePath('vim-mode-plus')
require "#{packPath}/lib/#{path}"
consumeService 'vim-mode-plus', 'provideVimModePlus', ({Base}) ->
_ = require 'underscore-plus'
{getIndentLevelForBufferRow} = requireVimModePlus './utils'
class MoveUpToSameIndent extends Base.getClass('MoveUpToNonBlank')
@commandPrefix: 'vim-mode-plus-user'
moveCursor: (cursor) ->
cursorRow = cursor.getBufferRow()
baseIndentLevel = getIndentLevelForBufferRow(@editor, cursorRow)
column = cursor.getBufferColumn()
@countTimes =>
newRow = _.detect @getScanRows(cursor), (row) =>
not @editor.isBufferRowBlank(row) and
getIndentLevelForBufferRow(@editor, row) is baseIndentLevel
if newRow?
cursor.setBufferPosition([newRow, column])
class MoveDownToSameIndent extends MoveUpToSameIndent
@extend()
direction: 'down'
MoveUpToSameIndent.registerCommand()
MoveDownToSameIndent.registerCommand()
By extending TransformStringByExternalCommand, user can add string transformer via external command(e.g. sort
, wc
).
consumeService 'vim-mode-plus', 'provideVimModePlus', ({Base}) ->
TransformStringByExternalCommand = Base.getClass('TransformStringByExternalCommand')
class Sort extends TransformStringByExternalCommand
command: 'sort'
class SortNumerical extends Sort
command: 'sort'
args: ['-n']
class ReverseSort extends SortNumerical
args: ['-r']
class ReverseSortNumerical extends ReverseSort
args: ['-rn']
class CoffeeCompile extends TransformStringByExternalCommand
command: 'coffee'
args: ['-csb', '--no-header']
getNewText: (text) ->
@input.shift().replace(/\n$/, '')
userTransformers = [
Sort, SortNumerical, ReverseSort, ReverseSortNumerical, CoffeeCompile
]
TransformStringBySelectList = Base.getClass('TransformStringBySelectList')
for transformer in userTransformers
transformer.commandPrefix = 'vim-mode-plus-user'
transformer.registerCommand()
# Push user transformer to transformers so that I can choose my transformers
# via transform-string-by-select-list command.
TransformStringBySelectList::transformers.push(transformer)
# Just for demonstration, Simplify IncrementNumber and DecrementNumber
Base.getClass('IncrementNumber')::displayName = '++'
Base.getClass('DecrementNumber')::displayName = '--'
In this example, directly modify existing motion to prevent cursor position change as a result of scrolling.
Thus, making ctrl-f
, ctrl-b
, ctrl-u
and ctrl-d
to do only scroll without changing cursor position.
You can go back to cursor position by escape
.
consumeService 'vim-mode-plus', 'provideVimModePlus', ({Base}) ->
# Override prototype function to do nothing(to prevent cursor position change.).
# This require understanding existing implementation and not recommended since it affects
# all the motions which inherits this class(in this case ctrl-b, ctrl-u, ctrl-d).
Base.getClass('ScrollFullScreenDown')::moveCursor = ->
- init.coffee
consumeService 'vim-mode-plus', 'provideVimModePlus', (service) ->
{Base, getEditorState, observeVimStates} = service
Delete = Base.getClass('Delete')
class DeleteWithBackholeRegister extends Delete
@commandPrefix: 'vim-mode-plus-user'
@registerCommand()
execute: ->
@vimState.register.name = "_"
super
- keymap.cson
'atom-text-editor.vim-mode-plus:not(.insert-mode)':
'\\ d': 'vim-mode-plus-user:delete-with-backhole-register'
'atom-text-editor.vim-mode-plus.delete-with-backhole-register-pending':
'd': 'vim-mode-plus-user:delete-with-backhole-register'