new version
This commit is contained in:
parent
d0388eace9
commit
34317da2d4
6 changed files with 691 additions and 318 deletions
|
@ -136,6 +136,7 @@
|
|||
|
||||
(defgroup ediff nil
|
||||
"A comprehensive visual interface to diff & patch"
|
||||
:tag "Ediff"
|
||||
:group 'tools)
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
(defvar viper-mode-string)
|
||||
(defvar viper-custom-file-name)
|
||||
(defvar iso-accents-mode)
|
||||
(defvar quail-mode)
|
||||
(defvar quail-current-str)
|
||||
(defvar zmacs-region-stays)
|
||||
(defvar mark-even-if-inactive)
|
||||
|
||||
|
@ -217,25 +219,23 @@
|
|||
(let ((replace-boundary (viper-replace-end)))
|
||||
(save-excursion
|
||||
(goto-char viper-last-posn-in-replace-region)
|
||||
(viper-trim-replace-chars-to-delete-if-necessary)
|
||||
(delete-char viper-replace-chars-to-delete)
|
||||
(setq viper-replace-chars-to-delete 0
|
||||
viper-replace-chars-deleted 0)
|
||||
(setq viper-replace-chars-to-delete 0)
|
||||
;; terminate replace mode if reached replace limit
|
||||
(if (= viper-last-posn-in-replace-region
|
||||
(viper-replace-end))
|
||||
(viper-finish-change viper-last-posn-in-replace-region)))
|
||||
(if (= viper-last-posn-in-replace-region (viper-replace-end))
|
||||
(viper-finish-change)))
|
||||
|
||||
(if (and (<= (viper-replace-start) (point))
|
||||
(<= (point) replace-boundary))
|
||||
(if (viper-pos-within-region
|
||||
(point) (viper-replace-start) replace-boundary)
|
||||
(progn
|
||||
;; the state may have changed in viper-finish-change above
|
||||
(if (eq viper-current-state 'replace-state)
|
||||
(viper-change-cursor-color viper-replace-overlay-cursor-color))
|
||||
(setq viper-last-posn-in-replace-region (point-marker))))
|
||||
))
|
||||
|
||||
(t ;; terminate replace mode if changed Viper states.
|
||||
(viper-finish-change viper-last-posn-in-replace-region))))
|
||||
;; terminate replace mode if changed Viper states.
|
||||
(t (viper-finish-change))))
|
||||
|
||||
|
||||
;; changing mode
|
||||
|
@ -286,7 +286,7 @@
|
|||
(viper-push-onto-ring viper-last-insertion
|
||||
'viper-insertion-ring))
|
||||
|
||||
(if viper-ex-style-editing-in-insert
|
||||
(if viper-ex-style-editing
|
||||
(or (bolp) (backward-char 1))))
|
||||
))
|
||||
|
||||
|
@ -305,7 +305,20 @@
|
|||
;; Nothing needs to be done to switch to emacs mode! Just set some
|
||||
;; variables, which is already done in viper-change-state-to-emacs!
|
||||
|
||||
;; ISO accents
|
||||
;; always turn off iso-accents-mode in vi-state, or else we won't be able to
|
||||
;; use the keys `,',^ , as they will do accents instead of Vi actions.
|
||||
(cond ((eq new-state 'vi-state) (viper-set-iso-accents-mode nil));accents off
|
||||
(viper-automatic-iso-accents (viper-set-iso-accents-mode t));accents on
|
||||
(t (viper-set-iso-accents-mode nil)))
|
||||
;; Always turn off quail mode in vi state
|
||||
(cond ((eq new-state 'vi-state) (viper-set-input-method nil)) ;intl input off
|
||||
(viper-special-input-method (viper-set-input-method t)) ;intl input on
|
||||
(t (viper-set-input-method nil)))
|
||||
|
||||
(setq viper-current-state new-state)
|
||||
|
||||
(viper-update-syntax-classes)
|
||||
(viper-normalize-minor-mode-map-alist)
|
||||
(viper-adjust-keys-for new-state)
|
||||
(viper-set-mode-vars-for new-state)
|
||||
|
@ -333,8 +346,14 @@
|
|||
|
||||
(if viper-want-ctl-h-help
|
||||
(progn
|
||||
(define-key viper-insert-basic-map [backspace] 'help-command)
|
||||
(define-key viper-replace-map [backspace] 'help-command)
|
||||
(define-key viper-insert-basic-map [(control h)] 'help-command)
|
||||
(define-key viper-replace-map [(control h)] 'help-command))
|
||||
(define-key viper-insert-basic-map
|
||||
[backspace] 'viper-del-backward-char-in-insert)
|
||||
(define-key viper-replace-map
|
||||
[backspace] 'viper-del-backward-char-in-replace)
|
||||
(define-key viper-insert-basic-map
|
||||
[(control h)] 'viper-del-backward-char-in-insert)
|
||||
(define-key viper-replace-map
|
||||
|
@ -343,7 +362,10 @@
|
|||
(t ; Vi state
|
||||
(setq viper-vi-diehard-minor-mode (not viper-want-emacs-keys-in-vi))
|
||||
(if viper-want-ctl-h-help
|
||||
(define-key viper-vi-basic-map [(control h)] 'help-command)
|
||||
(progn
|
||||
(define-key viper-vi-basic-map [backspace] 'help-command)
|
||||
(define-key viper-vi-basic-map [(control h)] 'help-command))
|
||||
(define-key viper-vi-basic-map [backspace] 'viper-backward-char)
|
||||
(define-key viper-vi-basic-map [(control h)] 'viper-backward-char)))
|
||||
))
|
||||
|
||||
|
@ -537,17 +559,12 @@
|
|||
(viper-over-whitespace-line))
|
||||
(indent-to-left-margin))
|
||||
(viper-add-newline-at-eob-if-necessary)
|
||||
(if viper-undo-needs-adjustment (viper-adjust-undo))
|
||||
(viper-adjust-undo)
|
||||
(viper-change-state 'vi-state)
|
||||
|
||||
;; always turn off iso-accents-mode, or else we won't be able to use the
|
||||
;; keys `,',^ in Vi state, as they will do accents instead of Vi actions.
|
||||
(if (and (boundp 'iso-accents-mode) iso-accents-mode)
|
||||
(iso-accents-mode -1))
|
||||
|
||||
(viper-restore-cursor-color-after-insert)
|
||||
|
||||
;; Protection against user errors in hooks
|
||||
;; Protect against user errors in hooks
|
||||
(condition-case conds
|
||||
(run-hooks 'viper-vi-state-hook)
|
||||
(error
|
||||
|
@ -557,8 +574,6 @@
|
|||
"Change Viper state to Insert."
|
||||
(interactive)
|
||||
(viper-change-state 'insert-state)
|
||||
(if (and viper-automatic-iso-accents (fboundp 'iso-accents-mode))
|
||||
(iso-accents-mode 1)) ; turn iso accents on
|
||||
|
||||
(or (stringp viper-saved-cursor-color)
|
||||
(string= (viper-get-cursor-color) viper-insert-state-cursor-color)
|
||||
|
@ -568,7 +583,8 @@
|
|||
;; bug related to local variables?
|
||||
;;;(if (stringp viper-saved-cursor-color)
|
||||
;;; (viper-change-cursor-color viper-insert-state-cursor-color))
|
||||
;; Protection against user errors in hooks
|
||||
|
||||
;; Protect against user errors in hooks
|
||||
(condition-case conds
|
||||
(run-hooks 'viper-insert-state-hook)
|
||||
(error
|
||||
|
@ -584,8 +600,6 @@
|
|||
;; replace state changes to insert state.
|
||||
(defun viper-change-state-to-replace (&optional non-R-cmd)
|
||||
(viper-change-state 'replace-state)
|
||||
(if (and viper-automatic-iso-accents (fboundp 'iso-accents-mode))
|
||||
(iso-accents-mode 1)) ; turn iso accents on
|
||||
;; Run insert-state-hook
|
||||
(condition-case conds
|
||||
(run-hooks 'viper-insert-state-hook 'viper-replace-state-hook)
|
||||
|
@ -603,10 +617,8 @@
|
|||
"Change Viper state to Emacs."
|
||||
(interactive)
|
||||
(viper-change-state 'emacs-state)
|
||||
(if (and viper-automatic-iso-accents (fboundp 'iso-accents-mode))
|
||||
(iso-accents-mode 1)) ; turn iso accents on
|
||||
|
||||
;; Protection agains user errors in hooks
|
||||
;; Protect agains user errors in hooks
|
||||
(condition-case conds
|
||||
(run-hooks 'viper-emacs-state-hook)
|
||||
(error
|
||||
|
@ -1395,12 +1407,12 @@ If the prefix argument, ARG, is non-nil, it is used instead of `val'."
|
|||
(funcall m-com (cons val com))
|
||||
(cond ((and (< save-point (point)) viper-keep-point-on-repeat)
|
||||
(goto-char save-point)) ; go back to before repeat.
|
||||
((and (< save-point (point)) viper-ex-style-editing-in-insert)
|
||||
((and (< save-point (point)) viper-ex-style-editing)
|
||||
(or (bolp) (backward-char 1))))
|
||||
(if (and (eolp) (not (bolp)))
|
||||
(backward-char 1))
|
||||
))
|
||||
(if viper-undo-needs-adjustment (viper-adjust-undo)) ; take care of undo
|
||||
(viper-adjust-undo) ; take care of undo
|
||||
;; If the prev cmd was rotating the command ring, this means that `.' has
|
||||
;; just executed a command from that ring. So, push it on the ring again.
|
||||
;; If we are just executing previous command , then don't push viper-d-com
|
||||
|
@ -1495,8 +1507,8 @@ invokes the command before that, etc."
|
|||
(viper-sit-for-short 300)
|
||||
(goto-char undo-end-posn)
|
||||
(viper-sit-for-short 300)
|
||||
(if (and (> (abs (- undo-beg-posn before-undo-pt)) 1)
|
||||
(> (abs (- undo-end-posn before-undo-pt)) 1))
|
||||
(if (and (> (viper-chars-in-region undo-beg-posn before-undo-pt) 1)
|
||||
(> (viper-chars-in-region undo-end-posn before-undo-pt) 1))
|
||||
(goto-char before-undo-pt)
|
||||
(goto-char undo-beg-posn)))
|
||||
(push-mark before-undo-pt t))
|
||||
|
@ -1518,24 +1530,26 @@ invokes the command before that, etc."
|
|||
;; In VI, unlike Emacs, if you open a line, say, and add a bunch of lines,
|
||||
;; they are undone all at once.
|
||||
(defun viper-adjust-undo ()
|
||||
(let ((inhibit-quit t)
|
||||
tmp tmp2)
|
||||
(setq viper-undo-needs-adjustment nil)
|
||||
(if (listp buffer-undo-list)
|
||||
(if (setq tmp (memq viper-buffer-undo-list-mark buffer-undo-list))
|
||||
(progn
|
||||
(setq tmp2 (cdr tmp)) ; the part after mark
|
||||
|
||||
;; cut tail from buffer-undo-list temporarily by direct
|
||||
;; manipulation with pointers in buffer-undo-list
|
||||
(setcdr tmp nil)
|
||||
|
||||
(setq buffer-undo-list (delq nil buffer-undo-list))
|
||||
(setq buffer-undo-list
|
||||
(delq viper-buffer-undo-list-mark buffer-undo-list))
|
||||
;; restore tail of buffer-undo-list
|
||||
(setq buffer-undo-list (nconc buffer-undo-list tmp2)))
|
||||
(setq buffer-undo-list (delq nil buffer-undo-list))))))
|
||||
(if viper-undo-needs-adjustment
|
||||
(let ((inhibit-quit t)
|
||||
tmp tmp2)
|
||||
(setq viper-undo-needs-adjustment nil)
|
||||
(if (listp buffer-undo-list)
|
||||
(if (setq tmp (memq viper-buffer-undo-list-mark buffer-undo-list))
|
||||
(progn
|
||||
(setq tmp2 (cdr tmp)) ; the part after mark
|
||||
|
||||
;; cut tail from buffer-undo-list temporarily by direct
|
||||
;; manipulation with pointers in buffer-undo-list
|
||||
(setcdr tmp nil)
|
||||
|
||||
(setq buffer-undo-list (delq nil buffer-undo-list))
|
||||
(setq buffer-undo-list
|
||||
(delq viper-buffer-undo-list-mark buffer-undo-list))
|
||||
;; restore tail of buffer-undo-list
|
||||
(setq buffer-undo-list (nconc buffer-undo-list tmp2)))
|
||||
(setq buffer-undo-list (delq nil buffer-undo-list)))))
|
||||
))
|
||||
|
||||
|
||||
(defun viper-set-complex-command-for-undo ()
|
||||
|
@ -1560,7 +1574,11 @@ invokes the command before that, etc."
|
|||
(concat "`" (viper-array-to-string keys) "'")
|
||||
(viper-abbreviate-string
|
||||
(if viper-xemacs-p
|
||||
(replace-in-string text "\n" "^J")
|
||||
(replace-in-string
|
||||
(cond ((characterp text) (char-to-string text))
|
||||
((stringp text) text)
|
||||
(t ""))
|
||||
"\n" "^J")
|
||||
text)
|
||||
max-text-len
|
||||
" inserting `" "'" " ......."))
|
||||
|
@ -1892,7 +1910,6 @@ Undo previous insertion and inserts new."
|
|||
(let ((col (current-indentation)))
|
||||
(if (equal com ?r)
|
||||
(viper-loop val
|
||||
(progn
|
||||
(end-of-line)
|
||||
(newline 1)
|
||||
(if viper-auto-indent
|
||||
|
@ -1902,7 +1919,7 @@ Undo previous insertion and inserts new."
|
|||
(indent-according-to-mode)
|
||||
(indent-to col))
|
||||
))
|
||||
(viper-yank-last-insertion)))
|
||||
(viper-yank-last-insertion))
|
||||
(end-of-line)
|
||||
(newline 1)
|
||||
(if viper-auto-indent
|
||||
|
@ -1923,7 +1940,6 @@ Undo previous insertion and inserts new."
|
|||
(let ((col (current-indentation)))
|
||||
(if (equal com ?r)
|
||||
(viper-loop val
|
||||
(progn
|
||||
(beginning-of-line)
|
||||
(open-line 1)
|
||||
(if viper-auto-indent
|
||||
|
@ -1933,7 +1949,7 @@ Undo previous insertion and inserts new."
|
|||
(indent-according-to-mode)
|
||||
(indent-to col))
|
||||
))
|
||||
(viper-yank-last-insertion)))
|
||||
(viper-yank-last-insertion))
|
||||
(beginning-of-line)
|
||||
(open-line 1)
|
||||
(if viper-auto-indent
|
||||
|
@ -1955,9 +1971,8 @@ Undo previous insertion and inserts new."
|
|||
(list 'viper-open-line-at-point val ?r nil nil nil))
|
||||
(if (equal com ?r)
|
||||
(viper-loop val
|
||||
(progn
|
||||
(open-line 1)
|
||||
(viper-yank-last-insertion)))
|
||||
(viper-yank-last-insertion))
|
||||
(open-line 1)
|
||||
(viper-change-state-to-insert))))
|
||||
|
||||
|
@ -1985,8 +2000,7 @@ Undo previous insertion and inserts new."
|
|||
(defun viper-start-replace ()
|
||||
(setq viper-began-as-replace t
|
||||
viper-sitting-in-replace t
|
||||
viper-replace-chars-to-delete 0
|
||||
viper-replace-chars-deleted 0)
|
||||
viper-replace-chars-to-delete 0)
|
||||
(viper-add-hook
|
||||
'viper-after-change-functions 'viper-replace-mode-spy-after t)
|
||||
(viper-add-hook
|
||||
|
@ -2007,90 +2021,86 @@ Undo previous insertion and inserts new."
|
|||
)
|
||||
|
||||
|
||||
;; checks how many chars were deleted by the last change
|
||||
(defun viper-replace-mode-spy-before (beg end)
|
||||
(setq viper-replace-chars-deleted
|
||||
(- end beg
|
||||
(max 0 (- end (viper-replace-end)))
|
||||
(max 0 (- (viper-replace-start) beg))
|
||||
)))
|
||||
(setq viper-replace-region-chars-deleted (viper-chars-in-region beg end))
|
||||
)
|
||||
|
||||
;; Invoked as an after-change-function to set up parameters of the last change
|
||||
;; Invoked as an after-change-function to calculate how many chars have to be
|
||||
;; deleted. This function may be called several times within a single command,
|
||||
;; if this command performs several separate buffer changes. Therefore, if adds
|
||||
;; up the number of chars inserted and subtracts the number of chars deleted.
|
||||
(defun viper-replace-mode-spy-after (beg end length)
|
||||
(if (memq viper-intermediate-command '(repeating-insertion-from-ring))
|
||||
(if (memq viper-intermediate-command
|
||||
'(dabbrev-expand repeating-insertion-from-ring))
|
||||
;; Take special care of text insertion from insertion ring inside
|
||||
;; replacement overlays.
|
||||
(progn
|
||||
(setq viper-replace-chars-to-delete 0)
|
||||
(viper-move-marker-locally
|
||||
'viper-last-posn-in-replace-region (point)))
|
||||
|
||||
(let (beg-col end-col real-end chars-to-delete)
|
||||
(setq real-end (min end (viper-replace-end)))
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(setq beg-col (current-column))
|
||||
(goto-char real-end)
|
||||
(setq end-col (current-column)))
|
||||
|
||||
;; If beg of change is outside the replacement region, then don't
|
||||
;; delete anything in the repl region (set chars-to-delete to 0).
|
||||
;;
|
||||
;; This works fine except that we have to take special care of
|
||||
;; dabbrev-expand. The problem stems from new-dabbrev.el, which
|
||||
;; sometimes simply shifts the repl region rightwards, without
|
||||
;; deleting an equal amount of characters.
|
||||
;;
|
||||
;; The reason why new-dabbrev.el causes this are this:
|
||||
;; if one dinamically completes a partial word that starts before the
|
||||
;; replacement region (but ends inside) then new-dabbrev.el first
|
||||
;; moves cursor backwards, to the beginning of the word to be
|
||||
;; completed (say, pt A). Then it inserts the
|
||||
;; completed word and then deletes the old, incomplete part.
|
||||
;; Since the complete word is inserted at position before the repl
|
||||
;; region, the next If-statement would have set chars-to-delete to 0
|
||||
;; unless we check for the current command, which must be
|
||||
;; dabbrev-expand.
|
||||
;;
|
||||
;; In fact, it might be also useful to have overlays for insert
|
||||
;; regions as well, since this will let us capture the situation when
|
||||
;; dabbrev-expand goes back past the insertion point to find the
|
||||
;; beginning of the word to be expanded.
|
||||
(if (or (and (<= (viper-replace-start) beg)
|
||||
(<= beg (viper-replace-end)))
|
||||
(and (= length 0) (eq this-command 'dabbrev-expand)))
|
||||
(setq chars-to-delete
|
||||
(max (- end-col beg-col) (- real-end beg) 0))
|
||||
(setq chars-to-delete 0))
|
||||
|
||||
;; if beg = last change position, it means that we are within the
|
||||
;; same command that does multiple changes. Moreover, it means
|
||||
;; that we have two subsequent changes (insert/delete) that
|
||||
;; complement each other.
|
||||
(if (= beg (marker-position viper-last-posn-in-replace-region))
|
||||
(setq viper-replace-chars-to-delete
|
||||
(- (+ chars-to-delete viper-replace-chars-to-delete)
|
||||
viper-replace-chars-deleted))
|
||||
(setq viper-replace-chars-to-delete chars-to-delete))
|
||||
|
||||
(let* ((real-end (min end (viper-replace-end)))
|
||||
(column-shift (- (save-excursion (goto-char real-end)
|
||||
(current-column))
|
||||
(save-excursion (goto-char beg)
|
||||
(current-column))))
|
||||
(chars-deleted 0))
|
||||
|
||||
(if (> length 0)
|
||||
(setq chars-deleted viper-replace-region-chars-deleted))
|
||||
(setq viper-replace-region-chars-deleted 0)
|
||||
(setq viper-replace-chars-to-delete
|
||||
(+ viper-replace-chars-to-delete
|
||||
(-
|
||||
;; if column shift is bigger, due to a TAB insertion, take
|
||||
;; column-shift instead of the number of inserted chars
|
||||
(max (viper-chars-in-region beg real-end)
|
||||
;; This test accounts for Chinese/Japanese/... chars,
|
||||
;; which occupy 2 columns instead of one. If we use
|
||||
;; column-shift here, we may delete two chars instead of
|
||||
;; one when the user types one Chinese character. Deleting
|
||||
;; two would be OK, if they were European chars, but it is
|
||||
;; not OK if they are Chinese chars. Since it is hard to
|
||||
;; figure out which characters are being deleted in any
|
||||
;; given region, we decided to treat Eastern and European
|
||||
;; characters equally, even though Eastern chars may
|
||||
;; occupy more columns.
|
||||
(if (memq this-command '(self-insert-command
|
||||
quoted-insert viper-insert-tab))
|
||||
column-shift
|
||||
0))
|
||||
;; the number of deleted chars
|
||||
chars-deleted)))
|
||||
|
||||
(viper-move-marker-locally
|
||||
'viper-last-posn-in-replace-region
|
||||
(max (if (> end (viper-replace-end)) (viper-replace-start) end)
|
||||
(max (if (> end (viper-replace-end)) (viper-replace-end) end)
|
||||
(or (marker-position viper-last-posn-in-replace-region)
|
||||
(viper-replace-start))
|
||||
))
|
||||
|
||||
(setq viper-replace-chars-to-delete
|
||||
(max 0
|
||||
(min viper-replace-chars-to-delete
|
||||
(- (viper-replace-end) viper-last-posn-in-replace-region)
|
||||
(- (viper-line-pos 'end)
|
||||
viper-last-posn-in-replace-region)
|
||||
)))
|
||||
)))
|
||||
|
||||
;; Make sure we don't delete more than needed.
|
||||
;; This is executed at viper-last-posn-in-replace-region
|
||||
(defsubst viper-trim-replace-chars-to-delete-if-necessary ()
|
||||
(setq viper-replace-chars-to-delete
|
||||
(max 0
|
||||
(min viper-replace-chars-to-delete
|
||||
;; Don't delete more than to the end of repl overlay
|
||||
(viper-chars-in-region
|
||||
(viper-replace-end) viper-last-posn-in-replace-region)
|
||||
;; point is viper-last-posn-in-replace-region now
|
||||
;; So, this limits deletion to the end of line
|
||||
(viper-chars-in-region (point) (viper-line-pos 'end))
|
||||
))))
|
||||
|
||||
;; Delete stuff between posn and the end of viper-replace-overlay-marker, if
|
||||
;; posn is within the overlay.
|
||||
(defun viper-finish-change (posn)
|
||||
|
||||
;; Delete stuff between viper-last-posn-in-replace-region and the end of
|
||||
;; viper-replace-overlay-marker, if viper-last-posn-in-replace-region is within
|
||||
;; the overlay and current point is before the end of the overlay.
|
||||
;; Don't delete anything if current point is past the end of the overlay.
|
||||
(defun viper-finish-change ()
|
||||
(viper-remove-hook
|
||||
'viper-after-change-functions 'viper-replace-mode-spy-after)
|
||||
(viper-remove-hook
|
||||
|
@ -2102,12 +2112,13 @@ Undo previous insertion and inserts new."
|
|||
(viper-restore-cursor-color-after-replace)
|
||||
(setq viper-sitting-in-replace nil) ; just in case we'll need to know it
|
||||
(save-excursion
|
||||
(if (and
|
||||
viper-replace-overlay
|
||||
(>= posn (viper-replace-start))
|
||||
(< posn (viper-replace-end)))
|
||||
(delete-region posn (viper-replace-end)))
|
||||
)
|
||||
(if (and viper-replace-overlay
|
||||
(viper-pos-within-region viper-last-posn-in-replace-region
|
||||
(viper-replace-start)
|
||||
(viper-replace-end))
|
||||
(< (point) (viper-replace-end)))
|
||||
(delete-region
|
||||
viper-last-posn-in-replace-region (viper-replace-end))))
|
||||
|
||||
(if (eq viper-current-state 'replace-state)
|
||||
(viper-downgrade-to-insert))
|
||||
|
@ -2150,9 +2161,9 @@ Undo previous insertion and inserts new."
|
|||
"Binding for keys that cause Replace state to switch to Vi or to Insert.
|
||||
These keys are ESC, RET, and LineFeed"
|
||||
(interactive)
|
||||
(if overwrite-mode ;; If you are in replace mode invoked via 'R'
|
||||
(if overwrite-mode ; if in replace mode invoked via 'R'
|
||||
(viper-finish-R-mode)
|
||||
(viper-finish-change viper-last-posn-in-replace-region))
|
||||
(viper-finish-change))
|
||||
(let (com)
|
||||
(if (eq this-command 'viper-intercept-ESC-key)
|
||||
(setq com 'viper-exit-insert-state)
|
||||
|
@ -2269,29 +2280,66 @@ These keys are ESC, RET, and LineFeed"
|
|||
(com (viper-getcom arg)))
|
||||
(viper-replace-char-subr com val)
|
||||
(if (and (eolp) (not (bolp))) (forward-char 1))
|
||||
(setq viper-this-command-keys
|
||||
(format "%sr" (if (integerp arg) arg "")))
|
||||
(viper-set-destructive-command
|
||||
(list 'viper-replace-char val ?r nil viper-d-char nil))
|
||||
))
|
||||
|
||||
(defun viper-replace-char-subr (com arg)
|
||||
(let ((take-care-of-iso-accents
|
||||
(and (boundp 'iso-accents-mode) viper-automatic-iso-accents))
|
||||
char)
|
||||
(let (char)
|
||||
(setq char (if (equal com ?r)
|
||||
viper-d-char
|
||||
(read-char)))
|
||||
(if (and take-care-of-iso-accents (memq char '(?' ?\" ?^ ?~)))
|
||||
;; get European characters
|
||||
(progn
|
||||
(iso-accents-mode 1)
|
||||
(viper-set-unread-command-events char)
|
||||
(setq char (aref (read-key-sequence nil) 0))
|
||||
(iso-accents-mode -1)))
|
||||
(delete-char arg t)
|
||||
(setq viper-d-char char)
|
||||
(viper-loop (if (> arg 0) arg (- arg))
|
||||
(if (eq char ?\C-m) (insert "\n") (insert char)))
|
||||
(backward-char arg)))
|
||||
(let (inhibit-quit) ; preserve consistency of undo-list and iso-accents
|
||||
(if (and viper-automatic-iso-accents (memq char '(?' ?\" ?^ ?~)))
|
||||
;; get European characters
|
||||
(progn
|
||||
(viper-set-iso-accents-mode t)
|
||||
(viper-set-unread-command-events char)
|
||||
(setq char (aref (read-key-sequence nil) 0))
|
||||
(viper-set-iso-accents-mode nil)))
|
||||
(viper-set-complex-command-for-undo)
|
||||
(if (eq char ?\C-m) (setq char ?\n))
|
||||
(if (and viper-special-input-method (fboundp 'quail-start-translation))
|
||||
;; get Intl. characters
|
||||
(progn
|
||||
(viper-set-input-method t)
|
||||
(setq last-command-event
|
||||
(viper-copy-event
|
||||
(if viper-xemacs-p (character-to-event char) char)))
|
||||
(delete-char 1 t)
|
||||
(condition-case nil
|
||||
(if com
|
||||
(insert char)
|
||||
(if viper-emacs-p
|
||||
(quail-start-translation 1)
|
||||
(quail-start-translation)))
|
||||
(error))
|
||||
;; quail translation failed
|
||||
(if (and (not (stringp quail-current-str))
|
||||
(not (viper-characterp quail-current-str)))
|
||||
(progn
|
||||
(viper-adjust-undo)
|
||||
(undo-start)
|
||||
(undo-more 1)
|
||||
(viper-set-input-method nil)
|
||||
(error "Composing character failed, changes undone")))
|
||||
;; quail translation seems ok
|
||||
(or com
|
||||
;;(setq char quail-current-str))
|
||||
(setq char (viper-char-at-pos 'backward)))
|
||||
(setq viper-d-char char)
|
||||
(viper-loop (1- (if (> arg 0) arg (- arg)))
|
||||
(delete-char 1 t)
|
||||
(insert char))
|
||||
(viper-set-input-method nil))
|
||||
(delete-char arg t)
|
||||
(setq viper-d-char char)
|
||||
(viper-loop (if (> arg 0) arg (- arg))
|
||||
(insert char)))
|
||||
(viper-adjust-undo)
|
||||
(backward-char arg))))
|
||||
|
||||
|
||||
;; basic cursor movement. j, k, l, h commands.
|
||||
|
@ -2334,18 +2382,30 @@ On reaching beginning of line, stop and signal error."
|
|||
(if com (viper-execute-com 'viper-backward-char val com)))))
|
||||
|
||||
;; Like forward-char, but doesn't move at end of buffer.
|
||||
;; Returns distance traveled
|
||||
;; (positive or 0, if arg positive; negative if arg negative).
|
||||
(defun viper-forward-char-carefully (&optional arg)
|
||||
(setq arg (or arg 1))
|
||||
(if (>= (point-max) (+ (point) arg))
|
||||
(forward-char arg)
|
||||
(goto-char (point-max))))
|
||||
(let ((pt (point)))
|
||||
(condition-case nil
|
||||
(forward-char arg)
|
||||
(error))
|
||||
(if (< (point) pt) ; arg was negative
|
||||
(- (viper-chars-in-region pt (point)))
|
||||
(viper-chars-in-region pt (point)))))
|
||||
|
||||
;; Like backward-char, but doesn't move at end of buffer.
|
||||
;; Like backward-char, but doesn't move at beg of buffer.
|
||||
;; Returns distance traveled
|
||||
;; (negative or 0, if arg positive; positive if arg negative).
|
||||
(defun viper-backward-char-carefully (&optional arg)
|
||||
(setq arg (or arg 1))
|
||||
(if (<= (point-min) (- (point) arg))
|
||||
(backward-char arg)
|
||||
(goto-char (point-min))))
|
||||
(let ((pt (point)))
|
||||
(condition-case nil
|
||||
(backward-char arg)
|
||||
(error))
|
||||
(if (> (point) pt) ; arg was negative
|
||||
(viper-chars-in-region pt (point))
|
||||
(- (viper-chars-in-region pt (point))))))
|
||||
|
||||
(defun viper-next-line-carefully (arg)
|
||||
(condition-case nil
|
||||
|
@ -2372,7 +2432,7 @@ On reaching beginning of line, stop and signal error."
|
|||
(forward-char)
|
||||
(viper-skip-all-separators-forward 'within-line))))
|
||||
(viper-skip-all-separators-backward 'within-line)
|
||||
(backward-char)
|
||||
(viper-backward-char-carefully)
|
||||
(if (looking-at "\n")
|
||||
(viper-skip-all-separators-backward 'within-line)
|
||||
(forward-char))))
|
||||
|
@ -2389,16 +2449,43 @@ On reaching beginning of line, stop and signal error."
|
|||
(viper-skip-separators t)))
|
||||
(setq val (1- val))))
|
||||
|
||||
;; first search backward for pat. Then skip chars backwards using aux-pat
|
||||
(defun viper-fwd-skip (pat aux-pat lim)
|
||||
(if (and (save-excursion
|
||||
(re-search-backward pat lim t))
|
||||
(= (point) (match-end 0)))
|
||||
(goto-char (match-beginning 0)))
|
||||
(skip-chars-backward aux-pat lim)
|
||||
(if (= (point) lim)
|
||||
(viper-forward-char-carefully))
|
||||
)
|
||||
;; first skip non-newline separators backward, then skip \n. Then, if TWICE is
|
||||
;; non-nil, skip non-\n back again, but don't overshoot the limit LIM.
|
||||
(defun viper-separator-skipback-special (twice lim)
|
||||
(let ((prev-char (viper-char-at-pos 'backward))
|
||||
(saved-point (point)))
|
||||
;; skip non-newline separators backward
|
||||
(while (and (not (memq prev-char '(nil \n)))
|
||||
(< lim (point))
|
||||
;; must be non-newline separator
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(memq prev-char '(?\ ?\t))
|
||||
(memq (char-syntax prev-char) '(?\ ?-))))
|
||||
(viper-backward-char-carefully)
|
||||
(setq prev-char (viper-char-at-pos 'backward)))
|
||||
|
||||
(if (and (< lim (point)) (eq prev-char ?\n))
|
||||
(backward-char)
|
||||
;; If we skipped to the next word and the prefix of this line doesn't
|
||||
;; consist of separators preceded by a newline, then don't skip backwards
|
||||
;; at all.
|
||||
(goto-char saved-point))
|
||||
(setq prev-char (viper-char-at-pos 'backward))
|
||||
|
||||
;; skip again, but make sure we don't overshoot the limit
|
||||
(if twice
|
||||
(while (and (not (memq prev-char '(nil \n)))
|
||||
(< lim (point))
|
||||
;; must be non-newline separator
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(memq prev-char '(?\ ?\t))
|
||||
(memq (char-syntax prev-char) '(?\ ?-))))
|
||||
(viper-backward-char-carefully)
|
||||
(setq prev-char (viper-char-at-pos 'backward))))
|
||||
|
||||
(if (= (point) lim)
|
||||
(viper-forward-char-carefully))
|
||||
))
|
||||
|
||||
|
||||
(defun viper-forward-word (arg)
|
||||
|
@ -2411,12 +2498,12 @@ On reaching beginning of line, stop and signal error."
|
|||
(viper-forward-word-kernel val)
|
||||
(if com (progn
|
||||
(cond ((memq com (list ?c (- ?c)))
|
||||
(viper-fwd-skip "\n[ \t]*" " \t" viper-com-point))
|
||||
(viper-separator-skipback-special 'twice viper-com-point))
|
||||
;; Yank words including the whitespace, but not newline
|
||||
((memq com (list ?y (- ?y)))
|
||||
(viper-fwd-skip "\n[ \t]*" "" viper-com-point))
|
||||
(viper-separator-skipback-special nil viper-com-point))
|
||||
((viper-dotable-command-p com)
|
||||
(viper-fwd-skip "\n[ \t]*" "" viper-com-point)))
|
||||
(viper-separator-skipback-special nil viper-com-point)))
|
||||
(viper-execute-com 'viper-forward-word val com)))))
|
||||
|
||||
|
||||
|
@ -2428,17 +2515,16 @@ On reaching beginning of line, stop and signal error."
|
|||
(com (viper-getcom arg)))
|
||||
(if com (viper-move-marker-locally 'viper-com-point (point)))
|
||||
(viper-loop val
|
||||
(progn
|
||||
(viper-skip-nonseparators 'forward)
|
||||
(viper-skip-separators t)))
|
||||
(viper-skip-separators t))
|
||||
(if com (progn
|
||||
(cond ((memq com (list ?c (- ?c)))
|
||||
(viper-fwd-skip "\n[ \t]*" " \t" viper-com-point))
|
||||
(viper-separator-skipback-special 'twice viper-com-point))
|
||||
;; Yank words including the whitespace, but not newline
|
||||
((memq com (list ?y (- ?y)))
|
||||
(viper-fwd-skip "\n[ \t]*" "" viper-com-point))
|
||||
(viper-separator-skipback-special nil viper-com-point))
|
||||
((viper-dotable-command-p com)
|
||||
(viper-fwd-skip "\n[ \t]*" "" viper-com-point)))
|
||||
(viper-separator-skipback-special nil viper-com-point)))
|
||||
(viper-execute-com 'viper-forward-Word val com)))))
|
||||
|
||||
|
||||
|
@ -2485,10 +2571,9 @@ On reaching beginning of line, stop and signal error."
|
|||
(com (viper-getcom arg)))
|
||||
(if com (viper-move-marker-locally 'viper-com-point (point)))
|
||||
(viper-loop val
|
||||
(progn
|
||||
(viper-end-of-word-kernel)
|
||||
(viper-skip-nonseparators 'forward)
|
||||
(backward-char)))
|
||||
(backward-char))
|
||||
(if com
|
||||
(progn
|
||||
(forward-char)
|
||||
|
@ -2496,17 +2581,18 @@ On reaching beginning of line, stop and signal error."
|
|||
|
||||
(defun viper-backward-word-kernel (val)
|
||||
(while (> val 0)
|
||||
(backward-char)
|
||||
(viper-backward-char-carefully)
|
||||
(cond ((viper-looking-at-alpha)
|
||||
(viper-skip-alpha-backward "_"))
|
||||
((viper-looking-at-separator)
|
||||
(forward-char)
|
||||
(viper-skip-separators nil)
|
||||
(backward-char)
|
||||
(viper-backward-char-carefully)
|
||||
(cond ((viper-looking-at-alpha)
|
||||
(viper-skip-alpha-backward "_"))
|
||||
((not (viper-looking-at-alphasep))
|
||||
(viper-skip-nonalphasep-backward))
|
||||
((bobp)) ; could still be at separator, but at beg of buffer
|
||||
(t (forward-char))))
|
||||
((not (viper-looking-at-alphasep))
|
||||
(viper-skip-nonalphasep-backward)))
|
||||
|
@ -2540,9 +2626,8 @@ On reaching beginning of line, stop and signal error."
|
|||
(viper-move-marker-locally 'viper-com-point (point))
|
||||
(if i (forward-char))))
|
||||
(viper-loop val
|
||||
(progn
|
||||
(viper-skip-separators nil)
|
||||
(viper-skip-nonseparators 'backward)))
|
||||
(viper-skip-separators nil) ; nil means backward here
|
||||
(viper-skip-nonseparators 'backward))
|
||||
(if com (viper-execute-com 'viper-backward-Word val com))))
|
||||
|
||||
|
||||
|
@ -2593,7 +2678,9 @@ On reaching beginning of line, stop and signal error."
|
|||
(let ((val (viper-p-val arg))
|
||||
(com (viper-getcom arg))
|
||||
line-len)
|
||||
(setq line-len (- (viper-line-pos 'end) (viper-line-pos 'start)))
|
||||
(setq line-len
|
||||
(viper-chars-in-region
|
||||
(viper-line-pos 'start) (viper-line-pos 'end)))
|
||||
(if com (viper-move-marker-locally 'viper-com-point (point)))
|
||||
(beginning-of-line)
|
||||
(forward-char (1- (min line-len val)))
|
||||
|
@ -2733,7 +2820,10 @@ On reaching beginning of line, stop and signal error."
|
|||
(search-forward (char-to-string char) nil 0 arg))
|
||||
(setq point (point))
|
||||
(error "Command `%s': `%c' not found" cmd char))))
|
||||
(goto-char (+ point (if (> arg 0) (if offset -2 -1) (if offset 1 0))))))
|
||||
(goto-char point)
|
||||
(if (> arg 0)
|
||||
(backward-char (if offset 2 1))
|
||||
(forward-char (if offset 1 0)))))
|
||||
|
||||
(defun viper-find-char-forward (arg)
|
||||
"Find char on the line.
|
||||
|
@ -3696,67 +3786,68 @@ To turn this feature off, set this variable to nil."
|
|||
|
||||
|
||||
(defun viper-delete-char (arg)
|
||||
"Delete character."
|
||||
"Delete next character."
|
||||
(interactive "P")
|
||||
(let ((val (viper-p-val arg)))
|
||||
(let ((val (viper-p-val arg))
|
||||
end-del-pos)
|
||||
(viper-set-destructive-command
|
||||
(list 'viper-delete-char val nil nil nil nil))
|
||||
(if (> val 1)
|
||||
(save-excursion
|
||||
(let ((here (point)))
|
||||
(end-of-line)
|
||||
(if (> val (- (point) here))
|
||||
(setq val (- (point) here))))))
|
||||
(if (and (eq val 0) (not viper-ex-style-motion)) (setq val 1))
|
||||
(if (and viper-ex-style-editing
|
||||
(> val (viper-chars-in-region (point) (viper-line-pos 'end))))
|
||||
(setq val (viper-chars-in-region (point) (viper-line-pos 'end))))
|
||||
(if (and viper-ex-style-motion (eolp))
|
||||
(if (bolp) (error "") (setq val 0))) ; not bol---simply back 1 ch
|
||||
(save-excursion
|
||||
(viper-forward-char-carefully val)
|
||||
(setq end-del-pos (point)))
|
||||
(if viper-use-register
|
||||
(progn
|
||||
(cond ((viper-valid-register viper-use-register '((Letter)))
|
||||
(viper-append-to-register
|
||||
(downcase viper-use-register) (point) (- (point) val)))
|
||||
(downcase viper-use-register) (point) end-del-pos))
|
||||
((viper-valid-register viper-use-register)
|
||||
(copy-to-register
|
||||
viper-use-register (point) (- (point) val) nil))
|
||||
viper-use-register (point) end-del-pos nil))
|
||||
(t (error viper-InvalidRegister viper-use-register)))
|
||||
(setq viper-use-register nil)))
|
||||
|
||||
(delete-char val t)
|
||||
(if viper-ex-style-motion
|
||||
(progn
|
||||
(delete-char val t)
|
||||
(if (and (eolp) (not (bolp))) (backward-char 1)))
|
||||
(if (eolp)
|
||||
(delete-backward-char val t)
|
||||
(delete-char val t)))))
|
||||
(if (and (eolp) (not (bolp))) (backward-char 1)))
|
||||
))
|
||||
|
||||
(defun viper-delete-backward-char (arg)
|
||||
"Delete previous character. On reaching beginning of line, stop and beep."
|
||||
(interactive "P")
|
||||
(let ((val (viper-p-val arg)))
|
||||
(let ((val (viper-p-val arg))
|
||||
end-del-pos)
|
||||
(viper-set-destructive-command
|
||||
(list 'viper-delete-backward-char val nil nil nil nil))
|
||||
(if (> val 1)
|
||||
(save-excursion
|
||||
(let ((here (point)))
|
||||
(beginning-of-line)
|
||||
(if (> val (- here (point)))
|
||||
(setq val (- here (point)))))))
|
||||
(if (and
|
||||
viper-ex-style-editing
|
||||
(> val (viper-chars-in-region (viper-line-pos 'start) (point))))
|
||||
(setq val (viper-chars-in-region (viper-line-pos 'start) (point))))
|
||||
(save-excursion
|
||||
(viper-backward-char-carefully val)
|
||||
(setq end-del-pos (point)))
|
||||
(if viper-use-register
|
||||
(progn
|
||||
(cond ((viper-valid-register viper-use-register '(Letter))
|
||||
(viper-append-to-register
|
||||
(downcase viper-use-register) (point) (+ (point) val)))
|
||||
(downcase viper-use-register) end-del-pos (point)))
|
||||
((viper-valid-register viper-use-register)
|
||||
(copy-to-register
|
||||
viper-use-register (point) (+ (point) val) nil))
|
||||
viper-use-register end-del-pos (point) nil))
|
||||
(t (error viper-InvalidRegister viper-use-register)))
|
||||
(setq viper-use-register nil)))
|
||||
(if (bolp) (ding)
|
||||
(delete-backward-char val t))))
|
||||
(if (and (bolp) viper-ex-style-editing)
|
||||
(ding))
|
||||
(delete-backward-char val t)))
|
||||
|
||||
(defun viper-del-backward-char-in-insert ()
|
||||
"Delete 1 char backwards while in insert mode."
|
||||
(interactive)
|
||||
(if (and viper-ex-style-editing-in-insert (bolp))
|
||||
(if (and viper-ex-style-editing (bolp))
|
||||
(beep 1)
|
||||
(delete-backward-char 1 t)))
|
||||
|
||||
|
@ -3764,19 +3855,19 @@ To turn this feature off, set this variable to nil."
|
|||
"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
|
||||
to Vi. The variable `viper-ex-style-editing-in-insert', if t, doesn't let the
|
||||
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))
|
||||
(delete-backward-char 1 t))
|
||||
(viper-ex-style-editing-in-insert
|
||||
(viper-ex-style-editing
|
||||
(beep 1))
|
||||
((bobp)
|
||||
(beep 1))
|
||||
(t
|
||||
(delete-backward-char 1 t))))
|
||||
(viper-ex-style-editing-in-insert
|
||||
(viper-ex-style-editing
|
||||
(if (bolp)
|
||||
(beep 1)
|
||||
(backward-char 1)))
|
||||
|
@ -3794,7 +3885,6 @@ cursor move past the beginning of line."
|
|||
(viper-set-destructive-command
|
||||
(list 'viper-join-lines val nil nil nil nil))
|
||||
(viper-loop (if (null val) 1 (1- val))
|
||||
(progn
|
||||
(end-of-line)
|
||||
(if (not (eobp))
|
||||
(progn
|
||||
|
@ -3806,7 +3896,7 @@ cursor move past the beginning of line."
|
|||
(or (looking-at " ")
|
||||
(insert " ")
|
||||
(backward-char 1))
|
||||
))))))
|
||||
)))))
|
||||
|
||||
|
||||
;; Replace state
|
||||
|
@ -4262,7 +4352,7 @@ sensitive for VI-style look-and-feel."
|
|||
|
||||
(setq viper-always t
|
||||
viper-ex-style-motion t
|
||||
viper-ex-style-editing-in-insert t
|
||||
viper-ex-style-editing t
|
||||
viper-want-ctl-h-help nil)
|
||||
|
||||
(cond ((eq viper-expert-level 1) ; novice or beginner
|
||||
|
@ -4289,14 +4379,14 @@ sensitive for VI-style look-and-feel."
|
|||
; and viper-no-multiple-ESC
|
||||
(progn
|
||||
(setq-default
|
||||
viper-ex-style-editing-in-insert
|
||||
(viper-standard-value 'viper-ex-style-editing-in-insert)
|
||||
viper-ex-style-editing
|
||||
(viper-standard-value 'viper-ex-style-editing)
|
||||
viper-ex-style-motion
|
||||
(viper-standard-value 'viper-ex-style-motion))
|
||||
(setq viper-ex-style-motion
|
||||
(viper-standard-value 'viper-ex-style-motion)
|
||||
viper-ex-style-editing-in-insert
|
||||
(viper-standard-value 'viper-ex-style-editing-in-insert)
|
||||
viper-ex-style-editing
|
||||
(viper-standard-value 'viper-ex-style-editing)
|
||||
viper-re-search
|
||||
(viper-standard-value 'viper-re-search)
|
||||
viper-no-multiple-ESC
|
||||
|
@ -4305,8 +4395,8 @@ sensitive for VI-style look-and-feel."
|
|||
;; A wizard!!
|
||||
;; Ideally, if 5 is selected, a buffer should pop up to let the
|
||||
;; user toggle the values of variables.
|
||||
(t (setq-default viper-ex-style-editing-in-insert
|
||||
(viper-standard-value 'viper-ex-style-editing-in-insert)
|
||||
(t (setq-default viper-ex-style-editing
|
||||
(viper-standard-value 'viper-ex-style-editing)
|
||||
viper-ex-style-motion
|
||||
(viper-standard-value 'viper-ex-style-motion))
|
||||
(setq viper-want-ctl-h-help
|
||||
|
@ -4317,8 +4407,8 @@ sensitive for VI-style look-and-feel."
|
|||
(viper-standard-value 'viper-no-multiple-ESC)
|
||||
viper-ex-style-motion
|
||||
(viper-standard-value 'viper-ex-style-motion)
|
||||
viper-ex-style-editing-in-insert
|
||||
(viper-standard-value 'viper-ex-style-editing-in-insert)
|
||||
viper-ex-style-editing
|
||||
(viper-standard-value 'viper-ex-style-editing)
|
||||
viper-re-search
|
||||
(viper-standard-value 'viper-re-search)
|
||||
viper-electric-mode
|
||||
|
@ -4366,7 +4456,7 @@ You can change it at any time by typing `M-x viper-set-expert-level RET'
|
|||
3 -- GRAND MASTER: Like 3, but most Emacs commands are available also
|
||||
in Viper's insert state.
|
||||
4 -- GURU: Like 3, but user settings are respected for viper-no-multiple-ESC,
|
||||
viper-ex-style-motion, viper-ex-style-editing-in-insert, and
|
||||
viper-ex-style-motion, viper-ex-style-editing, and
|
||||
viper-re-search variables. Adjust these settings to your taste.
|
||||
5 -- WIZARD: Like 4, but user settings are also respected for viper-always,
|
||||
viper-electric-mode, viper-want-ctl-h-help, viper-want-emacs-keys-in-vi,
|
||||
|
@ -4487,6 +4577,7 @@ Please, specify your level now: ")
|
|||
'viper-emacs-global-user-minor-mode
|
||||
'viper-emacs-state-modifier-minor-mode
|
||||
'viper-automatic-iso-accents
|
||||
'viper-special-input-method
|
||||
'viper-want-emacs-keys-in-insert
|
||||
'viper-want-emacs-keys-in-vi
|
||||
'viper-keep-point-on-undo
|
||||
|
@ -4494,7 +4585,7 @@ Please, specify your level now: ")
|
|||
'viper-electric-mode
|
||||
'viper-ESC-key
|
||||
'viper-want-ctl-h-help
|
||||
'viper-ex-style-editing-in-insert
|
||||
'viper-ex-style-editing
|
||||
'viper-delete-backwards-in-replace
|
||||
'viper-vi-style-in-minibuffer
|
||||
'viper-vi-state-hook
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
|
||||
;; compiler pacifier
|
||||
(defvar mark-even-if-inactive)
|
||||
(defvar quail-mode)
|
||||
(defvar iso-accents-mode)
|
||||
(defvar viper-current-state)
|
||||
(defvar viper-version)
|
||||
(defvar viper-expert-level)
|
||||
;; end pacifier
|
||||
|
@ -83,13 +86,15 @@ In all likelihood, you don't need to bother with this setting."
|
|||
(make-variable-buffer-local '(, var))
|
||||
)))
|
||||
|
||||
(defmacro viper-loop (count body)
|
||||
"(viper-loop COUNT BODY) Execute BODY COUNT times."
|
||||
(list 'let (list (list 'count count))
|
||||
(list 'while '(> count 0)
|
||||
body
|
||||
'(setq count (1- count))
|
||||
)))
|
||||
;; (viper-loop COUNT BODY) Execute BODY COUNT times.
|
||||
(defmacro viper-loop (count &rest body)
|
||||
(` (let ((count (, count)))
|
||||
(while (> count 0)
|
||||
(progn
|
||||
(,@ body)
|
||||
(setq count (1- count))
|
||||
))
|
||||
)))
|
||||
|
||||
(defmacro viper-buffer-live-p (buf)
|
||||
(` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf))))))
|
||||
|
@ -124,6 +129,19 @@ In all likelihood, you don't need to bother with this setting."
|
|||
;; last elt of a sequence
|
||||
(defsubst viper-seq-last-elt (seq)
|
||||
(elt seq (1- (length seq))))
|
||||
|
||||
(defsubst viper-string-to-list (string)
|
||||
(append (vconcat string) nil))
|
||||
|
||||
(defsubst viper-charlist-to-string (list)
|
||||
(mapconcat 'char-to-string list ""))
|
||||
|
||||
;; like char-after/before, but saves typing
|
||||
(defun viper-char-at-pos (direction &optional offset)
|
||||
(or (integerp offset) (setq offset 0))
|
||||
(if (eq direction 'forward)
|
||||
(char-after (+ (point) offset))
|
||||
(char-before (- (point) offset))))
|
||||
|
||||
|
||||
(defvar viper-minibuffer-overlay-priority 300)
|
||||
|
@ -251,16 +269,81 @@ Use `M-x viper-set-expert-level' to change this.")
|
|||
(defconst viper-max-expert-level 5)
|
||||
|
||||
|
||||
;;; ISO characters
|
||||
|
||||
;;; ISO characters and MULE
|
||||
|
||||
;; If non-nil, ISO accents will be turned on in insert/replace emacs states and
|
||||
;; turned off in vi-state. For some users, this behavior may be too
|
||||
;; primitive. In this case, use insert/emacs/vi state hooks.
|
||||
(viper-deflocalvar viper-automatic-iso-accents nil "")
|
||||
(defcustom viper-automatic-iso-accents nil
|
||||
"*If non-nil, ISO accents will be turned on in insert/replace emacs states and turned off in vi-state.
|
||||
For some users, this behavior may be too primitive. In this case, use
|
||||
insert/emacs/vi state hooks."
|
||||
:type 'boolean
|
||||
:group 'viper)
|
||||
;; Set iso-accents-mode to ARG. Check if it is bound first
|
||||
(defsubst viper-set-iso-accents-mode (arg)
|
||||
(if (boundp 'iso-accents-mode)
|
||||
(setq iso-accents-mode arg)))
|
||||
|
||||
;; Internal flag used to control when viper mule hooks are run.
|
||||
;; Don't change this!
|
||||
(defvar viper-mule-hook-flag t)
|
||||
;; If non-nil, the default intl. input method is turned on.
|
||||
(viper-deflocalvar viper-special-input-method nil "")
|
||||
|
||||
;; viper hook to run on input-method activation
|
||||
(defun viper-activate-input-method-action ()
|
||||
(if (null viper-mule-hook-flag)
|
||||
()
|
||||
(setq viper-special-input-method t)
|
||||
;; turn off special input methods in vi-state
|
||||
(if (eq viper-current-state 'vi-state)
|
||||
(viper-set-input-method nil))
|
||||
(if (memq viper-current-state '(vi-state insert-state replace-state))
|
||||
(message "Viper special input method%s: on"
|
||||
(if (or current-input-method default-input-method)
|
||||
(format " %S"
|
||||
(or current-input-method default-input-method))
|
||||
"")))
|
||||
))
|
||||
;; viper hook to run on input-method deactivation
|
||||
(defun viper-inactivate-input-method-action ()
|
||||
(if (null viper-mule-hook-flag)
|
||||
()
|
||||
(setq viper-special-input-method nil)
|
||||
(if (memq viper-current-state '(vi-state insert-state replace-state))
|
||||
(message "Viper special input method%s: off"
|
||||
(if (or current-input-method default-input-method)
|
||||
(format " %S"
|
||||
(or current-input-method default-input-method))
|
||||
"")))))
|
||||
|
||||
(defun viper-inactivate-input-method ()
|
||||
(cond ((and viper-emacs-p (fboundp 'inactivate-input-method))
|
||||
(inactivate-input-method))
|
||||
((and viper-xemacs-p (boundp 'current-input-method))
|
||||
;; XEmacs had broken quil-mode for some time, so we are working around
|
||||
;; it here
|
||||
(setq quail-mode nil)
|
||||
(if (featurep 'quail)
|
||||
(quail-delete-overlays))
|
||||
(setq describe-current-input-method-function nil)
|
||||
(setq current-input-method nil)
|
||||
(run-hooks 'input-method-inactivate-hook)
|
||||
(force-mode-line-update))
|
||||
))
|
||||
(defun viper-activate-input-method ()
|
||||
(cond ((and viper-emacs-p (fboundp 'activate-input-method))
|
||||
(activate-input-method default-input-method))
|
||||
((and viper-xemacs-p (fboundp 'quail-mode))
|
||||
(quail-mode 1))))
|
||||
|
||||
;; Set quail-mode to ARG
|
||||
(defun viper-set-input-method (arg)
|
||||
(setq viper-mule-hook-flag t) ; just a precaution
|
||||
(let (viper-mule-hook-flag) ; temporarily inactivate viper mule hooks
|
||||
(cond ((and arg (> (prefix-numeric-value arg) 0) default-input-method)
|
||||
;; activate input method
|
||||
(viper-activate-input-method))
|
||||
(t ; deactivate input method
|
||||
(viper-inactivate-input-method)))
|
||||
))
|
||||
|
||||
|
||||
;; VI-style Undo
|
||||
|
||||
|
@ -372,7 +455,12 @@ color displays. By default, the delimiters are used only on TTYs."
|
|||
;; Remember the number of characters that have to be deleted in replace
|
||||
;; mode to compensate for the inserted characters.
|
||||
(viper-deflocalvar viper-replace-chars-to-delete 0 "")
|
||||
(viper-deflocalvar viper-replace-chars-deleted 0 "")
|
||||
;; This variable is used internally by the before/after changed functions to
|
||||
;; determine how many chars were deleted by the change. This can't be
|
||||
;; determined inside after-change-functions because those get the length of the
|
||||
;; deleted region, not the number of chars deleted (which are two different
|
||||
;; things under MULE).
|
||||
(viper-deflocalvar viper-replace-region-chars-deleted 0 "")
|
||||
|
||||
;; Insertion ring and command ring
|
||||
(defcustom viper-insertion-ring-size 14
|
||||
|
@ -520,8 +608,7 @@ to a new place after repeating previous Vi command."
|
|||
(defvar viper-use-register nil)
|
||||
|
||||
|
||||
|
||||
;; Variables for Moves and Searches
|
||||
;;; Variables for Moves and Searches
|
||||
|
||||
;; For use by `;' command.
|
||||
(defvar viper-f-char nil)
|
||||
|
@ -589,18 +676,22 @@ If nil, these commands cross line boundaries."
|
|||
:type 'boolean
|
||||
:group 'viper)
|
||||
|
||||
(viper-deflocalvar viper-ex-style-editing-in-insert t "")
|
||||
(defcustom viper-ex-style-editing-in-insert t
|
||||
"*If t, `Backspace' and `Delete' don't cross line boundaries in insert, etc.
|
||||
(viper-deflocalvar viper-ex-style-editing t "")
|
||||
(defcustom viper-ex-style-editing t
|
||||
"*If t, Ex-style behavior while editing in Vi command and insert states.
|
||||
`Backspace' and `Delete' don't cross line boundaries in insert.
|
||||
`X' and `x' can't delete characters across line boundary in Vi, etc.
|
||||
Note: this doesn't preclude `Backspace' and `Delete' from deleting characters
|
||||
by moving past the insertion point. This is a feature, not a bug."
|
||||
by moving past the insertion point. This is a feature, not a bug.
|
||||
|
||||
If nil, the above commands can work across lines."
|
||||
:type 'boolean
|
||||
:group 'viper)
|
||||
|
||||
(viper-deflocalvar viper-ESC-moves-cursor-back viper-ex-style-editing-in-insert "")
|
||||
(viper-deflocalvar viper-ESC-moves-cursor-back viper-ex-style-editing "")
|
||||
(defcustom viper-ESC-moves-cursor-back nil
|
||||
"*If t, ESC moves cursor back when changing from insert to vi state.
|
||||
If nil, the cursor stays where it was."
|
||||
If nil, the cursor stays where it was when ESC was hit."
|
||||
:type 'boolean
|
||||
:group 'viper)
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
(defvar viper-current-state)
|
||||
(defvar viper-mode-string)
|
||||
(defvar viper-expert-level)
|
||||
(defvar viper-ex-style-editing-in-insert)
|
||||
(defvar viper-ex-style-editing)
|
||||
(defvar viper-ex-style-motion)
|
||||
|
||||
;; loading happens only in non-interactive compilation
|
||||
|
@ -597,8 +597,8 @@ Arguments: (major-mode viper-state keymap)"
|
|||
(princ (format "viper-always %S\n" viper-always))
|
||||
(princ (format "viper-ex-style-motion %S\n"
|
||||
viper-ex-style-motion))
|
||||
(princ (format "viper-ex-style-editing-in-insert %S\n"
|
||||
viper-ex-style-editing-in-insert))
|
||||
(princ (format "viper-ex-style-editing %S\n"
|
||||
viper-ex-style-editing))
|
||||
(princ (format "viper-want-emacs-keys-in-vi %S\n"
|
||||
viper-want-emacs-keys-in-vi))
|
||||
(princ (format "viper-want-emacs-keys-in-insert %S\n"
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
(defvar ex-unix-type-shell)
|
||||
(defvar ex-unix-type-shell-options)
|
||||
(defvar viper-ex-tmp-buf-name)
|
||||
(defvar viper-syntax-preference)
|
||||
|
||||
(require 'cl)
|
||||
(require 'ring)
|
||||
|
@ -216,6 +217,21 @@
|
|||
(goto-char cur-pos)
|
||||
result))
|
||||
|
||||
;; Emacs counts each multibyte character as several positions in the buffer, so
|
||||
;; we use Emacs' chars-in-region. XEmacs is counting each char as just one pos,
|
||||
;; so we can simply subtract.
|
||||
(defun viper-chars-in-region (beg end &optional preserve-sign)
|
||||
(let ((count (abs (if (fboundp 'chars-in-region)
|
||||
(chars-in-region beg end)
|
||||
(- end beg)))))
|
||||
(if (and (< end beg) preserve-sign)
|
||||
(- count)
|
||||
count)))
|
||||
|
||||
;; Test if POS is between BEG and END
|
||||
(defsubst viper-pos-within-region (pos beg end)
|
||||
(and (>= pos (min beg end)) (>= (max beg end) pos)))
|
||||
|
||||
|
||||
;; Like move-marker but creates a virgin marker if arg isn't already a marker.
|
||||
;; The first argument must eval to a variable name.
|
||||
|
@ -1058,45 +1074,104 @@ the `Local variables' section of a file."
|
|||
|
||||
;;; Movement utilities
|
||||
|
||||
(defcustom viper-syntax-preference 'strict-vi
|
||||
"*Syntax type characterizing Viper's alphanumeric symbols.
|
||||
`emacs' means only word constituents are considered to be alphanumeric.
|
||||
Word constituents are symbols specified as word constituents by the current
|
||||
syntax table.
|
||||
`extended' means word and symbol constituents.
|
||||
`reformed-vi' means Vi-ish behavior: word constituents and the symbol `_'.
|
||||
However, word constituents are determined according to Emacs syntax tables,
|
||||
which may be different from Vi in some major modes.
|
||||
`strict-vi' means Viper words are exactly as in Vi."
|
||||
:type '(radio (const strict-vi) (const reformed-vi)
|
||||
(const extended) (const emacs))
|
||||
:group 'viper)
|
||||
;; Characters that should not be considered as part of the word, in reformed-vi
|
||||
;; syntax mode.
|
||||
(defconst viper-non-word-characters-reformed-vi
|
||||
"!@#$%^&*()-+=|\\~`{}[];:'\",<.>/?")
|
||||
;; These are characters that are not to be considered as parts of a word in
|
||||
;; Viper.
|
||||
;; Set each time state changes and at loading time
|
||||
(viper-deflocalvar viper-non-word-characters nil)
|
||||
|
||||
;; must be buffer-local
|
||||
(viper-deflocalvar viper-ALPHA-char-class "w"
|
||||
"String of syntax classes characterizing Viper's alphanumeric symbols.
|
||||
In addition, the symbol `_' may be considered alphanumeric if
|
||||
`viper-syntax-preference'is `reformed-vi'.")
|
||||
`viper-syntax-preference' is `strict-vi' or `reformed-vi'.")
|
||||
|
||||
(viper-deflocalvar viper-strict-ALPHA-chars "a-zA-Z0-9_"
|
||||
(defconst viper-strict-ALPHA-chars "a-zA-Z0-9_"
|
||||
"Regexp matching the set of alphanumeric characters acceptable to strict
|
||||
Vi.")
|
||||
(viper-deflocalvar viper-strict-SEP-chars " \t\n"
|
||||
(defconst viper-strict-SEP-chars " \t\n"
|
||||
"Regexp matching the set of alphanumeric characters acceptable to strict
|
||||
Vi.")
|
||||
(defconst viper-strict-SEP-chars-sans-newline " \t"
|
||||
"Regexp matching the set of alphanumeric characters acceptable to strict
|
||||
Vi.")
|
||||
|
||||
(viper-deflocalvar viper-SEP-char-class " -"
|
||||
(defconst viper-SEP-char-class " -"
|
||||
"String of syntax classes for Vi separators.
|
||||
Usually contains ` ', linefeed, TAB or formfeed.")
|
||||
|
||||
(defun viper-update-alphanumeric-class ()
|
||||
"Set the syntax class of Viper alphanumerals according to `viper-syntax-preference'.
|
||||
Must be called in order for changes to `viper-syntax-preference' to take effect."
|
||||
|
||||
;; Set Viper syntax classes and related variables according to
|
||||
;; `viper-syntax-preference'.
|
||||
(defun viper-update-syntax-classes (&optional set-default)
|
||||
(let ((preference (cond ((eq viper-syntax-preference 'emacs)
|
||||
"w") ; Viper words have only Emacs word chars
|
||||
((eq viper-syntax-preference 'extended)
|
||||
"w_") ; Viper words have Emacs word & symbol chars
|
||||
(t "w"))) ; Viper words are Emacs words plus `_'
|
||||
(non-word-chars (cond ((eq viper-syntax-preference 'reformed-vi)
|
||||
(viper-string-to-list
|
||||
viper-non-word-characters-reformed-vi))
|
||||
(t nil))))
|
||||
(if set-default
|
||||
(setq-default viper-ALPHA-char-class preference
|
||||
viper-non-word-characters non-word-chars)
|
||||
(setq viper-ALPHA-char-class preference
|
||||
viper-non-word-characters non-word-chars))
|
||||
))
|
||||
|
||||
;; SYMBOL is used because customize requires it, but it is ignored, unless it
|
||||
;; is `nil'. If nil, use setq.
|
||||
(defun viper-set-syntax-preference (&optional symbol value)
|
||||
"Set Viper syntax preference.
|
||||
If called interactively or if SYMBOL is nil, sets syntax preference in current
|
||||
buffer. If called non-interactively, preferably via the customization widget,
|
||||
sets the default value."
|
||||
(interactive)
|
||||
(setq-default
|
||||
viper-ALPHA-char-class
|
||||
(cond ((eq viper-syntax-preference 'emacs) "w") ; only word constituents
|
||||
((eq viper-syntax-preference 'extended) "w_") ; word & symbol chars
|
||||
(t "w")))) ; vi syntax: word constituents and the symbol `_'
|
||||
(or value
|
||||
(setq value
|
||||
(completing-read
|
||||
"Viper syntax preference: "
|
||||
'(("strict-vi") ("reformed-vi") ("extended") ("emacs"))
|
||||
nil 'require-match)))
|
||||
(if (stringp value) (setq value (intern value)))
|
||||
(or (memq value '(strict-vi reformed-vi extended emacs))
|
||||
(error "Invalid Viper syntax preference, %S" value))
|
||||
(if symbol
|
||||
(setq-default viper-syntax-preference value)
|
||||
(setq viper-syntax-preference value))
|
||||
(viper-update-syntax-classes))
|
||||
|
||||
(defcustom viper-syntax-preference 'reformed-vi
|
||||
"*Syntax type characterizing Viper's alphanumeric symbols.
|
||||
Affects movement and change commands that deal with Vi-style words.
|
||||
Works best when set in the hooks to various major modes.
|
||||
|
||||
`strict-vi' means Viper words are (hopefully) exactly as in Vi.
|
||||
|
||||
`reformed-vi' means Viper words are like Emacs words \(as determined using
|
||||
Emacs syntax tables, which are different for different major modes\) with two
|
||||
exceptions: the symbol `_' is always part of a word and typical Vi non-word
|
||||
symbols, such as `,',:,\",),{, etc., are excluded.
|
||||
This behaves very close to `strict-vi', but also works well with non-ASCII
|
||||
characters from various alphabets.
|
||||
|
||||
`extended' means Viper word constituents are symbols that are marked as being
|
||||
parts of words OR symbols in Emacs syntax tables.
|
||||
This is most appropriate for major modes intended for editing programs.
|
||||
|
||||
`emacs' means Viper words are the same as Emacs words as specified by Emacs
|
||||
syntax tables.
|
||||
This option is appropriate if you like Emacs-style words."
|
||||
:type '(radio (const strict-vi) (const reformed-vi)
|
||||
(const extended) (const emacs))
|
||||
:set 'viper-set-syntax-preference
|
||||
:group 'viper)
|
||||
(make-variable-buffer-local 'viper-syntax-preference)
|
||||
|
||||
|
||||
;; addl-chars are characters to be temporarily considered as alphanumerical
|
||||
(defun viper-looking-at-alpha (&optional addl-chars)
|
||||
|
@ -1107,19 +1182,26 @@ Must be called in order for changes to `viper-syntax-preference' to take effect.
|
|||
(if char
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(looking-at (concat "[" viper-strict-ALPHA-chars addl-chars "]"))
|
||||
(or (memq char
|
||||
;; convert string to list
|
||||
(append (vconcat addl-chars) nil))
|
||||
(memq (char-syntax char)
|
||||
(append (vconcat viper-ALPHA-char-class) nil)))))
|
||||
(or
|
||||
;; or one of the additional chars being asked to include
|
||||
(memq char (viper-string-to-list addl-chars))
|
||||
(and
|
||||
;; not one of the excluded word chars
|
||||
(not (memq char viper-non-word-characters))
|
||||
;; char of the Viper-word syntax class
|
||||
(memq (char-syntax char)
|
||||
(viper-string-to-list viper-ALPHA-char-class))))))
|
||||
))
|
||||
|
||||
(defun viper-looking-at-separator ()
|
||||
(let ((char (char-after (point))))
|
||||
(if char
|
||||
(or (eq char ?\n) ; RET is always a separator in Vi
|
||||
(memq (char-syntax char)
|
||||
(append (vconcat viper-SEP-char-class) nil))))))
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(memq char (viper-string-to-list viper-strict-SEP-chars))
|
||||
(or (eq char ?\n) ; RET is always a separator in Vi
|
||||
(memq (char-syntax char)
|
||||
(viper-string-to-list viper-SEP-char-class)))))
|
||||
))
|
||||
|
||||
(defsubst viper-looking-at-alphasep (&optional addl-chars)
|
||||
(or (viper-looking-at-separator) (viper-looking-at-alpha addl-chars)))
|
||||
|
@ -1148,51 +1230,102 @@ Must be called in order for changes to `viper-syntax-preference' to take effect.
|
|||
|
||||
;; weird syntax tables may confuse strict-vi style
|
||||
(defsubst viper-skip-all-separators-forward (&optional within-line)
|
||||
(viper-skip-syntax 'forward
|
||||
viper-SEP-char-class
|
||||
(or within-line "\n")
|
||||
(if within-line (viper-line-pos 'end))))
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(if within-line
|
||||
(skip-chars-forward viper-strict-SEP-chars-sans-newline)
|
||||
(skip-chars-forward viper-strict-SEP-chars))
|
||||
(viper-skip-syntax 'forward
|
||||
viper-SEP-char-class
|
||||
(or within-line "\n")
|
||||
(if within-line (viper-line-pos 'end)))))
|
||||
(defsubst viper-skip-all-separators-backward (&optional within-line)
|
||||
(viper-skip-syntax 'backward
|
||||
viper-SEP-char-class
|
||||
(or within-line "\n")
|
||||
(if within-line (viper-line-pos 'start))))
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(if within-line
|
||||
(skip-chars-backward viper-strict-SEP-chars-sans-newline)
|
||||
(skip-chars-backward viper-strict-SEP-chars))
|
||||
(viper-skip-syntax 'backward
|
||||
viper-SEP-char-class
|
||||
(or within-line "\n")
|
||||
(if within-line (viper-line-pos 'start)))))
|
||||
(defun viper-skip-nonseparators (direction)
|
||||
(let ((func (intern (format "skip-syntax-%S" direction))))
|
||||
(funcall func (concat "^" viper-SEP-char-class)
|
||||
(viper-line-pos (if (eq direction 'forward) 'end 'start)))))
|
||||
(viper-skip-syntax
|
||||
direction
|
||||
(concat "^" viper-SEP-char-class)
|
||||
nil
|
||||
(viper-line-pos (if (eq direction 'forward) 'end 'start))))
|
||||
|
||||
|
||||
;; skip over non-word constituents and non-separators
|
||||
(defun viper-skip-nonalphasep-forward ()
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(skip-chars-forward
|
||||
(concat "^" viper-strict-SEP-chars viper-strict-ALPHA-chars))
|
||||
(skip-syntax-forward
|
||||
(concat
|
||||
"^" viper-ALPHA-char-class viper-SEP-char-class) (viper-line-pos 'end))))
|
||||
(viper-skip-syntax
|
||||
'forward
|
||||
(concat "^" viper-ALPHA-char-class viper-SEP-char-class)
|
||||
;; Emacs may consider some of these as words, but we don't want them
|
||||
viper-non-word-characters
|
||||
(viper-line-pos 'end))))
|
||||
(defun viper-skip-nonalphasep-backward ()
|
||||
(if (eq viper-syntax-preference 'strict-vi)
|
||||
(skip-chars-backward
|
||||
(concat "^" viper-strict-SEP-chars viper-strict-ALPHA-chars))
|
||||
(skip-syntax-backward
|
||||
(concat
|
||||
"^"
|
||||
viper-ALPHA-char-class viper-SEP-char-class)
|
||||
(viper-skip-syntax
|
||||
'backward
|
||||
(concat "^" viper-ALPHA-char-class viper-SEP-char-class)
|
||||
;; Emacs may consider some of these as words, but we don't want them
|
||||
viper-non-word-characters
|
||||
(viper-line-pos 'start))))
|
||||
|
||||
;; Skip SYNTAX like skip-syntax-* and ADDL-CHARS like skip-chars-*
|
||||
;; Return the number of chars traveled.
|
||||
;; Either SYNTAX or ADDL-CHARS can be nil, in which case they are interpreted
|
||||
;; as an empty string.
|
||||
;; Both SYNTAX or ADDL-CHARS can be strings or lists of characters.
|
||||
;; When SYNTAX is "w", then viper-non-word-characters are not considered to be
|
||||
;; words, even if Emacs syntax table says they are.
|
||||
(defun viper-skip-syntax (direction syntax addl-chars &optional limit)
|
||||
(let ((total 0)
|
||||
(local 1)
|
||||
(skip-chars-func (intern (format "skip-chars-%S" direction)))
|
||||
(skip-syntax-func (intern (format "skip-syntax-%S" direction))))
|
||||
(or (stringp addl-chars) (setq addl-chars ""))
|
||||
(or (stringp syntax) (setq syntax ""))
|
||||
(skip-chars-func
|
||||
(if (eq direction 'forward)
|
||||
'skip-chars-forward 'skip-chars-backward))
|
||||
(skip-syntax-func
|
||||
(if (eq direction 'forward)
|
||||
'viper-forward-char-carefully 'viper-backward-char-carefully))
|
||||
char-looked-at syntax-of-char-looked-at negated-syntax)
|
||||
(setq addl-chars
|
||||
(cond ((listp addl-chars) (viper-charlist-to-string addl-chars))
|
||||
((stringp addl-chars) addl-chars)
|
||||
(t "")))
|
||||
(setq syntax
|
||||
(cond ((listp syntax) syntax)
|
||||
((stringp syntax) (viper-string-to-list syntax))
|
||||
(t nil)))
|
||||
(if (memq ?^ syntax) (setq negated-syntax t))
|
||||
|
||||
(while (and (not (= local 0)) (not (eobp)))
|
||||
(setq char-looked-at (viper-char-at-pos direction)
|
||||
;; if outside the range, set to nil
|
||||
syntax-of-char-looked-at (if char-looked-at
|
||||
(char-syntax char-looked-at)))
|
||||
(setq local
|
||||
(+ (funcall skip-syntax-func syntax limit)
|
||||
(+ (if (and
|
||||
(cond ((and limit (eq direction 'forward))
|
||||
(< (point) limit))
|
||||
(limit ; backward & limit
|
||||
(> (point) limit))
|
||||
(t t)) ; no limit
|
||||
;; char under/before cursor has appropriate syntax
|
||||
(if negated-syntax
|
||||
(not (memq syntax-of-char-looked-at syntax))
|
||||
(memq syntax-of-char-looked-at syntax))
|
||||
;; if char-syntax class is "word", make sure it is not one
|
||||
;; of the excluded characters
|
||||
(if (and (eq syntax-of-char-looked-at ?w)
|
||||
(not negated-syntax))
|
||||
(not (memq char-looked-at viper-non-word-characters))
|
||||
t))
|
||||
(funcall skip-syntax-func 1)
|
||||
0)
|
||||
(funcall skip-chars-func addl-chars limit)))
|
||||
(setq total (+ total local)))
|
||||
total
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
|
||||
|
||||
(defconst viper-version "2.96 of August 7, 1997"
|
||||
(defconst viper-version "3.00 (Polyglot) of August 18, 1997"
|
||||
"The current version of Viper")
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
@ -302,6 +302,7 @@
|
|||
|
||||
;; compiler pacifier
|
||||
(defvar mark-even-if-inactive)
|
||||
(defvar quail-mode)
|
||||
(defvar viper-expert-level)
|
||||
(defvar viper-expert-level)
|
||||
|
||||
|
@ -469,7 +470,7 @@ This startup message appears whenever you load Viper, unless you type `y' now."
|
|||
;; This hook designed to enable Vi-style editing in comint-based modes."
|
||||
(defun viper-comint-mode-hook ()
|
||||
(setq require-final-newline nil
|
||||
viper-ex-style-editing-in-insert nil
|
||||
viper-ex-style-editing nil
|
||||
viper-ex-style-motion nil)
|
||||
(viper-change-state-to-insert))
|
||||
|
||||
|
@ -828,6 +829,62 @@ remains buffer-local."
|
|||
(defadvice rmail-cease-edit (after viper-rmail-advice activate)
|
||||
"Switch to emacs state when done editing message."
|
||||
(viper-change-state-to-emacs))
|
||||
|
||||
;; ISO accents
|
||||
;; Need to do it after loading iso-acc, or else this loading will wipe out
|
||||
;; the advice.
|
||||
(eval-after-load
|
||||
"iso-acc"
|
||||
(defadvice iso-accents-mode (around viper-iso-accents-advice activate)
|
||||
"Set viper-automatic-iso-accents to iso-accents-mode."
|
||||
(let ((arg (ad-get-arg 0)))
|
||||
ad-do-it
|
||||
(setq viper-automatic-iso-accents
|
||||
(if (eq viper-current-state 'vi-state)
|
||||
(if arg
|
||||
;; if iso-accents-mode was called with positive arg, turn
|
||||
;; accents on
|
||||
(> (prefix-numeric-value arg) 0)
|
||||
;; else: toggle viper-automatic-iso-accents
|
||||
(not viper-automatic-iso-accents))
|
||||
;; other states: accept what iso-accents-mode has done
|
||||
iso-accents-mode))
|
||||
;; turn off ISO accents in vi-state
|
||||
(if (eq viper-current-state 'vi-state)
|
||||
(viper-set-iso-accents-mode nil))
|
||||
(if (memq viper-current-state '(vi-state insert-state replace-state))
|
||||
(message "Viper ISO accents mode: %s"
|
||||
(if viper-automatic-iso-accents "on" "off")))
|
||||
)))
|
||||
|
||||
;; International input methods
|
||||
(if viper-emacs-p
|
||||
(eval-after-load "mule-cmds"
|
||||
(progn
|
||||
(defadvice inactivate-input-method (after viper-mule-advice activate)
|
||||
"Set viper-special-input-method to disable intl. input methods."
|
||||
(viper-inactivate-input-method-action))
|
||||
(defadvice activate-input-method (after viper-mule-advice activate)
|
||||
"Set viper-special-input-method to enable intl. input methods."
|
||||
(viper-activate-input-method-action))
|
||||
))
|
||||
;; XEmacs Although these hooks exist in Emacs, they don't seem to be always
|
||||
;; called on input-method activation/deactivation, so we the above advise
|
||||
;; functions instead.
|
||||
(eval-after-load "mule-cmds"
|
||||
(progn
|
||||
(add-hook 'input-method-activate-hook
|
||||
'viper-activate-input-method-action t)
|
||||
(add-hook 'input-method-inactivate-hook
|
||||
'viper-inactivate-input-method-action t)))
|
||||
)
|
||||
(eval-after-load "mule-cmds"
|
||||
(defadvice toggle-input-method (around viper-mule-advice activate)
|
||||
"Adjust input-method toggling in vi-state."
|
||||
(if (and viper-special-input-method (eq viper-current-state 'vi-state))
|
||||
(viper-inactivate-input-method)
|
||||
ad-do-it)))
|
||||
|
||||
) ; viper-set-hooks
|
||||
|
||||
|
||||
|
@ -1089,8 +1146,8 @@ These two lines must come in the order given.
|
|||
(cons 'viper-always (list viper-always))
|
||||
(cons 'viper-no-multiple-ESC (list viper-no-multiple-ESC))
|
||||
(cons 'viper-ex-style-motion (list viper-ex-style-motion))
|
||||
(cons 'viper-ex-style-editing-in-insert
|
||||
(list viper-ex-style-editing-in-insert))
|
||||
(cons 'viper-ex-style-editing
|
||||
(list viper-ex-style-editing))
|
||||
(cons 'viper-want-emacs-keys-in-vi
|
||||
(list viper-want-emacs-keys-in-vi))
|
||||
(cons 'viper-electric-mode (list viper-electric-mode))
|
||||
|
@ -1104,7 +1161,7 @@ These two lines must come in the order given.
|
|||
(viper-set-minibuffer-style)
|
||||
(if viper-buffer-search-char
|
||||
(viper-buffer-search-enable))
|
||||
(viper-update-alphanumeric-class)
|
||||
(viper-update-syntax-classes 'set-default)
|
||||
))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue