Xref: utzoo gnu.emacs:1332 alt.religion.computers:427 Path: utzoo!utgpu!watmath!watdragon!watsol!tbray From: tbray@watsol.waterloo.edu (Tim Bray) Newsgroups: gnu.emacs,alt.religion.computers Subject: Vi word hopping in emacs Message-ID: <15516@watdragon.waterloo.edu> Date: 30 Jul 89 17:30:23 GMT Sender: daemon@watdragon.waterloo.edu Reply-To: tbray@watsol.waterloo.edu (Tim Bray) Organization: U. of Waterloo, Ontario Lines: 57 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))))