]> code.delx.au - gnu-emacs/blobdiff - lisp/emulation/viper-cmd.el
Pass lambdas to `skeleton-read'
[gnu-emacs] / lisp / emulation / viper-cmd.el
index f06428d81eb7e1dd902f99d0ee29cd4dc5e3dbf3..5e1620df57ce455f89fb291c97a03150568a5e4a 100644 (file)
@@ -1,6 +1,6 @@
 ;;; viper-cmd.el --- Vi command support for Viper
 
-;; Copyright (C) 1997-201 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2015 Free Software Foundation, Inc.
 
 ;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
 ;; Package: viper
     (or (viper-overlay-p viper-replace-overlay)
       (viper-set-replace-overlay (point-min) (point-min)))
     (viper-hide-replace-overlay)
-    (if abbrev-mode (expand-abbrev))
+    ;; Expand abbrevs iff the previous character has word syntax.
+    (and abbrev-mode
+        (eq (char-syntax (preceding-char)) ?w)
+        (expand-abbrev))
     (if (and auto-fill-function (> (current-column) fill-column))
        (funcall auto-fill-function))
     ;; don't leave whitespace lines around
     (error
      (viper-message-conditions conds))))
 
-;; escape to emacs mode termporarily
+;; escape to emacs mode temporarily
 (defun viper-escape-to-emacs (arg &optional events)
   "Escape to Emacs state from Vi state for one Emacs command.
 ARG is used as the prefix value for the executed command.  If
@@ -723,7 +726,7 @@ EVENTS is a list of events, which become the beginning of the command."
       (message "Switched to EMACS state for the next command..."))
   (viper-escape-to-state arg events 'emacs-state))
 
-;; escape to Vi mode termporarily
+;; escape to Vi mode temporarily
 (defun viper-escape-to-vi (arg)
   "Escape from Emacs state to Vi state for one Vi 1-character command.
 If the Vi command that the user types has a prefix argument, e.g., `d2w', then
@@ -958,11 +961,11 @@ Suffixes such as .el or .elc should be stripped."
 (defun viper-ESC (arg)
   "Emulate ESC key in Emacs.
 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.
+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 works
+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)
@@ -993,98 +996,15 @@ as a Meta key and any number of multiple escapes are allowed."
        (suspend-emacs))
     (viper-change-state-to-emacs)))
 
