;;; viper-cmd.el --- Vi command support for Viper
-;; Copyright (C) 1997-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2016 Free Software Foundation, Inc.
;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
;; Package: viper
(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)
(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)
;; 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* ((event (viper-envelop-ESC-key))
- (cmd (cond ((equal event viper-ESC-key)
- 'viper-intercept-ESC-key)
- ((let ((emulation-mode-map-alists nil))
- (key-binding event)))
- (t
- (error "Viper bell")))))
+ (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
(car viper-shell-history)
))
viper-last-shell-com)
- t)))
+ t t)))
(defun viper-exec-equals (m-com com)
(save-excursion
(defun viper-repeat (arg)
"Re-execute last destructive command.
Use the info in viper-d-com, which has the form
-\(com val ch reg inserted-text command-keys\),
+\(com val ch reg inserted-text command-keys),
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'.
(setq this-command 'viper-display-current-destructive-command)
- (message " `.' runs %s%s"
- (concat "`" (viper-array-to-string keys) "'")
+ (message " `.' runs `%s'%s"
+ (viper-array-to-string keys)
(viper-abbreviate-string
(if (featurep 'xemacs)
(replace-in-string ; xemacs
text ; emacs
)
max-text-len
- " inserting `" "'" " ......."))
+ (format-message " inserting `") (format-message "'")
+ " ......."))
))
;; Quote region by each line with a user supplied string.
(defun viper-quote-region ()
(let ((quote-str viper-quote-string)
- (donot-change-default t))
+ (do-not-change-default t))
(setq quote-str
(viper-read-string-with-history
"Quote string: "
((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-default nil)
+ (t (setq do-not-change-default nil)
quote-str))))
- (or donot-change-default
+ (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))
((re-search-backward "[][(){}]" beg-lim t))
(t
(error "No matching character on line"))))
- (cond ((looking-at "[\(\[{]")
+ (cond ((looking-at "[([{]")
(if com (viper-move-marker-locally 'viper-com-point (point)))
(forward-sexp 1)
(if com
(interactive)
(setq viper-parse-sexp-ignore-comments
(not viper-parse-sexp-ignore-comments))
- (princ (format
+ (princ (format-message
"From now on, `%%' will %signore parentheses inside comment fields"
(if viper-parse-sexp-ignore-comments "" "NOT "))))
(let (msg)
(cond ((or (eq arg 1)
(and (null arg)
- (y-or-n-p (format "Search style: '%s'. Want '%s'? "
- (if viper-case-fold-search
- "case-insensitive" "case-sensitive")
- (if viper-case-fold-search
- "case-sensitive"
- "case-insensitive")))))
+ (y-or-n-p (format-message
+ "Search style: `%s'. Want `%s'? "
+ (if viper-case-fold-search
+ "case-insensitive" "case-sensitive")
+ (if viper-case-fold-search
+ "case-sensitive"
+ "case-insensitive")))))
(setq viper-case-fold-search (null viper-case-fold-search))
(if viper-case-fold-search
(setq msg "Search becomes case-insensitive")
(setq msg "Search becomes case-sensitive")))
((or (eq arg 2)
(and (null arg)
- (y-or-n-p (format "Search style: '%s'. Want '%s'? "
- (if viper-re-search
- "regexp-search" "vanilla-search")
- (if viper-re-search
- "vanilla-search"
- "regexp-search")))))
+ (y-or-n-p (format-message
+ "Search style: `%s'. Want `%s'? "
+ (if viper-re-search
+ "regexp-search" "vanilla-search")
+ (if viper-re-search
+ "vanilla-search"
+ "regexp-search")))))
(setq viper-re-search (null viper-re-search))
(if viper-re-search
(setq msg "Search becomes regexp-style")
"///" '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)
"%%%" '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))))
If the optional prefix argument is non-nil and specifies a valid major mode,
this sets the macros only in the macros in that major mode. Otherwise,
the macros are set in the current major mode.
-\(When unsetting the macros, the second argument has no effect.\)"
+\(When unsetting the macros, the second argument has no effect.)"
(interactive "P")
(or noninteractive
(if (not unset)
"///" '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)
(let (buffer buffer-name)
(setq buffer-name
(funcall viper-read-buffer-function
- (format "Kill buffer \(%s\): "
+ (format "Kill buffer (%s): "
(buffer-name (current-buffer)))))
(setq buffer
(if (null buffer-name)
(if (null buffer) (error "`%s': No such buffer" buffer-name))
(if (or (not (buffer-modified-p buffer))
(y-or-n-p
- (format
+ (format-message
"Buffer `%s' is modified, are you sure you want to kill it? "
buffer-name)))
(kill-buffer buffer)
(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.
(query-replace-regexp
str
(viper-read-string-with-history
- (format "Query replace regexp `%s' with: " str)
+ (format-message "Query replace regexp `%s' with: " str)
nil ; no initial
'viper-replace1-history
(car viper-replace1-history) ; default
(query-replace
str
(viper-read-string-with-history
- (format "Query replace `%s' with: " str)
+ (format-message "Query replace `%s' with: " str)
nil ; no initial
'viper-replace1-history
(car viper-replace1-history) ; default
;; 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
;; 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 ()
(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))
(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
;; Viewing registers
(defun viper-ket-function (arg)
- "Function called by \], the ket. View registers and call \]\]."
+ "Function called by ], the ket. View registers and call ]]."
(interactive "P")
(let ((reg (read-char)))
(cond ((viper-valid-register reg '(letter Letter))
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)
(substring text 0 (- pos s))
reg (substring text (- pos s)))))
(princ
- (format
+ (format-message
"Textmarker `%c' is in buffer `%s' at line %d.\n"
reg (buffer-name buf) line-no))
(princ (format "Here is some text around %c:\n\n %s"
reg text)))
- (princ (format viper-EmptyTextmarker reg))))
+ (princ (format-message viper-EmptyTextmarker reg))))
))
(t (error viper-InvalidTextmarker reg)))))
(setq repeated t))
(setq dont-change-unless t
level-changed t)
- (insert "
+ (insert (substitute-command-keys "
Please specify your level of familiarity with the venomous VI PERil
\(and the VI Plan for Emacs Rescue).
-You can change it at any time by typing `M-x viper-set-expert-level RET'
+You can change it at any time by typing `\\[viper-set-expert-level]'
1 -- BEGINNER: Almost all Emacs features are suppressed.
Feels almost like straight Vi. File name completion and
viper-electric-mode, viper-want-ctl-h-help, viper-want-emacs-keys-in-vi,
and viper-want-emacs-keys-in-insert. Adjust these to your taste.
-Please, specify your level now: ")
+Please, specify your level now: "))
(setq viper-expert-level (- (viper-read-char-exclusive) ?0))
) ; end while
(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."
(interactive)
(if (< viper-expert-level 2)
(save-buffers-kill-emacs)
- (save-buffer)
+ (if (buffer-modified-p) (save-buffer))
(kill-buffer (current-buffer))))
trace in your bug report.
If you believe that one of Viper's commands goes into an infinite loop
-\(e.g., Emacs freezes\), type:
+\(e.g., Emacs freezes), type:
M-x set-variable <Return> debug-on-quit <Return> t <Return>