surround.vim vimpulse extension
vegard_oye at hotmail.com
Sat Jul 24 23:23:48 CEST 2010
On 2010-07-23 20:46, Tim Harper wrote:
> I'm not extremely happy with my approach on how I'm looking into the
> delete/change commands. Basically, I'm hijacking them in doing an
> advise (as in defadvice) approach.
There isn't a perfect way, not even in Vim itself. surround.vim does
nmap ds <Plug>Dsurround
Which corresponds to making a "careful" binding in Vimpulse -- that
is, one of these lines:
(vimpulse-map "ds" 'vimpulse-surround-delete)
(vimpulse-make-careful-binding viper-vi-basic-map "ds" 'vimpulse-surround-delete)
Which will execute `vimpulse-surround-delete' when the user hits "ds"
and `vimpulse-delete' when the user hits "d" + any other key than "s".
The fatal flaw with this approach, both in Emacs and Vim, is that the
keystrokes are read /before/ Operator-Pending mode is entered, so the
half-height "operator cursor" is permanently lost.
Second approach: write a "null motion" (one that returns an empty
range) and bind it to "s" in Operator-Pending mode:
(defun vimpulse-surround-delete (&optional arg)
;; Delete surrounding characters
(viper-move-marker-locally 'viper-com-point (point)))
(define-key vimpulse-operator-basic-map "s" 'vimpulse-surround-delete)
This will preserve the half-height cursor. The call to
`viper-move-marker-locally' ensures that the starting point is
equivalent to the ending point -- e.g., (vimpulse-delete 45 45) --
hence no actual deletion takes place.
Third approach: we could make the function bodies of `vimpulse-delete'
and `vimpulse-delete' contingent on a "cancellation variable". A
pseudo-motion like above could set this to t during its execution to
inhibit the deletion code of `vimpulse-delete', the change code of
`vimpulse-change', and so on. (Conceivably, `vimpulse-range' itself
could cancel further code execution with `keyboard-quit', but this
would probably be noisy.)
Fourth approach: stay with the delete-or-surround DWIM functions, but
bind them in a separate, toggleable keymap rather than overwriting the
basic bindings. Like this:
(vimpulse-define-key 'surround-mode 'vi-state "d" 'vimpulse-delete-surround-or-delete)
(vimpulse-define-key 'surround-mode 'vi-state "c" 'vimpulse-change-surround-or-change)
Then you can enable surround-mode in certain buffers as appropriate,
or turn it into a global minor mode.
More information about the implementations-list