Skip to content

ExtendVimModePlusInInitFile

t9md edited this page Feb 26, 2018 · 17 revisions

Overview

You can create original Motion/Operator/TextObject by extending existing operation class defined in vmp-core.

🚨 🚨 🚨 🚨 🚨 🚨
From vmp v1.9.0, you must use JavaScript(ES6 class) to extend vmp, CoffeeScript-v1 is no longer supported to extend vmp.
Why? vmp's operations are implemented as ES6 class which is incompatible with CoffeeScript's class.
🚨 🚨 🚨 🚨 🚨 🚨

Here is the steps.

  1. Define your own operation in your init.js
  2. Configure keymap if necessary

1. Define consumeService utility functions

See this template

function consumeVimModePlusService(callback) { const consume = (pack) => callback(pack.mainModule.provideVimModePlus()) const pack = atom.packages.getActivePackage('vim-mode-plus') if (pack) { consume(pack) } else { const disposable = atom.packages.onDidActivatePackage(pack => { if (pack.name === 'vim-mode-plus') { disposable.dispose() consume(pack) } }) } } consumeVimModePlusService(service => { // Define your own operation FROM HERE class MyMotion extends service.getClass("Motion") { execute() { console.log("my motion!"); } } MyMotion.commandPrefix = "vim-mode-plus-user" // `registerCommand()` here register "vim-mode-plus-user:my-motion" command // Which log "my motion" to console when invoked. MyMotion.registerCommand() // Define your own operation TO HERE })

2. Define your own operation class and register command

As simple example we will define our own version of move-up/move-down motion.

  • All vmp command class must inherit Base class directly or indirectly.
  • You can register command by calling Base.registerCommand() static fucntion.
  • Command name is derived from class name by klass.commandPrefix + ':' + _.dasherize(klass.name).
    • When klass.commandPrefix is vim-mode-plus-user
      • MoveUp.registerCommand() register vim-mode-plus-user:move-up
      • MoveDown.registerCommand() register vim-mode-plus-user:move-down

You must define vmp operation in ES6 class, you cannot use CoffeeScript, since vmp-core class is defined in ES6 class which is incompatible with CoffeScript-v1 used in Atom.

  • init.js
consumeVimModePlusService(service => { class MoveUp extends service.getClass("Motion") { moveCursor(cursor) { cursor.moveUp() } } MoveUp.commandPrefix = "vim-mode-plus-user" MoveUp.registerCommand() class MoveDown extends MoveUp { moveCursor(cursor) { cursor.moveDown() } } MoveDown.registerCommand() })

3. Configure keymap if necessary

  • 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'

Examples

[Basic] InsertSpaces operator which insert specified count of spaces

  • init.js
"use babel" consumeVimModePlusService(service => { class InsertSpaces extends service.getClass('Operator') { static commandPrefix = 'vim-mode-plus-user' requireTarget = false execute() { this.editor.insertText(" ".repeat(this.getCount())) } } InsertSpaces.registerCommand() }) // 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 `.`

[Basic] 5 lines moveUp/moveDown motion

  • init.js
"use babel" consumeVimModePlusService(service => { class MoveFiveLinesUp extends service.getClass("MoveUp") { static commandPrefix = "vim-mode-plus-user" defaultCount = 5 } MoveFiveLinesUp.registerCommand() class MoveFiveLinesDown extends service.getClass("MoveDown") { static commandPrefix = "vim-mode-plus-user" defaultCount = 5 } MoveFiveLinesDown.registerCommand() })
  • keymap.cson
'atom-text-editor.vim-mode-plus:not(.insert-mode)': 'J': 'vim-mode-plus-user:move-five-lines-down' 'K': 'vim-mode-plus-user:move-five-lines-up'

[Advanced] move-up(down)-to-same-indent

MoveUp/MoveDown to row which have same level of indentation.

  • init.js
"use babel" // borrow MoveUpToEdge.prototype.getScanRows() consumeVimModePlusService(service => { class MoveUpToSameIndent service.getClass("MoveUpToEdge") { static commandPrefix = "vim-mode-plus-user" moveCursor(cursor) { const cursorRow = cursor.getBufferRow() const baseIndentLevel = this.utils.getIndentLevelForBufferRow(this.editor, cursorRow) const column = cursor.getBufferColumn() this.countTimes(() => { const newRow = this.getScanRows(cursor).find( row => this.utils.getIndentLevelForBufferRow(this.editor, row) === baseIndentLevel ) if (newRow != null) cursor.setBufferPosition([newRow, column]) }) } } MoveUpToSameIndent.registerCommand() class MoveDownToSameIndent extends MoveUpToSameIndent { direction = "down" } MoveDownToSameIndent.registerCommand() })
  • 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'

[Advanced] TransformString by external command

By extending TransformStringByExternalCommand, user can add string transformer via external command.

consumeVimModePlusService(service => { const TransformStringByExternalCommand = service.getClass("TransformStringByExternalCommand") class CoffeeCompile extends TransformStringByExternalCommand { command = "coffee" args = ["-csb", "--no-header"] } class CoffeeEval extends TransformStringByExternalCommand { command = "coffee" args = ["-se"] getStdin(selection) { return `console.log ${selection.getText()}` } } class CoffeeInspect extends TransformStringByExternalCommand { command = "coffee" args = ["-se"] getStdin(selection) { return `{inspect} = require 'util';console.log ${selection.getText()}` } } for (const klass of [CoffeeCompile, CoffeeEval, CoffeeInspect]) { klass.commandPrefix = "vim-mode-plus-user" klass.registerCommand() } })

[Advanced] DeleteWithBackholeRegister

consumeVimModePlusService(service => { class DeleteWithBackholeRegister extends service.getClass("Delete") { execute() { this.vimState.register.name = "_" super.execute() } } DeleteWithBackholeRegister.commandPrefix = "vim-mode-plus-user" DeleteWithBackholeRegister.registerCommand() })
  • 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' # to support `\ d d`.

[Advanced] InsertCharacter

"use babel" // This must be at top of file consumeVimModePlusService(service => { class InsertCharacter extends service.getClass("Operator") { static commandPrefix = "vim-mode-plus-user" target = "Empty" readInputAfterSelect = true mutateSelection(selection) { const point = selection.getHeadBufferPosition() this.editor.setTextInBufferRange([point, point], this.input.repeat(this.getCount())) } } InsertCharacter.registerCommand() })

Clone this wiki locally