tbray@watsol.waterloo.edu (Tim Bray) (07/31/89)
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). Did people know that in vi, if a line ends with some blanks, and you go to those blanks, and press 'w', it just beeps at you?!?!? Go find me the Next WORD, you braindead piece of junk! This package does not duplicate that silliness. Also, it does not share vi's ideas about the role of '_' in words, but that could be fixed. It actually might be a good idea to change this idea automatically when in C-mode. Actually the package should use a global variable called in-word-chars or some such. ------------------------------------------------------------------- ;; vi-style word hopping (defvar WordHop-vi-mode 't "*Use vi-style word movement if true") (defun next-word (count) "Like forward-word, but also do vi-style" (interactive "p") (if WordHop-vi-mode (while (not (zerop count)) (word-hop-forward) (setq count (1- count))) (forward-word count))) (defun prev-word (count) "Like backword-word, but also do vi-style" (interactive "p") (if WordHop-vi-mode (while (not (zerop count)) (word-hop-backward) (setq count (1- count))) (backward-word count))) (defun word-hop-forward () "Hop one word, vi style" (cond ;; This behaviour is *incredibly* kludgy. Differ from vi in '_' handling ((looking-at "\n") (forward-char 1) (re-search-forward "[ \t]*")) ((looking-at "[ \t]") (re-search-forward "[ \t]*")) ((looking-at "[a-zA-Z0-9]") (re-search-forward "[a-zA-Z0-9]*") (if (looking-at "[ \t\n]") (word-hop-forward))) (t (re-search-forward "[a-zA-Z0-9 \t\n]") (backward-char 1) (if (looking-at "[ \t\n]") (word-hop-forward))))) (defun word-hop-backward () "Back one word, vi style" (backward-char 1) (if (looking-at "[ \t\n]") (re-search-backward "[^ \t\n]")) (cond ((looking-at "\n")) ;; just leave it ((looking-at "[a-zA-Z0-9]") (re-search-backward "[^a-zA-Z0-9]") (forward-char 1)) (t (re-search-backward "[a-zA-Z0-9 \t]") (forward-char 1))))
julian@uhccux.uhcc.hawaii.edu (Julian Cowley) (07/31/89)
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
boris@prodigal.psych.rochester.edu (Boris Goldowsky) (08/01/89)
In article <15516@watdragon.waterloo.edu> tbray@watsol.waterloo.edu (Tim Bray) writes: >ideas about the role of '_' in words, but that could be fixed. It >actually might be a good idea to change this idea automatically when in >C-mode. Actually the package should use a global variable called >in-word-chars or some such. But we already have syntax tables which specify which characters are part of words. Couldn't this behavior be more easily gotten with modify-syntax-entry? Bng
rms@ai.mit.edu (08/03/89)
heh! So, what's one bug more, or one bug less in vi anyway? ;-) oooops..I forgot, Tim, consider that a feature! :-) Please learn not to send messages like this to info-gnu-emacs, or to any other large mailing list which exists for a practical purpose. You wasted the time of a large number of people. which is one phenomenol reason why one does not want to learn emacs. For some users, learning Emacs is clearly not worth while. For everyone else, it is a matter of taste. Arguments about taste are a waste of time. Don't start them here!