aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kifer1997-05-31 00:02:53 +0000
committerMichael Kifer1997-05-31 00:02:53 +0000
commit9b70a748edea012ecad578c42495ffa01e9eb80b (patch)
tree1b41eab6d65ce322053fd967ea7aeb85ef7847d8
parentcec36122044f1a8f0a3d92a5f031a7e78f557ca4 (diff)
downloademacs-9b70a748edea012ecad578c42495ffa01e9eb80b.tar.gz
emacs-9b70a748edea012ecad578c42495ffa01e9eb80b.zip
new version
-rw-r--r--lisp/emulation/viper-ex.el125
-rw-r--r--lisp/emulation/viper-init.el677
-rw-r--r--lisp/emulation/viper-keym.el53
-rw-r--r--lisp/emulation/viper-macs.el24
-rw-r--r--lisp/emulation/viper-mous.el25
-rw-r--r--lisp/emulation/viper-util.el400
-rw-r--r--lisp/emulation/viper.el978
7 files changed, 1288 insertions, 994 deletions
diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el
index 93846321476..8e35403e570 100644
--- a/lisp/emulation/viper-ex.el
+++ b/lisp/emulation/viper-ex.el
@@ -1,6 +1,6 @@
1;;; viper-ex.el --- functions implementing the Ex commands for Viper 1;;; viper-ex.el --- functions implementing the Ex commands for Viper
2 2
3;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -19,14 +19,35 @@
19;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA. 20;; Boston, MA 02111-1307, USA.
21 21
22
23;; Code 22;; Code
24 23
25(require 'viper-util) 24(provide 'viper-ex)
26 25
27;; Compiler pacifier 26;; Compiler pacifier
28(defvar read-file-name-map) 27(defvar read-file-name-map)
29;; end compiler pacifier 28(defvar vip-use-register)
29(defvar vip-s-string)
30(defvar vip-shift-width)
31(defvar vip-ex-history)
32(defvar vip-related-files-and-buffers-ring)
33(defvar vip-local-search-start-marker)
34(defvar vip-expert-level)
35(defvar vip-custom-file-name)
36(defvar vip-case-fold-search)
37
38(eval-when-compile
39 (let ((load-path (cons (expand-file-name ".") load-path)))
40 (or (featurep 'viper-util)
41 (load "viper-util.el" nil nil 'nosuffix))
42 (or (featurep 'viper-keym)
43 (load "viper-keym.el" nil nil 'nosuffix))
44 (or (featurep 'viper)
45 (load "viper.el" nil nil 'nosuffix))
46 ))
47;; end pacifier
48
49(require 'viper-util)
50
30 51
31;;; Variables 52;;; Variables
32 53
@@ -637,7 +658,8 @@ reversed.")
637 658
638;; Get an ex-address as a marker and set ex-flag if a flag is found 659;; Get an ex-address as a marker and set ex-flag if a flag is found
639(defun vip-get-ex-address () 660(defun vip-get-ex-address ()
640 (let ((address (point-marker)) (cont t)) 661 (let ((address (point-marker))
662 (cont t))
641 (setq ex-token "") 663 (setq ex-token "")
642 (setq ex-flag nil) 664 (setq ex-flag nil)
643 (while cont 665 (while cont
@@ -1852,7 +1874,12 @@ Please contact your system administrator. "
1852(defun ex-write (q-flag) 1874(defun ex-write (q-flag)
1853 (vip-default-ex-addresses t) 1875 (vip-default-ex-addresses t)
1854 (vip-get-ex-file) 1876 (vip-get-ex-file)
1855 (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))) 1877 (let ((end (car ex-addresses))
1878 (beg (car (cdr ex-addresses)))
1879 (orig-buf (current-buffer))
1880 (orig-buf-file-name (buffer-file-name))
1881 (orig-buf-name (buffer-name))
1882 (buff-changed-p (buffer-modified-p))
1856 temp-buf writing-same-file region 1883 temp-buf writing-same-file region
1857 file-exists writing-whole-file) 1884 file-exists writing-whole-file)
1858 (if (> beg end) (error vip-FirstAddrExceedsSecond)) 1885 (if (> beg end) (error vip-FirstAddrExceedsSecond))
@@ -1875,8 +1902,9 @@ Please contact your system administrator. "
1875 buffer-file-name 1902 buffer-file-name
1876 (not (file-directory-p buffer-file-name))) 1903 (not (file-directory-p buffer-file-name)))
1877 (setq ex-file 1904 (setq ex-file
1878 (concat ex-file (file-name-nondirectory buffer-file-name)))) 1905 (concat (file-name-as-directory ex-file)
1879 1906 (file-name-nondirectory buffer-file-name))))
1907
1880 (setq file-exists (file-exists-p ex-file) 1908 (setq file-exists (file-exists-p ex-file)
1881 writing-same-file (string= ex-file (buffer-file-name))) 1909 writing-same-file (string= ex-file (buffer-file-name)))
1882 1910
@@ -1884,35 +1912,58 @@ Please contact your system administrator. "
1884 (if (not (buffer-modified-p)) 1912 (if (not (buffer-modified-p))
1885 (message "(No changes need to be saved)") 1913 (message "(No changes need to be saved)")
1886 (save-buffer) 1914 (save-buffer)
1887 (ex-write-info file-exists ex-file beg end)) 1915 (save-restriction
1888 ;; writing some other file or portion of the currents 1916 (widen)
1889 ;; file---create temp buffer for it 1917 (ex-write-info file-exists ex-file (point-min) (point-max))
1890 ;; disable undo in that buffer, for efficiency 1918 ))
1891 (buffer-disable-undo (setq temp-buf (create-file-buffer ex-file))) 1919 ;; writing some other file or portion of the current file
1892 (unwind-protect 1920 (cond ((and file-exists
1893 (save-excursion 1921 (not writing-same-file)
1894 (if (and file-exists 1922 (not (yes-or-no-p
1895 (not writing-same-file) 1923 (format "File %s exists. Overwrite? " ex-file))))
1896 (not (yes-or-no-p 1924 (error "Quit"))
1897 (format "File %s exists. Overwrite? " ex-file)))) 1925 ((and writing-whole-file (not ex-append))
1898 (error "Quit") 1926 (unwind-protect
1899 (vip-enlarge-region beg end) 1927 (progn
1900 (setq region (buffer-substring (point) (mark t))) 1928 (set-visited-file-name ex-file)
1901 (set-buffer temp-buf) 1929 (set-buffer-modified-p t)
1902 (set-visited-file-name ex-file) 1930 (save-buffer))
1903 (erase-buffer) 1931 ;; restore the buffer file name
1904 (if (and file-exists ex-append) 1932 (set-visited-file-name orig-buf-file-name)
1905 (insert-file-contents ex-file)) 1933 (set-buffer-modified-p buff-changed-p)
1906 (goto-char (point-max)) 1934 ;; If the buffer wasn't visiting a file, restore buffer name.
1907 (insert region) 1935 ;; Name could've been changed by packages such as uniquify.
1908 (save-buffer) 1936 (or orig-buf-file-name
1909 (ex-write-info file-exists ex-file (point-min) (point-max)) 1937 (progn
1910 ) 1938 (unlock-buffer)
1911 (set-buffer temp-buf) 1939 (rename-buffer orig-buf-name))))
1912 (set-buffer-modified-p nil) 1940 (save-restriction
1913 (kill-buffer temp-buf) 1941 (widen)
1942 (ex-write-info
1943 file-exists ex-file (point-min) (point-max))))
1944 (t ; writing a region
1945 (unwind-protect
1946 (save-excursion
1947 (vip-enlarge-region beg end)
1948 (setq region (buffer-substring (point) (mark t)))
1949 ;; create temp buffer for the region
1950 (setq temp-buf (get-buffer-create " *ex-write*"))
1951 (set-buffer temp-buf)
1952 (set-visited-file-name ex-file 'noquerry)
1953 (erase-buffer)
1954 (if (and file-exists ex-append)
1955 (insert-file-contents ex-file))
1956 (goto-char (point-max))
1957 (insert region)
1958 (save-buffer)
1959 (ex-write-info
1960 file-exists ex-file (point-min) (point-max))
1961 ))
1962 (set-buffer temp-buf)
1963 (set-buffer-modified-p nil)
1964 (kill-buffer temp-buf))
1914 )) 1965 ))
1915 ) 1966 (set-buffer orig-buf)
1916 ;; this prevents the loss of data if writing part of the buffer 1967 ;; this prevents the loss of data if writing part of the buffer
1917 (if (and (buffer-file-name) writing-same-file) 1968 (if (and (buffer-file-name) writing-same-file)
1918 (set-visited-file-modtime)) 1969 (set-visited-file-modtime))
@@ -2024,6 +2075,4 @@ Please contact your system administrator. "
2024 )) 2075 ))
2025 2076
2026 2077
2027(provide 'viper-ex)
2028
2029;;; viper-ex.el ends here 2078;;; viper-ex.el ends here
diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el
index e69de29bb2d..fa29b3add68 100644
--- a/lisp/emulation/viper-init.el
+++ b/lisp/emulation/viper-init.el
@@ -0,0 +1,677 @@
1;;; viper-init.el --- some common definitions for Viper
2
3;; Copyright (C) 1997 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software; you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs; see the file COPYING. If not, write to the
19;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20;; Boston, MA 02111-1307, USA.
21
22;; Code
23
24(provide 'viper-init)
25
26;; compiler pacifier
27(defvar mark-even-if-inactive)
28;; end pacifier
29
30;; Is it XEmacs?
31(defconst vip-xemacs-p (string-match "\\(Lucid\\|XEmacs\\)" emacs-version))
32;; Is it Emacs?
33(defconst vip-emacs-p (not vip-xemacs-p))
34;; Tell whether we are running as a window application or on a TTY
35(defsubst vip-device-type ()
36 (if vip-emacs-p
37 window-system
38 (device-type (selected-device))))
39;; in XEmacs: device-type is tty on tty and stream in batch.
40(defun vip-window-display-p ()
41 (and (vip-device-type) (not (memq (vip-device-type) '(tty stream pc)))))
42
43(defvar vip-ms-style-os-p (memq system-type '(ms-dos windows-nt windows-95))
44 "Tells if Emacs is running under an MS-style OS: ms-dos, windows-nt, W95.")
45(defvar vip-vms-os-p (memq system-type '(vax-vms axp-vms))
46 "Tells if Emacs is running under VMS.")
47
48(defvar vip-force-faces nil
49 "If t, Viper will think that it is running on a display that supports faces.
50This is provided as a temporary relief for users of face-capable displays
51that Viper doesn't know about.")
52
53(defun vip-has-face-support-p ()
54 (cond ((vip-window-display-p))
55 (vip-force-faces)
56 (vip-emacs-p (memq (vip-device-type) '(pc)))
57 (vip-xemacs-p (memq (vip-device-type) '(tty pc)))))
58
59(defun vip-convert-standard-file-name (fname)
60 (if vip-emacs-p
61 (convert-standard-filename fname)
62 ;; hopefully, XEmacs adds this functionality
63 fname))
64
65
66;;; Macros
67
68(defmacro vip-deflocalvar (var default-value &optional documentation)
69 (` (progn
70 (defvar (, var) (, default-value)
71 (, (format "%s\n\(buffer local\)" documentation)))
72 (make-variable-buffer-local '(, var))
73 )))
74
75(defmacro vip-loop (count body)
76 "(vip-loop COUNT BODY) Execute BODY COUNT times."
77 (list 'let (list (list 'count count))
78 (list 'while '(> count 0)
79 body
80 '(setq count (1- count))
81 )))
82
83(defmacro vip-buffer-live-p (buf)
84 (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf))))))
85
86;; return buffer-specific macro definition, given a full macro definition
87(defmacro vip-kbd-buf-alist (macro-elt)
88 (` (nth 1 (, macro-elt))))
89;; get a pair: (curr-buffer . macro-definition)
90(defmacro vip-kbd-buf-pair (macro-elt)
91 (` (assoc (buffer-name) (vip-kbd-buf-alist (, macro-elt)))))
92;; get macro definition for current buffer
93(defmacro vip-kbd-buf-definition (macro-elt)
94 (` (cdr (vip-kbd-buf-pair (, macro-elt)))))
95
96;; return mode-specific macro definitions, given a full macro definition
97(defmacro vip-kbd-mode-alist (macro-elt)
98 (` (nth 2 (, macro-elt))))
99;; get a pair: (major-mode . macro-definition)
100(defmacro vip-kbd-mode-pair (macro-elt)
101 (` (assoc major-mode (vip-kbd-mode-alist (, macro-elt)))))
102;; get macro definition for the current major mode
103(defmacro vip-kbd-mode-definition (macro-elt)
104 (` (cdr (vip-kbd-mode-pair (, macro-elt)))))
105
106;; return global macro definition, given a full macro definition
107(defmacro vip-kbd-global-pair (macro-elt)
108 (` (nth 3 (, macro-elt))))
109;; get global macro definition from an elt of macro-alist
110(defmacro vip-kbd-global-definition (macro-elt)
111 (` (cdr (vip-kbd-global-pair (, macro-elt)))))
112
113;; last elt of a sequence
114(defsubst vip-seq-last-elt (seq)
115 (elt seq (1- (length seq))))
116
117
118(defvar vip-minibuffer-overlay-priority 300)
119(defvar vip-replace-overlay-priority 400)
120(defvar vip-search-overlay-priority 500)
121
122
123;;; Viper minor modes
124
125;; This is not local in Emacs, so we make it local.
126;; This must be local because although the stack of minor modes can be the same
127;; for all buffers, the associated *keymaps* can be different. In Viper,
128;; vip-vi-local-user-map, vip-insert-local-user-map, and others can have
129;; different keymaps for different buffers.
130;; Also, the keymaps associated with vip-vi/insert-state-modifier-minor-mode
131;; can be different.
132(make-variable-buffer-local 'minor-mode-map-alist)
133
134;; Mode for vital things like \e, C-z.
135(vip-deflocalvar vip-vi-intercept-minor-mode nil)
136
137(vip-deflocalvar vip-vi-basic-minor-mode nil
138 "Viper's minor mode for Vi bindings.")
139
140(vip-deflocalvar vip-vi-local-user-minor-mode nil
141 "Auxiliary minor mode for user-defined local bindings in Vi state.")
142
143(vip-deflocalvar vip-vi-global-user-minor-mode nil
144 "Auxiliary minor mode for user-defined global bindings in Vi state.")
145
146(vip-deflocalvar vip-vi-state-modifier-minor-mode nil
147 "Minor mode used to make major-mode-specific modification to Vi state.")
148
149(vip-deflocalvar vip-vi-diehard-minor-mode nil
150 "This minor mode is in effect when the user wants Viper to be Vi.")
151
152(vip-deflocalvar vip-vi-kbd-minor-mode nil
153 "Minor mode for Ex command macros in Vi state.
154The corresponding keymap stores key bindings of Vi macros defined with
155the Ex command :map.")
156
157;; Mode for vital things like \e, C-z.
158(vip-deflocalvar vip-insert-intercept-minor-mode nil)
159
160(vip-deflocalvar vip-insert-basic-minor-mode nil
161 "Viper's minor mode for bindings in Insert mode.")
162
163(vip-deflocalvar vip-insert-local-user-minor-mode nil
164 "Auxiliary minor mode for buffer-local user-defined bindings in Insert state.
165This is a way to overshadow normal Insert mode bindings locally to certain
166designated buffers.")
167
168(vip-deflocalvar vip-insert-global-user-minor-mode nil
169 "Auxiliary minor mode for global user-defined bindings in Insert state.")
170
171(vip-deflocalvar vip-insert-state-modifier-minor-mode nil
172 "Minor mode used to make major-mode-specific modification to Insert state.")
173
174(vip-deflocalvar vip-insert-diehard-minor-mode nil
175 "Minor mode that simulates Vi very closely.
176Not recommened, except for the novice user.")
177
178(vip-deflocalvar vip-insert-kbd-minor-mode nil
179"Minor mode for Ex command macros Insert state.
180The corresponding keymap stores key bindings of Vi macros defined with
181the Ex command :map!.")
182
183(vip-deflocalvar vip-replace-minor-mode nil
184 "Minor mode in effect in replace state (cw, C, and the like commands).")
185
186;; Mode for vital things like \C-z and \C-x)
187;; This is t, by default. So, any new buffer will have C-z defined as
188;; switch to Vi, unless we switched states in this buffer
189(vip-deflocalvar vip-emacs-intercept-minor-mode t)
190
191(vip-deflocalvar vip-emacs-local-user-minor-mode t
192 "Minor mode for local user bindings effective in Emacs state.
193Users can use it to override Emacs bindings when Viper is in its Emacs
194state.")
195
196(vip-deflocalvar vip-emacs-global-user-minor-mode t
197 "Minor mode for global user bindings in effect in Emacs state.
198Users can use it to override Emacs bindings when Viper is in its Emacs
199state.")
200
201(vip-deflocalvar vip-emacs-kbd-minor-mode t
202 "Minor mode for Vi style macros in Emacs state.
203The corresponding keymap stores key bindings of Vi macros defined with
204`vip-record-kbd-macro' command. There is no Ex-level command to do this
205interactively.")
206
207(vip-deflocalvar vip-emacs-state-modifier-minor-mode t
208 "Minor mode used to make major-mode-specific modification to Emacs state.
209For instance, a Vi purist may want to bind `dd' in Dired mode to a function
210that deletes a file.")
211
212(vip-deflocalvar vip-vi-minibuffer-minor-mode nil
213 "Minor mode that forces Vi-style when the Minibuffer is in Vi state.")
214
215(vip-deflocalvar vip-insert-minibuffer-minor-mode nil
216 "Minor mode that forces Vi-style when the Minibuffer is in Insert state.")
217
218
219
220;; Some common error messages
221
222(defconst vip-SpuriousText "Spurious text after command" "")
223(defconst vip-BadExCommand "Not an editor command" "")
224(defconst vip-InvalidCommandArgument "Invalid command argument" "")
225(defconst vip-NoPrevSearch "No previous search string" "")
226(defconst vip-EmptyRegister "`%c': Nothing in this register" "")
227(defconst vip-InvalidRegister "`%c': Invalid register" "")
228(defconst vip-EmptyTextmarker "`%c': Text marker doesn't point anywhere" "")
229(defconst vip-InvalidTextmarker "`%c': Invalid text marker" "")
230(defconst vip-InvalidViCommand "Invalid command" "")
231(defconst vip-BadAddress "Ill-formed address" "")
232(defconst vip-FirstAddrExceedsSecond "First address exceeds second" "")
233(defconst vip-NoFileSpecified "No file specified" "")
234
235;; Is t until viper-mode executes for the very first time.
236;; Prevents recursive descend into startup messages.
237(defvar vip-first-time t)
238
239(defvar vip-expert-level 0
240 "User's expert level.
241The minor mode vip-vi-diehard-minor-mode is in effect when
242vip-expert-level is 1 or 2 or when vip-want-emacs-keys-in-vi is t.
243The minor mode vip-insert-diehard-minor-mode is in effect when
244vip-expert-level is 1 or 2 or if vip-want-emacs-keys-in-insert is t.
245Use `M-x vip-set-expert-level' to change this.")
246
247;; Max expert level supported by Viper. This is NOT a user option.
248;; It is here to make it hard for the user from resetting it.
249(defconst vip-max-expert-level 5)
250
251;; Contains user settings for vars affected by vip-set-expert-level function.
252;; Not a user option.
253(defvar vip-saved-user-settings nil)
254
255
256;;; ISO characters
257
258(vip-deflocalvar vip-automatic-iso-accents nil
259 "*If non-nil, ISO accents will be turned on in insert/replace emacs states and turned off in vi-state.
260For some users, this behavior may be too primitive. In this case, use
261insert/emacs/vi state hooks.")
262
263
264;; VI-style Undo
265
266;; Used to 'undo' complex commands, such as replace and insert commands.
267(vip-deflocalvar vip-undo-needs-adjustment nil)
268(put 'vip-undo-needs-adjustment 'permanent-local t)
269
270;; A mark that Viper puts on buffer-undo-list. Marks the beginning of a
271;; complex command that must be undone atomically. If inserted, it is
272;; erased by vip-change-state-to-vi and vip-repeat.
273(defconst vip-buffer-undo-list-mark 'viper)
274
275(defvar vip-keep-point-on-undo nil
276 "*Non-nil means not to move point while undoing commands.
277This style is different from Emacs and Vi. Try it to see if
278it better fits your working style.")
279
280;; Replace mode and changing text
281
282;; Viper's own after/before change functions, which get vip-add-hook'ed to
283;; Emacs's
284(vip-deflocalvar vip-after-change-functions nil "")
285(vip-deflocalvar vip-before-change-functions nil "")
286(vip-deflocalvar vip-post-command-hooks nil "")
287(vip-deflocalvar vip-pre-command-hooks nil "")
288
289;; Can be used to pass global states around for short period of time
290(vip-deflocalvar vip-intermediate-command nil "")
291
292;; Indicates that the current destructive command has started in replace mode.
293(vip-deflocalvar vip-began-as-replace nil "")
294
295(defvar vip-allow-multiline-replace-regions t
296 "If non-nil, Viper will allow multi-line replace regions.
297This is an extension to standard Vi.
298If nil, commands that attempt to replace text spanning multiple lines first
299delete the text being replaced, as in standard Vi.")
300
301(defvar vip-replace-overlay-cursor-color "Red"
302 "*Cursor color to use in Replace state")
303(defvar vip-insert-state-cursor-color nil
304 "Cursor color for Viper insert state.")
305(put 'vip-insert-state-cursor-color 'permanent-local t)
306;; place to save cursor colow when switching to insert mode
307(vip-deflocalvar vip-saved-cursor-color nil "")
308
309(vip-deflocalvar vip-replace-overlay nil "")
310(put 'vip-replace-overlay 'permanent-local t)
311
312(defvar vip-replace-overlay-pixmap "gray3"
313 "Pixmap to use for search face on non-color displays.")
314(defvar vip-search-face-pixmap "gray3"
315 "Pixmap to use for search face on non-color displays.")
316
317
318(defvar vip-replace-region-end-delimiter "$"
319 "A string marking the end of replacement regions.
320It is used only with TTYs or if `vip-use-replace-region-delimiters'
321is non-nil.")
322(defvar vip-replace-region-start-delimiter ""
323 "A string marking the beginning of replacement regions.
324It is used only with TTYs or if `vip-use-replace-region-delimiters'
325is non-nil.")
326(defvar vip-use-replace-region-delimiters (not (vip-has-face-support-p))
327 "*If non-nil, Viper will always use `vip-replace-region-end-delimiter' and
328`vip-replace-region-start-delimiter' to delimit replacement regions, even on
329color displays. By default, the delimiters are used only on TTYs.")
330
331;; XEmacs requires glyphs
332(if vip-xemacs-p
333 (progn
334 (or (glyphp vip-replace-region-end-delimiter)
335 (setq vip-replace-region-end-delimiter
336 (make-glyph vip-replace-region-end-delimiter)))
337 (or (glyphp vip-replace-region-start-delimiter)
338 (setq vip-replace-region-start-delimiter
339 (make-glyph vip-replace-region-start-delimiter)))
340 ))
341
342
343;; These are local marker that must be initialized to nil and moved with
344;; `vip-move-marker-locally'
345;;
346;; Remember the last position inside the replace region.
347(vip-deflocalvar vip-last-posn-in-replace-region nil)
348;; Remember the last position while inserting
349(vip-deflocalvar vip-last-posn-while-in-insert-state nil)
350(put 'vip-last-posn-in-replace-region 'permanent-local t)
351(put 'vip-last-posn-while-in-insert-state 'permanent-local t)
352
353(vip-deflocalvar vip-sitting-in-replace nil "")
354(put 'vip-sitting-in-replace 'permanent-local t)
355
356;; Remember the number of characters that have to be deleted in replace
357;; mode to compensate for the inserted characters.
358(vip-deflocalvar vip-replace-chars-to-delete 0 "")
359(vip-deflocalvar vip-replace-chars-deleted 0 "")
360
361;; Insertion ring and command ring
362(defvar vip-insertion-ring-size 14
363 "The size of the insertion ring.")
364;; The insertion ring.
365(defvar vip-insertion-ring nil)
366;; This is temp insertion ring. Used to do rotation for display purposes.
367;; When rotation just started, it is initialized to vip-insertion-ring.
368(defvar vip-temp-insertion-ring nil)
369(defvar vip-last-inserted-string-from-insertion-ring "")
370
371(defvar vip-command-ring-size 14
372 "The size of the command ring.")
373;; The command ring.
374(defvar vip-command-ring nil)
375;; This is temp command ring. Used to do rotation for display purposes.
376;; When rotation just started, it is initialized to vip-command-ring.
377(defvar vip-temp-command-ring nil)
378
379;; Modes and related variables
380
381;; Current mode. One of: `emacs-state', `vi-state', `insert-state'
382(vip-deflocalvar vip-current-state 'emacs-state)
383
384
385;; Autoindent in insert
386
387;; Variable that keeps track of whether C-t has been pressed.
388(vip-deflocalvar vip-cted nil "")
389
390;; Preserve the indent value, used by C-d in insert mode.
391(vip-deflocalvar vip-current-indent 0)
392
393;; Whether to preserve the indent, used by C-d in insert mode.
394(vip-deflocalvar vip-preserve-indent nil)
395
396(vip-deflocalvar vip-auto-indent nil
397 "*Autoindent if t.")
398(vip-deflocalvar vip-electric-mode t
399 "*If t, enable electric behavior.
400Currently only enables auto-indentation `according to mode'.")
401
402(defconst vip-shift-width 8
403 "*The shiftwidth variable.")
404
405;; Variables for repeating destructive commands
406
407(defconst vip-keep-point-on-repeat t
408 "*If t, don't move point when repeating previous command.
409This is useful for doing repeated changes with the '.' key.
410The user can change this to nil, if she likes when the cursor moves
411to a new place after repeating previous Vi command.")
412
413;; Remember insert point as a marker. This is a local marker that must be
414;; initialized to nil and moved with `vip-move-marker-locally'.
415(vip-deflocalvar vip-insert-point nil)
416(put 'vip-insert-point 'permanent-local t)
417
418;; This remembers the point before dabbrev-expand was called.
419;; If vip-insert-point turns out to be bigger than that, it is reset
420;; back to vip-pre-command-point.
421;; The reason this is needed is because dabbrev-expand (and possibly
422;; others) may jump to before the insertion point, delete something and
423;; then reinsert a bigger piece. For instance: bla^blo
424;; If dabbrev-expand is called after `blo' and ^ undicates vip-insert-point,
425;; then point jumps to the beginning of `blo'. If expansion is found, `blablo'
426;; is deleted, and we have |^, where | denotes point. Next, dabbrev-expand
427;; will insert the expansion, and we get: blablo^
428;; Whatever we insert next goes before the ^, i.e., before the
429;; vip-insert-point marker. So, Viper will think that nothing was
430;; inserted. Remembering the orig position of the marker circumvents the
431;; problem.
432;; We don't know of any command, except dabbrev-expand, that has the same
433;; problem. However, the same trick can be used if such a command is
434;; discovered later.
435;;
436(vip-deflocalvar vip-pre-command-point nil)
437(put 'vip-pre-command-point 'permanent-local t) ; this is probably an overkill
438
439;; This is used for saving inserted text.
440(defvar vip-last-insertion nil)
441
442;; Remembers the last replaced region.
443(defvar vip-last-replace-region "")
444
445;; Remember com point as a marker.
446;; This is a local marker. Should be moved with `vip-move-marker-locally'
447(vip-deflocalvar vip-com-point nil)
448
449;; If non-nil, the value is a list (M-COM VAL COM REG inserted-text cmd-keys)
450;; It is used to re-execute last destructive command.
451;; M-COM is a Lisp symbol representing the function to be executed.
452;; VAL is the prefix argument that was used with that command.
453;; COM is an internal descriptor, such as ?r, ?c, ?C, which contains
454;; additional information on how the function in M-COM is to be handled.
455;; REG is the register used by command
456;; INSERTED-TEXT is text inserted by that command (in case of o, c, C, i, r
457;; commands).
458;; COMMAND-KEYS are the keys that were typed to invoke the command.
459(defvar vip-d-com nil)
460
461;; The character remembered by the Vi `r' command.
462(defvar vip-d-char nil)
463
464;; Name of register to store deleted or yanked strings
465(defvar vip-use-register nil)
466
467
468
469;; Variables for Moves and Searches
470
471;; For use by `;' command.
472(defvar vip-f-char nil)
473
474;; For use by `.' command.
475(defvar vip-F-char nil)
476
477;; For use by `;' command.
478(defvar vip-f-forward nil)
479
480;; For use by `;' command.
481(defvar vip-f-offset nil)
482
483;; Last search string
484(defvar vip-s-string "")
485
486(defvar vip-quote-string "> "
487 "String inserted at the beginning of quoted region.")
488
489;; If t, search is forward.
490(defvar vip-s-forward nil)
491
492(defconst vip-case-fold-search nil
493 "*If not nil, search ignores cases.")
494
495(defconst vip-re-search t
496 "*If not nil, search is reg-exp search, otherwise vanilla search.")
497
498(defvar vip-search-scroll-threshold 2
499 "*If search lands within this threshnold from the window top/bottom,
500the window will be scrolled up or down appropriately, to reveal context.
501If you want Viper search to behave as usual in Vi, set this variable to a
502negative number.")
503
504(defconst vip-re-query-replace t
505 "*If t then do regexp replace, if nil then do string replace.")
506
507(defconst vip-re-replace t
508 "*If t, do regexp replace. nil means do string replace.")
509
510(defvar vip-parse-sexp-ignore-comments t
511 "*If t, `%' ignores the parentheses that occur inside comments.")
512
513(vip-deflocalvar vip-ex-style-motion t
514 "*Ex-style: the commands l,h do not cross lines, etc.")
515
516(vip-deflocalvar vip-ex-style-editing-in-insert t
517 "*The keys ^H, ^? don't jump lines in insert, ESC moves cursor back, etc.
518Note: this doesn't preclude ^H and ^? from deleting characters by moving
519past the insertion point. This is a feature, not a bug. ")
520
521(vip-deflocalvar vip-delete-backwards-in-replace nil
522 "*If t, DEL key will delete characters while moving the cursor backwards.
523If nil, the cursor will move backwards without deleting anything.")
524
525(defconst vip-buffer-search-char nil
526 "*Key bound for buffer-searching.")
527
528(defconst vip-search-wrap-around-t t
529 "*If t, search wraps around.")
530
531(vip-deflocalvar vip-related-files-and-buffers-ring nil
532 "*Ring of file and buffer names that are considered to be related to the
533current buffer.
534These buffers can be cycled through via :R and :P commands.")
535(put 'vip-related-files-and-buffers-ring 'permanent-local t)
536
537;; Used to find out if we are done with searching the current buffer.
538(vip-deflocalvar vip-local-search-start-marker nil)
539;; As above, but global
540(defvar vip-search-start-marker (make-marker))
541
542;; the search overlay
543(vip-deflocalvar vip-search-overlay nil)
544
545
546(defvar vip-heading-start
547 (concat "^\\s-*(\\s-*defun\\s-\\|" ; lisp
548 "^{\\s-*$\\|^[_a-zA-Z][^()]*[()].*{\\s-*$\\|" ; C/C++
549 "^\\s-*class.*{\\|^\\s-*struct.*{\\|^\\s-*enum.*{\\|"
550 "^\\\\[sb][a-z]*{.*}\\s-*$\\|" ; latex
551 "^@node\\|@table\\|^@m?enu\\|^@itemize\\|^@if\\|" ; texinfo
552 "^.+:-") ; prolog
553 "*Regexps for Headings. Used by \[\[ and \]\].")
554
555(defvar vip-heading-end
556 (concat "^}\\|" ; C/C++
557 "^\\\\end{\\|" ; latex
558 "^@end \\|" ; texinfo
559 ")\n\n[ \t\n]*\\|" ; lisp
560 "\\.\\s-*$") ; prolog
561 "*Regexps to end Headings/Sections. Used by \[\].")
562
563
564;; These two vars control the interaction of jumps performed by ' and `.
565;; In this new version, '' doesn't erase the marks set by ``, so one can
566;; use both kinds of jumps interchangeably and without loosing positions
567;; inside the lines.
568
569;; Remembers position of the last jump done using ``'.
570(vip-deflocalvar vip-last-jump nil)
571;; Remembers position of the last jump done using `''.
572(vip-deflocalvar vip-last-jump-ignore 0)
573
574;; History variables
575
576;; History of search strings.
577(defvar vip-search-history (list ""))
578;; History of query-replace strings used as a source.
579(defvar vip-replace1-history nil)
580;; History of query-replace strings used as replacement.
581(defvar vip-replace2-history nil)
582;; History of region quoting strings.
583(defvar vip-quote-region-history (list vip-quote-string))
584;; History of Ex-style commands.
585(defvar vip-ex-history nil)
586;; History of shell commands.
587(defvar vip-shell-history nil)
588
589
590;; Last shell command. There are two of these, one for Ex (in viper-ex)
591;; and one for Vi.
592
593;; Last shell command executed with ! command.
594(defvar vip-last-shell-com nil)
595
596
597
598;;; Miscellaneous
599
600;; don't bark when mark is inactive
601(setq mark-even-if-inactive t)
602
603(defvar vip-inhibit-startup-message nil
604 "Whether Viper startup message should be inhibited.")
605
606(defvar vip-always t
607 "t means, arrange that vi-state will be a default.")
608
609(defvar vip-custom-file-name (vip-convert-standard-file-name "~/.vip")
610 "Viper customisation file.
611This variable must be set _before_ loading Viper.")
612
613
614(defvar vip-spell-function 'ispell-region
615 "Spell function used by #s<move> command to spell.")
616
617(defvar vip-tags-file-name "TAGS"
618 "The tags file used by Viper.")
619
620;; Indicates if we are in the middle of executing a command that takes another
621;; command as an argument, e.g., cw, dw, etc.
622(defvar vip-inside-command-argument-action nil)
623
624;; Minibuffer
625
626(defvar vip-vi-style-in-minibuffer t
627 "If t, use vi-style editing in minibuffer.
628Should be set in `~/.vip' file.")
629
630;; overlay used in the minibuffer to indicate which state it is in
631(vip-deflocalvar vip-minibuffer-overlay nil)
632
633;; Hook, specific to Viper, which is run just *before* exiting the minibuffer.
634;; Beginning with Emacs 19.26, the standard `minibuffer-exit-hook' is run
635;; *after* exiting the minibuffer
636(defvar vip-minibuffer-exit-hook nil)
637
638;; setup emacs-supported vi-style feel
639(setq next-line-add-newlines nil
640 require-final-newline t)
641
642(make-variable-buffer-local 'require-final-newline)
643
644
645;; Mode line
646(defconst vip-vi-state-id "<V> "
647 "Mode line tag identifying the Vi mode of Viper.")
648(defconst vip-emacs-state-id "<E> "
649 "Mode line tag identifying the Emacs mode of Viper.")
650(defconst vip-insert-state-id "<I> "
651 "Mode line tag identifying the Insert mode of Viper.")
652(defconst vip-replace-state-id "<R> "
653 "Mode line tag identifying the Replace mode of Viper.")
654
655;; Viper changes the default mode-line-buffer-identification
656(setq-default mode-line-buffer-identification '(" %b"))
657
658;; Variable displaying the current Viper state in the mode line.
659(vip-deflocalvar vip-mode-string vip-emacs-state-id)
660(or (memq 'vip-mode-string global-mode-string)
661 (setq global-mode-string
662 (append '("" vip-mode-string) (cdr global-mode-string))))
663
664
665(defvar vip-vi-state-hook nil
666 "*Hooks run just before the switch to Vi mode is completed.")
667(defvar vip-insert-state-hook nil
668 "*Hooks run just before the switch to Insert mode is completed.")
669(defvar vip-replace-state-hook nil
670 "*Hooks run just before the switch to Replace mode is completed.")
671(defvar vip-emacs-state-hook nil
672 "*Hooks run just before the switch to Emacs mode is completed.")
673
674(defvar vip-load-hook nil
675 "Hooks run just after loading Viper.")
676
677;;; viper-ex.el ends here
diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el
index f9c09514d79..2ff89a7f6df 100644
--- a/lisp/emulation/viper-keym.el
+++ b/lisp/emulation/viper-keym.el
@@ -1,6 +1,6 @@
1;;; viper-keym.el --- Viper keymaps 1;;; viper-keym.el --- Viper keymaps
2 2
3;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -21,8 +21,26 @@
21 21
22;; Code 22;; Code
23 23
24(provide 'viper-keym)
25
26;; compiler pacifier
27(defvar vip-always)
28(defvar vip-current-state)
29(defvar vip-mode-string)
30(defvar vip-expert-level)
31(defvar vip-ex-style-editing-in-insert)
32(defvar vip-ex-style-motion)
33
34(eval-when-compile
35 (let ((load-path (cons (expand-file-name ".") load-path)))
36 (or (featurep 'viper-util)
37 (load "viper-util.el" nil nil 'nosuffix))
38 ))
39;; end pacifier
40
24(require 'viper-util) 41(require 'viper-util)
25 42
43
26;;; Variables 44;;; Variables
27 45
28(defvar vip-toggle-key "\C-z" 46(defvar vip-toggle-key "\C-z"
@@ -35,6 +53,29 @@ This setting cannot be changed interactively.")
35 "Key used to ESC. 53 "Key used to ESC.
36Must be set in .vip file or prior to loading Viper. 54Must be set in .vip file or prior to loading Viper.
37This setting cannot be changed interactively.") 55This setting cannot be changed interactively.")
56
57;;; Emacs keys in other states.
58
59(defvar vip-want-emacs-keys-in-insert t
60 "*Set to nil if you want complete Vi compatibility in insert mode.
61Complete compatibility with Vi is not recommended for power use of Viper.")
62
63(defvar vip-want-emacs-keys-in-vi t
64 "*Set to nil if you want complete Vi compatibility in Vi mode.
65Full Vi compatibility is not recommended for power use of Viper.")
66
67(defvar vip-no-multiple-ESC t
68 "*If true, multiple ESC in Vi mode will cause bell to ring.
69This is set to t on a windowing terminal and to 'twice on a dumb
70terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this
71enables cursor keys and is generally more convenient, as terminals usually
72don't have a convenient Meta key.
73Setting vip-no-multiple-ESC to nil will allow as many multiple ESC,
74as is allowed by the major mode in effect.")
75
76(defvar vip-want-ctl-h-help nil
77 "*If t then C-h is bound to help-command in insert mode, if nil then it is
78bound to delete-backward-char.")
38 79
39 80
40;;; Keymaps 81;;; Keymaps
@@ -199,8 +240,8 @@ vip-insert-basic-map. Not recommended, except for novice users.")
199 240
200;; Replace keymap 241;; Replace keymap
201(define-key vip-replace-map "\C-t" 'vip-forward-indent) 242(define-key vip-replace-map "\C-t" 'vip-forward-indent)
202(define-key vip-replace-map "\C-j" 'vip-replace-state-exit-cmd) 243(define-key vip-replace-map "\C-j" 'vip-replace-state-carriage-return)
203(define-key vip-replace-map "\C-m" 'vip-replace-state-exit-cmd) 244(define-key vip-replace-map "\C-m" 'vip-replace-state-carriage-return)
204(define-key vip-replace-map "\C-?" 'vip-del-backward-char-in-replace) 245(define-key vip-replace-map "\C-?" 'vip-del-backward-char-in-replace)
205 246
206 247
@@ -400,6 +441,10 @@ Useful in some modes, such as Gnus, MH, etc.")
400(define-key vip-dired-modifier-map ":" 'vip-ex) 441(define-key vip-dired-modifier-map ":" 'vip-ex)
401(define-key vip-dired-modifier-map "/" 'vip-search-forward) 442(define-key vip-dired-modifier-map "/" 'vip-search-forward)
402 443
444(defvar vip-help-modifier-map (make-sparse-keymap)
445 "This map modifies Help mode behavior.")
446(define-key vip-help-modifier-map "q" (if vip-xemacs-p 'help-mode-quit))
447
403 448
404 449
405;;; Code 450;;; Code
@@ -579,6 +624,4 @@ form ((key . function) (key . function) ... )."
579 alist)) 624 alist))
580 625
581 626
582(provide 'viper-keym)
583
584;;; viper-keym.el ends here 627;;; viper-keym.el ends here
diff --git a/lisp/emulation/viper-macs.el b/lisp/emulation/viper-macs.el
index 6b0b2fb99ea..27ac95e5dd7 100644
--- a/lisp/emulation/viper-macs.el
+++ b/lisp/emulation/viper-macs.el
@@ -1,6 +1,6 @@
1;;; viper-macs.el --- functions implementing keyboard macros for Viper 1;;; viper-macs.el --- functions implementing keyboard macros for Viper
2 2
3;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -21,6 +21,26 @@
21 21
22;; Code 22;; Code
23 23
24(provide 'viper-macs)
25
26;; compiler pacifier
27(defvar vip-ex-work-buf)
28(defvar vip-custom-file-name)
29(defvar vip-current-state)
30
31(eval-when-compile
32 (let ((load-path (cons (expand-file-name ".") load-path)))
33 (or (featurep 'viper-util)
34 (load "viper-util.el" nil nil 'nosuffix))
35 (or (featurep 'viper-keym)
36 (load "viper-keym.el" nil nil 'nosuffix))
37 (or (featurep 'viper-mous)
38 (load "viper-mous.el" nil nil 'nosuffix))
39 (or (featurep 'viper)
40 (load "viper.el" nil nil 'nosuffix))
41 ))
42;; end pacifier
43
24(require 'viper-util) 44(require 'viper-util)
25(require 'viper-keym) 45(require 'viper-keym)
26 46
@@ -938,6 +958,4 @@ there."
938 (call-last-kbd-macro))) 958 (call-last-kbd-macro)))
939 959
940 960
941(provide 'viper-macs)
942
943;;; viper-macs.el ends here 961;;; viper-macs.el ends here
diff --git a/lisp/emulation/viper-mous.el b/lisp/emulation/viper-mous.el
index 73cef2eef85..aaab02e5f6c 100644
--- a/lisp/emulation/viper-mous.el
+++ b/lisp/emulation/viper-mous.el
@@ -1,6 +1,6 @@
1;;; viper-mous.el --- mouse support for Viper 1;;; viper-mous.el --- mouse support for Viper
2 2
3;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -21,12 +21,28 @@
21 21
22;; Code 22;; Code
23 23
24(require 'viper-util) 24(provide 'viper-mous)
25 25
26;; compiler pacifier 26;; compiler pacifier
27(defvar double-click-time) 27(defvar double-click-time)
28(defvar mouse-track-multi-click-time) 28(defvar mouse-track-multi-click-time)
29;; end compiler pacifier 29(defvar vip-search-start-marker)
30(defvar vip-local-search-start-marker)
31(defvar vip-search-history)
32(defvar vip-s-string)
33(defvar vip-re-search)
34
35(eval-when-compile
36 (let ((load-path (cons (expand-file-name ".") load-path)))
37 (or (featurep 'viper-util)
38 (load "viper-util.el" nil nil 'nosuffix))
39 (or (featurep 'viper)
40 (load "viper.el" nil nil 'nosuffix))
41 ))
42;; end pacifier
43
44(require 'viper-util)
45
30 46
31 47
32;;; Variables 48;;; Variables
@@ -453,7 +469,4 @@ bindings in viper.el and in the Viper manual."
453 ))) 469 )))
454 470
455 471
456
457(provide 'viper-mous)
458
459;;; viper-mous.el ends here 472;;; viper-mous.el ends here
diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el
index 059e840d3a4..95ac4476a35 100644
--- a/lisp/emulation/viper-util.el
+++ b/lisp/emulation/viper-util.el
@@ -1,6 +1,6 @@
1;;; viper-util.el --- Utilities used by viper.el 1;;; viper-util.el --- Utilities used by viper.el
2 2
3;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. 3;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -22,141 +22,45 @@
22 22
23;; Code 23;; Code
24 24
25(require 'ring)
26
27;; Compiler pacifier 25;; Compiler pacifier
28(defvar vip-overriding-map) 26(defvar vip-overriding-map)
29(defvar pm-color-alist) 27(defvar pm-color-alist)
30(defvar zmacs-region-stays) 28(defvar zmacs-region-stays)
31(defvar vip-search-face)
32(defvar vip-minibuffer-current-face) 29(defvar vip-minibuffer-current-face)
33(defvar vip-minibuffer-insert-face) 30(defvar vip-minibuffer-insert-face)
34(defvar vip-minibuffer-vi-face) 31(defvar vip-minibuffer-vi-face)
35(defvar vip-minibuffer-emacs-face) 32(defvar vip-minibuffer-emacs-face)
36(defvar vip-replace-overlay-face) 33(defvar vip-replace-overlay-face)
37(defvar vip-minibuffer-overlay)
38(defvar vip-replace-overlay)
39(defvar vip-search-overlay)
40(defvar vip-replace-overlay-cursor-color)
41(defvar vip-intermediate-command)
42(defvar vip-use-replace-region-delimiters)
43(defvar vip-fast-keyseq-timeout) 34(defvar vip-fast-keyseq-timeout)
44(defvar vip-related-files-and-buffers-ring) 35(defvar ex-unix-type-shell)
45;; end compiler pacifier 36(defvar ex-unix-type-shell-options)
46 37(defvar vip-ex-tmp-buf-name)
47;; Is it XEmacs? 38
48(defconst vip-xemacs-p (string-match "\\(Lucid\\|XEmacs\\)" emacs-version)) 39(require 'cl)
49;; Is it Emacs? 40(require 'ring)
50(defconst vip-emacs-p (not vip-xemacs-p)) 41
51;; Tell whether we are running as a window application or on a TTY 42(and noninteractive
52(defsubst vip-device-type () 43 (eval-when-compile
53 (if vip-emacs-p 44 (let ((load-path (cons (expand-file-name ".") load-path)))
54 window-system 45 (or (featurep 'viper-init)
55 (device-type (selected-device)))) 46 (load "viper-init.el" nil nil 'nosuffix))
56;; in XEmacs: device-type is tty on tty and stream in batch. 47 )))
57(defun vip-window-display-p () 48;; end pacifier
58 (and (vip-device-type) (not (memq (vip-device-type) '(tty stream pc))))) 49
59 50(require 'viper-init)
60(defvar vip-ms-style-os-p (memq system-type '(ms-dos windows-nt windows-95))
61 "Tells if Emacs is running under an MS-style OS: ms-dos, windows-nt, W95.")
62(defvar vip-vms-os-p (memq system-type '(vax-vms axp-vms))
63 "Tells if Emacs is running under VMS.")
64
65(defvar vip-force-faces nil
66 "If t, Viper will think that it is running on a display that supports faces.
67This is provided as a temporary relief for users of face-capable displays
68that Viper doesn't know about.")
69
70(defun vip-has-face-support-p ()
71 (cond ((vip-window-display-p))
72 (vip-force-faces)
73 (vip-emacs-p (memq (vip-device-type) '(pc)))
74 (vip-xemacs-p (memq (vip-device-type) '(tty pc)))))
75 51
76
77;;; Macros
78
79(defmacro vip-deflocalvar (var default-value &optional documentation)
80 (` (progn
81 (defvar (, var) (, default-value)
82 (, (format "%s\n\(buffer local\)" documentation)))
83 (make-variable-buffer-local '(, var))
84 )))
85
86(defmacro vip-loop (count body)
87 "(vip-loop COUNT BODY) Execute BODY COUNT times."
88 (list 'let (list (list 'count count))
89 (list 'while '(> count 0)
90 body
91 '(setq count (1- count))
92 )))
93 52
94(defmacro vip-buffer-live-p (buf)
95 (` (and (, buf) (get-buffer (, buf)) (buffer-name (get-buffer (, buf))))))
96
97;; return buffer-specific macro definition, given a full macro definition
98(defmacro vip-kbd-buf-alist (macro-elt)
99 (` (nth 1 (, macro-elt))))
100;; get a pair: (curr-buffer . macro-definition)
101(defmacro vip-kbd-buf-pair (macro-elt)
102 (` (assoc (buffer-name) (vip-kbd-buf-alist (, macro-elt)))))
103;; get macro definition for current buffer
104(defmacro vip-kbd-buf-definition (macro-elt)
105 (` (cdr (vip-kbd-buf-pair (, macro-elt)))))
106
107;; return mode-specific macro definitions, given a full macro definition
108(defmacro vip-kbd-mode-alist (macro-elt)
109 (` (nth 2 (, macro-elt))))
110;; get a pair: (major-mode . macro-definition)
111(defmacro vip-kbd-mode-pair (macro-elt)
112 (` (assoc major-mode (vip-kbd-mode-alist (, macro-elt)))))
113;; get macro definition for the current major mode
114(defmacro vip-kbd-mode-definition (macro-elt)
115 (` (cdr (vip-kbd-mode-pair (, macro-elt)))))
116
117;; return global macro definition, given a full macro definition
118(defmacro vip-kbd-global-pair (macro-elt)
119 (` (nth 3 (, macro-elt))))
120;; get global macro definition from an elt of macro-alist
121(defmacro vip-kbd-global-definition (macro-elt)
122 (` (cdr (vip-kbd-global-pair (, macro-elt)))))
123
124;; last elt of a sequence
125(defsubst vip-seq-last-elt (seq)
126 (elt seq (1- (length seq))))
127
128;; Check if arg is a valid character for register
129;; TYPE is a list that can contain `letter', `Letter', and `digit'.
130;; Letter means lowercase letters, Letter means uppercase letters, and
131;; digit means digits from 1 to 9.
132;; If TYPE is nil, then down/uppercase letters and digits are allowed.
133(defun vip-valid-register (reg &optional type)
134 (or type (setq type '(letter Letter digit)))
135 (or (if (memq 'letter type)
136 (and (<= ?a reg) (<= reg ?z)))
137 (if (memq 'digit type)
138 (and (<= ?1 reg) (<= reg ?9)))
139 (if (memq 'Letter type)
140 (and (<= ?A reg) (<= reg ?Z)))
141 ))
142
143;; checks if object is a marker, has a buffer, and points to within that buffer
144(defun vip-valid-marker (marker)
145 (if (and (markerp marker) (marker-buffer marker))
146 (let ((buf (marker-buffer marker))
147 (pos (marker-position marker)))
148 (save-excursion
149 (set-buffer buf)
150 (and (<= pos (point-max)) (<= (point-min) pos))))))
151
152
153(defvar vip-minibuffer-overlay-priority 300)
154(defvar vip-replace-overlay-priority 400)
155(defvar vip-search-overlay-priority 500)
156
157 53
158;;; XEmacs support 54;;; XEmacs support
159 55
56;; A fix for NeXT Step
57;; Should probably be eliminated in later versions.
58(if (and (vip-window-display-p) (eq (vip-device-type) 'ns))
59 (progn
60 (fset 'x-display-color-p (symbol-function 'ns-display-color-p))
61 (fset 'x-color-defined-p (symbol-function 'ns-color-defined-p))
62 ))
63
160(if vip-xemacs-p 64(if vip-xemacs-p
161 (progn 65 (progn
162 (fset 'vip-read-event (symbol-function 'next-command-event)) 66 (fset 'vip-read-event (symbol-function 'next-command-event))
@@ -189,6 +93,7 @@ that Viper doesn't know about.")
189 (fset 'vip-color-defined-p (symbol-function 'x-color-defined-p)) 93 (fset 'vip-color-defined-p (symbol-function 'x-color-defined-p))
190 ))) 94 )))
191 95
96
192(fset 'vip-characterp 97(fset 'vip-characterp
193 (symbol-function 98 (symbol-function
194 (if vip-xemacs-p 'characterp 'integerp))) 99 (if vip-xemacs-p 'characterp 'integerp)))
@@ -242,7 +147,7 @@ that Viper doesn't know about.")
242 (modify-frame-parameters 147 (modify-frame-parameters
243 (selected-frame) (list (cons 'cursor-color new-color))))) 148 (selected-frame) (list (cons 'cursor-color new-color)))))
244 149
245(defsubst vip-save-cursor-color () 150(defun vip-save-cursor-color ()
246 (if (and (vip-window-display-p) (vip-color-display-p)) 151 (if (and (vip-window-display-p) (vip-color-display-p))
247 (let ((color (vip-get-cursor-color))) 152 (let ((color (vip-get-cursor-color)))
248 (if (and (stringp color) (vip-color-defined-p color) 153 (if (and (stringp color) (vip-color-defined-p color)
@@ -257,6 +162,115 @@ that Viper doesn't know about.")
257 (vip-change-cursor-color vip-saved-cursor-color)) 162 (vip-change-cursor-color vip-saved-cursor-color))
258 163
259 164
165;; Face-saving tricks
166
167(defvar vip-search-face
168 (if (vip-has-face-support-p)
169 (progn
170 (make-face 'vip-search-face)
171 (vip-hide-face 'vip-search-face)
172 (or (face-differs-from-default-p 'vip-search-face)
173 ;; face wasn't set in .vip or .Xdefaults
174 (if (vip-can-use-colors "Black" "khaki")
175 (progn
176 (set-face-background 'vip-search-face "khaki")
177 (set-face-foreground 'vip-search-face "Black"))
178 (set-face-underline-p 'vip-search-face t)
179 (vip-set-face-pixmap 'vip-search-face vip-search-face-pixmap)))
180 'vip-search-face))
181 "*Face used to flash out the search pattern.")
182
183(defvar vip-replace-overlay-face
184 (if (vip-has-face-support-p)
185 (progn
186 (make-face 'vip-replace-overlay-face)
187 (vip-hide-face 'vip-replace-overlay-face)
188 (or (face-differs-from-default-p 'vip-replace-overlay-face)
189 (progn
190 (if (vip-can-use-colors "darkseagreen2" "Black")
191 (progn
192 (set-face-background
193 'vip-replace-overlay-face "darkseagreen2")
194 (set-face-foreground 'vip-replace-overlay-face "Black")))
195 (set-face-underline-p 'vip-replace-overlay-face t)
196 (vip-set-face-pixmap
197 'vip-replace-overlay-face vip-replace-overlay-pixmap)))
198 'vip-replace-overlay-face))
199 "*Face for highlighting replace regions on a window display.")
200
201(defvar vip-minibuffer-emacs-face
202 (if (vip-has-face-support-p)
203 (progn
204 (make-face 'vip-minibuffer-emacs-face)
205 (vip-hide-face 'vip-minibuffer-emacs-face)
206 (or (face-differs-from-default-p 'vip-minibuffer-emacs-face)
207 ;; face wasn't set in .vip or .Xdefaults
208 (if vip-vi-style-in-minibuffer
209 ;; emacs state is an exception in the minibuffer
210 (if (vip-can-use-colors "darkseagreen2" "Black")
211 (progn
212 (set-face-background
213 'vip-minibuffer-emacs-face "darkseagreen2")
214 (set-face-foreground
215 'vip-minibuffer-emacs-face "Black"))
216 (copy-face 'modeline 'vip-minibuffer-emacs-face))
217 ;; emacs state is the main state in the minibuffer
218 (if (vip-can-use-colors "Black" "pink")
219 (progn
220 (set-face-background 'vip-minibuffer-emacs-face "pink")
221 (set-face-foreground
222 'vip-minibuffer-emacs-face "Black"))
223 (copy-face 'italic 'vip-minibuffer-emacs-face))
224 ))
225 'vip-minibuffer-emacs-face))
226 "Face used in the Minibuffer when it is in Emacs state.")
227
228(defvar vip-minibuffer-insert-face
229 (if (vip-has-face-support-p)
230 (progn
231 (make-face 'vip-minibuffer-insert-face)
232 (vip-hide-face 'vip-minibuffer-insert-face)
233 (or (face-differs-from-default-p 'vip-minibuffer-insert-face)
234 (if vip-vi-style-in-minibuffer
235 (if (vip-can-use-colors "Black" "pink")
236 (progn
237 (set-face-background 'vip-minibuffer-insert-face "pink")
238 (set-face-foreground
239 'vip-minibuffer-insert-face "Black"))
240 (copy-face 'italic 'vip-minibuffer-insert-face))
241 ;; If Insert state is an exception
242 (if (vip-can-use-colors "darkseagreen2" "Black")
243 (progn
244 (set-face-background
245 'vip-minibuffer-insert-face "darkseagreen2")
246 (set-face-foreground
247 'vip-minibuffer-insert-face "Black"))
248 (copy-face 'modeline 'vip-minibuffer-insert-face))
249 (vip-italicize-face 'vip-minibuffer-insert-face)))
250 'vip-minibuffer-insert-face))
251 "Face used in the Minibuffer when it is in Insert state.")
252
253(defvar vip-minibuffer-vi-face
254 (if (vip-has-face-support-p)
255 (progn
256 (make-face 'vip-minibuffer-vi-face)
257 (vip-hide-face 'vip-minibuffer-vi-face)
258 (or (face-differs-from-default-p 'vip-minibuffer-vi-face)
259 (if vip-vi-style-in-minibuffer
260 (if (vip-can-use-colors "Black" "grey")
261 (progn
262 (set-face-background 'vip-minibuffer-vi-face "grey")
263 (set-face-foreground 'vip-minibuffer-vi-face "Black"))
264 (copy-face 'bold 'vip-minibuffer-vi-face))
265 (copy-face 'bold 'vip-minibuffer-vi-face)
266 (invert-face 'vip-minibuffer-vi-face)))
267 'vip-minibuffer-vi-face))
268 "Face used in the Minibuffer when it is in Vi state.")
269
270;; the current face to be used in the minibuffer
271(vip-deflocalvar vip-minibuffer-current-face vip-minibuffer-emacs-face "")
272
273
260;; Check the current version against the major and minor version numbers 274;; Check the current version against the major and minor version numbers
261;; using op: cur-vers op major.minor If emacs-major-version or 275;; using op: cur-vers op major.minor If emacs-major-version or
262;; emacs-minor-version are not defined, we assume that the current version 276;; emacs-minor-version are not defined, we assume that the current version
@@ -285,8 +299,8 @@ that Viper doesn't know about.")
285 ((memq op '(< <=)) t)))) 299 ((memq op '(< <=)) t))))
286 300
287;;;; warn if it is a wrong version of emacs 301;;;; warn if it is a wrong version of emacs
288;;(if (or (vip-check-version '< 19 29 'emacs) 302;;(if (or (vip-check-version '< 19 35 'emacs)
289;; (vip-check-version '< 19 12 'xemacs)) 303;; (vip-check-version '< 19 15 'xemacs))
290;; (progn 304;; (progn
291;; (with-output-to-temp-buffer " *vip-info*" 305;; (with-output-to-temp-buffer " *vip-info*"
292;; (switch-to-buffer " *vip-info*") 306;; (switch-to-buffer " *vip-info*")
@@ -295,9 +309,9 @@ that Viper doesn't know about.")
295;; 309;;
296;;This version of Viper requires 310;;This version of Viper requires
297;; 311;;
298;;\t Emacs 19.29 and higher 312;;\t Emacs 19.35 and higher
299;;\t OR 313;;\t OR
300;;\t XEmacs 19.12 and higher 314;;\t XEmacs 19.15 and higher
301;; 315;;
302;;It is unlikely to work under Emacs version %s 316;;It is unlikely to work under Emacs version %s
303;;that you are using... " emacs-version)) 317;;that you are using... " emacs-version))
@@ -556,13 +570,6 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
556 (setq tmp (cdr tmp))) 570 (setq tmp (cdr tmp)))
557 (reverse (apply 'append tmp2)))) 571 (reverse (apply 'append tmp2))))
558 572
559(defun vip-convert-standard-file-name (fname)
560 (if vip-emacs-p
561 (convert-standard-filename fname)
562 ;; hopefully, XEmacs adds this functionality
563 fname))
564
565
566 573
567;;; Insertion ring 574;;; Insertion ring
568 575
@@ -774,7 +781,15 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
774 (vip-overlay-put 781 (vip-overlay-put
775 vip-replace-overlay (if vip-emacs-p 'evaporate 'detachable) nil) 782 vip-replace-overlay (if vip-emacs-p 'evaporate 'detachable) nil)
776 (vip-overlay-put 783 (vip-overlay-put
777 vip-replace-overlay 'priority vip-replace-overlay-priority)) 784 vip-replace-overlay 'priority vip-replace-overlay-priority)
785 ;; If Emacs will start supporting overlay maps, as it currently supports
786 ;; text-property maps, we could do away with vip-replace-minor-mode and
787 ;; just have keymap attached to replace overlay.
788 ;;(vip-overlay-put
789 ;; vip-replace-overlay
790 ;; (if vip-xemacs-p 'keymap 'local-map)
791 ;; vip-replace-map)
792 )
778 (if (vip-has-face-support-p) 793 (if (vip-has-face-support-p)
779 (vip-overlay-put vip-replace-overlay 'face vip-replace-overlay-face)) 794 (vip-overlay-put vip-replace-overlay 'face vip-replace-overlay-face))
780 (vip-save-cursor-color) 795 (vip-save-cursor-color)
@@ -782,7 +797,7 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
782 ) 797 )
783 798
784 799
785(defsubst vip-set-replace-overlay-glyphs (before-glyph after-glyph) 800(defun vip-set-replace-overlay-glyphs (before-glyph after-glyph)
786 (if (or (not (vip-has-face-support-p)) 801 (if (or (not (vip-has-face-support-p))
787 vip-use-replace-region-delimiters) 802 vip-use-replace-region-delimiters)
788 (let ((before-name (if vip-xemacs-p 'begin-glyph 'before-string)) 803 (let ((before-name (if vip-xemacs-p 'begin-glyph 'before-string))
@@ -790,7 +805,7 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
790 (vip-overlay-put vip-replace-overlay before-name before-glyph) 805 (vip-overlay-put vip-replace-overlay before-name before-glyph)
791 (vip-overlay-put vip-replace-overlay after-name after-glyph)))) 806 (vip-overlay-put vip-replace-overlay after-name after-glyph))))
792 807
793(defsubst vip-hide-replace-overlay () 808(defun vip-hide-replace-overlay ()
794 (vip-set-replace-overlay-glyphs nil nil) 809 (vip-set-replace-overlay-glyphs nil nil)
795 (vip-restore-cursor-color-after-replace) 810 (vip-restore-cursor-color-after-replace)
796 (vip-restore-cursor-color-after-insert) 811 (vip-restore-cursor-color-after-insert)
@@ -861,7 +876,15 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
861 (let ((ESC-keys '(?\e (control \[) escape)) 876 (let ((ESC-keys '(?\e (control \[) escape))
862 (key (vip-event-key event))) 877 (key (vip-event-key event)))
863 (member key ESC-keys))) 878 (member key ESC-keys)))
864 879
880;; checks if object is a marker, has a buffer, and points to within that buffer
881(defun vip-valid-marker (marker)
882 (if (and (markerp marker) (marker-buffer marker))
883 (let ((buf (marker-buffer marker))
884 (pos (marker-position marker)))
885 (save-excursion
886 (set-buffer buf)
887 (and (<= pos (point-max)) (<= (point-min) pos))))))
865 888
866(defsubst vip-mark-marker () 889(defsubst vip-mark-marker ()
867 (if vip-xemacs-p 890 (if vip-xemacs-p
@@ -886,6 +909,21 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
886 (if vip-xemacs-p 909 (if vip-xemacs-p
887 (setq zmacs-region-stays t))) 910 (setq zmacs-region-stays t)))
888 911
912;; Check if arg is a valid character for register
913;; TYPE is a list that can contain `letter', `Letter', and `digit'.
914;; Letter means lowercase letters, Letter means uppercase letters, and
915;; digit means digits from 1 to 9.
916;; If TYPE is nil, then down/uppercase letters and digits are allowed.
917(defun vip-valid-register (reg &optional type)
918 (or type (setq type '(letter Letter digit)))
919 (or (if (memq 'letter type)
920 (and (<= ?a reg) (<= reg ?z)))
921 (if (memq 'digit type)
922 (and (<= ?1 reg) (<= reg ?9)))
923 (if (memq 'Letter type)
924 (and (<= ?A reg) (<= reg ?Z)))
925 ))
926
889 927
890(defsubst vip-events-to-keys (events) 928(defsubst vip-events-to-keys (events)
891 (cond (vip-xemacs-p (events-to-keys events)) 929 (cond (vip-xemacs-p (events-to-keys events))
@@ -947,6 +985,12 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
947 (set hook hook-value)))) 985 (set hook hook-value))))
948 986
949 987
988;; it is suggested that an event must be copied before it is assigned to
989;; last-command-event in XEmacs
990(defun vip-copy-event (event)
991 (if vip-xemacs-p
992 (copy-event event)
993 event))
950 994
951;; like read-event, but in XEmacs also try to convert to char, if possible 995;; like read-event, but in XEmacs also try to convert to char, if possible
952(defun vip-read-event-convert-to-char () 996(defun vip-read-event-convert-to-char ()
@@ -979,40 +1023,44 @@ to write a custom function, similar to `vip-ex-nontrivial-find-file-unix'."
979(defun vip-event-key (event) 1023(defun vip-event-key (event)
980 (or (and event (eventp event)) 1024 (or (and event (eventp event))
981 (error "vip-event-key: Wrong type argument, eventp, %S" event)) 1025 (error "vip-event-key: Wrong type argument, eventp, %S" event))
982 (let ((mod (event-modifiers event)) 1026 (when (cond (vip-xemacs-p (or (key-press-event-p event)
983 basis) 1027 (mouse-event-p event)))
984 (setq basis 1028 (t t))
985 (cond 1029 (let ((mod (event-modifiers event))
986 (vip-xemacs-p 1030 basis)
987 (cond ((key-press-event-p event) 1031 (setq basis
988 (event-key event)) 1032 (cond
989 ((button-event-p event) 1033 (vip-xemacs-p
990 (concat "mouse-" (prin1-to-string (event-button event)))) 1034 (cond ((key-press-event-p event)
991 (t 1035 (event-key event))
992 (error "vip-event-key: Unknown event, %S" event)))) 1036 ((button-event-p event)
993 (t 1037 (concat "mouse-" (prin1-to-string (event-button event))))
994 ;; Emacs doesn't handle capital letters correctly, since 1038 (t
995 ;; \S-a isn't considered the same as A (it behaves as 1039 (error "vip-event-key: Unknown event, %S" event))))
996 ;; plain `a' instead). So we take care of this here 1040 (t
997 (cond ((and (vip-characterp event) (<= ?A event) (<= event ?Z)) 1041 ;; Emacs doesn't handle capital letters correctly, since
998 (setq mod nil 1042 ;; \S-a isn't considered the same as A (it behaves as
999 event event)) 1043 ;; plain `a' instead). So we take care of this here
1000 ;; Emacs has the oddity whereby characters 128+char 1044 (cond ((and (vip-characterp event) (<= ?A event) (<= event ?Z))
1001 ;; represent M-char *if* this appears inside a string. 1045 (setq mod nil
1002 ;; So, we convert them manually to (meta char). 1046 event event))
1003 ((and (vip-characterp event) (< ?\C-? event) (<= event 255)) 1047 ;; Emacs has the oddity whereby characters 128+char
1004 (setq mod '(meta) 1048 ;; represent M-char *if* this appears inside a string.
1005 event (- event ?\C-? 1))) 1049 ;; So, we convert them manually to (meta char).
1006 (t (event-basic-type event))) 1050 ((and (vip-characterp event)
1007 ))) 1051 (< ?\C-? event) (<= event 255))
1008 (if (vip-characterp basis) 1052 (setq mod '(meta)
1009 (setq basis 1053 event (- event ?\C-? 1)))
1010 (if (= basis ?\C-?) 1054 (t (event-basic-type event)))
1011 (list 'control '\?) ; taking care of an emacs bug 1055 )))
1012 (intern (char-to-string basis))))) 1056 (if (vip-characterp basis)
1013 (if mod 1057 (setq basis
1014 (append mod (list basis)) 1058 (if (= basis ?\C-?)
1015 basis))) 1059 (list 'control '\?) ; taking care of an emacs bug
1060 (intern (char-to-string basis)))))
1061 (if mod
1062 (append mod (list basis))
1063 basis))))
1016 1064
1017(defun vip-key-to-emacs-key (key) 1065(defun vip-key-to-emacs-key (key)
1018 (let (key-name char-p modifiers mod-char-list base-key base-key-name) 1066 (let (key-name char-p modifiers mod-char-list base-key base-key-name)
@@ -1179,7 +1227,7 @@ Must be called in order for changes to `vip-syntax-preference' to take effect."
1179 (append (vconcat vip-ALPHA-char-class) nil))))) 1227 (append (vconcat vip-ALPHA-char-class) nil)))))
1180 )) 1228 ))
1181 1229
1182(defsubst vip-looking-at-separator () 1230(defun vip-looking-at-separator ()
1183 (let ((char (char-after (point)))) 1231 (let ((char (char-after (point))))
1184 (if char 1232 (if char
1185 (or (eq char ?\n) ; RET is always a separator in Vi 1233 (or (eq char ?\n) ; RET is always a separator in Vi
@@ -1189,7 +1237,7 @@ Must be called in order for changes to `vip-syntax-preference' to take effect."
1189(defsubst vip-looking-at-alphasep (&optional addl-chars) 1237(defsubst vip-looking-at-alphasep (&optional addl-chars)
1190 (or (vip-looking-at-separator) (vip-looking-at-alpha addl-chars))) 1238 (or (vip-looking-at-separator) (vip-looking-at-alpha addl-chars)))
1191 1239
1192(defsubst vip-skip-alpha-forward (&optional addl-chars) 1240(defun vip-skip-alpha-forward (&optional addl-chars)
1193 (or (stringp addl-chars) (setq addl-chars "")) 1241 (or (stringp addl-chars) (setq addl-chars ""))
1194 (vip-skip-syntax 1242 (vip-skip-syntax
1195 'forward 1243 'forward
@@ -1200,7 +1248,7 @@ Must be called in order for changes to `vip-syntax-preference' to take effect."
1200 (concat vip-strict-ALPHA-chars addl-chars)) 1248 (concat vip-strict-ALPHA-chars addl-chars))
1201 (t addl-chars)))) 1249 (t addl-chars))))
1202 1250
1203(defsubst vip-skip-alpha-backward (&optional addl-chars) 1251(defun vip-skip-alpha-backward (&optional addl-chars)
1204 (or (stringp addl-chars) (setq addl-chars "")) 1252 (or (stringp addl-chars) (setq addl-chars ""))
1205 (vip-skip-syntax 1253 (vip-skip-syntax
1206 'backward 1254 'backward
@@ -1227,14 +1275,14 @@ Must be called in order for changes to `vip-syntax-preference' to take effect."
1227 (funcall func (concat "^" vip-SEP-char-class) 1275 (funcall func (concat "^" vip-SEP-char-class)
1228 (vip-line-pos (if (eq direction 'forward) 'end 'start))))) 1276 (vip-line-pos (if (eq direction 'forward) 'end 'start)))))
1229 1277
1230(defsubst vip-skip-nonalphasep-forward () 1278(defun vip-skip-nonalphasep-forward ()
1231 (if (eq vip-syntax-preference 'strict-vi) 1279 (if (eq vip-syntax-preference 'strict-vi)
1232 (skip-chars-forward 1280 (skip-chars-forward
1233 (concat "^" vip-strict-SEP-chars vip-strict-ALPHA-chars)) 1281 (concat "^" vip-strict-SEP-chars vip-strict-ALPHA-chars))
1234 (skip-syntax-forward 1282 (skip-syntax-forward
1235 (concat 1283 (concat
1236 "^" vip-ALPHA-char-class vip-SEP-char-class) (vip-line-pos 'end)))) 1284 "^" vip-ALPHA-char-class vip-SEP-char-class) (vip-line-pos 'end))))
1237(defsubst vip-skip-nonalphasep-backward () 1285(defun vip-skip-nonalphasep-backward ()
1238 (if (eq vip-syntax-preference 'strict-vi) 1286 (if (eq vip-syntax-preference 'strict-vi)
1239 (skip-chars-backward 1287 (skip-chars-backward
1240 (concat "^" vip-strict-SEP-chars vip-strict-ALPHA-chars)) 1288 (concat "^" vip-strict-SEP-chars vip-strict-ALPHA-chars))
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el
index 592f15021ac..8527e2ad66a 100644
--- a/lisp/emulation/viper.el
+++ b/lisp/emulation/viper.el
@@ -6,9 +6,9 @@
6;; Keywords: emulations 6;; Keywords: emulations
7;; Author: Michael Kifer <kifer@cs.sunysb.edu> 7;; Author: Michael Kifer <kifer@cs.sunysb.edu>
8 8
9;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. 9;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
10 10
11(defconst viper-version "2.91 of August 5, 1996" 11(defconst viper-version "2.93 of May 20, 1997"
12 "The current version of Viper") 12 "The current version of Viper")
13 13
14;; This file is part of GNU Emacs. 14;; This file is part of GNU Emacs.
@@ -300,7 +300,7 @@
300(require 'cl) 300(require 'cl)
301(require 'ring) 301(require 'ring)
302 302
303(require 'viper-util) 303(provide 'viper)
304 304
305;; Compiler pacifier 305;; Compiler pacifier
306(defvar vip-minibuffer-current-face) 306(defvar vip-minibuffer-current-face)
@@ -309,596 +309,32 @@
309(defvar vip-minibuffer-emacs-face) 309(defvar vip-minibuffer-emacs-face)
310(defvar iso-accents-mode) 310(defvar iso-accents-mode)
311(defvar zmacs-region-stays) 311(defvar zmacs-region-stays)
312;; end pacifier 312(defvar mark-even-if-inactive)
313 313
314 314(eval-when-compile
315;;; Variables 315 (let ((load-path (cons (expand-file-name ".") load-path)))
316 316 (or (featurep 'viper-util)
317;; Is t until viper-mode executes for the very first time. 317 (load "viper-util.el" nil nil 'nosuffix))
318;; Prevents recursive descend into startup messages. 318 (or (featurep 'viper-keym)
319(defvar vip-first-time t) 319 (load "viper-keym.el" nil nil 'nosuffix))
320 320 (or (featurep 'viper-mous)
321(defvar vip-expert-level 0 321 (load "viper-mous.el" nil nil 'nosuffix))
322 "User's expert level. 322 (or (featurep 'viper-macs)
323The minor mode vip-vi-diehard-minor-mode is in effect when 323 (load "viper-macs.el" nil nil 'nosuffix))
324vip-expert-level is 1 or 2 or when vip-want-emacs-keys-in-vi is t. 324 (or (featurep 'viper-ex)
325The minor mode vip-insert-diehard-minor-mode is in effect when 325 (load "viper-ex.el" nil nil 'nosuffix))
326vip-expert-level is 1 or 2 or if vip-want-emacs-keys-in-insert is t.
327Use `M-x vip-set-expert-level' to change this.")
328
329;; Max expert level supported by Viper. This is NOT a user option.
330;; It is here to make it hard for the user from resetting it.
331(defconst vip-max-expert-level 5)
332
333;; Contains user settings for vars affected by vip-set-expert-level function.
334;; Not a user option.
335(defvar vip-saved-user-settings nil)
336
337
338;;; Viper minor modes
339
340;; This is not local in Emacs, so we make it local.
341;; This must be local because although the stack of minor modes can be the same
342;; for all buffers, the associated *keymaps* can be different. In Viper,
343;; vip-vi-local-user-map, vip-insert-local-user-map, and others can have
344;; different keymaps for different buffers.
345;; Also, the keymaps associated with vip-vi/insert-state-modifier-minor-mode
346;; can be different.
347(make-variable-buffer-local 'minor-mode-map-alist)
348
349;; Mode for vital things like \e, C-z.
350(vip-deflocalvar vip-vi-intercept-minor-mode nil)
351
352(vip-deflocalvar vip-vi-basic-minor-mode nil
353 "Viper's minor mode for Vi bindings.")
354
355(vip-deflocalvar vip-vi-local-user-minor-mode nil
356 "Auxiliary minor mode for user-defined local bindings in Vi state.")
357
358(vip-deflocalvar vip-vi-global-user-minor-mode nil
359 "Auxiliary minor mode for user-defined global bindings in Vi state.")
360
361(vip-deflocalvar vip-vi-state-modifier-minor-mode nil
362 "Minor mode used to make major-mode-specific modification to Vi state.")
363
364(vip-deflocalvar vip-vi-diehard-minor-mode nil
365 "This minor mode is in effect when the user wants Viper to be Vi.")
366
367(vip-deflocalvar vip-vi-kbd-minor-mode nil
368 "Minor mode for Ex command macros in Vi state.
369The corresponding keymap stores key bindings of Vi macros defined with
370the Ex command :map.")
371
372;; Mode for vital things like \e, C-z.
373(vip-deflocalvar vip-insert-intercept-minor-mode nil)
374
375(vip-deflocalvar vip-insert-basic-minor-mode nil
376 "Viper's minor mode for bindings in Insert mode.")
377
378(vip-deflocalvar vip-insert-local-user-minor-mode nil
379 "Auxiliary minor mode for buffer-local user-defined bindings in Insert state.
380This is a way to overshadow normal Insert mode bindings locally to certain
381designated buffers.")
382
383(vip-deflocalvar vip-insert-global-user-minor-mode nil
384 "Auxiliary minor mode for global user-defined bindings in Insert state.")
385
386(vip-deflocalvar vip-insert-state-modifier-minor-mode nil
387 "Minor mode used to make major-mode-specific modification to Insert state.")
388
389(vip-deflocalvar vip-insert-diehard-minor-mode nil
390 "Minor mode that simulates Vi very closely.
391Not recommened, except for the novice user.")
392
393(vip-deflocalvar vip-insert-kbd-minor-mode nil
394"Minor mode for Ex command macros Insert state.
395The corresponding keymap stores key bindings of Vi macros defined with
396the Ex command :map!.")
397
398(vip-deflocalvar vip-replace-minor-mode nil
399 "Minor mode in effect in replace state (cw, C, and the like commands).")
400
401;; Mode for vital things like \C-z and \C-x)
402;; This is t, by default. So, any new buffer will have C-z defined as
403;; switch to Vi, unless we switched states in this buffer
404(vip-deflocalvar vip-emacs-intercept-minor-mode t)
405
406(vip-deflocalvar vip-emacs-local-user-minor-mode t
407 "Minor mode for local user bindings effective in Emacs state.
408Users can use it to override Emacs bindings when Viper is in its Emacs
409state.")
410
411(vip-deflocalvar vip-emacs-global-user-minor-mode t
412 "Minor mode for global user bindings in effect in Emacs state.
413Users can use it to override Emacs bindings when Viper is in its Emacs
414state.")
415
416(vip-deflocalvar vip-emacs-kbd-minor-mode t
417 "Minor mode for Vi style macros in Emacs state.
418The corresponding keymap stores key bindings of Vi macros defined with
419`vip-record-kbd-macro' command. There is no Ex-level command to do this
420interactively.")
421
422(vip-deflocalvar vip-emacs-state-modifier-minor-mode t
423 "Minor mode used to make major-mode-specific modification to Emacs state.
424For instance, a Vi purist may want to bind `dd' in Dired mode to a function
425that deletes a file.")
426
427
428
429;;; ISO characters
430
431(vip-deflocalvar vip-automatic-iso-accents nil
432 "*If non-nil, ISO accents will be turned on in insert/replace emacs states and turned off in vi-state.
433For some users, this behavior may be too primitive. In this case, use
434insert/emacs/vi state hooks.")
435
436
437;;; Emacs keys in other states.
438
439(defvar vip-want-emacs-keys-in-insert t
440 "*Set to nil if you want complete Vi compatibility in insert mode.
441Complete compatibility with Vi is not recommended for power use of Viper.")
442
443(defvar vip-want-emacs-keys-in-vi t
444 "*Set to nil if you want complete Vi compatibility in Vi mode.
445Full Vi compatibility is not recommended for power use of Viper.")
446
447
448
449;; VI-style Undo
450
451;; Used to 'undo' complex commands, such as replace and insert commands.
452(vip-deflocalvar vip-undo-needs-adjustment nil)
453(put 'vip-undo-needs-adjustment 'permanent-local t)
454
455;; A mark that Viper puts on buffer-undo-list. Marks the beginning of a
456;; complex command that must be undone atomically. If inserted, it is
457;; erased by vip-change-state-to-vi and vip-repeat.
458(defconst vip-buffer-undo-list-mark 'viper)
459
460(defvar vip-keep-point-on-undo nil
461 "*Non-nil means not to move point while undoing commands.
462This style is different from Emacs and Vi. Try it to see if
463it better fits your working style.")
464
465;; Replace mode and changing text
466
467;; Viper's own after/before change functions, which get vip-add-hook'ed to
468;; Emacs's
469(vip-deflocalvar vip-after-change-functions nil "")
470(vip-deflocalvar vip-before-change-functions nil "")
471(vip-deflocalvar vip-post-command-hooks nil "")
472(vip-deflocalvar vip-pre-command-hooks nil "")
473
474;; Can be used to pass global states around for short period of time
475(vip-deflocalvar vip-intermediate-command nil "")
476
477;; Indicates that the current destructive command has started in replace mode.
478(vip-deflocalvar vip-began-as-replace nil "")
479
480(defvar vip-replace-overlay-cursor-color "Red"
481 "*Cursor color to use in Replace state")
482(defvar vip-insert-state-cursor-color nil
483 "Cursor color for Viper insert state.")
484(put 'vip-insert-state-cursor-color 'permanent-local t)
485;; place to save cursor colow when switching to insert mode
486(vip-deflocalvar vip-saved-cursor-color nil "")
487
488(vip-deflocalvar vip-replace-overlay nil "")
489(put 'vip-replace-overlay 'permanent-local t)
490
491(defvar vip-replace-overlay-pixmap "gray3"
492 "Pixmap to use for search face on non-color displays.")
493(defvar vip-search-face-pixmap "gray3"
494 "Pixmap to use for search face on non-color displays.")
495
496
497(defun vip-set-replace-overlay-face ()
498 (if (vip-has-face-support-p)
499 (defvar vip-replace-overlay-face
500 (progn
501 (make-face 'vip-replace-overlay-face)
502 (vip-hide-face 'vip-replace-overlay-face)
503 (or (face-differs-from-default-p 'vip-replace-overlay-face)
504 (progn
505 (if (vip-can-use-colors "darkseagreen2" "Black")
506 (progn
507 (set-face-background
508 'vip-replace-overlay-face "darkseagreen2")
509 (set-face-foreground 'vip-replace-overlay-face "Black")))
510 (set-face-underline-p 'vip-replace-overlay-face t)
511 (vip-set-face-pixmap
512 'vip-replace-overlay-face vip-replace-overlay-pixmap)))
513 'vip-replace-overlay-face)
514 "*Face for highlighting replace regions on a window display.")
515 )) 326 ))
516 327;; end pacifier
517(defvar vip-replace-region-end-delimiter "$"
518 "A string marking the end of replacement regions.
519It is used only with TTYs or if `vip-use-replace-region-delimiters'
520is non-nil.")
521(defvar vip-replace-region-start-delimiter ""
522 "A string marking the beginning of replacement regions.
523It is used only with TTYs or if `vip-use-replace-region-delimiters'
524is non-nil.")
525(defvar vip-use-replace-region-delimiters (not (vip-has-face-support-p))
526 "*If non-nil, Viper will always use `vip-replace-region-end-delimiter' and
527`vip-replace-region-start-delimiter' to delimit replacement regions, even on
528color displays. By default, the delimiters are used only on TTYs.")
529
530;; XEmacs requires glyphs
531(if vip-xemacs-p
532 (progn
533 (or (glyphp vip-replace-region-end-delimiter)
534 (setq vip-replace-region-end-delimiter
535 (make-glyph vip-replace-region-end-delimiter)))
536 (or (glyphp vip-replace-region-start-delimiter)
537 (setq vip-replace-region-start-delimiter
538 (make-glyph vip-replace-region-start-delimiter)))
539 ))
540
541
542;; These are local marker that must be initialized to nil and moved with
543;; `vip-move-marker-locally'
544;;
545;; Remember the last position inside the replace region.
546(vip-deflocalvar vip-last-posn-in-replace-region nil)
547;; Remember the last position while inserting
548(vip-deflocalvar vip-last-posn-while-in-insert-state nil)
549(put 'vip-last-posn-in-replace-region 'permanent-local t)
550(put 'vip-last-posn-while-in-insert-state 'permanent-local t)
551
552(vip-deflocalvar vip-sitting-in-replace nil "")
553(put 'vip-sitting-in-replace 'permanent-local t)
554
555;; Remember the number of characters that have to be deleted in replace
556;; mode to compensate for the inserted characters.
557(vip-deflocalvar vip-replace-chars-to-delete 0 "")
558(vip-deflocalvar vip-replace-chars-deleted 0 "")
559
560;; Insertion ring and command ring
561(defvar vip-insertion-ring-size 14
562 "The size of the insertion ring.")
563;; The insertion ring.
564(defvar vip-insertion-ring nil)
565;; This is temp insertion ring. Used to do rotation for display purposes.
566;; When rotation just started, it is initialized to vip-insertion-ring.
567(defvar vip-temp-insertion-ring nil)
568(defvar vip-last-inserted-string-from-insertion-ring "")
569
570(defvar vip-command-ring-size 14
571 "The size of the command ring.")
572;; The command ring.
573(defvar vip-command-ring nil)
574;; This is temp command ring. Used to do rotation for display purposes.
575;; When rotation just started, it is initialized to vip-command-ring.
576(defvar vip-temp-command-ring nil)
577
578;; Modes and related variables
579
580;; Current mode. One of: `emacs-state', `vi-state', `insert-state'
581(vip-deflocalvar vip-current-state 'emacs-state)
582
583(defvar vip-no-multiple-ESC t
584 "*If true, multiple ESC in Vi mode will cause bell to ring.
585This is set to t on a windowing terminal and to 'twice on a dumb
586terminal (unless the user level is 1, 2, or 5). On a dumb terminal, this
587enables cursor keys and is generally more convenient, as terminals usually
588don't have a convenient Meta key.
589Setting vip-no-multiple-ESC to nil will allow as many multiple ESC,
590as is allowed by the major mode in effect.")
591
592
593(defvar vip-want-ctl-h-help nil
594 "*If t then C-h is bound to help-command in insert mode, if nil then it is
595bound to delete-backward-char.")
596
597;; Autoindent in insert
598
599;; Variable that keeps track of whether C-t has been pressed.
600(vip-deflocalvar vip-cted nil "")
601
602;; Preserve the indent value, used by C-d in insert mode.
603(vip-deflocalvar vip-current-indent 0)
604
605;; Whether to preserve the indent, used by C-d in insert mode.
606(vip-deflocalvar vip-preserve-indent nil)
607
608(vip-deflocalvar vip-auto-indent nil
609 "*Autoindent if t.")
610(vip-deflocalvar vip-electric-mode t
611 "*If t, enable electric behavior.
612Currently only enables auto-indentation `according to mode'.")
613
614(defconst vip-shift-width 8
615 "*The shiftwidth variable.")
616
617;; Variables for repeating destructive commands
618
619(defconst vip-keep-point-on-repeat t
620 "*If t, don't move point when repeating previous command.
621This is useful for doing repeated changes with the '.' key.
622The user can change this to nil, if she likes when the cursor moves
623to a new place after repeating previous Vi command.")
624
625;; Remember insert point as a marker. This is a local marker that must be
626;; initialized to nil and moved with `vip-move-marker-locally'.
627(vip-deflocalvar vip-insert-point nil)
628(put 'vip-insert-point 'permanent-local t)
629
630;; This remembers the point before dabbrev-expand was called.
631;; If vip-insert-point turns out to be bigger than that, it is reset
632;; back to vip-pre-command-point.
633;; The reason this is needed is because dabbrev-expand (and possibly
634;; others) may jump to before the insertion point, delete something and
635;; then reinsert a bigger piece. For instance: bla^blo
636;; If dabbrev-expand is called after `blo' and ^ undicates vip-insert-point,
637;; then point jumps to the beginning of `blo'. If expansion is found, `blablo'
638;; is deleted, and we have |^, where | denotes point. Next, dabbrev-expand
639;; will insert the expansion, and we get: blablo^
640;; Whatever we insert next goes before the ^, i.e., before the
641;; vip-insert-point marker. So, Viper will think that nothing was
642;; inserted. Remembering the orig position of the marker circumvents the
643;; problem.
644;; We don't know of any command, except dabbrev-expand, that has the same
645;; problem. However, the same trick can be used if such a command is
646;; discovered later.
647;;
648(vip-deflocalvar vip-pre-command-point nil)
649(put 'vip-pre-command-point 'permanent-local t) ; this is probably an overkill
650
651;; This is used for saving inserted text.
652(defvar vip-last-insertion nil)
653
654;; Remembers the last replaced region.
655(defvar vip-last-replace-region "")
656
657;; Remember com point as a marker.
658;; This is a local marker. Should be moved with `vip-move-marker-locally'
659(vip-deflocalvar vip-com-point nil)
660
661;; If non-nil, the value is a list (M-COM VAL COM REG inserted-text cmd-keys)
662;; It is used to re-execute last destructive command.
663;; M-COM is a Lisp symbol representing the function to be executed.
664;; VAL is the prefix argument that was used with that command.
665;; COM is an internal descriptor, such as ?r, ?c, ?C, which contains
666;; additional information on how the function in M-COM is to be handled.
667;; REG is the register used by command
668;; INSERTED-TEXT is text inserted by that command (in case of o, c, C, i, r
669;; commands).
670;; COMMAND-KEYS are the keys that were typed to invoke the command.
671(defvar vip-d-com nil)
672
673;; The character remembered by the Vi `r' command.
674(defvar vip-d-char nil)
675
676;; Name of register to store deleted or yanked strings
677(defvar vip-use-register nil)
678
679
680
681;; Variables for Moves and Searches
682
683;; For use by `;' command.
684(defvar vip-f-char nil)
685
686;; For use by `.' command.
687(defvar vip-F-char nil)
688
689;; For use by `;' command.
690(defvar vip-f-forward nil)
691
692;; For use by `;' command.
693(defvar vip-f-offset nil)
694
695;; Last search string
696(defvar vip-s-string "")
697
698(defvar vip-quote-string "> "
699 "String inserted at the beginning of quoted region.")
700
701;; If t, search is forward.
702(defvar vip-s-forward nil)
703
704(defconst vip-case-fold-search nil
705 "*If not nil, search ignores cases.")
706
707(defconst vip-re-search t
708 "*If not nil, search is reg-exp search, otherwise vanilla search.")
709
710(defvar vip-adjust-window-after-search t
711 "*If not nil, pull the window up or down, depending on the direction of the
712search, if search ends up near the bottom or near the top of the window.")
713
714(defconst vip-re-query-replace t
715 "*If t then do regexp replace, if nil then do string replace.")
716
717(defconst vip-re-replace t
718 "*If t, do regexp replace. nil means do string replace.")
719
720(vip-deflocalvar vip-ex-style-motion t
721 "*Ex-style: the commands l,h do not cross lines, etc.")
722
723(vip-deflocalvar vip-ex-style-editing-in-insert t
724 "*The keys ^H, ^? don't jump lines in insert, ESC moves cursor back, etc.
725Note: this doesn't preclude ^H and ^? from deleting characters by moving
726past the insertion point. This is a feature, not a bug. ")
727
728(vip-deflocalvar vip-delete-backwards-in-replace nil
729 "*If t, DEL key will delete characters while moving the cursor backwards.
730If nil, the cursor will move backwards without deleting anything.")
731 328
732(defconst vip-buffer-search-char nil
733 "*Key bound for buffer-searching.")
734 329
735(defconst vip-search-wrap-around-t t 330(require 'viper-util)
736 "*If t, search wraps around.") 331(require 'viper-keym)
737 332(require 'viper-mous)
738(vip-deflocalvar vip-related-files-and-buffers-ring nil 333(require 'viper-macs)
739 "*Ring of file and buffer names that are considered to be related to the 334(require 'viper-ex)
740current buffer.
741These buffers can be cycled through via :R and :P commands.")
742(put 'vip-related-files-and-buffers-ring 'permanent-local t)
743
744;; Used to find out if we are done with searching the current buffer.
745(vip-deflocalvar vip-local-search-start-marker nil)
746;; As above, but global
747(defvar vip-search-start-marker (make-marker))
748
749;; the search overlay
750(vip-deflocalvar vip-search-overlay nil)
751
752
753(defvar vip-heading-start
754 (concat "^\\s-*(\\s-*defun\\s-\\|" ; lisp
755 "^{\\s-*$\\|^[_a-zA-Z][^()]*[()].*{\\s-*$\\|" ; C/C++
756 "^\\s-*class.*{\\|^\\s-*struct.*{\\|^\\s-*enum.*{\\|"
757 "^\\\\[sb][a-z]*{.*}\\s-*$\\|" ; latex
758 "^@node\\|@table\\|^@m?enu\\|^@itemize\\|^@if\\|" ; texinfo
759 "^.+:-") ; prolog
760 "*Regexps for Headings. Used by \[\[ and \]\].")
761
762(defvar vip-heading-end
763 (concat "^}\\|" ; C/C++
764 "^\\\\end{\\|" ; latex
765 "^@end \\|" ; texinfo
766 ")\n\n[ \t\n]*\\|" ; lisp
767 "\\.\\s-*$") ; prolog
768 "*Regexps to end Headings/Sections. Used by \[\].")
769
770
771;; These two vars control the interaction of jumps performed by ' and `.
772;; In this new version, '' doesn't erase the marks set by ``, so one can
773;; use both kinds of jumps interchangeably and without loosing positions
774;; inside the lines.
775
776;; Remembers position of the last jump done using ``'.
777(vip-deflocalvar vip-last-jump nil)
778;; Remembers position of the last jump done using `''.
779(vip-deflocalvar vip-last-jump-ignore 0)
780
781;; Some common error messages
782
783(defconst vip-SpuriousText "Spurious text after command" "")
784(defconst vip-BadExCommand "Not an editor command" "")
785(defconst vip-InvalidCommandArgument "Invalid command argument" "")
786(defconst vip-NoPrevSearch "No previous search string" "")
787(defconst vip-EmptyRegister "`%c': Nothing in this register" "")
788(defconst vip-InvalidRegister "`%c': Invalid register" "")
789(defconst vip-EmptyTextmarker "`%c': Text marker doesn't point anywhere" "")
790(defconst vip-InvalidTextmarker "`%c': Invalid text marker" "")
791(defconst vip-InvalidViCommand "Invalid command" "")
792(defconst vip-BadAddress "Ill-formed address" "")
793(defconst vip-FirstAddrExceedsSecond "First address exceeds second" "")
794(defconst vip-NoFileSpecified "No file specified" "")
795
796
797;; History variables
798
799;; History of search strings.
800(defvar vip-search-history (list ""))
801;; History of query-replace strings used as a source.
802(defvar vip-replace1-history nil)
803;; History of query-replace strings used as replacement.
804(defvar vip-replace2-history nil)
805;; History of region quoting strings.
806(defvar vip-quote-region-history (list vip-quote-string))
807;; History of Ex-style commands.
808(defvar vip-ex-history nil)
809;; History of shell commands.
810(defvar vip-shell-history nil)
811
812
813;; Last shell command. There are two of these, one for Ex (in viper-ex)
814;; and one for Vi.
815
816;; Last shell command executed with ! command.
817(defvar vip-last-shell-com nil)
818 335
819 336
820 337
821;;; Miscellaneous
822
823;; don't bark when mark is inactive
824(setq mark-even-if-inactive t)
825
826(defvar vip-inhibit-startup-message nil
827 "Whether Viper startup message should be inhibited.")
828
829(defvar vip-always t
830 "t means, arrange that vi-state will be a default.")
831
832(defvar vip-custom-file-name (vip-convert-standard-file-name "~/.vip")
833 "Viper customisation file.
834This variable must be set _before_ loading Viper.")
835
836
837(defvar vip-spell-function 'ispell-region
838 "Spell function used by #s<move> command to spell.")
839
840(defvar vip-tags-file-name "TAGS"
841 "The tags file used by Viper.")
842
843;; Minibuffer
844
845(defvar vip-vi-style-in-minibuffer t
846 "If t, use vi-style editing in minibuffer.
847Should be set in `~/.vip' file.")
848
849;; overlay used in the minibuffer to indicate which state it is in
850(vip-deflocalvar vip-minibuffer-overlay nil)
851
852;; Hook, specific to Viper, which is run just *before* exiting the minibuffer.
853;; Beginning with Emacs 19.26, the standard `minibuffer-exit-hook' is run
854;; *after* exiting the minibuffer
855(defvar vip-minibuffer-exit-hook nil)
856
857(vip-deflocalvar vip-vi-minibuffer-minor-mode nil
858 "Minor mode that forces Vi-style when the Minibuffer is in Vi state.")
859(vip-deflocalvar vip-insert-minibuffer-minor-mode nil
860 "Minor mode that forces Vi-style when the Minibuffer is in Insert state.")
861
862;; setup emacs-supported vi-style feel
863(setq next-line-add-newlines nil
864 require-final-newline t)
865
866(make-variable-buffer-local 'require-final-newline)
867
868
869;; Mode line
870(defconst vip-vi-state-id "<V> "
871 "Mode line tag identifying the Vi mode of Viper.")
872(defconst vip-emacs-state-id "<E> "
873 "Mode line tag identifying the Emacs mode of Viper.")
874(defconst vip-insert-state-id "<I> "
875 "Mode line tag identifying the Insert mode of Viper.")
876(defconst vip-replace-state-id "<R> "
877 "Mode line tag identifying the Replace mode of Viper.")
878
879;; Viper changes the default mode-line-buffer-identification
880(setq-default mode-line-buffer-identification '(" %b"))
881
882;; Variable displaying the current Viper state in the mode line.
883(vip-deflocalvar vip-mode-string vip-emacs-state-id)
884(or (memq 'vip-mode-string global-mode-string)
885 (setq global-mode-string
886 (append '("" vip-mode-string) (cdr global-mode-string))))
887
888
889(defvar vip-vi-state-hook nil
890 "*Hooks run just before the switch to Vi mode is completed.")
891(defvar vip-insert-state-hook nil
892 "*Hooks run just before the switch to Insert mode is completed.")
893(defvar vip-replace-state-hook nil
894 "*Hooks run just before the switch to Replace mode is completed.")
895(defvar vip-emacs-state-hook nil
896 "*Hooks run just before the switch to Emacs mode is completed.")
897
898(defvar vip-load-hook nil
899 "Hooks run just after loading Viper.")
900
901
902;; Generic predicates 338;; Generic predicates
903 339
904;; These test functions are shamelessly lifted from vip 4.4.2 by Aamod Sane 340;; These test functions are shamelessly lifted from vip 4.4.2 by Aamod Sane
@@ -920,46 +356,55 @@ Should be set in `~/.vip' file.")
920 356
921;; Modifying commands that can be prefixes to movement commands 357;; Modifying commands that can be prefixes to movement commands
922(defconst vip-prefix-commands '(?c ?d ?y ?! ?= ?# ?< ?> ?\")) 358(defconst vip-prefix-commands '(?c ?d ?y ?! ?= ?# ?< ?> ?\"))
359;; define vip-prefix-command-p
923(vip-test-com-defun vip-prefix-command) 360(vip-test-com-defun vip-prefix-command)
924 361
925;; Commands that are pairs eg. dd. r and R here are a hack 362;; Commands that are pairs eg. dd. r and R here are a hack
926(defconst vip-charpair-commands '(?c ?d ?y ?! ?= ?< ?> ?r ?R)) 363(defconst vip-charpair-commands '(?c ?d ?y ?! ?= ?< ?> ?r ?R))
364;; define vip-charpair-command-p
927(vip-test-com-defun vip-charpair-command) 365(vip-test-com-defun vip-charpair-command)
928 366
929(defconst vip-movement-commands '(?b ?B ?e ?E ?f ?F ?G ?h ?H ?j ?k ?l 367(defconst vip-movement-commands '(?b ?B ?e ?E ?f ?F ?G ?h ?H ?j ?k ?l
930 ?H ?M ?n ?t ?T ?w ?W ?$ ?% 368 ?H ?M ?L ?n ?t ?T ?w ?W ?$ ?%
931 ?^ ?( ?) ?- ?+ ?| ?{ ?} ?[ ?] ?' ?` 369 ?^ ?( ?) ?- ?+ ?| ?{ ?} ?[ ?] ?' ?`
932 ?; ?, ?0 ?? ?/ 370 ?; ?, ?0 ?? ?/
933 ) 371 )
934 "Movement commands") 372 "Movement commands")
373;; define vip-movement-command-p
935(vip-test-com-defun vip-movement-command) 374(vip-test-com-defun vip-movement-command)
936 375
376(defconst vip-digit-commands '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)
377 "Digit commands")
378;; define vip-digit-command-p
379(vip-test-com-defun vip-digit-command)
380
937;; Commands that can be repeated by . (dotted) 381;; Commands that can be repeated by . (dotted)
938(defconst vip-dotable-commands '(?c ?d ?C ?D ?> ?<)) 382(defconst vip-dotable-commands '(?c ?d ?C ?s ?S ?D ?> ?<))
383;; define vip-dotable-command-p
939(vip-test-com-defun vip-dotable-command) 384(vip-test-com-defun vip-dotable-command)
940 385
941;; Commands that can follow a # 386;; Commands that can follow a #
942(defconst vip-hash-cmds '(?c ?C ?g ?q ?S)) 387(defconst vip-hash-commands '(?c ?C ?g ?q ?s))
943(vip-test-com-defun vip-hash-cmd) 388;; define vip-hash-command-p
389(vip-test-com-defun vip-hash-command)
944 390
945;; Commands that may have registers as prefix 391;; Commands that may have registers as prefix
946(defconst vip-regsuffix-commands '(?d ?y ?Y ?D ?p ?P ?x ?X)) 392(defconst vip-regsuffix-commands '(?d ?y ?Y ?D ?p ?P ?x ?X))
393;; define vip-regsuffix-command-p
947(vip-test-com-defun vip-regsuffix-command) 394(vip-test-com-defun vip-regsuffix-command)
948 395
949(defconst vip-vi-commands (append vip-movement-commands 396(defconst vip-vi-commands (append vip-movement-commands
397 vip-digit-commands
950 vip-dotable-commands 398 vip-dotable-commands
951 vip-charpair-commands 399 vip-charpair-commands
952 vip-hash-cmds 400 vip-hash-commands
953 vip-prefix-commands 401 vip-prefix-commands
954 vip-regsuffix-commands) 402 vip-regsuffix-commands)
955 "The list of all commands in Vi-state.") 403 "The list of all commands in Vi-state.")
404;; define vip-vi-command-p
956(vip-test-com-defun vip-vi-command) 405(vip-test-com-defun vip-vi-command)
957 406
958 407
959;;; Arrange the keymaps
960(require 'viper-keym)
961
962
963;;; CODE 408;;; CODE
964 409
965;; sentinels 410;; sentinels
@@ -1162,7 +607,9 @@ Should be set in `~/.vip' file.")
1162 ;; expert 607 ;; expert
1163 (define-key vip-insert-basic-map "\C-j" nil) 608 (define-key vip-insert-basic-map "\C-j" nil)
1164 ;; novice 609 ;; novice
1165 (define-key vip-insert-basic-map "\C-j" 'vip-autoindent)))) 610 (define-key vip-insert-basic-map "\C-j" 'vip-autoindent)))
611 (define-key vip-insert-basic-map "\C-m" nil)
612 (define-key vip-insert-basic-map "\C-j" nil))
1166 613
1167 (setq vip-insert-diehard-minor-mode 614 (setq vip-insert-diehard-minor-mode
1168 (not vip-want-emacs-keys-in-insert)) 615 (not vip-want-emacs-keys-in-insert))
@@ -1575,10 +1022,10 @@ Vi's prefix argument will be used. Otherwise, the prefix argument passed to
1575 ;; this-command, last-command-char, last-command-event 1022 ;; this-command, last-command-char, last-command-event
1576 (setq this-command com) 1023 (setq this-command com)
1577 (if vip-xemacs-p ; XEmacs represents key sequences as vectors 1024 (if vip-xemacs-p ; XEmacs represents key sequences as vectors
1578 (setq last-command-event (vip-seq-last-elt key) 1025 (setq last-command-event (vip-copy-event (vip-seq-last-elt key))
1579 last-command-char (event-to-character last-command-event)) 1026 last-command-char (event-to-character last-command-event))
1580 ;; Emacs represents them as sequences (str or vec) 1027 ;; Emacs represents them as sequences (str or vec)
1581 (setq last-command-event (vip-seq-last-elt key) 1028 (setq last-command-event (vip-copy-event (vip-seq-last-elt key))
1582 last-command-char last-command-event)) 1029 last-command-char last-command-event))
1583 1030
1584 (if (commandp com) 1031 (if (commandp com)
@@ -1596,7 +1043,12 @@ Vi's prefix argument will be used. Otherwise, the prefix argument passed to
1596 (let ((buff (current-buffer)) 1043 (let ((buff (current-buffer))
1597 result) 1044 result)
1598 (vip-set-mode-vars-for 'vi-state) 1045 (vip-set-mode-vars-for 'vi-state)
1599 (setq result (eval form)) 1046
1047 (condition-case nil
1048 (setq result (eval form))
1049 (error
1050 (signal 'quit nil)))
1051
1600 (if (not (equal buff (current-buffer))) ; cmd switched buffer 1052 (if (not (equal buff (current-buffer))) ; cmd switched buffer
1601 (save-excursion 1053 (save-excursion
1602 (set-buffer buff) 1054 (set-buffer buff)
@@ -1745,7 +1197,7 @@ as a Meta key and any number of multiple escapes is allowed."
1745 (setq last-input-event event 1197 (setq last-input-event event
1746 keyseq (vector (character-to-event ?\e)))) 1198 keyseq (vector (character-to-event ?\e))))
1747 ((eventp first-key) 1199 ((eventp first-key)
1748 (setq last-command-event first-key)) 1200 (setq last-command-event (vip-copy-event first-key)))
1749 )) 1201 ))
1750 ) ; end progn 1202 ) ; end progn
1751 1203
@@ -1814,6 +1266,7 @@ as a Meta key and any number of multiple escapes is allowed."
1814 (t 'vip-change-state-to-vi) 1266 (t 'vip-change-state-to-vi)
1815 ))) 1267 )))
1816 (call-interactively cmd))) 1268 (call-interactively cmd)))
1269
1817 1270
1818 1271
1819 1272
@@ -1857,7 +1310,7 @@ as a Meta key and any number of multiple escapes is allowed."
1857 (let (value func) 1310 (let (value func)
1858 ;; read while number 1311 ;; read while number
1859 (while (and (vip-characterp event) (>= event ?0) (<= event ?9)) 1312 (while (and (vip-characterp event) (>= event ?0) (<= event ?9))
1860 (setq value (+ (* (if (vip-characterp value) value 0) 10) (- event ?0))) 1313 (setq value (+ (* (if (integerp value) value 0) 10) (- event ?0)))
1861 (setq event (vip-read-event-convert-to-char))) 1314 (setq event (vip-read-event-convert-to-char)))
1862 1315
1863 (setq prefix-arg value) 1316 (setq prefix-arg value)
@@ -1880,9 +1333,9 @@ as a Meta key and any number of multiple escapes is allowed."
1880 ;; the user typed, say, d2. In this case, `com' would be `d', `w', 1333 ;; the user typed, say, d2. In this case, `com' would be `d', `w',
1881 ;; etc. 1334 ;; etc.
1882 ;; If vip-digit-argument was invoked by vip-escape-to-vi (which is 1335 ;; If vip-digit-argument was invoked by vip-escape-to-vi (which is
1883 ;; indicated by the fact that the current state is not vi-state, 1336 ;; indicated by the fact that the current state is not vi-state),
1884 ;; then `event' represents the vi command to be executed (e.g., `d', 1337 ;; then `event' represents the vi command to be executed (e.g., `d',
1885 ;; `w', etc. Again, last-command-char must make emacs believe that 1338 ;; `w', etc). Again, last-command-char must make emacs believe that
1886 ;; this is the command we typed. 1339 ;; this is the command we typed.
1887 (setq last-command-char (or com event)) 1340 (setq last-command-char (or com event))
1888 (setq func (vip-exec-form-in-vi 1341 (setq func (vip-exec-form-in-vi
@@ -1931,7 +1384,7 @@ as a Meta key and any number of multiple escapes is allowed."
1931 (setq char (read-char)))) 1384 (setq char (read-char))))
1932 (t 1385 (t
1933 (setq com char) 1386 (setq com char)
1934 (setq char (vip-read-char-exclusive)))))) 1387 (setq char (read-char))))))
1935 1388
1936 (if (atom com) 1389 (if (atom com)
1937 ;; `com' is a single char, so we construct the command argument 1390 ;; `com' is a single char, so we construct the command argument
@@ -1942,8 +1395,12 @@ as a Meta key and any number of multiple escapes is allowed."
1942 (while (= char ?U) 1395 (while (= char ?U)
1943 (vip-describe-arg cmd-info) 1396 (vip-describe-arg cmd-info)
1944 (setq char (read-char))) 1397 (setq char (read-char)))
1945 ;; `char' is a movement command or a digit arg command---so we execute 1398 ;; `char' is a movement cmd, a digit arg cmd, or a register cmd---so we
1946 ;; it at the very end 1399 ;; execute it at the very end
1400 (or (vip-movement-command-p char)
1401 (vip-digit-command-p char)
1402 (vip-regsuffix-command-p char)
1403 (error ""))
1947 (setq mv-or-digit-cmd 1404 (setq mv-or-digit-cmd
1948 (vip-exec-form-in-vi 1405 (vip-exec-form-in-vi
1949 (` (key-binding (char-to-string (, char))))))) 1406 (` (key-binding (char-to-string (, char)))))))
@@ -1973,7 +1430,13 @@ as a Meta key and any number of multiple escapes is allowed."
1973 (if mv-or-digit-cmd 1430 (if mv-or-digit-cmd
1974 (progn 1431 (progn
1975 (setq last-command-char char) 1432 (setq last-command-char char)
1976 (funcall mv-or-digit-cmd cmd-info))) 1433 (setq last-command-event
1434 (vip-copy-event
1435 (if vip-xemacs-p (character-to-event char) char)))
1436 (condition-case nil
1437 (funcall mv-or-digit-cmd cmd-info)
1438 (error
1439 (error "")))))
1977 )) 1440 ))
1978 1441
1979(defun vip-describe-arg (arg) 1442(defun vip-describe-arg (arg)
@@ -1998,20 +1461,21 @@ as a Meta key and any number of multiple escapes is allowed."
1998(defun vip-command-argument (arg) 1461(defun vip-command-argument (arg)
1999 "Accept a motion command as an argument." 1462 "Accept a motion command as an argument."
2000 (interactive "P") 1463 (interactive "P")
2001 (condition-case nil 1464 (let ((vip-inside-command-argument-action t))
2002 (vip-prefix-arg-com 1465 (condition-case nil
2003 last-command-char 1466 (vip-prefix-arg-com
2004 (cond ((null arg) nil) 1467 last-command-char
2005 ((consp arg) (car arg)) 1468 (cond ((null arg) nil)
2006 ((integerp arg) arg) 1469 ((consp arg) (car arg))
2007 (t (error vip-InvalidCommandArgument))) 1470 ((integerp arg) arg)
2008 (cond ((null arg) nil) 1471 (t (error vip-InvalidCommandArgument)))
2009 ((consp arg) (cdr arg)) 1472 (cond ((null arg) nil)
2010 ((integerp arg) nil) 1473 ((consp arg) (cdr arg))
2011 (t (error vip-InvalidCommandArgument)))) 1474 ((integerp arg) nil)
2012 (quit (setq vip-use-register nil) 1475 (t (error vip-InvalidCommandArgument))))
2013 (signal 'quit nil))) 1476 (quit (setq vip-use-register nil)
2014 (vip-deactivate-mark)) 1477 (signal 'quit nil)))
1478 (vip-deactivate-mark)))
2015 1479
2016 1480
2017;; repeat last destructive command 1481;; repeat last destructive command
@@ -2048,6 +1512,8 @@ as a Meta key and any number of multiple escapes is allowed."
2048 1512
2049;; invoked by the `C' command 1513;; invoked by the `C' command
2050(defun vip-exec-change (m-com com) 1514(defun vip-exec-change (m-com com)
1515 (or (and (markerp vip-com-point) (marker-position vip-com-point))
1516 (set-marker vip-com-point (point) (current-buffer)))
2051 ;; handle C cmd at the eol and at eob. 1517 ;; handle C cmd at the eol and at eob.
2052 (if (or (and (eolp) (= vip-com-point (point))) 1518 (if (or (and (eolp) (= vip-com-point (point)))
2053 (= vip-com-point (point-max))) 1519 (= vip-com-point (point-max)))
@@ -2081,6 +1547,8 @@ as a Meta key and any number of multiple escapes is allowed."
2081 (if (= com ?C) (vip-change-mode-to-insert) (vip-yank-last-insertion))) 1547 (if (= com ?C) (vip-change-mode-to-insert) (vip-yank-last-insertion)))
2082 1548
2083(defun vip-exec-delete (m-com com) 1549(defun vip-exec-delete (m-com com)
1550 (or (and (markerp vip-com-point) (marker-position vip-com-point))
1551 (set-marker vip-com-point (point) (current-buffer)))
2084 (if vip-use-register 1552 (if vip-use-register
2085 (progn 1553 (progn
2086 (cond ((vip-valid-register vip-use-register '(letter digit)) 1554 (cond ((vip-valid-register vip-use-register '(letter digit))
@@ -2123,6 +1591,8 @@ as a Meta key and any number of multiple escapes is allowed."
2123 (back-to-indentation)) 1591 (back-to-indentation))
2124 1592
2125(defun vip-exec-yank (m-com com) 1593(defun vip-exec-yank (m-com com)
1594 (or (and (markerp vip-com-point) (marker-position vip-com-point))
1595 (set-marker vip-com-point (point) (current-buffer)))
2126 (if vip-use-register 1596 (if vip-use-register
2127 (progn 1597 (progn
2128 (cond ((vip-valid-register vip-use-register '(letter digit)) 1598 (cond ((vip-valid-register vip-use-register '(letter digit))
@@ -2331,7 +1801,8 @@ invokes the command before that, etc."
2331 )) 1801 ))
2332 1802
2333 1803
2334;; This command is invoked interactively by the key sequence #<char> 1804;; The hash-command. It is invoked interactively by the key sequence #<char>.
1805;; The chars that can follow `#' are determined by vip-hash-command-p
2335(defun vip-special-prefix-com (char) 1806(defun vip-special-prefix-com (char)
2336 (cond ((= char ?c) 1807 (cond ((= char ?c)
2337 (downcase-region (min vip-com-point (point)) 1808 (downcase-region (min vip-com-point (point))
@@ -2633,100 +2104,6 @@ Undo previous insertion and inserts new."
2633 (command-execute command) 2104 (command-execute command)
2634 (exit-minibuffer)))) 2105 (exit-minibuffer))))
2635 2106
2636
2637(defun vip-set-search-face ()
2638 (if (vip-has-face-support-p)
2639 (defvar vip-search-face
2640 (progn
2641 (make-face 'vip-search-face)
2642 (vip-hide-face 'vip-search-face)
2643 (or (face-differs-from-default-p 'vip-search-face)
2644 ;; face wasn't set in .vip or .Xdefaults
2645 (if (vip-can-use-colors "Black" "khaki")
2646 (progn
2647 (set-face-background 'vip-search-face "khaki")
2648 (set-face-foreground 'vip-search-face "Black"))
2649 (set-face-underline-p 'vip-search-face t)
2650 (vip-set-face-pixmap 'vip-search-face vip-search-face-pixmap)))
2651 'vip-search-face)
2652 "*Face used to flash out the search pattern.")
2653 ))
2654
2655
2656(defun vip-set-minibuffer-faces ()
2657 (if (not (vip-has-face-support-p))
2658 ()
2659 (defvar vip-minibuffer-emacs-face
2660 (progn
2661 (make-face 'vip-minibuffer-emacs-face)
2662 (vip-hide-face 'vip-minibuffer-emacs-face)
2663 (or (face-differs-from-default-p 'vip-minibuffer-emacs-face)
2664 ;; face wasn't set in .vip or .Xdefaults
2665 (if vip-vi-style-in-minibuffer
2666 ;; emacs state is an exception in the minibuffer
2667 (if (vip-can-use-colors "darkseagreen2" "Black")
2668 (progn
2669 (set-face-background
2670 'vip-minibuffer-emacs-face "darkseagreen2")
2671 (set-face-foreground
2672 'vip-minibuffer-emacs-face "Black"))
2673 (copy-face 'modeline 'vip-minibuffer-emacs-face))
2674 ;; emacs state is the main state in the minibuffer
2675 (if (vip-can-use-colors "Black" "pink")
2676 (progn
2677 (set-face-background 'vip-minibuffer-emacs-face "pink")
2678 (set-face-foreground
2679 'vip-minibuffer-emacs-face "Black"))
2680 (copy-face 'italic 'vip-minibuffer-emacs-face))
2681 ))
2682 'vip-minibuffer-emacs-face)
2683 "Face used in the Minibuffer when it is in Emacs state.")
2684
2685 (defvar vip-minibuffer-insert-face
2686 (progn
2687 (make-face 'vip-minibuffer-insert-face)
2688 (vip-hide-face 'vip-minibuffer-insert-face)
2689 (or (face-differs-from-default-p 'vip-minibuffer-insert-face)
2690 (if vip-vi-style-in-minibuffer
2691 (if (vip-can-use-colors "Black" "pink")
2692 (progn
2693 (set-face-background 'vip-minibuffer-insert-face "pink")
2694 (set-face-foreground
2695 'vip-minibuffer-insert-face "Black"))
2696 (copy-face 'italic 'vip-minibuffer-insert-face))
2697 ;; If Insert state is an exception
2698 (if (vip-can-use-colors "darkseagreen2" "Black")
2699 (progn
2700 (set-face-background
2701 'vip-minibuffer-insert-face "darkseagreen2")
2702 (set-face-foreground
2703 'vip-minibuffer-insert-face "Black"))
2704 (copy-face 'modeline 'vip-minibuffer-insert-face))
2705 (vip-italicize-face 'vip-minibuffer-insert-face)))
2706 'vip-minibuffer-insert-face)
2707 "Face used in the Minibuffer when it is in Insert state.")
2708
2709 (defvar vip-minibuffer-vi-face
2710 (progn
2711 (make-face 'vip-minibuffer-vi-face)
2712 (vip-hide-face 'vip-minibuffer-vi-face)
2713 (or (face-differs-from-default-p 'vip-minibuffer-vi-face)
2714 (if vip-vi-style-in-minibuffer
2715 (if (vip-can-use-colors "Black" "grey")
2716 (progn
2717 (set-face-background 'vip-minibuffer-vi-face "grey")
2718 (set-face-foreground 'vip-minibuffer-vi-face "Black"))
2719 (copy-face 'bold 'vip-minibuffer-vi-face))
2720 (copy-face 'bold 'vip-minibuffer-vi-face)
2721 (invert-face 'vip-minibuffer-vi-face)))
2722 'vip-minibuffer-vi-face)
2723 "Face used in the Minibuffer when it is in Vi state.")
2724
2725 ;; the current face used in the minibuffer
2726 (vip-deflocalvar vip-minibuffer-current-face vip-minibuffer-emacs-face "")
2727 ))
2728
2729
2730 2107
2731;;; Reading string with history 2108;;; Reading string with history
2732 2109
@@ -2968,6 +2345,10 @@ Undo previous insertion and inserts new."
2968 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel t) 2345 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel t)
2969 (vip-add-hook 2346 (vip-add-hook
2970 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t) 2347 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t)
2348 ;; guard against a smartie who switched from R-replace to normal replace
2349 (vip-remove-hook
2350 'vip-post-command-hooks 'vip-R-state-post-command-sentinel)
2351 (if overwrite-mode (overwrite-mode nil))
2971 ) 2352 )
2972 2353
2973 2354
@@ -3043,9 +2424,11 @@ Undo previous insertion and inserts new."
3043 )) 2424 ))
3044 2425
3045 (setq vip-replace-chars-to-delete 2426 (setq vip-replace-chars-to-delete
3046 (max 0 (min vip-replace-chars-to-delete 2427 (max 0
3047 (- (vip-replace-end) 2428 (min vip-replace-chars-to-delete
3048 vip-last-posn-in-replace-region)))) 2429 (- (vip-replace-end) vip-last-posn-in-replace-region)
2430 (- (vip-line-pos 'end) vip-last-posn-in-replace-region)
2431 )))
3049 ))) 2432 )))
3050 2433
3051 2434
@@ -3097,6 +2480,9 @@ Undo previous insertion and inserts new."
3097 'vip-post-command-hooks 'vip-R-state-post-command-sentinel t) 2480 'vip-post-command-hooks 'vip-R-state-post-command-sentinel t)
3098 (vip-add-hook 2481 (vip-add-hook
3099 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t) 2482 'vip-pre-command-hooks 'vip-replace-state-pre-command-sentinel t)
2483 ;; guard against a smartie who switched from R-replace to normal replace
2484 (vip-remove-hook
2485 'vip-post-command-hooks 'vip-replace-state-post-command-sentinel)
3100 ) 2486 )
3101 2487
3102 2488
@@ -3121,6 +2507,29 @@ These keys are ESC, RET, and LineFeed"
3121 ) 2507 )
3122 (vip-hide-replace-overlay)) 2508 (vip-hide-replace-overlay))
3123 2509
2510(defun vip-replace-state-carriage-return ()
2511 "Implements carriage return in Viper replace state."
2512 (interactive)
2513 ;; If Emacs start supporting overlay maps, as it currently supports
2514 ;; text-property maps, we could do away with vip-replace-minor-mode and
2515 ;; just have keymap attached to replace overlay. Then the "if part" of this
2516 ;; statement can be deleted.
2517 (if (or (< (point) (vip-replace-start))
2518 (> (point) (vip-replace-end)))
2519 (let (vip-replace-minor-mode com)
2520 (vip-set-unread-command-events last-input-char)
2521 (setq com (key-binding (read-key-sequence nil)))
2522 (condition-case conds
2523 (command-execute com)
2524 (error
2525 (vip-message-conditions conds))))
2526 (if (not vip-allow-multiline-replace-regions)
2527 (vip-replace-state-exit-cmd)
2528 (if (vip-same-line (point) (vip-replace-end))
2529 (vip-replace-state-exit-cmd)
2530 (vip-kill-line nil)
2531 (vip-next-line-at-bol nil)))))
2532
3124 2533
3125;; This is the function bound to 'R'---unlimited replace. 2534;; This is the function bound to 'R'---unlimited replace.
3126;; Similar to Emacs's own overwrite-mode. 2535;; Similar to Emacs's own overwrite-mode.
@@ -3516,14 +2925,19 @@ On reaching beginning of line, stop and signal error."
3516 (interactive "P") 2925 (interactive "P")
3517 (vip-leave-region-active) 2926 (vip-leave-region-active)
3518 (let ((val (vip-p-val arg)) 2927 (let ((val (vip-p-val arg))
3519 (com (vip-getcom arg))) 2928 (com (vip-getcom arg))
3520 (save-excursion 2929 line-len)
3521 (end-of-line) 2930 (setq line-len (- (vip-line-pos 'end) (vip-line-pos 'start)))
3522 (if (> val (1+ (current-column))) (error "")))
3523 (if com (vip-move-marker-locally 'vip-com-point (point))) 2931 (if com (vip-move-marker-locally 'vip-com-point (point)))
3524 (beginning-of-line) 2932 (beginning-of-line)
3525 (forward-char (1- val)) 2933 (forward-char (1- (min line-len val)))
3526 (if com (vip-execute-com 'vip-goto-col val com)))) 2934 (while (> (current-column) (1- val))
2935 (backward-char 1))
2936 (if com (vip-execute-com 'vip-goto-col val com))
2937 (save-excursion
2938 (end-of-line)
2939 (if (> val (current-column)) (error "")))
2940 ))
3527 2941
3528 2942
3529(defun vip-next-line (arg) 2943(defun vip-next-line (arg)
@@ -3874,10 +3288,11 @@ controlled by the sign of prefix numeric value."
3874 (interactive "p") 3288 (interactive "p")
3875 (recenter (- (window-height) (1+ arg)))) 3289 (recenter (- (window-height) (1+ arg))))
3876 3290
3877;; If vip-adjust-window-after-search is t, scroll up or down 1/4 of window 3291;; If point is within vip-search-scroll-threshold of window top or bottom,
3878;; height, depending on whether we are at the bottom or at the top of the 3292;; scroll up or down 1/7 of window height, depending on whether we are at the
3879;; window. This function is called by vip-search (which is called from 3293;; bottom or at the top of the window. This function is called by vip-search
3880;; vip-search-forward/backward/next) 3294;; (which is called from vip-search-forward/backward/next). If the value of
3295;; vip-search-scroll-threshold is negative - don't scroll.
3881(defun vip-adjust-window () 3296(defun vip-adjust-window ()
3882 (let ((win-height (if vip-emacs-p 3297 (let ((win-height (if vip-emacs-p
3883 (1- (window-height)) ; adjust for modeline 3298 (1- (window-height)) ; adjust for modeline
@@ -3887,15 +3302,18 @@ controlled by the sign of prefix numeric value."
3887 min-scroll direction) 3302 min-scroll direction)
3888 (save-excursion 3303 (save-excursion
3889 (move-to-window-line 0) ; top 3304 (move-to-window-line 0) ; top
3890 (setq at-top-p (<= (count-lines pt (point)) 2)) 3305 (setq at-top-p
3306 (<= (count-lines pt (point))
3307 vip-search-scroll-threshold))
3891 (move-to-window-line -1) ; bottom 3308 (move-to-window-line -1) ; bottom
3892 (setq at-bottom-p (<= (count-lines pt (point)) 2)) 3309 (setq at-bottom-p
3310 (<= (count-lines pt (point)) vip-search-scroll-threshold))
3893 ) 3311 )
3894 (cond (at-top-p (setq min-scroll 1 3312 (cond (at-top-p (setq min-scroll (1- vip-search-scroll-threshold)
3895 direction 1)) 3313 direction 1))
3896 (at-bottom-p (setq min-scroll 2 3314 (at-bottom-p (setq min-scroll (1+ vip-search-scroll-threshold)
3897 direction -1))) 3315 direction -1)))
3898 (if (and vip-adjust-window-after-search min-scroll) 3316 (if min-scroll
3899 (recenter 3317 (recenter
3900 (* (max min-scroll (/ win-height 7)) direction))) 3318 (* (max min-scroll (/ win-height 7)) direction)))
3901 )) 3319 ))
@@ -3911,7 +3329,8 @@ controlled by the sign of prefix numeric value."
3911 (interactive "P") 3329 (interactive "P")
3912 (vip-leave-region-active) 3330 (vip-leave-region-active)
3913 (let ((com (vip-getcom arg)) 3331 (let ((com (vip-getcom arg))
3914 parse-sexp-ignore-comments anchor-point) 3332 (parse-sexp-ignore-comments vip-parse-sexp-ignore-comments)
3333 anchor-point)
3915 (if (integerp arg) 3334 (if (integerp arg)
3916 (if (or (> arg 99) (< arg 1)) 3335 (if (or (> arg 99) (< arg 1))
3917 (error "Prefix must be between 1 and 99") 3336 (error "Prefix must be between 1 and 99")
@@ -3954,6 +3373,13 @@ controlled by the sign of prefix numeric value."
3954 (if com (vip-execute-com 'vip-paren-match nil com))) 3373 (if com (vip-execute-com 'vip-paren-match nil com)))
3955 (t (error "")))))) 3374 (t (error ""))))))
3956 3375
3376(defun vip-toggle-parse-sexp-ignore-comments ()
3377 (interactive)
3378 (setq vip-parse-sexp-ignore-comments (not vip-parse-sexp-ignore-comments))
3379 (prin1 (format "`%%' will %signore parentheses inside the comments"
3380 (if vip-parse-sexp-ignore-comments "" "NOT ")))
3381 )
3382
3957 3383
3958;; sentence ,paragraph and heading 3384;; sentence ,paragraph and heading
3959 3385
@@ -4322,6 +3748,7 @@ Null string will repeat previous search."
4322 ;; highlight the result of search 3748 ;; highlight the result of search
4323 ;; don't wait and don't highlight in macros 3749 ;; don't wait and don't highlight in macros
4324 (or executing-kbd-macro 3750 (or executing-kbd-macro
3751 vip-inside-command-argument-action
4325 (vip-flash-search-pattern)) 3752 (vip-flash-search-pattern))
4326 ))) 3753 )))
4327 3754
@@ -4424,7 +3851,8 @@ Null string will repeat previous search."
4424 (error "Buffer not killed")))) 3851 (error "Buffer not killed"))))
4425 3852
4426 3853
4427(defvar vip-smart-suffix-list '("" "tex" "c" "cc" "el" "p") 3854(defvar vip-smart-suffix-list
3855 '("" "tex" "c" "cc" "C" "el" "java" "html" "htm" "pl" "P" "p")
4428 "*List of suffixes that Viper automatically tries to append to filenames ending with a `.'. 3856 "*List of suffixes that Viper automatically tries to append to filenames ending with a `.'.
4429This is useful when you the current directory contains files with the same 3857This is useful when you the current directory contains files with the same
4430prefix and many different suffixes. Usually, only one of the suffixes 3858prefix and many different suffixes. Usually, only one of the suffixes
@@ -4482,18 +3910,38 @@ To turn this feature off, set this variable to nil.")
4482 3910
4483(defadvice find-file (before vip-add-suffix-advice activate) 3911(defadvice find-file (before vip-add-suffix-advice activate)
4484 "Use `read-file-name' for reading arguments." 3912 "Use `read-file-name' for reading arguments."
4485 (interactive (list (read-file-name "Find file: " 3913 (interactive (cons (read-file-name "Find file: " nil default-directory)
4486 nil default-directory)))) 3914 ;; if Mule and prefix argument, ask for coding system
3915 (if (or (boundp 'MULE) ; mule integrated Emacs 19
3916 (featurep 'mule)) ; mule integrated XEmacs 20
3917 (list
3918 (and current-prefix-arg
3919 (read-coding-system "Coding-system: "))))
3920 )))
4487 3921
4488(defadvice find-file-other-window (before vip-add-suffix-advice activate) 3922(defadvice find-file-other-window (before vip-add-suffix-advice activate)
4489 "Use `read-file-name' for reading arguments." 3923 "Use `read-file-name' for reading arguments."
4490 (interactive (list (read-file-name "Find file in other window: " 3924 (interactive (cons (read-file-name "Find file in other window: "
4491 nil default-directory)))) 3925 nil default-directory)
3926 ;; if Mule and prefix argument, ask for coding system
3927 (if (or (boundp 'MULE) ; mule integrated Emacs 19
3928 (featurep 'mule)) ; mule integrated XEmacs 20
3929 (list
3930 (and current-prefix-arg
3931 (read-coding-system "Coding-system: "))))
3932 )))
4492 3933
4493(defadvice find-file-other-frame (before vip-add-suffix-advice activate) 3934(defadvice find-file-other-frame (before vip-add-suffix-advice activate)
4494 "Use `read-file-name' for reading arguments." 3935 "Use `read-file-name' for reading arguments."
4495 (interactive (list (read-file-name "Find file in other frame: " 3936 (interactive (cons (read-file-name "Find file in other frame: "
4496 nil default-directory)))) 3937 nil default-directory)
3938 ;; if Mule and prefix argument, ask for coding system
3939 (if (or (boundp 'MULE) ; mule integrated Emacs 19
3940 (featurep 'mule)) ; mule integrated XEmacs 20
3941 (list
3942 (and current-prefix-arg
3943 (read-coding-system "Coding-system: "))))
3944 )))
4497 3945
4498(defadvice read-file-name (around vip-suffix-advice activate) 3946(defadvice read-file-name (around vip-suffix-advice activate)
4499 "Tell `exit-minibuffer' to run `vip-file-add-suffix' as a hook." 3947 "Tell `exit-minibuffer' to run `vip-file-add-suffix' as a hook."
@@ -4723,8 +4171,9 @@ cursor move past the beginning of line."
4723 ;; protect against error while inserting "@" and other disasters 4171 ;; protect against error while inserting "@" and other disasters
4724 ;; (e.g., read-only buff) 4172 ;; (e.g., read-only buff)
4725 (condition-case conds 4173 (condition-case conds
4726 (if (vip-same-line (vip-replace-start) 4174 (if (or vip-allow-multiline-replace-regions
4727 (vip-replace-end)) 4175 (vip-same-line (vip-replace-start)
4176 (vip-replace-end)))
4728 (progn 4177 (progn
4729 ;; tabs cause problems in replace, so untabify 4178 ;; tabs cause problems in replace, so untabify
4730 (goto-char (vip-replace-end)) 4179 (goto-char (vip-replace-end))
@@ -4844,16 +4293,16 @@ and regexp replace."
4844(defun vip-mark-point () 4293(defun vip-mark-point ()
4845 "Set mark at point of buffer." 4294 "Set mark at point of buffer."
4846 (interactive) 4295 (interactive)
4847 (let ((char (vip-read-char-exclusive))) 4296 (let ((char (read-char)))
4848 (cond ((and (<= ?a char) (<= char ?z)) 4297 (cond ((and (<= ?a char) (<= char ?z))
4849 (point-to-register (1+ (- char ?a)))) 4298 (point-to-register (1+ (- char ?a))))
4850 ((= char ?<) (vip-mark-beginning-of-buffer)) 4299 ((= char ?<) (vip-mark-beginning-of-buffer))
4851 ((= char ?>) (vip-mark-end-of-buffer)) 4300 ((= char ?>) (vip-mark-end-of-buffer))
4852 ((= char ?.) (vip-set-mark-if-necessary)) 4301 ((= char ?.) (vip-set-mark-if-necessary))
4853 ((= char ?,) (vip-cycle-through-mark-ring)) 4302 ((= char ?,) (vip-cycle-through-mark-ring))
4854 ((= char ?D) (mark-defun)) 4303 ((= char ?D) (mark-defun))
4855 (t (error "")) 4304 (t (error ""))
4856 ))) 4305 )))
4857 4306
4858;; Algorithm: If first invocation of this command save mark on ring, goto 4307;; Algorithm: If first invocation of this command save mark on ring, goto
4859;; mark, M0, and pop the most recent elt from the mark ring into mark, 4308;; mark, M0, and pop the most recent elt from the mark ring into mark,
@@ -5012,6 +4461,7 @@ One can use `` and '' to temporarily jump 1 step back."
5012 "Auto Indentation, Vi-style." 4461 "Auto Indentation, Vi-style."
5013 (interactive) 4462 (interactive)
5014 (let ((col (current-indentation))) 4463 (let ((col (current-indentation)))
4464 (if abbrev-mode (expand-abbrev))
5015 (if vip-preserve-indent 4465 (if vip-preserve-indent
5016 (setq vip-preserve-indent nil) 4466 (setq vip-preserve-indent nil)
5017 (setq vip-current-indent col)) 4467 (setq vip-current-indent col))
@@ -5547,13 +4997,6 @@ Mail anyway (y or n)? ")
5547 4997
5548 4998
5549 4999
5550;;; Bring in the rest of the files
5551(require 'viper-mous)
5552(require 'viper-macs)
5553(require 'viper-ex)
5554
5555
5556
5557;; The following is provided for compatibility with older VIP's 5000;; The following is provided for compatibility with older VIP's
5558 5001
5559(defalias 'vip-change-mode-to-vi 'vip-change-state-to-vi) 5002(defalias 'vip-change-mode-to-vi 'vip-change-state-to-vi)
@@ -5591,6 +5034,7 @@ Mail anyway (y or n)? ")
5591 5034
5592 (defvar help-mode-hook) 5035 (defvar help-mode-hook)
5593 (add-hook 'help-mode-hook 'viper-mode) 5036 (add-hook 'help-mode-hook 'viper-mode)
5037 (vip-modify-major-mode 'help-mode 'vi-state vip-help-modifier-map)
5594 5038
5595 (defvar awk-mode-hook) 5039 (defvar awk-mode-hook)
5596 (add-hook 'awk-mode-hook 'viper-mode) 5040 (add-hook 'awk-mode-hook 'viper-mode)
@@ -5802,6 +5246,12 @@ Mail anyway (y or n)? ")
5802 5246
5803;; set the toggle case sensitivity and regexp search macros 5247;; set the toggle case sensitivity and regexp search macros
5804(vip-set-vi-search-style-macros nil) 5248(vip-set-vi-search-style-macros nil)
5249
5250;; Make %%% toggle parsing comments for matching parentheses
5251(vip-record-kbd-macro
5252 "%%%" 'vi-state
5253 [(meta x) v i p - 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]
5254 't)
5805 5255
5806 5256
5807;; ~/.vip is loaded if it exists 5257;; ~/.vip is loaded if it exists
@@ -5830,9 +5280,6 @@ Mail anyway (y or n)? ")
5830 5280
5831 5281
5832(vip-set-minibuffer-style) 5282(vip-set-minibuffer-style)
5833(vip-set-minibuffer-faces)
5834(vip-set-search-face)
5835(vip-set-replace-overlay-face)
5836(if vip-buffer-search-char 5283(if vip-buffer-search-char
5837 (vip-buffer-search-enable)) 5284 (vip-buffer-search-enable))
5838(vip-update-alphanumeric-class) 5285(vip-update-alphanumeric-class)
@@ -5885,7 +5332,6 @@ Mail anyway (y or n)? ")
5885 5332
5886(run-hooks 'vip-load-hook) ; the last chance to change something 5333(run-hooks 'vip-load-hook) ; the last chance to change something
5887 5334
5888(provide 'viper)
5889(provide 'vip19) 5335(provide 'vip19)
5890(provide 'vip) 5336(provide 'vip)
5891 5337