Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!uhccux!julian From: julian@uhccux.uhcc.hawaii.edu (Julian Cowley) Newsgroups: gnu.emacs Subject: Re: Vi word hopping in emacs Message-ID: <4461@uhccux.uhcc.hawaii.edu> Date: 31 Jul 89 05:03:00 GMT References: <15516@watdragon.waterloo.edu> Organization: University of Hawaii at Manoa Lines: 71 In article <15516@watdragon.waterloo.edu> tbray@watsol.waterloo.edu (Tim Bray) writes: >I was editing and editing and editing this huge file, and got really mad >at Emacs' idea of where the next word was. For this file at least, the >vi word model was appropriate. > >So this is emacs, oughta be able to whip up an appropriate forward-word >and backward-word, right? Gack. A couple hours later, here it is. >Most of that time was spent figuring out just what vi actually *does* >(no source code). You're not the only person who's wanted to change the behavior of Emacs' word movement functions! Here's my own crack at it, but I've never considered posting it before for fear of insulting hardcore Emacsers (I've also got the start of a WordStar mode on the backburner). Note that the function vi-forward-word completely replaces the forward-word function, so that kill-word and other Lisp editing functions work in the same manner as vi. The only functions that aren't affected are those which call forward-word (really scan_words) in C (abbrev mode, case fiddling commands, etc.). This version is not entirely like vi, for it skips characters until the syntax of the current character changes, and then skips any remaining whitespace. This was close enough to vi for my tastes. It also has the advantage of being modifiable through the syntax table. --------------- cut here --------------- ;; redefine forward-word to act more like vi (defun vi-forward-word (count) "Move point forward ARG words in a manner similar to vi (backward if ARG is negative). Normally returns t. If an edge of the buffer is reached, point is left there and nil is returned." (interactive "p") (while (> count 0) (skip-syntax-forward (char-syntax (following-char))) (skip-syntax-forward ? ) (setq count (1- count))) (while (< count 0) (skip-syntax-backward ? ) (skip-syntax-backward (char-syntax (preceding-char))) (setq count (1+ count))) (null (or (eobp) (bobp)))) (defun skip-syntax-forward (syntax) "Move point forward, stopping after a character does not match SYNTAX or the end of the buffer is reached." (while (and (not (eobp)) (eq (char-syntax (following-char)) syntax)) (forward-char))) (defun skip-syntax-backward (syntax) "Move point backward, stopping after a character does not match SYNTAX or the beginning of the buffer is reached." (while (and (not (bobp)) (eq (char-syntax (preceding-char)) syntax)) (backward-char))) (fset 'original-forward-word (symbol-function 'forward-word)) (fset 'forward-word 'vi-forward-word) --------------- cut here --------------- julian@uhccux.uhcc.hawaii.edu uunet!nosc!humu!uhccux!julian julian@uhccux.bitnet University of Hawaii at Manoa