))
(if (and (eq this-command 'dabbrev-expand)
(integerp viper-pre-command-point)
+ (markerp viper-insert-point)
+ (marker-position viper-insert-point)
(> viper-insert-point viper-pre-command-point))
- (move-marker viper-insert-point viper-pre-command-point))
+ (viper-move-marker-locally viper-insert-point viper-pre-command-point))
)
(defsubst viper-insert-state-pre-command-sentinel ()
;; Saves last inserted text for possible use by viper-repeat command.
(defun viper-save-last-insertion (beg end)
+ (condition-case nil
+ (setq viper-last-insertion (buffer-substring beg end))
+ (error
+ ;; beg or end marker are somehow screwed up
+ (setq viper-last-insertion nil)))
(setq viper-last-insertion (buffer-substring beg end))
(or (< (length viper-d-com) 5)
(setcar (nthcdr 4 viper-d-com) viper-last-insertion))
(funcall hook)
))
-;; Interpret last event in the local map
+;; Interpret last event in the local map first; if fails, use exit-minibuffer.
+;; Run viper-minibuffer-exit-hook before exiting.
(defun viper-exit-minibuffer ()
+ "Exit minibuffer Viper way."
(interactive)
(let (command)
(setq command (local-key-binding (char-to-string last-command-char)))
+ (run-hooks 'viper-minibuffer-exit-hook)
(if command
(command-execute command)
(exit-minibuffer))))
+
+(defcustom viper-smart-suffix-list
+ '("" "tex" "c" "cc" "C" "el" "java" "html" "htm" "pl" "P" "p")
+ "*List of suffixes that Viper automatically tries to append to filenames ending with a `.'.
+This is useful when you 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 `.'
+The smart suffix feature lets you hit RET in such a case, and Viper will
+select the appropriate suffix.
+
+Suffixes are tried in the order given and the first suffix for which a
+corresponding file exists is selected. If no file exists for any of the
+suffixes, the user is asked to confirm.
+
+To turn this feature off, set this variable to nil."
+ :type '(set string)
+ :group 'viper)
+
+
+;; Try to add a suitable suffix to files whose name ends with a `.'
+;; Useful when the user hits RET on a non-completed file name.
+;; Used as a minibuffer exit hook in read-file-name
+(defun viper-file-add-suffix ()
+ (let ((count 0)
+ (len (length viper-smart-suffix-list))
+ (file (buffer-string))
+ found key cmd suff)
+ (goto-char (point-max))
+ (if (and viper-smart-suffix-list (string-match "\\.$" file))
+ (progn
+ (while (and (not found) (< count len))
+ (setq suff (nth count viper-smart-suffix-list)
+ count (1+ count))
+ (if (file-exists-p
+ (format "%s%s" (substitute-in-file-name file) suff))
+ (progn
+ (setq found t)
+ (insert suff))))
+
+ (if found
+ ()
+ (viper-tmp-insert-at-eob " [Please complete file name]")
+ (unwind-protect
+ (while (not (memq cmd
+ '(exit-minibuffer viper-exit-minibuffer)))
+ (setq cmd
+ (key-binding (setq key (read-key-sequence nil))))
+ (cond ((eq cmd 'self-insert-command)
+ (if viper-xemacs-p
+ (insert (events-to-keys key))
+ (insert key)))
+ ((memq cmd '(exit-minibuffer viper-exit-minibuffer))
+ nil)
+ (t (command-execute cmd)))
+ )))
+ ))))
+
+
+(defun viper-minibuffer-trim-tail ()
+ "Delete junk at the end of the first line of the minibuffer input.
+Remove this function from `viper-minibuffer-exit-hook', if this causes
+problems."
+ (if (viper-is-in-minibuffer)
+ (progn
+ (goto-char (point-min))
+ (end-of-line)
+ (delete-region (point) (point-max)))))
+
\f
;;; Reading string with history
(kill-buffer buffer)
(error "Buffer not killed"))))
-
-(defcustom viper-smart-suffix-list
- '("" "tex" "c" "cc" "C" "el" "java" "html" "htm" "pl" "P" "p")
- "*List of suffixes that Viper automatically tries to append to filenames ending with a `.'.
-This is useful when you 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 `.'
-The smart suffix feature lets you hit RET in such a case, and Viper will
-select the appropriate suffix.
-
-Suffixes are tried in the order given and the first suffix for which a
-corresponding file exists is selected. If no file exists for any of the
-suffixes, the user is asked to confirm.
-
-To turn this feature off, set this variable to nil."
- :type '(set string)
- :group 'viper)
-
-;; Try to add suffix to files ending with a `.'
-;; Useful when the user hits RET on a non-completed file name.
-(defun viper-file-add-suffix ()
- (let ((count 0)
- (len (length viper-smart-suffix-list))
- (file (buffer-string))
- found key cmd suff)
- (goto-char (point-max))
- (if (and viper-smart-suffix-list (string-match "\\.$" file))
- (progn
- (while (and (not found) (< count len))
- (setq suff (nth count viper-smart-suffix-list)
- count (1+ count))
- (if (file-exists-p
- (format "%s%s" (substitute-in-file-name file) suff))
- (progn
- (setq found t)
- (insert suff))))
-
- (if found
- ()
- (viper-tmp-insert-at-eob " [Please complete file name]")
- (unwind-protect
- (while (not (memq cmd
- '(exit-minibuffer viper-exit-minibuffer)))
- (setq cmd
- (key-binding (setq key (read-key-sequence nil))))
- (cond ((eq cmd 'self-insert-command)
- (if viper-xemacs-p
- (insert (events-to-keys key))
- (insert key)))
- ((memq cmd '(exit-minibuffer viper-exit-minibuffer))
- nil)
- (t (command-execute cmd)))
- )))
- ))))
-
-
\f
;; yank and pop
(setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t|")
- (cond ((looking-at "#")
- (setq ex-token-type 'command)
- (setq ex-token (char-to-string (following-char)))
- (forward-char 1))
- ((looking-at "[a-z]") (viper-get-ex-com-subr))
- ((looking-at "\\.")
- (forward-char 1)
- (setq ex-token-type 'dot))
- ((looking-at "[0-9]")
- (set-mark (point))
- (re-search-forward "[0-9]*")
- (setq ex-token-type
- (cond ((eq ex-token-type 'plus) 'add-number)
- ((eq ex-token-type 'minus) 'sub-number)
- (t 'abs-number)))
- (setq ex-token (string-to-int (buffer-substring (point) (mark t)))))
- ((looking-at "\\$")
- (forward-char 1)
- (setq ex-token-type 'end))
- ((looking-at "%")
- (forward-char 1)
- (setq ex-token-type 'whole))
- ((looking-at "+")
- (cond ((or (looking-at "+[-+]") (looking-at "+[\n|]"))
- (forward-char 1)
- (insert "1")
- (backward-char 1)
+ (let ((case-fold-search t))
+ (cond ((looking-at "#")
+ (setq ex-token-type 'command)
+ (setq ex-token (char-to-string (following-char)))
+ (forward-char 1))
+ ((looking-at "[a-z]") (viper-get-ex-com-subr))
+ ((looking-at "\\.")
+ (forward-char 1)
+ (setq ex-token-type 'dot))
+ ((looking-at "[0-9]")
+ (set-mark (point))
+ (re-search-forward "[0-9]*")
+ (setq ex-token-type
+ (cond ((eq ex-token-type 'plus) 'add-number)
+ ((eq ex-token-type 'minus) 'sub-number)
+ (t 'abs-number)))
+ (setq ex-token
+ (string-to-int (buffer-substring (point) (mark t)))))
+ ((looking-at "\\$")
+ (forward-char 1)
+ (setq ex-token-type 'end))
+ ((looking-at "%")
+ (forward-char 1)
+ (setq ex-token-type 'whole))
+ ((looking-at "+")
+ (cond ((or (looking-at "+[-+]") (looking-at "+[\n|]"))
+ (forward-char 1)
+ (insert "1")
+ (backward-char 1)
(setq ex-token-type 'plus))
- ((looking-at "+[0-9]")
- (forward-char 1)
- (setq ex-token-type 'plus))
- (t
- (error viper-BadAddress))))
- ((looking-at "-")
- (cond ((or (looking-at "-[-+]") (looking-at "-[\n|]"))
- (forward-char 1)
- (insert "1")
- (backward-char 1)
- (setq ex-token-type 'minus))
- ((looking-at "-[0-9]")
- (forward-char 1)
- (setq ex-token-type 'minus))
- (t
- (error viper-BadAddress))))
- ((looking-at "/")
- (forward-char 1)
- (set-mark (point))
- (let ((cont t))
- (while (and (not (eolp)) cont)
- ;;(re-search-forward "[^/]*/")
- (re-search-forward "[^/]*\\(/\\|\n\\)")
- (if (not (viper-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/"))
- (setq cont nil))))
- (backward-char 1)
- (setq ex-token (buffer-substring (point) (mark t)))
- (if (looking-at "/") (forward-char 1))
- (setq ex-token-type 'search-forward))
- ((looking-at "\\?")
- (forward-char 1)
- (set-mark (point))
- (let ((cont t))
- (while (and (not (eolp)) cont)
- ;;(re-search-forward "[^\\?]*\\?")
- (re-search-forward "[^\\?]*\\(\\?\\|\n\\)")
- (if (not (viper-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\\\?"))
- (setq cont nil))
- (backward-char 1)
- (if (not (looking-at "\n")) (forward-char 1))))
- (setq ex-token-type 'search-backward)
- (setq ex-token (buffer-substring (1- (point)) (mark t))))
- ((looking-at ",")
- (forward-char 1)
- (setq ex-token-type 'comma))
- ((looking-at ";")
- (forward-char 1)
- (setq ex-token-type 'semi-colon))
- ((looking-at "[!=><&~]")
- (setq ex-token-type 'command)
- (setq ex-token (char-to-string (following-char)))
- (forward-char 1))
- ((looking-at "'")
- (setq ex-token-type 'goto-mark)
- (forward-char 1)
- (cond ((looking-at "'") (setq ex-token nil))
- ((looking-at "[a-z]") (setq ex-token (following-char)))
- (t (error "Marks are ' and a-z")))
- (forward-char 1))
- ((looking-at "\n")
- (setq ex-token-type 'end-mark)
- (setq ex-token "goto"))
- (t
- (error viper-BadExCommand)))))
+ ((looking-at "+[0-9]")
+ (forward-char 1)
+ (setq ex-token-type 'plus))
+ (t
+ (error viper-BadAddress))))
+ ((looking-at "-")
+ (cond ((or (looking-at "-[-+]") (looking-at "-[\n|]"))
+ (forward-char 1)
+ (insert "1")
+ (backward-char 1)
+ (setq ex-token-type 'minus))
+ ((looking-at "-[0-9]")
+ (forward-char 1)
+ (setq ex-token-type 'minus))
+ (t
+ (error viper-BadAddress))))
+ ((looking-at "/")
+ (forward-char 1)
+ (set-mark (point))
+ (let ((cont t))
+ (while (and (not (eolp)) cont)
+ ;;(re-search-forward "[^/]*/")
+ (re-search-forward "[^/]*\\(/\\|\n\\)")
+ (if (not (viper-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/"))
+ (setq cont nil))))
+ (backward-char 1)
+ (setq ex-token (buffer-substring (point) (mark t)))
+ (if (looking-at "/") (forward-char 1))
+ (setq ex-token-type 'search-forward))
+ ((looking-at "\\?")
+ (forward-char 1)
+ (set-mark (point))
+ (let ((cont t))
+ (while (and (not (eolp)) cont)
+ ;;(re-search-forward "[^\\?]*\\?")
+ (re-search-forward "[^\\?]*\\(\\?\\|\n\\)")
+ (if (not (viper-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\\\?"))
+ (setq cont nil))
+ (backward-char 1)
+ (if (not (looking-at "\n")) (forward-char 1))))
+ (setq ex-token-type 'search-backward)
+ (setq ex-token (buffer-substring (1- (point)) (mark t))))
+ ((looking-at ",")
+ (forward-char 1)
+ (setq ex-token-type 'comma))
+ ((looking-at ";")
+ (forward-char 1)
+ (setq ex-token-type 'semi-colon))
+ ((looking-at "[!=><&~]")
+ (setq ex-token-type 'command)
+ (setq ex-token (char-to-string (following-char)))
+ (forward-char 1))
+ ((looking-at "'")
+ (setq ex-token-type 'goto-mark)
+ (forward-char 1)
+ (cond ((looking-at "'") (setq ex-token nil))
+ ((looking-at "[a-z]") (setq ex-token (following-char)))
+ (t (error "Marks are ' and a-z")))
+ (forward-char 1))
+ ((looking-at "\n")
+ (setq ex-token-type 'end-mark)
+ (setq ex-token "goto"))
+ (t
+ (error viper-BadExCommand))))))
;; Reads Ex command. Tries to determine if it has to exit because command
;; is complete or invalid. If not, keeps reading command.
is non-nil."
:type 'string
:group 'viper)
-(defcustom viper-use-replace-region-delimiters (not (viper-has-face-support-p))
+(defcustom viper-use-replace-region-delimiters
+ (or (not (viper-has-face-support-p))
+ (and viper-xemacs-p (eq (viper-device-type) 'tty)))
"*If non-nil, Viper will always use `viper-replace-region-end-delimiter' and
`viper-replace-region-start-delimiter' to delimit replacement regions, even on
color displays. By default, the delimiters are used only on TTYs."
;; Hook, specific to Viper, which is run just *before* exiting the minibuffer.
;; Beginning with Emacs 19.26, the standard `minibuffer-exit-hook' is run
;; *after* exiting the minibuffer
-(defvar viper-minibuffer-exit-hook nil)
+(defvar viper-minibuffer-exit-hook '(viper-minibuffer-trim-tail))
;; Mode line
(interactive "e\nP")
(if viper-frame-of-focus ;; to handle clicks in another frame
(select-frame viper-frame-of-focus))
-
- ;; turn arg into a number
- (cond ((integerp arg) nil)
- ;; prefix arg is a list when one hits C-u then command
- ((and (listp arg) (integerp (car arg)))
- (setq arg (car arg)))
- (t (setq arg 1)))
-
- (if (not (eq (key-binding viper-mouse-down-insert-key-parsed)
- 'viper-mouse-catch-frame-switch))
- () ; do nothing
- (let (click-count interrupting-event)
- (if (and
- (viper-multiclick-p)
- ;; This trick checks if there is a pending mouse event if so, we use
- ;; this latter event and discard the current mouse click If the next
- ;; pending event is not a mouse event, we execute the current mouse
- ;; event
- (progn
- (setq interrupting-event (viper-read-event))
- (viper-mouse-event-p last-input-event)))
- (progn ; interrupted wait
- (setq viper-global-prefix-argument arg)
- ;; count this click for XEmacs
- (viper-event-click-count click))
- ;; uninterrupted wait or the interrupting event wasn't a mouse event
- (setq click-count (viper-event-click-count click))
- (if (> click-count 1)
- (setq arg viper-global-prefix-argument
- viper-global-prefix-argument nil))
- (insert (viper-mouse-click-get-word click arg click-count))
- (if (and interrupting-event
- (eventp interrupting-event)
- (not (viper-mouse-event-p interrupting-event)))
- (viper-set-unread-command-events interrupting-event))
- ))))
+ (if (or (not (eq (key-binding viper-mouse-down-insert-key-parsed)
+ 'viper-mouse-catch-frame-switch))
+ (not (eq (key-binding viper-mouse-up-insert-key-parsed)
+ 'viper-mouse-click-insert-word))
+ (and viper-xemacs-p (not (event-over-text-area-p click))))
+ () ; do nothing, if binding isn't right or not over text
+ ;; turn arg into a number
+ (cond ((integerp arg) nil)
+ ;; prefix arg is a list when one hits C-u then command
+ ((and (listp arg) (integerp (car arg)))
+ (setq arg (car arg)))
+ (t (setq arg 1)))
+
+ (if (not (eq (key-binding viper-mouse-down-insert-key-parsed)
+ 'viper-mouse-catch-frame-switch))
+ () ; do nothing
+ (let (click-count interrupting-event)
+ (if (and
+ (viper-multiclick-p)
+ ;; This trick checks if there is a pending mouse event if so, we
+ ;; use this latter event and discard the current mouse click If
+ ;; the next pending event is not a mouse event, we execute the
+ ;; current mouse event
+ (progn
+ (setq interrupting-event (viper-read-event))
+ (viper-mouse-event-p last-input-event)))
+ (progn ; interrupted wait
+ (setq viper-global-prefix-argument arg)
+ ;; count this click for XEmacs
+ (viper-event-click-count click))
+ ;; uninterrupted wait or the interrupting event wasn't a mouse event
+ (setq click-count (viper-event-click-count click))
+ (if (> click-count 1)
+ (setq arg viper-global-prefix-argument
+ viper-global-prefix-argument nil))
+ (insert (viper-mouse-click-get-word click arg click-count))
+ (if (and interrupting-event
+ (eventp interrupting-event)
+ (not (viper-mouse-event-p interrupting-event)))
+ (viper-set-unread-command-events interrupting-event))
+ )))))
;; arg is an event. accepts symbols and numbers, too
(defun viper-mouse-event-p (event)
(interactive "e\nP")
(if viper-frame-of-focus ;; to handle clicks in another frame
(select-frame viper-frame-of-focus))
- (if (not (eq (key-binding viper-mouse-down-search-key-parsed)
- 'viper-mouse-catch-frame-switch))
- () ; do nothing
+ (if (or (not (eq (key-binding viper-mouse-down-search-key-parsed)
+ 'viper-mouse-catch-frame-switch))
+ (not (eq (key-binding viper-mouse-up-search-key-parsed)
+ 'viper-mouse-click-search-word))
+ (and viper-xemacs-p (not (event-over-text-area-p click))))
+ () ; do nothing, if binding isn't right or not over text
(let ((previous-search-string viper-s-string)
click-word click-count)
(read-key-sequence "Describe key briefly: ")))))
- ;; Advice for use in find-file and read-file-name commands.
- (defadvice exit-minibuffer (before viper-exit-minibuffer-advice activate)
- "Run `viper-minibuffer-exit-hook' just before exiting the minibuffer."
- (run-hooks 'viper-minibuffer-exit-hook))
+ ;; This is now done in viper-minibuffer-exit-hook
+ ;;;; Advice for use in find-file and read-file-name commands.
+ ;;(defadvice exit-minibuffer (before viper-exit-minibuffer-advice activate)
+ ;; "Run `viper-minibuffer-exit-hook' just before exiting the minibuffer."
+ ;; (run-hooks 'viper-minibuffer-exit-hook))
(defadvice find-file (before viper-add-suffix-advice activate)
"Use `read-file-name' for reading arguments."
(defadvice read-file-name (around viper-suffix-advice activate)
"Tell `exit-minibuffer' to run `viper-file-add-suffix' as a hook."
- (let ((viper-minibuffer-exit-hook 'viper-file-add-suffix))
+ (let ((viper-minibuffer-exit-hook
+ (append viper-minibuffer-exit-hook '(viper-file-add-suffix))))
ad-do-it))
(defadvice start-kbd-macro (after viper-kbd-advice activate)