]> code.delx.au - gnu-emacs/blobdiff - lisp/emulation/viper-cmd.el
Implement mouse highlight for bidi-reordered lines.
[gnu-emacs] / lisp / emulation / viper-cmd.el
index 18fa94d1cd995d365852702e37aa618fbc3c4e54..07719ba45be503b802c0dfe28065c47f0cdc2b8b 100644 (file)
@@ -1,9 +1,10 @@
 ;;; viper-cmd.el --- Vi command support for Viper
 
 ;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;;   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 ;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
+;; Package: viper
 
 ;; This file is part of GNU Emacs.
 
           (marker-position viper-insert-point))
       (setq viper-pre-command-point (marker-position viper-insert-point))))
 
-(defsubst viper-R-state-post-command-sentinel ()
+(defun viper-R-state-post-command-sentinel ()
   ;; Restoring cursor color is needed despite
   ;; viper-replace-state-pre-command-sentinel: When you jump to another buffer
   ;; in another frame, the pre-command hook won't change cursor color to
                          (assoc major-mode viper-emacs-state-modifier-alist))
                       viper-empty-keymap))
               ))
-       
+
   ;; This var is not local in Emacs, so we make it local.  It must be local
   ;; because although the stack of minor modes can be the same for all buffers,
   ;; the associated *keymaps* can be different.  In Viper,
 ARG is used as the prefix value for the executed command.  If
 EVENTS is a list of events, which become the beginning of the command."
   (interactive "P")
