views:

243

answers:

1

I'm using the Colemak keyboard layout, and want to try the Vim layout from here with Vimpulse. However, the layout remaps the command prefix Vim keys 'c' and 'd' among others, and these keys don't seem to be easily remappable with the standard Viper key remap command. They are all mapped to "viper-command-argument" in the viper keymap, and the actual key functions seem to be defined elsewhere in the Viper source.

Is there an easier way to rebind the prefix commands to other keys than forking my local copy of the Viper source and redefining the magic prefix key values within it?

+2  A: 

Viper-mode command prefix keys are set up through two sets of indirection. You found the first, as in all the command keys are bound to 'viper-command-argument. The next thing that is done is a look up in the variable viper-exec-array. It is currently set like so:

(aset viper-exec-array ?c 'viper-exec-change)
(aset viper-exec-array ?C 'viper-exec-Change)
(aset viper-exec-array ?d 'viper-exec-delete)
(aset viper-exec-array ?D 'viper-exec-Delete)
(aset viper-exec-array ?y 'viper-exec-yank)
(aset viper-exec-array ?Y 'viper-exec-Yank)
(aset viper-exec-array ?r 'viper-exec-dummy)
(aset viper-exec-array ?! 'viper-exec-bang)
(aset viper-exec-array ?< 'viper-exec-shift)
(aset viper-exec-array ?> 'viper-exec-shift)
(aset viper-exec-array ?= 'viper-exec-equals)

So, if you want to make the key t act like a delete command, you would need the following two things:

(aset viper-exec-array ?t 'viper-exec-delete)
(define-key viper-vi-basic-map "t" 'viper-command-argument)

(And presumably you'd rebind the motion from t to somewhere, say the c key with:

(define-key viper-vi-basic-map "c" 'viper-goto-char-forward)

Lastly, you have to modify the routine 'viper-prefix-arg-com, which I don't pretend to fully understand. That being said, if you replace all the ?c with ?t, then the t binding works as expected. (Alternatively, you could add the ?t the same way the ?c is used - that works too). I'd provide the source for that, but it's 100 lines long, and not really worth including here (it's a 4 character change). You can get to the source by doing M-x find-function viper-prefix-arg-com.

Long story short, if you want to do a wholesale re-binding of the keys for viper, it's going to be a fair amount of work and you will become much more familiar with the viper source code.

Looking at the way 'viper-prefix-arg-com is coded, you cannot make the change you want without redefining it. There are probably 3 or 4 other different types of vi commands that viper-mode implements (this one being a 'command-argument). The others are hopefully more straightforward to rebind...

Trey Jackson
I'm running GNU Emacs 23.1.50.1. Starting it with emacs -q to ignore my .emacs config, I did "M-x viper-mode" and evaluated the aset ?t example. Now instead of working as a delete prefix, pressing 't' in viper-mode prints the error:`byte-code: Variable binding depth exceeds max-specpdl-size`
rsaarelm
@rsaarelm So it does, I didn't notice you also have to modify the source of `'viper-prefix-arg-com`. I've updated my answer.
Trey Jackson
So the solution does go a bit into the "fork Viper" territory, but at least it's just a limited amount of code I need to redefine. Thanks for helping to focus things in.
rsaarelm