-\f
-;; Intercept ESC sequences on dumb terminals.
-;; Based on the idea contributed by Marcelino Veiga Tuimil <mveiga@dit.upm.es>
-
-;; Check if last key was ESC and if so try to reread it as a function key.
-;; But only if there are characters to read during a very short time.
-;; Returns the last event, if any.
-(defun viper-envelop-ESC-key ()
-  (let ((event last-input-event)
-       (keyseq [nil])
-       (inhibit-quit t))
-    (if (viper-ESC-event-p event)
-       (progn
-         ;; Some versions of Emacs (eg., 22.50.8 have a bug, which makes even
-         ;; a single ESC into ;; a fast keyseq. To guard against this, we
-         ;; added a check if there are other events as well. Keep the next
-         ;; line for the next time the bug reappears, so that will remember to
-         ;; report it.
-         ;;(if (and (viper-fast-keysequence-p) unread-command-events)
-         (if (viper-fast-keysequence-p) ;; for Emacsen without the above bug
-             (progn
-               (let (minor-mode-map-alist emulation-mode-map-alists)
-                 (viper-set-unread-command-events event)
-                 (setq keyseq (read-key-sequence nil 'continue-echo))
-                 ) ; let
-               ;; If keyseq translates into something that still has ESC
-               ;; at the beginning, separate ESC from the rest of the seq.
-               ;; In XEmacs we check for events that are keypress meta-key
-               ;; and convert them into [escape key]
-               ;;
-               ;; This is needed for the following reason:
-               ;; If ESC is the first symbol, we interpret it as if the
-               ;; user typed ESC and then quickly some other symbols.
-               ;; If ESC is not the first one, then the key sequence
-               ;; entered was apparently translated into a function key or
-               ;; something (e.g., one may have
-               ;; (define-key function-key-map "\e[192z" [f11])
-               ;; which would translate the escape-sequence generated by
-               ;; f11 in an xterm window into the symbolic key f11.
-               ;;
-               ;; If `first-key' is not an ESC event, we make it into the
-               ;; last-command-event in order to pretend that this key was
-               ;; pressed.  This is needed to allow arrow keys to be bound to
-               ;; macros.  Otherwise, viper-exec-mapped-kbd-macro will think
-               ;; that the last event was ESC and so it'll execute whatever is
-               ;; bound to ESC. (Viper macros can't be bound to
-               ;; ESC-sequences).
-               (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)))
-                        ;; put keys following ESC on the unread list
-                        ;; and return ESC as the key-sequence
-                        (viper-set-unread-command-events (viper-subseq keyseq 1))
-                        (setq last-input-event event
-                              keyseq (if (featurep 'emacs)
-                                         "\e"
-                                       (vector (character-to-event ?\e)))))
-                       ((and (featurep 'xemacs)
-                             (key-press-event-p first-key)
-                             (equal '(meta) key-mod))
-                        (viper-set-unread-command-events
-                         (vconcat (vector
-                                   (character-to-event (event-key first-key)))
-                                  (viper-subseq keyseq 1)))
-                        (setq last-input-event event
-                              keyseq (vector (character-to-event ?\e))))
-                       ((eventp first-key)
-                        (setq last-command-event
-                              (viper-copy-event first-key)))
-                       ))
-               ) ; end progn
-
-           ;; this is escape event with nothing after it
-           ;; put in unread-command-event and then re-read
-           (viper-set-unread-command-events event)
-           (setq keyseq (read-key-sequence nil))
-           ))
-      ;; not an escape event
-      (setq keyseq (vector event)))
-    keyseq))
-
-
-
 ;; Listen to ESC key.
-;; If a sequence of keys starting with ESC is issued with very short delays,
-;; interpret these keys in Emacs mode, so ESC won't be interpreted as a Vi key.
 (defun viper-intercept-ESC-key ()
   "Function that implements ESC key in Viper emulation of Vi."
   (interactive)
-  (let ((cmd (or (key-binding (viper-envelop-ESC-key))
-                (lambda () (interactive) (error "Viper bell")))))
+  ;; `key-binding' needs to be called in a context where Viper's
+  ;; minor-mode map(s) have been temporarily disabled so the ESC
+  ;; binding to viper-intercept-ESC-key doesn't hide the binding we're
+  ;; looking for (Bug#9146):
+  (let* ((cmd 'viper-intercept-ESC-key))
 
     ;; call the actual function to execute ESC (if no other symbols followed)
     ;; or the key bound to the ESC sequence (if the sequence was issued
@@ -1384,7 +1304,7 @@ as a Meta key and any number of multiple escapes are allowed."
        (insert " ")(backward-char 1)))
   (if (= viper-com-point (point))
       (viper-forward-char-carefully))
-  (set-mark viper-com-point)
+  (push-mark viper-com-point)
   (if (eq m-com 'viper-next-line-at-bol)
       (viper-enlarge-region (mark t) (point)))
   (if (< (point) (mark t))
@@ -1393,8 +1313,7 @@ as a Meta key and any number of multiple escapes are allowed."
       (viper-backward-char-carefully)) ; give back the newline
   (if (eq viper-intermediate-command 'viper-repeat)
       (viper-change-subr (mark t) (point))
-    (viper-change (mark t) (point))
-    ))
+    (viper-change (mark t) (point))))
 
 ;; this is invoked by viper-substitute-line
 (defun viper-exec-Change (m-com com)
@@ -1537,7 +1456,7 @@ as a Meta key and any number of multiple escapes are allowed."
                (car viper-shell-history)
                ))
        viper-last-shell-com)
-     t)))
+     t t)))
 
 (defun viper-exec-equals (m-com com)
   (save-excursion
@@ -1597,7 +1516,7 @@ as a Meta key and any number of multiple escapes are allowed."
 ;; call viper-execute-com to execute viper-exec-change, which eventually will
 ;; call viper-change to invoke the replace mode on the region.
 ;;
-;; The var viper-d-com is set to (M-COM VAL COM REG INSETED-TEXT COMMAND-KEYS)
+;; The var viper-d-com is set to (M-COM VAL COM REG INSERTED-TEXT COMMAND-KEYS)
 ;; via a call to viper-set-destructive-command, for later use by viper-repeat.
 (defun viper-execute-com (m-com val com)
   (let ((reg viper-use-register))
@@ -1977,7 +1896,7 @@ Undo previous insertion and inserts new."
 ;; Quote region by each line with a user supplied string.
 (defun viper-quote-region ()
   (let ((quote-str viper-quote-string)
-       (donot-change-dafault t))
+       (do-not-change-default t))
     (setq quote-str
          (viper-read-string-with-history
           "Quote string: "
@@ -1989,9 +1908,9 @@ Undo previous insertion and inserts new."
                 ((string-match "lisp.*-mode" (symbol-name major-mode)) ";;")
                 ((memq major-mode '(c-mode cc-mode c++-mode)) "//")
                 ((memq major-mode '(sh-mode shell-mode)) "#")
-                (t (setq donot-change-dafault nil)
+                (t (setq do-not-change-default nil)
                    quote-str))))
-    (or donot-change-dafault
+    (or do-not-change-default
        (setq viper-quote-string quote-str))
     (viper-enlarge-region (point) (mark t))
     (if (> (point) (mark t)) (exchange-point-and-mark))
@@ -2108,7 +2027,7 @@ Undo previous insertion and inserts new."
 (defcustom viper-smart-suffix-list
   '("" "tex" "c" "cc" "C" "java" "el" "html" "htm" "xml"
     "pl" "flr" "P" "p" "h" "H")
-  "*List of suffixes that Viper tries to append to filenames ending with a `.'.
+  "List of suffixes that Viper tries to append to filenames ending with a `.'.
 This is useful when the current directory contains files with the same
 prefix and many different suffixes.  Usually, only one of the suffixes
 represents an editable file.  However, file completion will stop at the `.'
@@ -2405,7 +2324,7 @@ problems."
    t 'local)
   (add-hook
    'viper-pre-command-hooks 'viper-replace-state-pre-command-sentinel t 'local)
-  ;; guard against a smartie who switched from R-replace to normal replace
+  ;; guard against a smarty who switched from R-replace to normal replace
   (remove-hook
    'viper-post-command-hooks 'viper-R-state-post-command-sentinel 'local)
   (if overwrite-mode (overwrite-mode -1))
@@ -2529,7 +2448,7 @@ problems."
    'viper-post-command-hooks 'viper-R-state-post-command-sentinel t 'local)
   (add-hook
    'viper-pre-command-hooks 'viper-replace-state-pre-command-sentinel t 'local)
-  ;; guard against a smartie who switched from R-replace to normal replace
+  ;; guard against a smarty who switched from R-replace to normal replace
   (remove-hook
    'viper-post-command-hooks 'viper-replace-state-post-command-sentinel 'local)
   )
@@ -3451,7 +3370,7 @@ controlled by the sign of prefix numeric value."
 (defun viper-adjust-window ()
   (let ((win-height (if (featurep 'xemacs)
                        (window-displayed-height)
-                     (1- (window-height)))) ; adjust for modeline
+                     (1- (window-height)))) ; adjust for mode line
        (pt (point))
        at-top-p at-bottom-p
        min-scroll direction)
@@ -3713,7 +3632,7 @@ Although this function is bound to \\[viper-toggle-search-style], the most
 convenient way to use it is to bind `//' to the macro
 `1 M-x viper-toggle-search-style' and `///' to
 `2 M-x viper-toggle-search-style'.  In this way, hitting `//' quickly will
-toggle case-fold-search and hitting `/' three times witth toggle regexp
+toggle case-fold-search and hitting `/' three times with toggle regexp
 search.  Macros are more convenient in this case because they don't affect
 the Emacs binding of `/'."
   (interactive "P")
@@ -3765,14 +3684,14 @@ If MAJOR-MODE is set, set the macros only in that major mode."
               "//" 'vi-state
               [1 (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)
-             ;; toggle regexp/vanila search
+             ;; toggle regexp/vanilla search
              (viper-record-kbd-macro
               "///" '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)
+             (if (if (featurep 'xemacs)
+                     (interactive-p)
+                   (called-interactively-p 'interactive))
                  (message
                   "// and /// now toggle case-sensitivity and regexp search")))
          (viper-unrecord-kbd-macro "//" 'vi-state)
@@ -3795,10 +3714,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)
+           (if (if (featurep 'xemacs)
+                   (interactive-p)
+                 (called-interactively-p 'interactive))
                (message
                 "%%%%%% now toggles whether comments should be parsed for matching parentheses")))
        (viper-unrecord-kbd-macro "%%%" 'vi-state))))
@@ -3822,15 +3740,14 @@ the macros are set in the current major mode.
             "//" 'emacs-state
             [1 (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))
-           ;; toggle regexp/vanila search
+           ;; toggle regexp/vanilla search
            (viper-record-kbd-macro
             "///" '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)
+           (if (if (featurep 'xemacs)
+                   (interactive-p)
+                 (called-interactively-p 'interactive))
                (message
                 "// and /// now toggle case-sensitivity and regexp search.")))
        (viper-unrecord-kbd-macro "//" 'emacs-state)
@@ -4015,7 +3932,7 @@ Null string will repeat previous search."
   (setq viper-prefix-commands
        (cons viper-buffer-search-char viper-prefix-commands)))
 
-;; This is a Viper wraper for isearch-forward.
+;; This is a Viper wrapper for isearch-forward.
 (defun viper-isearch-forward (arg)
   "Do incremental search forward."
   (interactive "P")
@@ -4023,7 +3940,7 @@ Null string will repeat previous search."
   (if (listp arg) (setq arg (car arg)))
   (viper-exec-form-in-emacs (list 'isearch-forward arg)))
 
-;; This is a Viper wraper for isearch-backward."
+;; This is a Viper wrapper for isearch-backward."
 (defun viper-isearch-backward (arg)
   "Do incremental search backward."
   (interactive "P")
@@ -4280,6 +4197,11 @@ cursor move past the beginning of line."
        (t
         (backward-char 1))))
 
+(defun viper-del-forward-char-in-insert ()
+  "Delete 1 char forward if in insert or replace state."
+  (interactive)
+  ;; don't put on kill ring
+  (delete-char 1 nil))
 
 \f
 ;; join lines.
@@ -4395,7 +4317,7 @@ cursor move past the beginning of line."
 
 (defun viper-query-replace ()
   "Query replace.
-If a null string is suplied as the string to be replaced,
+If a null string is supplied as the string to be replaced,
 the query replace mode will toggle between string replace
 and regexp replace."
   (interactive)
@@ -4478,7 +4400,7 @@ and regexp replace."
 ;; etc.
 (defun viper-cycle-through-mark-ring ()
   "Visit previous locations on the mark ring.
-One can use `` and '' to temporarily jump 1 step back."
+One can use \\=`\\=` and '' to temporarily jump 1 step back."
   (let* ((sv-pt (point)))
        ;; if repeated `m,' command, pop the previously saved mark.
        ;; Prev saved mark is actually prev saved point.  It is used if the
@@ -4597,10 +4519,7 @@ One can use `` and '' to temporarily jump 1 step back."
 
 ;; Input Mode Indentation
 
-;; Returns t, if the string before point matches the regexp STR.
-(defsubst viper-looking-back (str)
-  (and (save-excursion (re-search-backward str nil t))
-       (= (point) (match-end 0))))
+(define-obsolete-function-alias 'viper-looking-back 'looking-back "24.4")
 
 
 (defun viper-forward-indent ()
@@ -4614,7 +4533,7 @@ One can use `` and '' to temporarily jump 1 step back."
   (interactive)
   (if viper-cted
       (let ((p (point)) (c (current-column)) bol (indent t))
-       (if (viper-looking-back "[0^]")
+       (if (looking-back "[0^]" (1- (point)))
            (progn
              (if (eq ?^ (preceding-char))
                  (setq viper-preserve-indent t))
@@ -4626,7 +4545,7 @@ One can use `` and '' to temporarily jump 1 step back."
        (delete-region (point) p)
        (if indent
            (indent-to (- c viper-shift-width)))
-       (if (or (bolp) (viper-looking-back "[^ \t]"))
+       (if (or (bolp) (looking-back "[^ \t]" (1- (point))))
            (setq viper-cted nil)))))
 
 ;; do smart indent
@@ -4912,6 +4831,7 @@ Please, specify your level now: ")
   (beep 1))
 
 
+;; FIXME Use register-read-with-preview?
 ;; 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."
@@ -4941,7 +4861,7 @@ Please, specify your level now: ")
   (interactive)
   (if (< viper-expert-level 2)
       (save-buffers-kill-emacs)
-    (save-buffer)
+    (if (buffer-modified-p) (save-buffer))
     (kill-buffer (current-buffer))))
 
 
@@ -5074,12 +4994,12 @@ Mail anyway (y or n)? ")
          (require 'reporter)
          (set-window-configuration window-config)
 
-         (reporter-submit-bug-report "kifer@cs.stonybrook.edu"
-                                     (viper-version)
-                                     varlist
-                                     nil 'delete-other-windows
-                                     salutation)
-         ))
+         (reporter-submit-bug-report
+          "kifer@cs.stonybrook.edu, bug-gnu-emacs@gnu.org"
+          (viper-version)
+          varlist
+          nil 'delete-other-windows
+          salutation)))