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 this: 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) (interactive) ;; 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: (define-minor-mode surround-mode) (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. -- Vegard