I'm working on a plugin that allows users to create custom operators. The operators would apply a VimL expression to the motion or text object that the operator moves over.
Keeping a clean user interface
I think the cleanest interface for defining the custom operators would be to use a command. I've defined a command :MapExpress
that would be invoked something like this:
:MapExpress cd '/* ' . v:val . ' */'
This would create a Normal mode operator and a Visual mode mapping for cd
that would surround the motion or selection in C-style comment delimiters.
Of course, here lies a problem. You can't call a command that's defined in a plugin from your .vimrc
file.
Less-than-satisfying workarounds
I've come up with a few workarounds that I'm not entirely happy with.
User uses autocmd VimEnter *
to call the command
While this would work, it adds a lot of "mental overhead". I would guess that a lot of Vim users don't have a solid grasp on how autocmd
works.
User creates a file in ~/.vim/after/plugin/
which calls the command
Again, this would work, but it has the drawback that this piece of configuration is off in its own file, easily lost and forgotten.
I move the command definitions into my plugin's autoload/
directory, and the user calls some method that triggers the file to be loaded, and thus the commands to be defined
This would look like this:
call express#init()
MapExpress cd '/* ' . v:val . ' */'
Slightly better, but this would cause confusion about whether the express#init()
method is necessary for the plugin to work at all.
Alternatives to using a command
I also considered some alternatives to using a command to define the operator, but each has its caveats.
User calls a function to define the operators
This would look something like this:
call express#operator('cd', '"/* ".v:val." */"')
This is not terrible, but it has the disadvantage of requiring a quoted expression. That can be annoying when you want to use quotes in your expression.
User uses an <expr>
mapping
Like this:
nmap <expr> cd express#nmap('"/* ".v:val." */"')
xmap <expr> cd express#xmap('"/* ".v:val." */"')
This has the same tedious quoted expression requirement, and also violates DRY unless you introduce a variable (not ideal).
Okay, so what?
Here are all of my ideas and why I don't like any of them. Am I being too fussy? Is there some better solution I haven't thought of?
call express#initMapCommands()
? Anything that requires extra quoting, though, is a super bad idea.<q-args>
really works. Thanks