[alt.religion.computers] Vi word hopping in emacs

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))))

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