-  (if (viper= last-command-char ?\\)
+  (if (viper= (viper-last-command-char) ?\\)
       (message "Switched to EMACS state for the next command..."))
   (viper-escape-to-state arg events 'emacs-state))
 
@@ -773,8 +774,7 @@ Vi's prefix argument will be used.  Otherwise, the prefix argument passed to
                    last-command-char (event-to-character last-command-event))
            ;; Emacs represents them as sequences (str or vec)
            (setq last-command-event
-                 (viper-copy-event (viper-seq-last-elt key))
-                 last-command-char last-command-event))
+                 (viper-copy-event (viper-seq-last-elt key))))
 
          (if (commandp com)
              ;; pretend that current state is the state we excaped to
@@ -892,7 +892,7 @@ Vi's prefix argument will be used.  Otherwise, the prefix argument passed to
 
 
 (defun viper-exec-form-in-vi  (form)
-  "Execute FORM in Vi state, regardless of the Ccurrent Vi state."
+  "Execute FORM in Vi state, regardless of the current Vi state."
   (let ((buff (current-buffer))
        result)
     (viper-set-mode-vars-for 'vi-state)
@@ -904,22 +904,20 @@ Vi's prefix argument will be used.  Otherwise, the prefix argument passed to
        (signal 'quit nil)))
 
     (if (not (equal buff (current-buffer))) ; cmd switched buffer
-       (save-excursion
-         (set-buffer buff)
+       (with-current-buffer buff
          (viper-set-mode-vars-for viper-current-state)))
     (viper-set-mode-vars-for viper-current-state)
     result))
 
 (defun viper-exec-form-in-emacs  (form)
   "Execute FORM in Emacs, temporarily disabling Viper's minor modes.
-Similar to viper-escape-to-emacs, but accepts forms rather than keystrokes."
+Similar to `viper-escape-to-emacs', but accepts forms rather than keystrokes."
   (let ((buff (current-buffer))
        result)
     (viper-set-mode-vars-for 'emacs-state)
     (setq result (eval form))
     (if (not (equal buff (current-buffer))) ; cmd switched buffer
-       (save-excursion
-         (set-buffer buff)
+       (with-current-buffer buff
          (viper-set-mode-vars-for viper-current-state)))
     (viper-set-mode-vars-for viper-current-state)
     result))
@@ -935,14 +933,14 @@ Similar to viper-escape-to-emacs, but accepts forms rather than keystrokes."
 ;; bindings.  By letting Viper know which files these modes are in, it will
 ;; arrange to reorganize minor-mode-map-alist so that things will work right.
 (defun viper-harness-minor-mode (load-file)
-  "Familiarize Viper with a minor mode defined in LOAD_FILE.
+  "Familiarize Viper with a minor mode defined in LOAD-FILE.
 Minor modes that have their own keymaps may overshadow Viper keymaps.
 This function is designed to make Viper aware of the packages that define
 such minor modes.
 Usage:
     (viper-harness-minor-mode load-file)
 
-LOAD-FILE is a name of the file where the specific minor mode is defined.
+LOAD-FILE is the name of the file where the specific minor mode is defined.
 Suffixes such as .el or .elc should be stripped."
 
   (interactive "sEnter name of the load file: ")
@@ -964,9 +962,9 @@ Prevents multiple escape keystrokes if viper-no-multiple-ESC is true.
 If viper-no-multiple-ESC is 'twice double ESC would ding in vi-state.
 Other ESC sequences are emulated via the current Emacs's major mode
 keymap.  This is more convenient on TTYs, since this won't block
-function keys such as up,down, etc.  ESC will also will also work as
-a Meta key in this case.  When viper-no-multiple-ESC is nil, ESC functions
-as a Meta key and any number of multiple escapes is allowed."
+function keys such as up, down, etc.  ESC will also will also work as
+a Meta key in this case.  When viper-no-multiple-ESC is nil, ESC works
+as a Meta key and any number of multiple escapes are allowed."
   (interactive "P")
   (let (char)
     (cond ((and (not viper-no-multiple-ESC) (eq viper-current-state 'vi-state))
@@ -1046,7 +1044,7 @@ as a Meta key and any number of multiple escapes is allowed."
                (let* ((first-key (elt keyseq 0))
                       (key-mod (event-modifiers first-key)))
                  (cond ((and (viper-ESC-event-p first-key)
-                             (not viper-translate-all-ESC-keysequences))
+                             (not (viper-translate-all-ESC-keysequences)))
                         ;; put keys following ESC on the unread list
                         ;; and return ESC as the key-sequence
                         (viper-set-unread-command-events (viper-subseq keyseq 1))
@@ -1170,7 +1168,7 @@ as a Meta key and any number of multiple escapes is allowed."
        ;; then execute it with funcall and clear prefix-arg in order to not
        ;; confuse subsequent commands
        (progn
-         ;; last-command-char is the char we want emacs to think was typed
+         ;; last-command-event is the char we want emacs to think was typed
          ;; last.  If com is not nil, the viper-digit-argument command was
          ;; called from within viper-prefix-arg command, such as `d', `w',
          ;; etc., i.e., the user typed, say, d2.  In this case, `com' would be
@@ -1178,13 +1176,16 @@ as a Meta key and any number of multiple escapes is allowed."
          ;; viper-escape-to-vi (which is indicated by the fact that the
          ;; current state is not vi-state), then `event-char' represents the
          ;; vi command to be executed (e.g., `d', `w', etc).  Again,
-         ;; last-command-char must make emacs believe that this is the command
+         ;; last-command-event must make emacs believe that this is the command
          ;; we typed.
          (cond ((eq event-char 'return) (setq event-char ?\C-m))
                ((eq event-char 'delete) (setq event-char ?\C-?))
                ((eq event-char 'backspace) (setq event-char ?\C-h))
                ((eq event-char 'space) (setq event-char ?\ )))
-         (setq last-command-char (or com event-char))
+         (setq last-command-event
+               (if (featurep 'xemacs)
+                   (character-to-event (or com event-char))
+                 (or com event-char)))
          (setq func (viper-exec-form-in-vi
                      `(key-binding (char-to-string ,event-char))))
          (funcall func prefix-arg)
@@ -1257,7 +1258,7 @@ as a Meta key and any number of multiple escapes is allowed."
 
       ;; as com is non-nil, this means that we have a command to execute
       (if (viper-memq-char (car com) '(?r ?R))
-         ;; execute apropriate region command.
+         ;; execute appropriate region command.
          (let ((char (car com)) (com (cdr com)))
            (setq prefix-arg (cons value com))
            (if (viper= char ?r)
@@ -1285,10 +1286,9 @@ as a Meta key and any number of multiple escapes is allowed."
         ;; gg  acts as G0
         ((equal (car com) ?g)   (viper-goto-line 0))
         (t (error "Viper bell")))))
-    
+
     (if cmd-to-exec-at-end
        (progn
-         (setq last-command-char char)
          (setq last-command-event
                (viper-copy-event
                 (if (featurep 'xemacs) (character-to-event char) char)))
@@ -1315,7 +1315,7 @@ as a Meta key and any number of multiple escapes is allowed."
   (interactive "P")
   (viper-leave-region-active)
   (viper-prefix-arg-value
-   last-command-char (if (consp arg) (cdr arg) nil)))
+   (viper-last-command-char) (if (consp arg) (cdr arg) nil)))
 
 (defun viper-command-argument (arg)
   "Accept a motion command as an argument."
@@ -1323,7 +1323,7 @@ as a Meta key and any number of multiple escapes is allowed."
   (let ((viper-intermediate-command 'viper-command-argument))
     (condition-case nil
        (viper-prefix-arg-com
-        last-command-char
+        (viper-last-command-char)
         (cond ((null arg) nil)
               ((consp arg) (car arg))
               ((integerp arg) arg)
@@ -1622,7 +1622,7 @@ Use the info in viper-d-com, which has the form
 where `com' is the command to be re-executed, `val' is the
 argument to `com', `ch' is a flag for repeat, and `reg' is optional;
 if it exists, it is the name of the register for `com'.
-If the prefix argument, ARG, is non-nil, it is used instead of `val'."
+If the prefix argument ARG is non-nil, it is used instead of `val'."
   (interactive "P")
   (let ((save-point (point)) ; save point before repeating prev cmd
        ;; Pass along that we are repeating a destructive command
@@ -1945,7 +1945,7 @@ Undo previous insertion and inserts new."
                 require-final-newline
                 ;; add newline only if we actually edited buffer. otherwise it
                 ;; might unintentionally modify binary buffers
-                (buffer-modified-p) 
+                (buffer-modified-p)
                 (not (viper-is-in-minibuffer))
                 (not buffer-read-only))
            ;; text property may be read-only
@@ -2100,7 +2100,7 @@ Undo previous insertion and inserts new."
   "Exit minibuffer Viper way."
   (interactive)
   (let (command)
-    (setq command (local-key-binding (char-to-string last-command-char)))
+    (setq command (local-key-binding (char-to-string (viper-last-command-char))))
     (run-hooks 'viper-minibuffer-exit-hook)
     (if command
        (command-execute command)
@@ -2540,7 +2540,7 @@ problems."
 
 (defun viper-replace-state-exit-cmd ()
   "Binding for keys that cause Replace state to switch to Vi or to Insert.
-These keys are ESC, RET, and LineFeed"
+These keys are ESC, RET, and LineFeed."
   (interactive)
   (if overwrite-mode   ; if in replace mode invoked via 'R'
       (viper-finish-R-mode)
@@ -2548,7 +2548,7 @@ These keys are ESC, RET, and LineFeed"
   (let (com)
     (if (eq this-command 'viper-intercept-ESC-key)
        (setq com 'viper-exit-insert-state)
-      (viper-set-unread-command-events last-input-char)
+      (viper-set-unread-command-events last-input-event)
       (setq com (key-binding (viper-read-key-sequence nil))))
 
     (condition-case conds
@@ -2569,7 +2569,7 @@ These keys are ESC, RET, and LineFeed"
   (if (or (< (point) (viper-replace-start))
          (> (point) (viper-replace-end)))
       (let (viper-replace-minor-mode com)
-       (viper-set-unread-command-events last-input-char)
+       (viper-set-unread-command-events last-input-event)
        (setq com (key-binding (read-key-sequence nil)))
        (condition-case conds
            (command-execute com)
@@ -2762,9 +2762,10 @@ On reaching beginning of line, stop and signal error."
 (defun viper-next-line-carefully (arg)
   (condition-case nil
       ;; do not use forward-line! need to keep column
-      (if (featurep 'emacs)
-         (with-no-warnings (next-line arg))
-       (next-line arg))
+      (let ((line-move-visual nil))
+       (if (featurep 'emacs)
+           (with-no-warnings (next-line arg))
+         (next-line arg)))
     (error nil)))
 
 
@@ -3064,9 +3065,10 @@ On reaching beginning of line, stop and signal error."
        (com (viper-getCom arg)))
     (if com (viper-move-marker-locally 'viper-com-point (point)))
     ;; do not use forward-line! need to keep column
-    (if (featurep 'emacs)
-       (with-no-warnings (next-line val))
-      (next-line val))
+    (let ((line-move-visual nil))
+      (if (featurep 'emacs)
+         (with-no-warnings (next-line val))
+       (next-line val)))
     (if viper-ex-style-motion
        (if (and (eolp) (not (bolp))) (backward-char 1)))
     (setq this-command 'next-line)
@@ -3113,9 +3115,10 @@ If point is on a widget or a button, simulate clicking on that widget/button."
        (com (viper-getCom arg)))
     (if com (viper-move-marker-locally 'viper-com-point (point)))
     ;; do not use forward-line! need to keep column
-    (if (featurep 'emacs)
-       (with-no-warnings (previous-line val))
-      (previous-line val))
+    (let ((line-move-visual nil))
+      (if (featurep 'emacs)
+         (with-no-warnings (previous-line val))
+       (previous-line val)))
     (if viper-ex-style-motion
        (if (and (eolp) (not (bolp))) (backward-char 1)))
     (setq this-command 'previous-line)
@@ -3684,15 +3687,24 @@ controlled by the sign of prefix numeric value."
 \f
 ;; searching
 
+(defun viper-insert-isearch-string ()
+  "Insert `isearch' last search string."
+  (interactive)
+  (when isearch-string (insert isearch-string)))
+
 (defun viper-if-string (prompt)
   (if (memq viper-intermediate-command
            '(viper-command-argument viper-digit-argument viper-repeat))
       (setq viper-this-command-keys (this-command-keys)))
-  (let ((s (viper-read-string-with-history
+  (let* ((keymap (let ((keymap (copy-keymap minibuffer-local-map)))
+                   (define-key keymap [(control ?s)] 'viper-insert-isearch-string)
+                   keymap))
+         (s (viper-read-string-with-history
            prompt
            nil ; no initial
            'viper-search-history
-           (car viper-search-history))))
+             (car viper-search-history)
+             keymap)))
     (if (not (string= s ""))
        (setq viper-s-string s))))
 
@@ -3700,7 +3712,7 @@ controlled by the sign of prefix numeric value."
 (defun viper-toggle-search-style (arg)
   "Toggle the value of viper-case-fold-search/viper-re-search.
 Without prefix argument, will ask which search style to toggle.  With prefix
-arg 1,toggles viper-case-fold-search; with arg 2 toggles viper-re-search.
+arg 1, toggles viper-case-fold-search; with arg 2 toggles viper-re-search.
 
 Although this function is bound to \\[viper-toggle-search-style], the most
 convenient way to use it is to bind `//' to the macro
@@ -3763,6 +3775,8 @@ If MAJOR-MODE is set, set the macros only in that major mode."
               "///" 'vi-state
               [2 (meta x) v i p e r - t o g g l e - s e a r c h - s t y l e return]
               scope)
+             ;; XEmacs has no called-interactively-p
+             ;; (if (called-interactively-p 'interactive)
              (if (interactive-p)
                  (message
                   "// and /// now toggle case-sensitivity and regexp search")))
@@ -3786,6 +3800,9 @@ With a prefix argument, unsets the macro."
             "%%%" 'vi-state
             [(meta x) v i p e r - t o g g l e - p a r s e - s e x p - i g n o r e - c o m m e n t s return]
             't)
+           ;; XEmacs has no called-interactively-p. And interactive-p
+           ;; works fine here.
+           ;; (if (called-interactively-p 'interactive)
            (if (interactive-p)
                (message
                 "%%%%%% now toggles whether comments should be parsed for matching parentheses")))
@@ -3815,6 +3832,9 @@ the macros are set in the current major mode.
             "///" 'emacs-state
             [2 (meta x) v i p e r - t o g g l e - s e a r c h - s t y l e return]
             (or arg-majormode major-mode))
+           ;; called-interactively-p does not work for
+           ;; XEmacs. interactive-p is ok here.
+           ;; (if (called-interactively-p 'interactive)
            (if (interactive-p)
                (message
                 "// and /// now toggle case-sensitivity and regexp search.")))
@@ -4228,7 +4248,7 @@ Null string will repeat previous search."
          (setq viper-use-register nil)))
     (if (and (bolp) viper-ex-style-editing)
        (ding))
-    (delete-backward-char val t)))
+    (delete-char (- val) t)))
 
 
 (defun viper-del-backward-char-in-insert ()
@@ -4237,27 +4257,27 @@ Null string will repeat previous search."
   (if (and viper-ex-style-editing (bolp))
       (beep 1)
     ;; don't put on kill ring
-    (delete-backward-char 1 nil)))
+    (delete-char -1 nil)))
 
 
 (defun viper-del-backward-char-in-replace ()
   "Delete one character in replace mode.
 If `viper-delete-backwards-in-replace' is t, then DEL key actually deletes
-charecters.  If it is nil, then the cursor just moves backwards, similarly
+characters.  If it is nil, then the cursor just moves backwards, similarly
 to Vi.  The variable `viper-ex-style-editing', if t, doesn't let the
 cursor move past the beginning of line."
   (interactive)
   (cond (viper-delete-backwards-in-replace
         (cond ((not (bolp))
                ;; don't put on kill ring
-               (delete-backward-char 1 nil))
+               (delete-char -1 nil))
               (viper-ex-style-editing
                (beep 1))
               ((bobp)
                (beep 1))
               (t
                ;; don't put on kill ring
-               (delete-backward-char 1 nil))))
+               (delete-char -1 nil))))
        (viper-ex-style-editing
         (if (bolp)
             (beep 1)
@@ -4325,7 +4345,7 @@ cursor move past the beginning of line."
            (insert-before-markers "@") ; put placeholder after the TAB
            (untabify (viper-replace-start) (point))
            ;; del @, don't put on kill ring
-           (delete-backward-char 1)
+           (delete-char -1)
 
            (viper-set-replace-overlay-glyphs
             viper-replace-region-start-delimiter
@@ -4595,7 +4615,7 @@ One can use `` and '' to temporarily jump 1 step back."
   (indent-to (+ (current-column) viper-shift-width)))
 
 (defun viper-backward-indent ()
-  "Backtab, C-d in VI"
+  "Backtab, `C-d' in Vi."
   (interactive)
   (if viper-cted
       (let ((p (point)) (c (current-column)) bol (indent t))
@@ -4603,7 +4623,7 @@ One can use `` and '' to temporarily jump 1 step back."
            (progn
              (if (eq ?^ (preceding-char))
                  (setq viper-preserve-indent t))
-             (delete-backward-char 1)
+             (delete-char -1)
              (setq p (point))
              (setq indent nil)))
        (save-excursion
@@ -4670,7 +4690,7 @@ One can use `` and '' to temporarily jump 1 step back."
              viper-InvalidRegister reg)))))
 
 (defun viper-brac-function (arg)
-  "Function called by \[, the brac.  View textmarkers and call \[\["
+  "Function called by \[, the brac.  View textmarkers and call \[\[."
   (interactive "P")
   (let ((reg (read-char)))
     (cond ((viper= ?\[ reg)
@@ -4687,8 +4707,7 @@ One can use `` and '' to temporarily jump 1 step back."
             (with-output-to-temp-buffer " *viper-info*"
               (if (and buf pos)
                   (progn
-                    (save-excursion
-                      (set-buffer buf)
+                    (with-current-buffer buf
                       (setq line-no (1+ (count-lines (point-min) val)))
                       (goto-char pos)
                       (beginning-of-line)
@@ -4904,7 +4923,7 @@ Please, specify your level now: ")
 
 ;; if ENFORCE-BUFFER is not nil, error if CHAR is a marker in another buffer
 (defun viper-register-to-point (char &optional enforce-buffer)
-  "Like jump-to-register, but switches to another buffer in another window."
+  "Like `jump-to-register', but switches to another buffer in another window."
   (interactive "cViper register to point: ")
   (let ((val (get-register char)))
     (cond
@@ -5029,7 +5048,7 @@ PLEASE FOLLOW THESE PROCEDURES
 ------------------------------
 
 Before reporting a bug, please verify that it is related to Viper, and is
-not cause by other packages you are using.
+not caused by other packages you are using.
 
 Don't report compilation warnings, unless you are certain that there is a
 problem.  These warnings are normal and unavoidable.