-
Notifications
You must be signed in to change notification settings - Fork 108
ExtendVimModePlusInInitFile
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.
- Define consumeService utility functions(one time).
- Define your own operation class and register command.
- Configure keymap if necessary
As preparation, define following function in your init.js
or init.coffee
- init.coffee
consumeService = (packageName, functionName, fn) ->
consume = (pack) -> fn(pack.mainModule[functionName]())
if atom.packages.isPackageActive(packageName)
consume(atom.packages.getActivePackage(packageName))
else
disposable = atom.packages.onDidActivatePackage (pack) ->
if pack.name is packageName
disposable.dispose()
consume(pack)
- init.js
function consumeService(packageName, functionName, fn) {
const consume = pack => fn(pack.mainModule[functionName]())
if (atom.packages.isPackageActive(packageName)) {
consume(atom.packages.getActivePackage(packageName))
} else {
const disposable = atom.packages.onDidActivatePackage(pack => {
if (pack.name === packageName) {
disposable.dispose()
consume(pack)
}
})
}
}
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. - Comand name is derived from class name by
klass.commandPrefix + ':' + _.dasherize(klass.name)
.- When
klass.commandPrefix
isvim-mode-plus-user
-
MoveUp.registerCommand()
registervim-mode-plus-user:move-up
-
MoveDown.registerCommand()
registervim-mode-plus-user:move-down
-
- When
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.
You have two option for how to load vmp command.
- Use
init.js
and define vmp-commands directly ininit.js
- Use
init.coffee
and require js file to load vmp-commands.
init.js
consumeService("vim-mode-plus", "provideVimModePlus", ({Base}) => {
class MoveUp extends Base.getClass("Motion") {
moveCursor(cursor) {
cursor.moveUp()
}
}
MoveUp.commandPrefix = "vim-mode-plus-user"
MoveUp.registerCommand()
class MoveDown extends MoveUp {
moveCursor(cursor) {
cursor.moveDown()
}
}
MoveDown.registerCommand()
})
init.coffee
consumeService 'vim-mode-plus', 'provideVimModePlus', (service) ->
commands = require('./load-vmp-commands')(service)
for name, klass of commands
klass.commandPrefix = "vim-mode-plus-user"
klass.registerCommand()
load-vmp-commands.js
module.exports = function loadVmpCommands({Base}) {
class MoveUp extends Base.getClass("Motion") {
moveCursor(cursor) {
cursor.moveUp()
}
}
class MoveDown extends MoveUp {
moveCursor(cursor) {
cursor.moveDown()
}
}
return {MoveUp, MoveDown}
}
- 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.js
"use babel"
class InsertSpaces extends Base.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 `.`
- init.js
"use babel"
class MoveFiveLinesUp extends Base.getClass("MoveUp") {
static commandPrefix = "vim-mode-plus-user"
defaultCount = 5
}
MoveFiveLinesUp.registerCommand()
class MoveFiveLinesDown extends Base.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'
MoveUp/MoveDown to row which have same level of indentation.
- init.js
"use babel"
// borrow MoveUpToEdge.prototype.getScanRows()
class MoveUpToSameIndent Base.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'
By extending TransformStringByExternalCommand, user can add string transformer via external command.
const TransformStringByExternalCommand = Base.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()
}
class DeleteWithBackholeRegister extends Base.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`.