Annotation of 43BSDReno/contrib/emacs-18.55/lisp/vip.el, revision 1.1.1.1

1.1       root        1: ;; VIP: A VI Package for GNU Emacs (version 3.5 of September 15, 1987)
                      2: 
                      3: ;; Author: Masahiko Sato ([email protected]).  In Japan, the author's
                      4: ;; address is: [email protected]
                      5: ;; Send suggestions and bug reports to one of the above addresses.
                      6: ;; When you report a bug, be sure to include the version number of VIP and
                      7: ;; Emacs you are using.
                      8: 
                      9: ;; Execute info command by typing "M-x info" to get information on VIP.
                     10: 
                     11: ;; external variables
                     12: 
                     13: (defvar vip-emacs-local-map nil
                     14:   "Local map used in emacs mode. \(buffer specific\)")
                     15: 
                     16: (defvar vip-insert-local-map nil
                     17:   "Local map used in insert command mode. \(buffer specific\)")
                     18:   
                     19: (make-variable-buffer-local 'vip-emacs-local-map)
                     20: (make-variable-buffer-local 'vip-insert-local-map)
                     21: 
                     22: (defvar vip-insert-point nil
                     23:   "Remember insert point as a marker. \(buffer specific\)")
                     24: 
                     25: (set-default 'vip-insert-point (make-marker))
                     26: (make-variable-buffer-local 'vip-insert-point)
                     27: 
                     28: (defvar vip-com-point nil
                     29:   "Remember com point as a marker. \(buffer specific\)")
                     30: 
                     31: (set-default 'vip-com-point (make-marker))
                     32: (make-variable-buffer-local 'vip-com-point)
                     33: 
                     34: (defvar vip-current-mode nil
                     35:   "Current mode.  One of emacs-mode, vi-mode, insert-mode.")
                     36: 
                     37: (make-variable-buffer-local 'vip-current-mode)
                     38: (setq-default vip-current-mode 'emacs-mode)
                     39: 
                     40: (defvar vip-emacs-mode-line-buffer-identification nil
                     41:   "value of mode-line-buffer-identification in emacs-mode.")
                     42: (make-variable-buffer-local 'vip-emacs-mode-line-buffer-identification)
                     43: (setq-default vip-emacs-mode-line-buffer-identification
                     44:              '("Emacs: %17b"))
                     45: 
                     46: (defvar vip-current-major-mode nil
                     47:   "vip-current-major-mode is the major-mode vi considers it is now.
                     48: \(buffer specific\)")
                     49: 
                     50: (make-variable-buffer-local 'vip-current-major-mode)
                     51: 
                     52: (defvar vip-last-shell-com nil
                     53:   "last shell command executed by ! command")
                     54: 
                     55: (defvar vip-use-register nil
                     56:   "name of register to store deleted or yanked strings.")
                     57: 
                     58: (defvar vip-d-com nil
                     59:   "If non-nil, it's value is a list (M-COM VAL COM), and is used to
                     60: re-execute last destrcutive command")
                     61: 
                     62: (defconst vip-shift-width 8
                     63:   "*The number of colums shifted by > and < command.")
                     64: 
                     65: (defconst vip-re-replace nil
                     66:   "*If t then do regexp replace, if nil then do string replace.")
                     67: 
                     68: (defvar vip-d-char nil
                     69:   "The character remenbered by the vi \"r\" command")
                     70: 
                     71: (defvar vip-f-char nil
                     72:   "for use by \";\" command")
                     73: 
                     74: (defvar vip-F-char nil
                     75:   "for use by \".\" command")
                     76: 
                     77: (defvar vip-f-forward nil
                     78:   "for use by \";\" command")
                     79:   
                     80: (defvar vip-f-offset nil
                     81:   "for use by \";\" command")
                     82: 
                     83: (defconst vip-search-wrap-around t
                     84:   "*if t, search wraps around")
                     85: 
                     86: (defconst vip-re-search nil
                     87:   "*if t, search is reg-exp search, otherwise vanilla search.")
                     88: 
                     89: (defvar vip-s-string nil
                     90:   "last search string")
                     91: 
                     92: (defvar vip-s-forward nil
                     93:   "if t, search is forward.")
                     94: 
                     95: (defconst vip-case-fold-search nil
                     96:   "*if t, search ignores cases.")
                     97: 
                     98: (defconst vip-re-query-replace nil
                     99:   "*If t then do regexp replace, if nil then do string replace.")
                    100: 
                    101: (defconst vip-open-with-indent nil
                    102:   "*if t, indent when open a new line.")
                    103: 
                    104: (defconst vip-help-in-insert-mode nil
                    105:   "*if t then C-h is bound to help-command in insert mode, if nil then it is
                    106: bound to delete-backward-char.")
                    107: 
                    108: (defvar vip-quote-string "> "
                    109:   "string inserted at the beginning of region")
                    110: 
                    111: (defvar vip-tags-file-name "TAGS")
                    112: 
                    113: (defvar vip-inhibit-startup-message nil)
                    114: 
                    115: ;; basic set up
                    116: 
                    117: (global-set-key "\C-z" 'vip-change-mode-to-vi)
                    118: 
                    119: (defmacro vip-loop (count body)
                    120:   "(COUNT BODY) Execute BODY COUNT times."
                    121:   (list 'let (list (list 'count count))
                    122:        (list 'while (list '> 'count 0)
                    123:              body
                    124:              (list 'setq 'count (list '1- 'count)))))
                    125: 
                    126: (defun vip-push-mark-silent (&optional location)
                    127:   "Set mark at LOCATION (point, by default) and push old mark on mark ring.
                    128: No message."
                    129:   (if (null (mark))
                    130:       nil
                    131:     (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
                    132:     (if (> (length mark-ring) mark-ring-max)
                    133:        (progn
                    134:          (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
                    135:          (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
                    136:   (set-mark (or location (point))))
                    137: 
                    138: (defun vip-goto-col (arg)
                    139:   "Go to ARG's column."
                    140:   (interactive "P")
                    141:   (let ((val (vip-p-val arg))
                    142:        (com (vip-getcom arg)))
                    143:     (save-excursion
                    144:       (end-of-line)
                    145:       (if (> val (1+ (current-column))) (error "")))
                    146:     (if com (move-marker vip-com-point (point)))
                    147:     (beginning-of-line)
                    148:     (forward-char (1- val))
                    149:     (if com (vip-execute-com 'vip-goto-col val com))))
                    150: 
                    151: (defun vip-refresh-mode-line ()
                    152:   "Redraw mode line."
                    153:   (set-buffer-modified-p (buffer-modified-p)))
                    154: 
                    155: (defun vip-copy-keymap (map)
                    156:   (if (null map) (make-sparse-keymap) (copy-keymap map)))
                    157: 
                    158: 
                    159: ;; changing mode
                    160: 
                    161: (defun vip-change-mode (new-mode)
                    162:   "Change mode to NEW-MODE.  NEW-MODE is either emacs-mode, vi-mode,
                    163: or insert-mode."
                    164:   (or (eq new-mode vip-current-mode)
                    165:       (progn
                    166:        (cond ((eq new-mode 'vi-mode)
                    167:               (if (eq vip-current-mode 'insert-mode)
                    168:                   (progn
                    169:                     (vip-copy-region-as-kill (point) vip-insert-point)
                    170:                     (vip-repeat-insert-command))
                    171:                 (setq vip-emacs-local-map (current-local-map)
                    172:                       vip-emacs-mode-line-buffer-identification
                    173:                       mode-line-buffer-identification
                    174:                       vip-insert-local-map (vip-copy-keymap
                    175:                                             (current-local-map))))
                    176:               (vip-change-mode-line "Vi:   ")
                    177:               (use-local-map vip-mode-map))
                    178:              ((eq new-mode 'insert-mode)
                    179:               (move-marker vip-insert-point (point))
                    180:               (if (eq vip-current-mode 'emacs-mode)
                    181:                   (setq vip-emacs-local-map (current-local-map)
                    182:                         vip-emacs-mode-line-buffer-identification
                    183:                         mode-line-buffer-identification
                    184:                         vip-insert-local-map (vip-copy-keymap
                    185:                                               (current-local-map)))
                    186:                 (setq vip-insert-local-map (vip-copy-keymap
                    187:                                             vip-emacs-local-map)))
                    188:               (vip-change-mode-line "Insert")
                    189:               (use-local-map vip-insert-local-map)
                    190:               (define-key vip-insert-local-map "\e" 'vip-change-mode-to-vi)
                    191:               (define-key vip-insert-local-map "\C-z" 'vip-ESC)
                    192:               (define-key vip-insert-local-map "\C-h"
                    193:                 (if vip-help-in-insert-mode 'help-command
                    194:                   'delete-backward-char))
                    195:               (define-key vip-insert-local-map "\C-w"
                    196:                 'vip-delete-backward-word))
                    197:              ((eq new-mode 'emacs-mode) 
                    198:               (vip-change-mode-line "Emacs:")
                    199:               (use-local-map vip-emacs-local-map)))
                    200:        (setq vip-current-mode new-mode)
                    201:        (vip-refresh-mode-line))))
                    202: 
                    203: (defun vip-copy-region-as-kill (beg end)
                    204:   "If BEG and END do not belong to the same buffer, it copies empty region."
                    205:   (condition-case nil
                    206:       (copy-region-as-kill beg end)
                    207:     (error (copy-region-as-kill beg beg))))
                    208: 
                    209: (defun vip-change-mode-line (string)
                    210:   "Assuming that the mode line format contains the string \"Emacs:\", this
                    211: function replaces the string by \"Vi:   \" etc."
                    212:   (setq mode-line-buffer-identification
                    213:        (if (string= string "Emacs:")
                    214:            vip-emacs-mode-line-buffer-identification
                    215:          (list (concat string " %17b")))))
                    216: 
                    217: (defun vip-mode ()
                    218:   "Turn on VIP emulation of VI."
                    219:   (interactive)
                    220:   (if (not vip-inhibit-startup-message)
                    221:       (progn
                    222:        (switch-to-buffer "VIP Startup Message")
                    223:        (erase-buffer)
                    224:        (insert
                    225:         "VIP is a Vi emulation package for GNU Emacs.  VIP provides most Vi commands
                    226: including Ex commands.  VIP is however different from Vi in several points.
                    227: You can get more information on VIP by:
                    228:     1.  Typing `M-x info' and selecting menu item \"vip\".
                    229:     2.  Typing `C-h k' followed by a key whose description you want.
                    230:     3.  Printing VIP manual which can be found as GNU/man/vip.texinfo
                    231:     4.  Printing VIP Reference Card which can be found as GNU/etc/vipcard.tex
                    232: 
                    233: This startup message appears whenever you load VIP unless you type `y' now.
                    234: Type `n' to quit this window for now.\n")
                    235:        (goto-char (point-min))
                    236:        (if (y-or-n-p "Inhibit VIP startup message? ")
                    237:            (progn
                    238:              (save-excursion
                    239:                (set-buffer
                    240:                 (find-file-noselect (substitute-in-file-name "~/.vip")))
                    241:                (goto-char (point-max))
                    242:                (insert "\n(setq vip-inhibit-startup-message t)\n")
                    243:                (save-buffer)
                    244:                (kill-buffer (current-buffer)))
                    245:              (message "VIP startup message inhibited.")
                    246:              (sit-for 2)))
                    247:        (kill-buffer (current-buffer))
                    248:        (message "")
                    249:        (setq vip-inhibit-startup-message t)))
                    250:   (vip-change-mode-to-vi))
                    251: 
                    252: (defun vip-change-mode-to-vi ()
                    253:   "Change mode to vi mode."
                    254:   (interactive)
                    255:   (vip-change-mode 'vi-mode))
                    256: 
                    257: (defun vip-change-mode-to-insert ()
                    258:   "Change mode to insert mode."
                    259:   (interactive)
                    260:   (vip-change-mode 'insert-mode))
                    261: 
                    262: (defun vip-change-mode-to-emacs ()
                    263:   "Change mode to emacs mode."
                    264:   (interactive)
                    265:   (vip-change-mode 'emacs-mode))
                    266: 
                    267: 
                    268: ;; escape to emacs mode termporarilly
                    269: 
                    270: (defun vip-get-editor-command (l-map g-map &optional str)
                    271:   "Read characters from keyboard until an editor command is formed, using
                    272: local keymap L-MAP and global keymap G-MAP.  If the command is a
                    273: self-insert-command, the character just read is returned instead.  Optional
                    274: string STR is used as initial input string."
                    275:   (let (char l-bind g-bind)
                    276:     (setq char
                    277:          (if (or (null str) (string= str ""))
                    278:              (read-char)
                    279:            (string-to-char str)))
                    280:     (setq last-command-char char)
                    281:     (setq l-bind (vip-binding-of char l-map))
                    282:     (if (null l-bind)
                    283:        ;; since local binding is empty, we concentrate on global one.
                    284:        (progn
                    285:          (setq g-bind (vip-binding-of char g-map))
                    286:          (if (null g-bind)
                    287:              nil ;; return nil, since both bindings are void.
                    288:            (if (keymapp g-bind)
                    289:                (vip-get-editor-command nil g-bind (vip-string-tail str))
                    290:              (if (eq g-bind 'self-insert-command) char g-bind))))
                    291:       ;; local binding is nonvoid
                    292:       (if (keymapp l-bind)
                    293:          ;; since l-bind is a keymap, we consider g-bind as well.
                    294:          (progn
                    295:            (setq g-bind (vip-binding-of char g-map))
                    296:            (if (null g-bind)
                    297:                (vip-get-editor-command l-bind nil (vip-string-tail str))
                    298:              (if (keymapp g-bind)
                    299:                  ;; both bindings are keymap
                    300:                  (vip-get-editor-command l-bind g-bind (vip-string-tail str))
                    301:                ;; l-bind is a keymap, so we neglect g-bind
                    302:                (vip-get-editor-command l-bind nil (vip-string-tail str)))))
                    303:        ;; l-bind is a command
                    304:        (if (eq l-bind 'self-insert-command) char l-bind)))))
                    305: 
                    306: (defun vip-binding-of (char map)
                    307:   "Return key-binding of CHAR under keymap MAP.  It is nil if the binding
                    308: is void, or a command, or a keymap"
                    309:   (let ((val (if (listp map)
                    310:                 (cdr (assq char map))
                    311:               (aref map char))))
                    312:     (cond ((null val) nil)
                    313:          ((keymapp val)
                    314:           (if (symbolp val) (symbol-function val) val))
                    315:          (t
                    316:           ;; otherwise, it is a function which is either a real function or
                    317:           ;; a keymap fset to val.
                    318:           (let ((fun (symbol-function val)))
                    319:             (if (or (null fun) (keymapp fun)) fun val))))))
                    320: 
                    321: (defun vip-escape-to-emacs (arg &optional char)
                    322:   "Escape to emacs mode and execute one emacs command and then return to
                    323: vi mode.  ARG is used as the prefix value for the executed command.  If
                    324: CHAR is given it becomes the first character of the command."
                    325:   (interactive "P")
                    326:   (let (com (buff (current-buffer)) (first t))
                    327:     (if char (setq unread-command-char char))
                    328:     (setq prefix-arg arg)
                    329:     (while (or first (>= unread-command-char 0))
                    330:       ;; this while loop is executed until unread command char will be
                    331:       ;; exhausted.
                    332:       (setq first nil)
                    333:       (setq com (vip-get-editor-command vip-emacs-local-map global-map))
                    334:       (if (numberp com)
                    335:          (vip-loop (vip-p-val prefix-arg)
                    336:                    (insert (char-to-string com)))
                    337:        (command-execute com prefix-arg)))
                    338:     (setq prefix-arg nil)  ;; reset prefix arg
                    339:     ))
                    340: 
                    341: (defun vip-message-conditions (conditions)
                    342:   "Print CONDITIONS as a message."
                    343:   (let ((case (car conditions)) (msg (cdr conditions)))
                    344:     (if (null msg)
                    345:        (message "%s" case)
                    346:       (message "%s %s" case (prin1-to-string msg)))
                    347:     (ding)))
                    348: 
                    349: (defun vip-ESC (arg)
                    350:   "Emulate ESC key in Emacs mode."
                    351:   (interactive "P")
                    352:   (vip-escape-to-emacs arg ?\e))
                    353: 
                    354: (defun vip-ctl-c (arg)
                    355:   "Emulate C-c key in Emacs mode."
                    356:   (interactive "P")
                    357:   (vip-escape-to-emacs arg ?\C-c))
                    358: 
                    359: (defun vip-ctl-x (arg)
                    360:   "Emulate C-x key in Emacs mode."
                    361:   (interactive "P")
                    362:   (vip-escape-to-emacs arg ?\C-x))
                    363: 
                    364: (defun vip-ctl-h (arg)
                    365:   "Emulate C-h key in Emacs mode."
                    366:   (interactive "P")
                    367:   (vip-escape-to-emacs arg ?\C-h))
                    368: 
                    369: 
                    370: ;; prefix argmument for vi mode
                    371: 
                    372: ;; In vi mode, prefix argument is a dotted pair (NUM . COM) where NUM
                    373: ;; represents the numeric value of the prefix argument and COM represents
                    374: ;; command prefix such as "c", "d", "m" and "y".
                    375: 
                    376: (defun vip-prefix-arg-value (char value com)
                    377:   "Compute numeric prefix arg value.  Invoked by CHAR.  VALUE is the value
                    378: obtained so far, and COM is the command part obtained so far."
                    379:   (while (and (>= char ?0) (<= char ?9))
                    380:     (setq value (+ (* (if (numberp value) value 0) 10) (- char ?0)))       
                    381:     (setq char (read-char)))
                    382:   (setq prefix-arg value)
                    383:   (if com (setq prefix-arg (cons prefix-arg com)))
                    384:   (while (= char ?U)
                    385:     (vip-describe-arg prefix-arg)
                    386:     (setq char (read-char)))
                    387:   (setq unread-command-char char))
                    388: 
                    389: (defun vip-prefix-arg-com (char value com)
                    390:   "Vi operator as prefix argument."
                    391:   (let ((cont t))
                    392:     (while (and cont
                    393:                (or (= char ?c) (= char ?d) (= char ?y)
                    394:                    (= char ?!) (= char ?<) (= char ?>) (= char ?=)
                    395:                    (= char ?#) (= char ?r) (= char ?R) (= char ?\")))
                    396:       (if com
                    397:          ;; this means that we already have a command character, so we
                    398:          ;; construct a com list and exit while.  however, if char is "
                    399:          ;; it is an error.
                    400:          (progn
                    401:            ;; new com is (CHAR . OLDCOM)
                    402:            (if (or (= char ?#) (= char ?\")) (error ""))
                    403:            (setq com (cons char com))
                    404:            (setq cont nil))
                    405:        ;; if com is nil we set com as char, and read more.  again, if char
                    406:        ;; is ", we read the name of register and store it in vip-use-register.
                    407:        ;; if char is !, =, or #, a copmlete com is formed so we exit while.
                    408:        (cond ((or (= char ?!) (= char ?=))
                    409:               (setq com char)
                    410:               (setq char (read-char))
                    411:               (setq cont nil))
                    412:              ((= char ?#)
                    413:               ;; read a char and encode it as com
                    414:               (setq com (+ 128 (read-char)))
                    415:               (setq char (read-char))
                    416:               (setq cont nil))
                    417:              ((or (= char ?<) (= char ?>))
                    418:               (setq com char)
                    419:               (setq char (read-char))
                    420:               (if (= com char) (setq com (cons char com)))
                    421:               (setq cont nil))
                    422:              ((= char ?\")
                    423:               (let ((reg (read-char)))
                    424:                 (if (or (and (<= ?A reg) (<= reg ?z))
                    425:                         (and (<= ?1 reg) (<= reg ?9)))
                    426:                     (setq vip-use-register reg)
                    427:                   (error ""))
                    428:                 (setq char (read-char))))
                    429:              (t
                    430:               (setq com char)
                    431:               (setq char (read-char)))))))
                    432:   (if (atom com)
                    433:       ;; com is a single char, so we construct prefix-arg 
                    434:       ;; and if char is ?, describe prefix arg, otherwise exit by
                    435:       ;; pushing the char back
                    436:       (progn
                    437:        (setq prefix-arg (cons value com))
                    438:        (while (= char ?U)
                    439:          (vip-describe-arg prefix-arg)
                    440:          (setq char (read-char)))
                    441:        (setq unread-command-char char))
                    442:     ;; as com is non-nil, this means that we have a command to execute
                    443:     (if (or (= (car com) ?r) (= (car com) ?R))
                    444:        ;; execute apropriate region command.
                    445:        (let ((char (car com)) (com (cdr com)))
                    446:          (setq prefix-arg (cons value com))
                    447:          (if (= char ?r) (vip-region prefix-arg)
                    448:            (vip-Region prefix-arg))
                    449:          ;; reset prefix-arg
                    450:          (setq prefix-arg nil))
                    451:       ;; otherwise, reset prefix arg and call appropriate command
                    452:       (setq value (if (null value) 1 value))
                    453:       (setq prefix-arg nil)
                    454:       (cond ((equal com '(?c . ?c)) (vip-line (cons value ?C)))
                    455:            ((equal com '(?d . ?d)) (vip-line (cons value ?D)))
                    456:            ((equal com '(?d . ?y)) (vip-yank-defun))
                    457:            ((equal com '(?y . ?y)) (vip-line (cons value ?Y)))
                    458:            ((equal com '(?< . ?<)) (vip-line (cons value ?<)))
                    459:            ((equal com '(?> . ?>)) (vip-line (cons value ?>)))
                    460:            ((equal com '(?! . ?!)) (vip-line (cons value ?!)))
                    461:            ((equal com '(?= . ?=)) (vip-line (cons value ?=)))
                    462:            (t (error ""))))))
                    463: 
                    464: (defun vip-describe-arg (arg)
                    465:   (let (val com)
                    466:     (setq val (vip-P-val arg)
                    467:          com (vip-getcom arg))
                    468:     (if (null val)
                    469:        (if (null com)
                    470:            (message "Value is nil, and commmand is nil.")
                    471:          (message "Value is nil, and command is %c." com))
                    472:       (if (null com)
                    473:          (message "Value is %d, and command is nil." val)
                    474:        (message "Value is %d, and command is %c." val com)))))
                    475: 
                    476: (defun vip-digit-argument (arg)
                    477:   "Begin numeric argument for the next command."
                    478:   (interactive "P")
                    479:   (vip-prefix-arg-value last-command-char nil
                    480:                        (if (consp arg) (cdr arg) nil)))
                    481: 
                    482: (defun vip-command-argument (arg)
                    483:   "Accept a motion command as an argument."
                    484:   (interactive "P")
                    485:   (condition-case conditions
                    486:       (vip-prefix-arg-com
                    487:        last-command-char   
                    488:        (cond ((null arg) nil)
                    489:             ((consp arg) (car arg))
                    490:             ((numberp arg) arg)
                    491:             (t (error "strange arg")))
                    492:        (cond ((null arg) nil)
                    493:             ((consp arg) (cdr arg))
                    494:             ((numberp arg) nil)
                    495:             (t (error "strange arg"))))
                    496:     (quit
                    497:      (setq vip-use-register nil)
                    498:      (signal 'quit nil))))
                    499: 
                    500: (defun vip-p-val (arg)
                    501:   "Get value part of prefix-argument ARG."
                    502:   (cond ((null arg) 1)
                    503:        ((consp arg) (if (null (car arg)) 1 (car arg)))
                    504:        (t arg)))
                    505: 
                    506: (defun vip-P-val (arg)
                    507:   "Get value part of prefix-argument ARG."
                    508:   (cond ((consp arg) (car arg))
                    509:        (t arg)))
                    510: 
                    511: (defun vip-getcom (arg)
                    512:   "Get com part of prefix-argument ARG."
                    513:   (cond ((null arg) nil)
                    514:        ((consp arg) (cdr arg))
                    515:        (t nil)))
                    516: 
                    517: (defun vip-getCom (arg)
                    518:   "Get com part of prefix-argument ARG and modify it."
                    519:   (let ((com (vip-getcom arg)))
                    520:     (cond ((equal com ?c) ?C)
                    521:          ((equal com ?d) ?D)
                    522:          ((equal com ?y) ?Y)
                    523:          (t com))))
                    524: 
                    525: 
                    526: ;; repeat last destructive command
                    527: 
                    528: (defun vip-append-to-register (reg start end)
                    529:   "Append region to text in register REG.
                    530: START and END are buffer positions indicating what to append."
                    531:   (set-register reg (concat (or (get-register reg) "")
                    532:                            (buffer-substring start end))))
                    533: 
                    534: (defun vip-execute-com (m-com val com)
                    535:   "(M-COM VAL COM)  Execute command COM. The list (M-COM VAL COM) is set
                    536: to vip-d-com for later use by vip-repeat"
                    537:   (let ((reg vip-use-register))
                    538:     (if com
                    539:        (cond ((= com ?c) (vip-change vip-com-point (point)))
                    540:              ((= com (- ?c)) (vip-change-subr vip-com-point (point)))
                    541:              ((or (= com ?C) (= com (- ?C)))
                    542:               (save-excursion
                    543:                 (set-mark vip-com-point)
                    544:                 (vip-enlarge-region (mark) (point))
                    545:                 (if vip-use-register
                    546:                     (progn
                    547:                       (cond ((and (<= ?a vip-use-register)
                    548:                                   (<= vip-use-register ?z))
                    549:                              (copy-to-register
                    550:                               vip-use-register (mark) (point) nil))
                    551:                             ((and (<= ?A vip-use-register)
                    552:                                   (<= vip-use-register ?Z))
                    553:                              (vip-append-to-register
                    554:                               (+ vip-use-register 32) (mark) (point)))
                    555:                             (t (setq vip-use-register nil)
                    556:                                (error "")))
                    557:                       (setq vip-use-register nil)))
                    558:                 (delete-region (mark) (point)))
                    559:               (open-line 1)
                    560:               (if (= com ?C) (vip-change-mode-to-insert) (yank)))
                    561:              ((= com ?d)
                    562:               (if vip-use-register
                    563:                   (progn
                    564:                     (cond ((and (<= ?a vip-use-register)
                    565:                                 (<= vip-use-register ?z))
                    566:                            (copy-to-register
                    567:                             vip-use-register vip-com-point (point) nil))
                    568:                           ((and (<= ?A vip-use-register)
                    569:                                 (<= vip-use-register ?Z))
                    570:                            (vip-append-to-register
                    571:                             (+ vip-use-register 32) vip-com-point (point)))
                    572:                           (t (setq vip-use-register nil)
                    573:                              (error "")))
                    574:                     (setq vip-use-register nil)))
                    575:               (setq last-command
                    576:                     (if (eq last-command 'd-command) 'kill-region nil))
                    577:               (kill-region vip-com-point (point))
                    578:               (setq this-command 'd-command))
                    579:              ((= com ?D)
                    580:               (save-excursion
                    581:                 (set-mark vip-com-point)
                    582:                 (vip-enlarge-region (mark) (point))
                    583:                 (if vip-use-register
                    584:                     (progn
                    585:                       (cond ((and (<= ?a vip-use-register)
                    586:                                   (<= vip-use-register ?z))
                    587:                              (copy-to-register
                    588:                               vip-use-register (mark) (point) nil))
                    589:                             ((and (<= ?A vip-use-register)
                    590:                                   (<= vip-use-register ?Z))
                    591:                              (vip-append-to-register
                    592:                               (+ vip-use-register 32) (mark) (point)))
                    593:                             (t (setq vip-use-register nil)
                    594:                                (error "")))
                    595:                       (setq vip-use-register nil)))
                    596:                 (setq last-command
                    597:                       (if (eq last-command 'D-command) 'kill-region nil))
                    598:                 (kill-region (mark) (point))
                    599:                 (if (eq m-com 'vip-line) (setq this-command 'D-command)))
                    600:               (back-to-indentation))
                    601:              ((= com ?y)
                    602:               (if vip-use-register
                    603:                   (progn
                    604:                     (cond ((and (<= ?a vip-use-register)
                    605:                                 (<= vip-use-register ?z))
                    606:                            (copy-to-register
                    607:                             vip-use-register vip-com-point (point) nil))
                    608:                           ((and (<= ?A vip-use-register)
                    609:                                 (<= vip-use-register ?Z))
                    610:                            (vip-append-to-register
                    611:                             (+ vip-use-register 32) vip-com-point (point)))
                    612:                           (t (setq vip-use-register nil)
                    613:                              (error "")))
                    614:                     (setq vip-use-register nil)))
                    615:               (setq last-command nil)
                    616:               (copy-region-as-kill vip-com-point (point))
                    617:               (goto-char vip-com-point))
                    618:              ((= com ?Y)
                    619:               (save-excursion
                    620:                 (set-mark vip-com-point)
                    621:                 (vip-enlarge-region (mark) (point))
                    622:                 (if vip-use-register
                    623:                     (progn
                    624:                       (cond ((and (<= ?a vip-use-register)
                    625:                                   (<= vip-use-register ?z))
                    626:                              (copy-to-register
                    627:                               vip-use-register (mark) (point) nil))
                    628:                             ((and (<= ?A vip-use-register)
                    629:                                   (<= vip-use-register ?Z))
                    630:                              (vip-append-to-register
                    631:                               (+ vip-use-register 32) (mark) (point)))
                    632:                             (t (setq vip-use-register nil)
                    633:                                (error "")))
                    634:                       (setq vip-use-register nil)))
                    635:                 (setq last-command nil)
                    636:                 (copy-region-as-kill (mark) (point)))
                    637:               (goto-char vip-com-point))
                    638:              ((or (= com ?!) (= com (- ?!)))
                    639:               (save-excursion
                    640:                 (set-mark vip-com-point)
                    641:                 (vip-enlarge-region (mark) (point))
                    642:                 (shell-command-on-region
                    643:                  (mark) (point)
                    644:                  (if (= com ?!)
                    645:                      (setq vip-last-shell-com (vip-read-string "!"))
                    646:                    vip-last-shell-com)
                    647:                  t)))
                    648:              ((= com ?=)
                    649:               (save-excursion
                    650:                 (set-mark vip-com-point)
                    651:                 (vip-enlarge-region (mark) (point))
                    652:                 (if (> (mark) (point)) (exchange-point-and-mark))
                    653:                 (indent-region (mark) (point) nil)))
                    654:              ((= com ?<)
                    655:               (save-excursion
                    656:                 (set-mark vip-com-point)
                    657:                 (vip-enlarge-region (mark) (point))
                    658:                 (indent-rigidly (mark) (point) (- vip-shift-width)))
                    659:               (goto-char vip-com-point))
                    660:              ((= com ?>)
                    661:               (save-excursion
                    662:                 (set-mark vip-com-point)
                    663:                 (vip-enlarge-region (mark) (point))
                    664:                 (indent-rigidly (mark) (point) vip-shift-width))
                    665:               (goto-char vip-com-point))
                    666:              ((>= com 128)
                    667:               ;; this is special command #
                    668:               (vip-special-prefix-com (- com 128)))))
                    669:     (setq vip-d-com (list m-com val (if (or (= com ?c) (= com ?C) (= com ?!))
                    670:                                        (- com) com)
                    671:                          reg))))
                    672: 
                    673: (defun vip-repeat (arg)
                    674:   "(ARG)  Re-excute last destructive command.  vip-d-com has the form
                    675: (COM ARG CH REG), where COM is the command to be re-executed, ARG is the
                    676: argument for COM, CH is a flag for repeat, and REG is optional and if exists
                    677: is the name of the register for COM."
                    678:   (interactive "P")
                    679:   (if (eq last-command 'vip-undo)
                    680:       ;; if the last command was vip-undo, then undo-more
                    681:       (vip-undo-more)
                    682:     ;; otherwise execute the command stored in vip-d-com.  if arg is non-nil
                    683:     ;; its prefix value is used as new prefix value for the command.
                    684:     (let ((m-com (car vip-d-com))
                    685:          (val (vip-P-val arg))
                    686:          (com (car (cdr (cdr vip-d-com))))
                    687:          (reg (nth 3 vip-d-com)))
                    688:       (if (null val) (setq val (car (cdr vip-d-com))))
                    689:       (if (null m-com) (error "No previous command to repeat."))
                    690:       (setq vip-use-register reg)
                    691:       (funcall m-com (cons val com)))))
                    692: 
                    693: (defun vip-special-prefix-com (char)
                    694:   "This command is invoked interactively by the key sequence #<char>"
                    695:   (cond ((= char ?c)
                    696:         (downcase-region (min vip-com-point (point))
                    697:                          (max vip-com-point (point))))
                    698:        ((= char ?C)
                    699:         (upcase-region (min vip-com-point (point))
                    700:                        (max vip-com-point (point))))
                    701:        ((= char ?g)
                    702:         (set-mark vip-com-point)
                    703:         (vip-global-execute))
                    704:        ((= char ?q)
                    705:         (set-mark vip-com-point)
                    706:         (vip-quote-region))
                    707:        ((= char ?s) (spell-region vip-com-point (point)))))
                    708: 
                    709: 
                    710: ;; undoing
                    711: 
                    712: (defun vip-undo ()
                    713:   "Undo previous change."
                    714:   (interactive)
                    715:   (message "undo!")
                    716:   (undo-start)
                    717:   (undo-more 2)
                    718:   (setq this-command 'vip-undo))
                    719: 
                    720: (defun vip-undo-more ()
                    721:   "Continue undoing previous changes."
                    722:   (message "undo more!")
                    723:   (undo-more 1)
                    724:   (setq this-command 'vip-undo))
                    725: 
                    726: 
                    727: ;; utilities
                    728: 
                    729: (defun vip-string-tail (str)
                    730:   (if (or (null str) (string= str "")) nil
                    731:     (substring str 1)))
                    732: 
                    733: (defun vip-yank-defun ()
                    734:   (mark-defun)
                    735:   (copy-region-as-kill (point) (mark)))
                    736: 
                    737: (defun vip-enlarge-region (beg end)
                    738:   "Enlarge region between BEG and END."
                    739:   (if (< beg end)
                    740:       (progn (goto-char beg) (set-mark end))
                    741:     (goto-char end)
                    742:     (set-mark beg))
                    743:   (beginning-of-line)
                    744:   (exchange-point-and-mark)
                    745:   (if (or (not (eobp)) (not (bolp))) (next-line 1))
                    746:   (beginning-of-line)
                    747:   (if (> beg end) (exchange-point-and-mark)))
                    748: 
                    749: (defun vip-global-execute ()
                    750:   "Call last keyboad macro for each line in the region."
                    751:   (if (> (point) (mark)) (exchange-point-and-mark))
                    752:   (beginning-of-line)
                    753:   (call-last-kbd-macro)
                    754:   (while (< (point) (mark))
                    755:     (forward-line 1)
                    756:     (beginning-of-line)
                    757:     (call-last-kbd-macro)))
                    758: 
                    759: (defun vip-quote-region ()
                    760:   "Quote region by inserting the user supplied string at the beginning of
                    761: each line in the region."
                    762:   (setq vip-quote-string
                    763:        (let ((str
                    764:               (vip-read-string (format "quote string \(default \"%s\"\): "
                    765:                                        vip-quote-string))))
                    766:          (if (string= str "") vip-quote-string str)))
                    767:   (vip-enlarge-region (point) (mark))
                    768:   (if (> (point) (mark)) (exchange-point-and-mark))
                    769:   (insert vip-quote-string)
                    770:   (beginning-of-line)
                    771:   (forward-line 1)
                    772:   (while (and (< (point) (mark)) (bolp))
                    773:     (insert vip-quote-string)
                    774:     (beginning-of-line)
                    775:     (forward-line 1)))
                    776: 
                    777: (defun vip-end-with-a-newline-p (string)
                    778:   "Check if the string ends with a newline."
                    779:   (or (string= text "")
                    780:       (= (aref string (1- (length string))) ?\n)))
                    781: 
                    782: (defun vip-read-string (prompt &optional init)
                    783:   (setq save-minibuffer-local-map (copy-keymap minibuffer-local-map))
                    784:   (define-key minibuffer-local-map "\C-h" 'backward-char)
                    785:   (define-key minibuffer-local-map "\C-w" 'backward-word)
                    786:   (define-key minibuffer-local-map "\e" 'exit-minibuffer)
                    787:   (let (str)
                    788:     (condition-case conditions
                    789:        (setq str (read-string prompt init))
                    790:       (quit
                    791:        (setq minibuffer-local-map save-minibuffer-local-map)
                    792:        (signal 'quit nil)))
                    793:     (setq minibuffer-local-map save-minibuffer-local-map)
                    794:     str))
                    795: 
                    796: 
                    797: ;; insertion commands
                    798: 
                    799: (defun vip-repeat-insert-command ()
                    800:   "This function is called when mode changes from insertion mode to
                    801: vi command mode.  It will repeat the insertion command if original insertion
                    802: command was invoked with argument > 1."
                    803:   (let ((i-com (car vip-d-com)) (val (car (cdr vip-d-com))))
                    804:     (if (and val (> val 1)) ;; first check that val is non-nil
                    805:        (progn        
                    806:          (setq vip-d-com (list i-com (1- val) ?r))
                    807:          (vip-repeat nil)
                    808:          (setq vip-d-com (list i-com val ?r))))))
                    809: 
                    810: (defun vip-insert (arg) ""
                    811:   (interactive "P")
                    812:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    813:     (setq vip-d-com (list 'vip-insert val ?r))
                    814:     (if com (vip-loop val (yank))
                    815:       (vip-change-mode-to-insert))))
                    816: 
                    817: (defun vip-append (arg)
                    818:   "Append after point."
                    819:   (interactive "P")
                    820:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    821:     (setq vip-d-com (list 'vip-append val ?r))
                    822:     (if (not (eolp)) (forward-char))
                    823:     (if (equal com ?r)
                    824:        (vip-loop val (yank))
                    825:       (vip-change-mode-to-insert))))
                    826: 
                    827: (defun vip-Append (arg)
                    828:   "Append at end of line."
                    829:   (interactive "P")
                    830:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    831:     (setq vip-d-com (list 'vip-Append val ?r))
                    832:     (end-of-line)
                    833:     (if (equal com ?r)
                    834:        (vip-loop val (yank))
                    835:       (vip-change-mode-to-insert))))
                    836: 
                    837: (defun vip-Insert (arg)
                    838:   "Insert before first non-white."
                    839:   (interactive "P")
                    840:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    841:     (setq vip-d-com (list 'vip-Insert val ?r))
                    842:     (back-to-indentation)
                    843:     (if (equal com ?r)
                    844:        (vip-loop val (yank))
                    845:       (vip-change-mode-to-insert))))
                    846: 
                    847: (defun vip-open-line (arg)
                    848:   "Open line below."
                    849:   (interactive "P")
                    850:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    851:     (setq vip-d-com (list 'vip-open-line val ?r))
                    852:     (let ((col (current-indentation)))
                    853:       (if (equal com ?r)
                    854:          (vip-loop val
                    855:                (progn
                    856:                  (end-of-line)
                    857:                  (newline 1)
                    858:                  (if vip-open-with-indent (indent-to col))
                    859:                  (yank)))
                    860:        (end-of-line)
                    861:        (newline 1)
                    862:        (if vip-open-with-indent (indent-to col))
                    863:        (vip-change-mode-to-insert)))))
                    864: 
                    865: (defun vip-Open-line (arg)
                    866:   "Open line above."
                    867:   (interactive "P")
                    868:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    869:   (setq vip-d-com (list 'vip-Open-line val ?r))
                    870:   (let ((col (current-indentation)))
                    871:     (if (equal com ?r)
                    872:        (vip-loop val
                    873:              (progn
                    874:                (beginning-of-line)
                    875:                (open-line 1)
                    876:                (if vip-open-with-indent (indent-to col))
                    877:                (yank)))
                    878:       (beginning-of-line)
                    879:       (open-line 1)
                    880:       (if vip-open-with-indent (indent-to col))
                    881:       (vip-change-mode-to-insert)))))
                    882: 
                    883: (defun vip-open-line-at-point (arg)
                    884:   "Open line at point."
                    885:   (interactive "P")
                    886:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    887:     (setq vip-d-com (list 'vip-open-line-at-point val ?r))
                    888:     (if (equal com ?r)
                    889:        (vip-loop val
                    890:              (progn
                    891:                (open-line 1)
                    892:                (yank)))
                    893:       (open-line 1)
                    894:       (vip-change-mode-to-insert))))
                    895: 
                    896: (defun vip-substitute (arg)
                    897:   "Substitute characters."
                    898:   (interactive "P")
                    899:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    900:     (save-excursion
                    901:       (set-mark (point))
                    902:       (forward-char val)
                    903:       (if (equal com ?r)
                    904:          (vip-change-subr (mark) (point))
                    905:        (vip-change (mark) (point))))
                    906:     (setq vip-d-com (list 'vip-substitute val ?r))))
                    907:   
                    908: (defun vip-substitute-line (arg)
                    909:   "Substitute lines."
                    910:   (interactive "p")
                    911:   (vip-line (cons arg ?C)))
                    912: 
                    913: 
                    914: ;; line command
                    915: 
                    916: (defun vip-line (arg)
                    917:   (let ((val (car arg)) (com (cdr arg)))
                    918:     (move-marker vip-com-point (point))
                    919:     (next-line (1- val))
                    920:     (vip-execute-com 'vip-line val com)))
                    921: 
                    922: (defun vip-yank-line (arg)
                    923:   "Yank ARG lines (in vi's sense)"
                    924:   (interactive "P")
                    925:   (let ((val (vip-p-val arg)))
                    926:     (vip-line (cons val ?Y))))
                    927:     
                    928: 
                    929: ;; region command
                    930: 
                    931: (defun vip-region (arg)
                    932:   (interactive "P")
                    933:   (let ((val (vip-P-val arg))
                    934:        (com (vip-getcom arg)))
                    935:     (move-marker vip-com-point (point))
                    936:     (exchange-point-and-mark)
                    937:     (vip-execute-com 'vip-region val com)))
                    938: 
                    939: (defun vip-Region (arg)
                    940:   (interactive "P")
                    941:   (let ((val (vip-P-val arg))
                    942:        (com (vip-getCom arg)))
                    943:     (move-marker vip-com-point (point))
                    944:     (exchange-point-and-mark)
                    945:     (vip-execute-com 'vip-Region val com)))
                    946:   
                    947: (defun vip-replace-char (arg)
                    948:   "Replace the following ARG chars by the character read."
                    949:   (interactive "P")
                    950:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    951:     (setq vip-d-com (list 'vip-replace-char val ?r))
                    952:     (vip-replace-char-subr (if (equal com ?r) vip-d-char (read-char)) val)))
                    953: 
                    954: (defun vip-replace-char-subr (char arg)
                    955:   (delete-char arg t)
                    956:   (setq vip-d-char char)
                    957:   (vip-loop (if (> arg 0) arg (- arg)) (insert char))
                    958:   (backward-char arg))
                    959: 
                    960: (defun vip-replace-string ()
                    961:   "Replace string.  If you supply null string as the string to be replaced,
                    962: the query replace mode will toggle between string replace and regexp replace."
                    963:   (interactive)
                    964:   (let (str)
                    965:     (setq str (vip-read-string
                    966:               (if vip-re-replace "Replace regexp: " "Replace string: ")))
                    967:     (if (string= str "")
                    968:        (progn
                    969:          (setq vip-re-replace (not vip-re-replace))
                    970:          (message (format "Replace mode changed to %s."
                    971:                           (if vip-re-replace "regexp replace"
                    972:                             "string replace"))))
                    973:       (if vip-re-replace
                    974:          (replace-regexp
                    975:           str
                    976:           (vip-read-string (format "Replace regexp \"%s\" with: " str)))
                    977:        (replace-string
                    978:         str
                    979:         (vip-read-string (format "Replace \"%s\" with: " str)))))))
                    980: 
                    981: 
                    982: ;; basic cursor movement.  j, k, l, m commands.
                    983: 
                    984: (defun vip-forward-char (arg)
                    985:   "Move point right ARG characters (left if ARG negative).On reaching end
                    986: of buffer, stop and signal error."
                    987:   (interactive "P")
                    988:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    989:     (if com (move-marker vip-com-point (point)))
                    990:     (forward-char val)
                    991:     (if com (vip-execute-com 'vip-forward-char val com))))
                    992: 
                    993: (defun vip-backward-char (arg)
                    994:   "Move point left ARG characters (right if ARG negative).  On reaching
                    995: beginning of buffer, stop and signal error."
                    996:   (interactive "P")
                    997:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                    998:     (if com (move-marker vip-com-point (point)))
                    999:     (backward-char val)
                   1000:     (if com (vip-execute-com 'vip-backward-char val com))))
                   1001: 
                   1002: 
                   1003: ;; word command
                   1004: 
                   1005: (defun vip-forward-word (arg)
                   1006:   "Forward word."
                   1007:   (interactive "P")
                   1008:   (let ((val (vip-p-val arg))
                   1009:        (com (vip-getcom arg)))
                   1010:     (if com (move-marker vip-com-point (point)))
                   1011:     (forward-word val)
                   1012:     (skip-chars-forward " \t\n")
                   1013:     (if com
                   1014:        (progn
                   1015:          (if (or (= com ?c) (= com (- ?c)))
                   1016:              (progn (backward-word 1) (forward-word 1)))
                   1017:          (if (or (= com ?d) (= com ?y))
                   1018:              (progn
                   1019:                (backward-word 1)
                   1020:                (forward-word 1)
                   1021:                (skip-chars-forward " \t")))
                   1022:          (vip-execute-com 'vip-forward-word val com)))))
                   1023: 
                   1024: (defun vip-end-of-word (arg)
                   1025:   "Move point to end of current word."
                   1026:   (interactive "P")
                   1027:   (let ((val (vip-p-val arg))
                   1028:        (com (vip-getcom arg)))
                   1029:     (if com (move-marker vip-com-point (point)))
                   1030:     (forward-char)
                   1031:     (forward-word val)
                   1032:     (backward-char)
                   1033:     (if com
                   1034:        (progn
                   1035:          (forward-char)
                   1036:          (vip-execute-com 'vip-end-of-word val com)))))
                   1037:                         
                   1038: (defun vip-backward-word (arg)
                   1039:   "Backward word."
                   1040:   (interactive "P")
                   1041:   (let ((val (vip-p-val arg))
                   1042:        (com (vip-getcom arg)))
                   1043:     (if com (move-marker vip-com-point (point)))
                   1044:     (backward-word val)
                   1045:     (if com (vip-execute-com 'vip-backward-word val com))))
                   1046: 
                   1047: (defun vip-forward-Word (arg)
                   1048:   "Forward word delimited by white character."
                   1049:   (interactive "P")
                   1050:   (let ((val (vip-p-val arg))
                   1051:        (com (vip-getcom arg)))
                   1052:     (if com (move-marker vip-com-point (point)))
                   1053:     (re-search-forward "[^ \t\n]*[ \t\n]+" nil t val)
                   1054:     (if com
                   1055:        (progn
                   1056:          (if (or (= com ?c) (= com (- ?c)))
                   1057:              (progn (backward-word 1) (forward-word 1)))
                   1058:          (if (or (= com ?d) (= com ?y))
                   1059:              (progn
                   1060:                (backward-word 1)
                   1061:                (forward-word 1)
                   1062:                (skip-chars-forward " \t")))
                   1063:          (vip-execute-com 'vip-forward-Word val com)))))
                   1064: 
                   1065: (defun vip-end-of-Word (arg)
                   1066:   "Move forward to end of word delimited by white character."
                   1067:   (interactive "P")
                   1068:   (let ((val (vip-p-val arg))
                   1069:        (com (vip-getcom arg)))
                   1070:     (if com (move-marker vip-com-point (point)))
                   1071:     (forward-char)
                   1072:     (if (re-search-forward "[^ \t\n]+" nil t val) (backward-char))
                   1073:     (if com
                   1074:        (progn
                   1075:          (forward-char)
                   1076:          (vip-execute-com 'vip-end-of-Word val com)))))
                   1077: 
                   1078: (defun vip-backward-Word (arg)
                   1079:   "Backward word delimited by white character."
                   1080:   (interactive "P")
                   1081:   (let ((val (vip-p-val arg))
                   1082:        (com (vip-getcom arg)))
                   1083:     (if com (move-marker vip-com-point (point)))
                   1084:     (if (re-search-backward "[ \t\n]+[^ \t\n]+" nil t val)
                   1085:        (forward-char)
                   1086:       (goto-char (point-min)))
                   1087:     (if com (vip-execute-com 'vip-backward-Word val com))))
                   1088: 
                   1089: (defun vip-beginning-of-line (arg)
                   1090:   "Go to beginning of line."
                   1091:   (interactive "P")
                   1092:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1093:     (if com (move-marker vip-com-point (point)))
                   1094:     (beginning-of-line val)
                   1095:     (if com (vip-execute-com 'vip-beginning-of-line val com))))
                   1096: 
                   1097: (defun vip-bol-and-skip-white (arg)
                   1098:   "Beginning of line at first non-white character."
                   1099:   (interactive "P")
                   1100:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1101:     (if com (move-marker vip-com-point (point)))
                   1102:     (back-to-indentation)
                   1103:     (if com (vip-execute-com 'vip-bol-and-skip-white val com))))
                   1104: 
                   1105: (defun vip-goto-eol (arg)
                   1106:   "Go to end of line."
                   1107:   (interactive "P")
                   1108:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1109:     (if com (move-marker vip-com-point (point)))
                   1110:     (end-of-line val)
                   1111:     (if com (vip-execute-com 'vip-goto-eol val com))))
                   1112: 
                   1113: (defun vip-next-line (arg)
                   1114:   "Go to next line."
                   1115:   (interactive "P")
                   1116:   (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
                   1117:     (if com (move-marker vip-com-point (point)))
                   1118:     (line-move val)
                   1119:     (setq this-command 'next-line)
                   1120:     (if com (vip-execute-com 'vip-next-line val com))))
                   1121: 
                   1122: (defun vip-next-line-at-bol (arg)
                   1123:   "Next line at beginning of line."
                   1124:   (interactive "P")
                   1125:   (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
                   1126:     (if com (move-marker vip-com-point (point)))
                   1127:     (next-line val)
                   1128:     (back-to-indentation)
                   1129:     (if com (vip-execute-com 'vip-next-line-at-bol val com))))
                   1130: 
                   1131: (defun vip-previous-line (arg)
                   1132:   "Go to previous line."
                   1133:   (interactive "P")
                   1134:   (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
                   1135:     (if com (move-marker vip-com-point (point)))
                   1136:     (next-line (- val))
                   1137:     (setq this-command 'previous-line)
                   1138:     (if com (vip-execute-com 'vip-previous-line val com))))
                   1139: 
                   1140: (defun vip-previous-line-at-bol (arg)
                   1141:   "Previous line at beginning of line."
                   1142:   (interactive "P")
                   1143:   (let ((val (vip-p-val arg)) (com (vip-getCom arg)))
                   1144:     (if com (move-marker vip-com-point (point)))
                   1145:     (next-line (- val))
                   1146:     (back-to-indentation)
                   1147:     (if com (vip-execute-com 'vip-previous-line val com))))
                   1148: 
                   1149: (defun vip-change-to-eol (arg)
                   1150:   "Change to end of line."
                   1151:   (interactive "P")
                   1152:   (vip-goto-eol (cons arg ?c)))
                   1153: 
                   1154: (defun vip-kill-line (arg)
                   1155:   "Delete line."
                   1156:   (interactive "P")
                   1157:   (vip-goto-eol (cons arg ?d)))
                   1158: 
                   1159: 
                   1160: ;; moving around
                   1161: 
                   1162: (defun vip-goto-line (arg)
                   1163:   "Go to ARG's line.  Without ARG go to end of buffer."
                   1164:   (interactive "P")
                   1165:   (let ((val (vip-P-val arg)) (com (vip-getCom arg)))
                   1166:     (move-marker vip-com-point (point))
                   1167:     (set-mark (point))
                   1168:     (if (null val)
                   1169:        (goto-char (point-max))
                   1170:       (goto-char (point-min))
                   1171:       (forward-line (1- val)))
                   1172:     (back-to-indentation)
                   1173:     (if com (vip-execute-com 'vip-goto-line val com))))
                   1174: 
                   1175: (defun vip-find-char (arg char forward offset)
                   1176:   "Find ARG's occurence of CHAR on the current line.  If FORWARD then
                   1177: search is forward, otherwise backward.  OFFSET is used to adjust point
                   1178: after search."
                   1179:   (let ((arg (if forward arg (- arg))) point)
                   1180:     (save-excursion
                   1181:       (save-restriction
                   1182:        (if (> arg 0)
                   1183:            (narrow-to-region
                   1184:             ;; forward search begins here
                   1185:             (if (eolp) (error "") (point))
                   1186:             ;; forward search ends here
                   1187:             (progn (next-line 1) (beginning-of-line) (point)))
                   1188:          (narrow-to-region
                   1189:           ;; backward search begins from here
                   1190:           (if (bolp) (error "") (point))
                   1191:           ;; backward search ends here
                   1192:           (progn (beginning-of-line) (point))))
                   1193:        ;; if arg > 0, point is forwarded before search.
                   1194:        (if (> arg 0) (goto-char (1+ (point-min)))
                   1195:          (goto-char (point-max)))
                   1196:        (let ((case-fold-search nil))
                   1197:          (search-forward (char-to-string char) nil 0 arg))
                   1198:        (setq point (point))
                   1199:        (if (or (and (> arg 0) (= point (point-max)))
                   1200:                (and (< arg 0) (= point (point-min))))
                   1201:            (error ""))))
                   1202:     (goto-char (+ point (if (> arg 0) (if offset -2 -1) (if offset 1 0))))))
                   1203: 
                   1204: (defun vip-find-char-forward (arg)
                   1205:   "Find char on the line.  If called interactively read the char to find
                   1206: from the terminal, and if called from vip-repeat, the char last used is
                   1207: used.  This behaviour is controlled by the sign of prefix numeric value."
                   1208:   (interactive "P")
                   1209:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1210:     (if (> val 0)
                   1211:        ;; this means that the function was called interactively
                   1212:        (setq vip-f-char (read-char)
                   1213:              vip-f-forward t
                   1214:              vip-f-offset nil)
                   1215:       (setq val (- val)))
                   1216:     (if com (move-marker vip-com-point (point)))
                   1217:     (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) t nil)
                   1218:     (setq val (- val))
                   1219:     (if com
                   1220:        (progn
                   1221:          (setq vip-F-char vip-f-char);; set new vip-F-char
                   1222:          (forward-char)
                   1223:          (vip-execute-com 'vip-find-char-forward val com)))))
                   1224: 
                   1225: (defun vip-goto-char-forward (arg)
                   1226:   "Go up to char ARG forward on line."
                   1227:   (interactive "P")
                   1228:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1229:     (if (> val 0)
                   1230:        ;; this means that the function was called interactively
                   1231:        (setq vip-f-char (read-char)
                   1232:              vip-f-forward t
                   1233:              vip-f-offset t)
                   1234:       (setq val (- val)))
                   1235:     (if com (move-marker vip-com-point (point)))
                   1236:     (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) t t)
                   1237:     (setq val (- val))
                   1238:     (if com
                   1239:        (progn
                   1240:          (setq vip-F-char vip-f-char);; set new vip-F-char
                   1241:          (forward-char)
                   1242:          (vip-execute-com 'vip-goto-char-forward val com)))))
                   1243: 
                   1244: (defun vip-find-char-backward (arg)
                   1245:   "Find char ARG on line backward."
                   1246:   (interactive "P")
                   1247:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1248:     (if (> val 0)
                   1249:        ;; this means that the function was called interactively
                   1250:        (setq vip-f-char (read-char)
                   1251:              vip-f-forward nil
                   1252:              vip-f-offset nil)
                   1253:       (setq val (- val)))
                   1254:     (if com (move-marker vip-com-point (point)))
                   1255:     (vip-find-char
                   1256:      val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) nil nil)
                   1257:     (setq val (- val))
                   1258:     (if com
                   1259:        (progn
                   1260:          (setq vip-F-char vip-f-char);; set new vip-F-char
                   1261:          (vip-execute-com 'vip-find-char-backward val com)))))
                   1262: 
                   1263: (defun vip-goto-char-backward (arg)
                   1264:   "Go up to char ARG backward on line."
                   1265:   (interactive "P")
                   1266:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1267:     (if (> val 0)
                   1268:        ;; this means that the function was called interactively
                   1269:        (setq vip-f-char (read-char)
                   1270:              vip-f-forward nil
                   1271:              vip-f-offset t)
                   1272:       (setq val (- val)))
                   1273:     (if com (move-marker vip-com-point (point)))
                   1274:     (vip-find-char val (if (> (vip-p-val arg) 0) vip-f-char vip-F-char) nil t)
                   1275:     (setq val (- val))
                   1276:     (if com
                   1277:        (progn
                   1278:          (setq vip-F-char vip-f-char);; set new vip-F-char
                   1279:          (vip-execute-com 'vip-goto-char-backward val com)))))
                   1280: 
                   1281: (defun vip-repeat-find (arg)
                   1282:   "Repeat previous find command."
                   1283:   (interactive "P")
                   1284:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1285:     (if com (move-marker vip-com-point (point)))
                   1286:     (vip-find-char val vip-f-char vip-f-forward vip-f-offset)
                   1287:     (if com
                   1288:        (progn
                   1289:          (if vip-f-forward (forward-char))
                   1290:          (vip-execute-com 'vip-repeat-find val com)))))
                   1291: 
                   1292: (defun vip-repeat-find-opposite (arg)
                   1293:   "Repeat previous find command in the opposite direction."
                   1294:   (interactive "P")
                   1295:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1296:     (if com (move-marker vip-com-point (point)))
                   1297:     (vip-find-char val vip-f-char (not vip-f-forward) vip-f-offset)
                   1298:     (if com
                   1299:        (progn
                   1300:          (if vip-f-forward (forward-char))
                   1301:          (vip-execute-com 'vip-repeat-find-opposite val com)))))
                   1302: 
                   1303: 
                   1304: ;; window scrolling etc.
                   1305: 
                   1306: (defun vip-other-window (arg)
                   1307:   "Switch to other window."
                   1308:   (interactive "p")
                   1309:   (other-window arg)
                   1310:   (or (not (eq vip-current-mode 'emacs-mode))
                   1311:       (string= (buffer-name (current-buffer)) " *Minibuf-1*")
                   1312:       (vip-change-mode-to-vi)))
                   1313: 
                   1314: (defun vip-window-top (arg)
                   1315:   "Go to home window line."
                   1316:   (interactive "P")
                   1317:   (let ((val (vip-p-val arg))
                   1318:        (com (vip-getCom arg)))
                   1319:     (if com (move-marker vip-com-point (point)))
                   1320:     (move-to-window-line (1- val))
                   1321:     (if com (vip-execute-com 'vip-window-top val com))))
                   1322: 
                   1323: (defun vip-window-middle (arg)
                   1324:   "Go to middle window line."
                   1325:   (interactive "P")
                   1326:   (let ((val (vip-p-val arg))
                   1327:        (com (vip-getCom arg)))
                   1328:     (if com (move-marker vip-com-point (point)))
                   1329:     (move-to-window-line (+ (/ (1- (window-height)) 2) (1- val)))
                   1330:     (if com (vip-execute-com 'vip-window-middle val com))))
                   1331: 
                   1332: (defun vip-window-bottom (arg)
                   1333:   "Go to last window line."
                   1334:   (interactive "P")
                   1335:   (let ((val (vip-p-val arg))
                   1336:        (com (vip-getCom arg)))
                   1337:     (if com (move-marker vip-com-point (point)))
                   1338:     (move-to-window-line (- val))
                   1339:     (if com (vip-execute-com 'vip-window-bottom val com))))
                   1340: 
                   1341: (defun vip-line-to-top (arg)
                   1342:   "Put current line on the home line."
                   1343:   (interactive "p")
                   1344:   (recenter (1- arg)))
                   1345: 
                   1346: (defun vip-line-to-middle (arg)
                   1347:   "Put current line on the middle line."
                   1348:   (interactive "p")
                   1349:   (recenter (+ (1- arg) (/ (1- (window-height)) 2))))
                   1350: 
                   1351: (defun vip-line-to-bottom (arg)
                   1352:   "Put current line on the last line."
                   1353:   (interactive "p")
                   1354:   (recenter (- (window-height) (1+ arg))))
                   1355: 
                   1356: 
                   1357: ;; paren match
                   1358: 
                   1359: (defun vip-paren-match (arg)
                   1360:   "Go to the matching parenthesis."
                   1361:   (interactive "P")
                   1362:   (let ((com (vip-getcom arg)))
                   1363:     (if (numberp arg)
                   1364:        (if (or (> arg 99) (< arg 1))
                   1365:            (error "Prefix must be between 1 and 99.")
                   1366:          (goto-char
                   1367:           (if (> (point-max) 80000)
                   1368:               (* (/ (point-max) 100) arg)
                   1369:             (/ (* (point-max) arg) 100)))
                   1370:          (back-to-indentation))
                   1371:     (cond ((looking-at "[\(\[{]")
                   1372:           (if com (move-marker vip-com-point (point)))
                   1373:           (forward-sexp 1)
                   1374:           (if com
                   1375:               (vip-execute-com 'vip-paren-match nil com)
                   1376:             (backward-char)))
                   1377:          ((looking-at "[])}]")
                   1378:           (forward-char)
                   1379:           (if com (move-marker vip-com-point (point)))
                   1380:           (backward-sexp 1)
                   1381:           (if com (vip-execute-com 'vip-paren-match nil com)))
                   1382:          (t (error ""))))))
                   1383: 
                   1384: 
                   1385: ;; sentence and paragraph
                   1386: 
                   1387: (defun vip-forward-sentence (arg)
                   1388:   "Forward sentence."
                   1389:   (interactive "P")
                   1390:   (let ((val (vip-p-val arg))
                   1391:        (com (vip-getcom arg)))
                   1392:     (if com (move-marker vip-com-point (point)))
                   1393:     (forward-sentence val)
                   1394:     (if com (vip-execute-com 'vip-forward-sentence nil com))))
                   1395: 
                   1396: (defun vip-backward-sentence (arg)
                   1397:   "Backward sentence."
                   1398:   (interactive "P")
                   1399:   (let ((val (vip-p-val arg))
                   1400:        (com (vip-getcom arg)))
                   1401:     (if com (move-marker vip-com-point (point)))
                   1402:     (backward-sentence val)
                   1403:     (if com (vip-execute-com 'vip-backward-sentence nil com))))
                   1404: 
                   1405: (defun vip-forward-paragraph (arg)
                   1406:   "Forward paragraph."
                   1407:   (interactive "P")
                   1408:   (let ((val (vip-p-val arg))
                   1409:        (com (vip-getCom arg)))
                   1410:     (if com (move-marker vip-com-point (point)))
                   1411:     (forward-paragraph val)
                   1412:     (if com (vip-execute-com 'vip-forward-paragraph nil com))))
                   1413: 
                   1414: (defun vip-backward-paragraph (arg)
                   1415:   "Backward paragraph."
                   1416:   (interactive "P")
                   1417:   (let ((val (vip-p-val arg))
                   1418:        (com (vip-getCom arg)))
                   1419:     (if com (move-marker vip-com-point (point)))
                   1420:     (backward-paragraph val)
                   1421:     (if com (vip-execute-com 'vip-backward-paragraph nil com))))
                   1422: 
                   1423: 
                   1424: ;; scrolling
                   1425: 
                   1426: (defun vip-scroll (arg)
                   1427:   "Scroll to next screen."
                   1428:   (interactive "p")
                   1429:   (if (> arg 0)
                   1430:       (while (> arg 0)
                   1431:        (scroll-up)
                   1432:        (setq arg (1- arg)))
                   1433:     (while (> 0 arg)
                   1434:       (scroll-down)
                   1435:       (setq arg (1+ arg)))))
                   1436: 
                   1437: (defun vip-scroll-back (arg)
                   1438:   "Scroll to previous screen."
                   1439:   (interactive "p")
                   1440:   (vip-scroll (- arg)))
                   1441: 
                   1442: (defun vip-scroll-down (arg)
                   1443:   "Scroll up half screen."
                   1444:   (interactive "P")
                   1445:   (if (null arg) (scroll-down (/ (window-height) 2))
                   1446:     (scroll-down arg)))
                   1447: 
                   1448: (defun vip-scroll-down-one (arg)
                   1449:   "Scroll up one line."
                   1450:   (interactive "p")
                   1451:   (scroll-down arg))
                   1452: 
                   1453: (defun vip-scroll-up (arg)
                   1454:   "Scroll down half screen."
                   1455:   (interactive "P")
                   1456:   (if (null arg) (scroll-up (/ (window-height) 2))
                   1457:     (scroll-up arg)))
                   1458: 
                   1459: (defun vip-scroll-up-one (arg)
                   1460:   "Scroll down one line."
                   1461:   (interactive "p")
                   1462:   (scroll-up arg))
                   1463: 
                   1464: 
                   1465: ;; splitting window
                   1466: 
                   1467: (defun vip-buffer-in-two-windows ()
                   1468:   "Show current buffer in two windows."
                   1469:   (interactive)
                   1470:   (delete-other-windows)
                   1471:   (split-window-vertically nil))
                   1472: 
                   1473: 
                   1474: ;; searching
                   1475: 
                   1476: (defun vip-search-forward (arg)
                   1477:   "Search a string forward.  ARG is used to find the ARG's occurence
                   1478: of the string.  Default is vanilla search.  Search mode can be toggled by
                   1479: giving null search string."
                   1480:   (interactive "P")
                   1481:   (let ((val (vip-P-val arg)) (com (vip-getcom arg)))
                   1482:     (setq vip-s-forward t
                   1483:          vip-s-string (vip-read-string (if vip-re-search "RE-/" "/")))
                   1484:     (if (string= vip-s-string "")
                   1485:        (progn
                   1486:          (setq vip-re-search (not vip-re-search))
                   1487:          (message (format "Search mode changed to %s search."
                   1488:                           (if vip-re-search "regular expression"
                   1489:                             "vanilla"))))
                   1490:       (vip-search vip-s-string t val)
                   1491:       (if com
                   1492:          (progn
                   1493:            (move-marker vip-com-point (mark))
                   1494:            (vip-execute-com 'vip-search-next val com))))))
                   1495: 
                   1496: (defun vip-search-backward (arg)
                   1497:   "Search a string backward.  ARG is used to find the ARG's occurence
                   1498: of the string.  Default is vanilla search.  Search mode can be toggled by
                   1499: giving null search string."
                   1500:   (interactive "P")
                   1501:   (let ((val (vip-P-val arg)) (com (vip-getcom arg)))
                   1502:     (setq vip-s-forward nil
                   1503:          vip-s-string (vip-read-string (if vip-re-search "RE-?" "?")))
                   1504:     (if (string= vip-s-string "")
                   1505:        (progn
                   1506:          (setq vip-re-search (not vip-re-search))
                   1507:          (message (format "Search mode changed to %s search."
                   1508:                           (if vip-re-search "regular expression"
                   1509:                             "vanilla"))))
                   1510:       (vip-search vip-s-string nil val)
                   1511:       (if com
                   1512:          (progn
                   1513:            (move-marker vip-com-point (mark))
                   1514:            (vip-execute-com 'vip-search-next val com))))))
                   1515: 
                   1516: (defun vip-search (string forward arg &optional no-offset init-point)
                   1517:   "(STRING FORWARD COUNT &optional NO-OFFSET) Search COUNT's occurrence of
                   1518: STRING.  Search will be forward if FORWARD, otherwise backward."
                   1519:   (let ((val (vip-p-val arg)) (com (vip-getcom arg))
                   1520:        (null-arg (null (vip-P-val arg))) (offset (not no-offset))
                   1521:        (case-fold-search vip-case-fold-search)
                   1522:        (start-point (or init-point (point))))
                   1523:     (if forward
                   1524:        (condition-case conditions
                   1525:            (progn
                   1526:              (if (and offset (not (eobp))) (forward-char))
                   1527:              (if vip-re-search
                   1528:                  (progn
                   1529:                    (re-search-forward string nil nil val)
                   1530:                    (re-search-backward string))
                   1531:                (search-forward string nil nil val)
                   1532:                (search-backward string))
                   1533:              (push-mark start-point))
                   1534:          (search-failed
                   1535:           (if (and null-arg vip-search-wrap-around)
                   1536:               (progn
                   1537:                 (goto-char (point-min))
                   1538:                 (vip-search string forward (cons 1 com) t start-point))
                   1539:             (goto-char start-point)
                   1540:             (signal 'search-failed (cdr conditions)))))
                   1541:       (condition-case conditions
                   1542:            (progn
                   1543:              (if vip-re-search
                   1544:                    (re-search-backward string nil nil val)
                   1545:                (search-backward string nil nil val))
                   1546:              (push-mark start-point))
                   1547:          (search-failed
                   1548:           (if (and null-arg vip-search-wrap-around)
                   1549:               (progn
                   1550:                 (goto-char (point-max))
                   1551:                 (vip-search string forward (cons 1 com) t start-point))
                   1552:             (goto-char start-point)
                   1553:             (signal 'search-failed (cdr conditions))))))))
                   1554: 
                   1555: (defun vip-search-next (arg)
                   1556:   "Repeat previous search."
                   1557:   (interactive "P")
                   1558:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1559:     (if (null vip-s-string) (error "No previous search string."))
                   1560:     (vip-search vip-s-string vip-s-forward arg)
                   1561:     (if com (vip-execute-com 'vip-search-next val com))))
                   1562: 
                   1563: (defun vip-search-Next (arg)
                   1564:   "Repeat previous search in the reverse direction."
                   1565:   (interactive "P")
                   1566:   (let ((val (vip-p-val arg)) (com (vip-getcom arg)))
                   1567:     (if (null vip-s-string) (error "No previous search string."))
                   1568:     (vip-search vip-s-string (not vip-s-forward) arg)
                   1569:     (if com (vip-execute-com 'vip-search-Next val com))))
                   1570: 
                   1571: 
                   1572: ;; visiting and killing files, buffers
                   1573: 
                   1574: (defun vip-switch-to-buffer ()
                   1575:   "Switch to buffer in the current window."
                   1576:   (interactive)
                   1577:   (let (buffer)
                   1578:     (setq buffer
                   1579:          (read-buffer
                   1580:           (format "switch to buffer \(%s\): "
                   1581:                   (buffer-name (other-buffer (current-buffer))))))
                   1582:     (switch-to-buffer buffer)
                   1583:     (vip-change-mode-to-vi)))
                   1584: 
                   1585: (defun vip-switch-to-buffer-other-window ()
                   1586:   "Switch to buffer in another window."
                   1587:   (interactive)
                   1588:   (let (buffer)
                   1589:     (setq buffer
                   1590:          (read-buffer
                   1591:           (format "Switch to buffer \(%s\): "
                   1592:                   (buffer-name (other-buffer (current-buffer))))))
                   1593:     (switch-to-buffer-other-window buffer)
                   1594:     (vip-change-mode-to-vi)))
                   1595: 
                   1596: (defun vip-kill-buffer ()
                   1597:   "Kill a buffer."
                   1598:   (interactive)
                   1599:   (let (buffer buffer-name)
                   1600:     (setq buffer-name
                   1601:          (read-buffer
                   1602:           (format "Kill buffer \(%s\): "
                   1603:                   (buffer-name (current-buffer)))))
                   1604:     (setq buffer
                   1605:          (if (null buffer-name)
                   1606:              (current-buffer)
                   1607:            (get-buffer buffer-name)))
                   1608:     (if (null buffer) (error "Buffer %s nonexistent." buffer-name))
                   1609:     (if (or (not (buffer-modified-p buffer))
                   1610:            (y-or-n-p "Buffer is modified, are you sure? "))
                   1611:        (kill-buffer buffer)
                   1612:       (error "Buffer not killed."))))
                   1613: 
                   1614: (defun vip-find-file ()
                   1615:   "Visit file in the current window."
                   1616:   (interactive)
                   1617:   (let (file)
                   1618:     (setq file (read-file-name "visit file: "))
                   1619:     (switch-to-buffer (find-file-noselect file))
                   1620:     (vip-change-mode-to-vi)))
                   1621: 
                   1622: (defun vip-find-file-other-window ()
                   1623:   "Visit file in another window."
                   1624:   (interactive)
                   1625:   (let (file)
                   1626:     (setq file (read-file-name "Visit file: "))
                   1627:     (switch-to-buffer-other-window (find-file-noselect file))
                   1628:     (vip-change-mode-to-vi)))
                   1629: 
                   1630: (defun vip-info-on-file ()
                   1631:   "Give information of the file associated to the current buffer."
                   1632:   (interactive)
                   1633:   (message "\"%s\" line %d of %d"
                   1634:           (if (buffer-file-name) (buffer-file-name) "")
                   1635:           (1+ (count-lines (point-min) (point)))
                   1636:           (1+ (count-lines (point-min) (point-max)))))
                   1637: 
                   1638: 
                   1639: ;; yank and pop
                   1640: 
                   1641: (defun vip-yank (text)
                   1642:   "yank TEXT silently."
                   1643:   (save-excursion
                   1644:     (vip-push-mark-silent (point))
                   1645:     (insert text)
                   1646:     (exchange-point-and-mark))
                   1647:   (skip-chars-forward " \t"))
                   1648: 
                   1649: (defun vip-put-back (arg)
                   1650:   "Put back after point/below line."
                   1651:   (interactive "P")
                   1652:   (let ((val (vip-p-val arg))
                   1653:        (text (if vip-use-register
                   1654:                  (if (and (<= ?1 vip-use-register) (<= vip-use-register ?9))
                   1655:                      (nth (- vip-use-register 49) kill-ring-yank-pointer)
                   1656:                    (get-register vip-use-register))
                   1657:                (car kill-ring-yank-pointer))))
                   1658:     (if (null text)
                   1659:        (if vip-use-register
                   1660:            (let ((reg vip-use-register))
                   1661:              (setq vip-use-register nil)
                   1662:              (error "Nothing in register %c" reg))
                   1663:          (error "")))
                   1664:     (setq vip-use-register nil)
                   1665:     (if (vip-end-with-a-newline-p text)
                   1666:        (progn
                   1667:          (next-line 1)
                   1668:          (beginning-of-line))
                   1669:       (if (and (not (eolp)) (not (eobp))) (forward-char)))
                   1670:     (setq vip-d-com (list 'vip-put-back val nil vip-use-register))
                   1671:     (vip-loop val (vip-yank text))))
                   1672: 
                   1673: (defun vip-Put-back (arg)
                   1674:   "Put back at point/above line."
                   1675:   (interactive "P")
                   1676:   (let ((val (vip-p-val arg))
                   1677:        (text (if vip-use-register
                   1678:                  (if (and (<= ?1 vip-use-register) (<= vip-use-register ?9))
                   1679:                      (nth (- vip-use-register 49) kill-ring-yank-pointer)
                   1680:                    (get-register vip-use-register))
                   1681:                (car kill-ring-yank-pointer))))
                   1682:     (if (null text)
                   1683:        (if vip-use-register
                   1684:            (let ((reg vip-use-register))
                   1685:              (setq vip-use-register nil)
                   1686:              (error "Nothing in register %c" reg))
                   1687:          (error "")))
                   1688:     (setq vip-use-register nil)
                   1689:     (if (vip-end-with-a-newline-p text) (beginning-of-line))
                   1690:     (setq vip-d-com (list 'vip-Put-back val nil vip-use-register))
                   1691:     (vip-loop val (vip-yank text))))
                   1692: 
                   1693: (defun vip-delete-char (arg)
                   1694:   "Delete character."
                   1695:   (interactive "P")
                   1696:   (let ((val (vip-p-val arg)))
                   1697:     (setq vip-d-com (list 'vip-delete-char val nil))
                   1698:     (if vip-use-register
                   1699:        (progn
                   1700:          (if (and (<= ?A vip-use-register) (<= vip-use-register ?Z))
                   1701:              (vip-append-to-register
                   1702:               (+ vip-use-register 32) (point) (- (point) val) nil)
                   1703:            (copy-to-register vip-use-register (point) (- (point) val) nil))
                   1704:          (setq vip-use-register nil)))
                   1705:     (delete-char val t)))
                   1706: 
                   1707: (defun vip-delete-backward-char (arg)
                   1708:   "Delete previous character."
                   1709:   (interactive "P")
                   1710:   (let ((val (vip-p-val arg)))
                   1711:     (setq vip-d-com (list 'vip-delete-backward-char val nil))
                   1712:     (if vip-use-register
                   1713:        (progn
                   1714:          (if (and (<= ?A vip-use-register) (<= vip-use-register ?Z))
                   1715:              (vip-append-to-register
                   1716:               (+ vip-use-register 32) (point) (+ (point) val) nil)
                   1717:            (copy-to-register vip-use-register (point) (+ (point) val) nil))
                   1718:          (setq vip-use-register nil)))
                   1719:     (delete-backward-char val t)))
                   1720: 
                   1721: 
                   1722: ;; join lines.
                   1723: 
                   1724: (defun vip-join-lines (arg)
                   1725:   "Join this line to next, if ARG is nil.  Otherwise, join ARG lines"
                   1726:   (interactive "*P")
                   1727:   (let ((val (vip-P-val arg)))
                   1728:     (setq vip-d-com (list 'vip-join-lines val nil))
                   1729:     (vip-loop (if (null val) 1 (1- val))
                   1730:          (progn
                   1731:            (end-of-line)
                   1732:            (if (not (eobp))
                   1733:                (progn
                   1734:                  (forward-line 1)
                   1735:                  (delete-region (point) (1- (point)))
                   1736:                  (fixup-whitespace)))))))
                   1737: 
                   1738: 
                   1739: ;; making small changes
                   1740: 
                   1741: (defun vip-change (beg end)
                   1742:   (setq c-string
                   1743:        (vip-read-string (format "%s => " (buffer-substring beg end))))
                   1744:   (vip-change-subr beg end))
                   1745: 
                   1746: (defun vip-change-subr (beg end)
                   1747:   (if vip-use-register
                   1748:       (progn
                   1749:        (copy-to-register vip-use-register beg end nil)
                   1750:        (setq vip-use-register nil)))
                   1751:   (kill-region beg end)
                   1752:   (setq this-command 'vip-change)
                   1753:   (insert c-string))
                   1754: 
                   1755: 
                   1756: ;; query replace
                   1757: 
                   1758: (defun vip-query-replace ()
                   1759:   "Query replace.  If you supply null string as the string to be replaced,
                   1760: the query replace mode will toggle between string replace and regexp replace."
                   1761:   (interactive)
                   1762:   (let (str)
                   1763:     (setq str (vip-read-string
                   1764:               (if vip-re-query-replace "Query replace regexp: "
                   1765:                 "Query replace: ")))
                   1766:     (if (string= str "")
                   1767:        (progn
                   1768:          (setq vip-re-query-replace (not vip-re-query-replace))
                   1769:          (message "Query replace mode changed to %s."
                   1770:                   (if vip-re-query-replace "regexp replace"
                   1771:                     "string replace")))
                   1772:       (if vip-re-query-replace
                   1773:          (query-replace-regexp
                   1774:           str
                   1775:           (vip-read-string (format "Query replace regexp \"%s\" with: " str)))
                   1776:        (query-replace
                   1777:         str
                   1778:         (vip-read-string (format "Query replace \"%s\" with: " str)))))))
                   1779: 
                   1780: 
                   1781: ;; marking
                   1782: 
                   1783: (defun vip-mark-beginning-of-buffer ()
                   1784:   (interactive)
                   1785:   (set-mark (point))
                   1786:   (goto-char (point-min))
                   1787:   (exchange-point-and-mark)
                   1788:   (message "mark set at the beginning of buffer"))
                   1789: 
                   1790: (defun vip-mark-end-of-buffer ()
                   1791:   (interactive)
                   1792:   (set-mark (point))
                   1793:   (goto-char (point-max))
                   1794:   (exchange-point-and-mark)
                   1795:   (message "mark set at the end of buffer"))
                   1796: 
                   1797: (defun vip-mark-point (char)
                   1798:   (interactive "c")
                   1799:   (cond ((and (<= ?a char) (<= char ?z))
                   1800:         (point-to-register (- char (- ?a ?\C-a))))
                   1801:        ((= char ?<) (vip-mark-beginning-of-buffer))
                   1802:        ((= char ?>) (vip-mark-end-of-buffer))
                   1803:        ((= char ?.) (push-mark))
                   1804:        ((= char ?,) (set-mark-command 1))
                   1805:        ((= char ?D) (mark-defun))
                   1806:        (t (error ""))))
                   1807: 
                   1808: (defun vip-goto-mark (arg)
                   1809:   "Go to mark."
                   1810:   (interactive "P")
                   1811:   (let ((char (read-char)) (com (vip-getcom arg)))
                   1812:     (vip-goto-mark-subr char com nil)))
                   1813: 
                   1814: (defun vip-goto-mark-and-skip-white (arg)
                   1815:   "Go to mark and skip to first non-white on line."
                   1816:   (interactive "P")
                   1817:   (let ((char (read-char)) (com (vip-getCom arg)))
                   1818:     (vip-goto-mark-subr char com t)))
                   1819: 
                   1820: (defun vip-goto-mark-subr (char com skip-white)
                   1821:   (cond ((and (<= ?a char) (<= char ?z))
                   1822:         (let ((buff (current-buffer)))
                   1823:           (if com (move-marker vip-com-point (point)))
                   1824:           (goto-char (register-to-point (- char (- ?a ?\C-a))))
                   1825:           (if skip-white (back-to-indentation))
                   1826:           (vip-change-mode-to-vi)
                   1827:           (if com
                   1828:               (if (equal buff (current-buffer))
                   1829:                   (vip-execute-com (if skip-white
                   1830:                                        'vip-goto-mark-and-skip-white
                   1831:                                      'vip-goto-mark)
                   1832:                                    nil com)
                   1833:                 (switch-to-buffer buff)
                   1834:                 (goto-char vip-com-point)
                   1835:                 (vip-change-mode-to-vi)
                   1836:                 (error "")))))
                   1837:        ((and (not skip-white) (= char ?`))
                   1838:         (if com (move-marker vip-com-point (point)))
                   1839:         (exchange-point-and-mark)
                   1840:         (if com (vip-execute-com 'vip-goto-mark nil com)))
                   1841:        ((and skip-white (= char ?'))
                   1842:         (if com (move-marker vip-com-point (point)))
                   1843:         (exchange-point-and-mark)
                   1844:         (back-to-indentation)
                   1845:         (if com (vip-execute-com 'vip-goto-mark-and-skip-white nil com)))
                   1846:        (t (error ""))))
                   1847: 
                   1848: (defun vip-exchange-point-and-mark ()
                   1849:   (interactive)
                   1850:   (exchange-point-and-mark)
                   1851:   (back-to-indentation))
                   1852: 
                   1853: (defun vip-keyboard-quit ()
                   1854:   "Abort partially formed or running command."
                   1855:   (interactive)
                   1856:   (setq vip-use-register nil)
                   1857:   (keyboard-quit))
                   1858: 
                   1859: (defun vip-ctl-c-equivalent (arg)
                   1860:   "Emulate C-c in Emacs mode."
                   1861:   (interactive "P")
                   1862:   (vip-ctl-key-equivalent "\C-c" arg))
                   1863: 
                   1864: (defun vip-ctl-x-equivalent (arg)
                   1865:   "Emulate C-x in Emacs mode."
                   1866:   (interactive "P")
                   1867:   (vip-ctl-key-equivalent "\C-x" arg))
                   1868: 
                   1869: (defun vip-ctl-key-equivalent (key arg)
                   1870:   (let ((char (read-char)))
                   1871:     (if (and (<= ?A char) (<= char ?Z))
                   1872:        (setq char (- char (- ?A ?\C-a))))
                   1873:          (setq prefix-arg arg)
                   1874:          (command-execute
                   1875:           (vip-get-editor-command
                   1876:            vip-emacs-local-map global-map
                   1877:            (format "%s%s" key (char-to-string char))))))
                   1878:   
                   1879: 
                   1880: ;; commands in insertion mode
                   1881: 
                   1882: (defun vip-delete-backward-word (arg)
                   1883:   "Delete previous word."
                   1884:   (interactive "p")
                   1885:   (save-excursion
                   1886:     (set-mark (point))
                   1887:     (backward-word arg)
                   1888:     (delete-region (point) (mark))))
                   1889: 
                   1890: 
                   1891: ;; key bindings
                   1892: 
                   1893: (set 'vip-mode-map (make-keymap))
                   1894: 
                   1895: (define-key vip-mode-map "\C-a" 'beginning-of-line)
                   1896: (define-key vip-mode-map "\C-b" 'vip-scroll-back)
                   1897: (define-key vip-mode-map "\C-c" 'vip-ctl-c)
                   1898: (define-key vip-mode-map "\C-d" 'vip-scroll-up)
                   1899: (define-key vip-mode-map "\C-e" 'vip-scroll-up-one)
                   1900: (define-key vip-mode-map "\C-f" 'vip-scroll)
                   1901: (define-key vip-mode-map "\C-g" 'vip-keyboard-quit)
                   1902: (define-key vip-mode-map "\C-h" 'help-command)
                   1903: (define-key vip-mode-map "\C-m" 'vip-scroll-back)
                   1904: (define-key vip-mode-map "\C-n" 'vip-other-window)
                   1905: (define-key vip-mode-map "\C-o" 'vip-open-line-at-point)
                   1906: (define-key vip-mode-map "\C-u" 'vip-scroll-down)
                   1907: (define-key vip-mode-map "\C-x" 'vip-ctl-x)
                   1908: (define-key vip-mode-map "\C-y" 'vip-scroll-down-one)
                   1909: (define-key vip-mode-map "\C-z" 'vip-change-mode-to-emacs)
                   1910: (define-key vip-mode-map "\e" 'vip-ESC)
                   1911: 
                   1912: (define-key vip-mode-map " " 'vip-scroll)
                   1913: (define-key vip-mode-map "!" 'vip-command-argument)
                   1914: (define-key vip-mode-map "\"" 'vip-command-argument)
                   1915: (define-key vip-mode-map "#" 'vip-command-argument)
                   1916: (define-key vip-mode-map "$" 'vip-goto-eol)
                   1917: (define-key vip-mode-map "%" 'vip-paren-match)
                   1918: (define-key vip-mode-map "&" 'vip-nil)
                   1919: (define-key vip-mode-map "'" 'vip-goto-mark-and-skip-white)
                   1920: (define-key vip-mode-map "(" 'vip-backward-sentence)
                   1921: (define-key vip-mode-map ")" 'vip-forward-sentence)
                   1922: (define-key vip-mode-map "*" 'call-last-kbd-macro)
                   1923: (define-key vip-mode-map "+" 'vip-next-line-at-bol)
                   1924: (define-key vip-mode-map "," 'vip-repeat-find-opposite)
                   1925: (define-key vip-mode-map "-" 'vip-previous-line-at-bol)
                   1926: (define-key vip-mode-map "." 'vip-repeat)
                   1927: (define-key vip-mode-map "/" 'vip-search-forward)
                   1928: 
                   1929: (define-key vip-mode-map "0" 'vip-beginning-of-line)
                   1930: (define-key vip-mode-map "1" 'vip-digit-argument)
                   1931: (define-key vip-mode-map "2" 'vip-digit-argument)
                   1932: (define-key vip-mode-map "3" 'vip-digit-argument)
                   1933: (define-key vip-mode-map "4" 'vip-digit-argument)
                   1934: (define-key vip-mode-map "5" 'vip-digit-argument)
                   1935: (define-key vip-mode-map "6" 'vip-digit-argument)
                   1936: (define-key vip-mode-map "7" 'vip-digit-argument)
                   1937: (define-key vip-mode-map "8" 'vip-digit-argument)
                   1938: (define-key vip-mode-map "9" 'vip-digit-argument)
                   1939: 
                   1940: (define-key vip-mode-map ":" 'vip-ex)
                   1941: (define-key vip-mode-map ";" 'vip-repeat-find)
                   1942: (define-key vip-mode-map "<" 'vip-command-argument)
                   1943: (define-key vip-mode-map "=" 'vip-command-argument)
                   1944: (define-key vip-mode-map ">" 'vip-command-argument)
                   1945: (define-key vip-mode-map "?" 'vip-search-backward)
                   1946: (define-key vip-mode-map "@" 'vip-nil)
                   1947: 
                   1948: (define-key vip-mode-map "A" 'vip-Append)
                   1949: (define-key vip-mode-map "B" 'vip-backward-Word)
                   1950: (define-key vip-mode-map "C" 'vip-ctl-c-equivalent)
                   1951: (define-key vip-mode-map "D" 'vip-kill-line)
                   1952: (define-key vip-mode-map "E" 'vip-end-of-Word)
                   1953: (define-key vip-mode-map "F" 'vip-find-char-backward)
                   1954: (define-key vip-mode-map "G" 'vip-goto-line)
                   1955: (define-key vip-mode-map "H" 'vip-window-top)
                   1956: (define-key vip-mode-map "I" 'vip-Insert)
                   1957: (define-key vip-mode-map "J" 'vip-join-lines)
                   1958: (define-key vip-mode-map "K" 'vip-kill-buffer)
                   1959: (define-key vip-mode-map "L" 'vip-window-bottom)
                   1960: (define-key vip-mode-map "M" 'vip-window-middle)
                   1961: (define-key vip-mode-map "N" 'vip-search-Next)
                   1962: (define-key vip-mode-map "O" 'vip-Open-line)
                   1963: (define-key vip-mode-map "P" 'vip-Put-back)
                   1964: (define-key vip-mode-map "Q" 'vip-query-replace)
                   1965: (define-key vip-mode-map "R" 'vip-replace-string)
                   1966: (define-key vip-mode-map "S" 'vip-switch-to-buffer-other-window)
                   1967: (define-key vip-mode-map "T" 'vip-goto-char-backward)
                   1968: (define-key vip-mode-map "U" 'vip-nil)
                   1969: (define-key vip-mode-map "V" 'vip-find-file-other-window)
                   1970: (define-key vip-mode-map "W" 'vip-forward-Word)
                   1971: (define-key vip-mode-map "X" 'vip-ctl-x-equivalent)
                   1972: (define-key vip-mode-map "Y" 'vip-yank-line)
                   1973: (define-key vip-mode-map "ZZ" 'save-buffers-kill-emacs)
                   1974: 
                   1975: (define-key vip-mode-map "[" 'vip-nil)
                   1976: (define-key vip-mode-map "\\" 'vip-escape-to-emacs)
                   1977: (define-key vip-mode-map "]" 'vip-nil)
                   1978: (define-key vip-mode-map "^" 'vip-bol-and-skip-white)
                   1979: (define-key vip-mode-map "_" 'vip-nil)
                   1980: (define-key vip-mode-map "`" 'vip-goto-mark)
                   1981: 
                   1982: (define-key vip-mode-map "a" 'vip-append)
                   1983: (define-key vip-mode-map "b" 'vip-backward-word)
                   1984: (define-key vip-mode-map "c" 'vip-command-argument)
                   1985: (define-key vip-mode-map "d" 'vip-command-argument)
                   1986: (define-key vip-mode-map "e" 'vip-end-of-word)
                   1987: (define-key vip-mode-map "f" 'vip-find-char-forward)
                   1988: (define-key vip-mode-map "g" 'vip-info-on-file)
                   1989: (define-key vip-mode-map "h" 'vip-backward-char)
                   1990: (define-key vip-mode-map "i" 'vip-insert)
                   1991: (define-key vip-mode-map "j" 'vip-next-line)
                   1992: (define-key vip-mode-map "k" 'vip-previous-line)
                   1993: (define-key vip-mode-map "l" 'vip-forward-char)
                   1994: (define-key vip-mode-map "m" 'vip-mark-point)
                   1995: (define-key vip-mode-map "n" 'vip-search-next)
                   1996: (define-key vip-mode-map "o" 'vip-open-line)
                   1997: (define-key vip-mode-map "p" 'vip-put-back)
                   1998: (define-key vip-mode-map "q" 'vip-nil)
                   1999: (define-key vip-mode-map "r" 'vip-replace-char)
                   2000: (define-key vip-mode-map "s" 'vip-switch-to-buffer)
                   2001: (define-key vip-mode-map "t" 'vip-goto-char-forward)
                   2002: (define-key vip-mode-map "u" 'vip-undo)
                   2003: (define-key vip-mode-map "v" 'vip-find-file)
                   2004: (define-key vip-mode-map "w" 'vip-forward-word)
                   2005: (define-key vip-mode-map "x" 'vip-delete-char)
                   2006: (define-key vip-mode-map "y" 'vip-command-argument)
                   2007: (define-key vip-mode-map "zH" 'vip-line-to-top)
                   2008: (define-key vip-mode-map "zM" 'vip-line-to-middle)
                   2009: (define-key vip-mode-map "zL" 'vip-line-to-bottom)
                   2010: (define-key vip-mode-map "z\C-m" 'vip-line-to-top)
                   2011: (define-key vip-mode-map "z." 'vip-line-to-middle)
                   2012: (define-key vip-mode-map "z-" 'vip-line-to-bottom)
                   2013: 
                   2014: (define-key vip-mode-map "{" 'vip-backward-paragraph)
                   2015: (define-key vip-mode-map "|" 'vip-goto-col)
                   2016: (define-key vip-mode-map "}" 'vip-forward-paragraph)
                   2017: (define-key vip-mode-map "~" 'vip-nil)
                   2018: (define-key vip-mode-map "\177" 'vip-delete-backward-char)
                   2019: 
                   2020: (define-key ctl-x-map "3" 'vip-buffer-in-two-windows)
                   2021: (define-key ctl-x-map "\C-i" 'insert-file)
                   2022: 
                   2023: (defun vip-version ()
                   2024:   (interactive)
                   2025:   (message "VIP version 3.5 of September 15, 1987"))
                   2026: 
                   2027: 
                   2028: ;; implement ex commands
                   2029: 
                   2030: (defvar ex-token-type nil
                   2031:   "type of token.  if non-nil, gives type of address.  if nil, it
                   2032: is a command.")
                   2033: 
                   2034: (defvar ex-token nil
                   2035:   "value of token.")
                   2036: 
                   2037: (defvar ex-addresses nil
                   2038:   "list of ex addresses")
                   2039: 
                   2040: (defvar ex-flag nil
                   2041:   "flag for ex flag")
                   2042: 
                   2043: (defvar ex-buffer nil
                   2044:   "name of ex buffer")
                   2045: 
                   2046: (defvar ex-count nil
                   2047:   "value of ex count")
                   2048: 
                   2049: (defvar ex-g-flag nil
                   2050:   "flag for global command")
                   2051: 
                   2052: (defvar ex-g-variant nil
                   2053:   "if t global command is executed on lines not matching ex-g-pat")
                   2054: 
                   2055: (defvar ex-reg-exp nil
                   2056:   "save reg-exp used in substitute")
                   2057: 
                   2058: (defvar ex-repl nil
                   2059:   "replace pattern for substitute")
                   2060: 
                   2061: (defvar ex-g-pat nil
                   2062:   "pattern for global command")
                   2063: 
                   2064: (defvar ex-map (make-sparse-keymap)
                   2065:   "save commnads for mapped keys")
                   2066: 
                   2067: (defvar ex-tag nil
                   2068:   "save ex tag")
                   2069: 
                   2070: (defvar ex-file nil)
                   2071: 
                   2072: (defvar ex-variant nil)
                   2073: 
                   2074: (defvar ex-offset nil)
                   2075: 
                   2076: (defvar ex-append nil)
                   2077: 
                   2078: (defun vip-nil ()
                   2079:   (interactive)
                   2080:   (error ""))
                   2081: 
                   2082: (defun vip-looking-back (str)
                   2083:   "returns t if looking back reg-exp STR before point."
                   2084:   (and (save-excursion (re-search-backward str nil t))
                   2085:        (= (point) (match-end 0))))
                   2086: 
                   2087: (defun vip-check-sub (str)
                   2088:   "check if ex-token is an initial segment of STR"
                   2089:   (let ((length (length ex-token)))
                   2090:     (if (and (<= length (length str))
                   2091:             (string= ex-token (substring str 0 length)))
                   2092:        (setq ex-token str)
                   2093:       (setq ex-token-type "non-command"))))
                   2094: 
                   2095: (defun vip-get-ex-com-subr ()
                   2096:   "get a complete ex command"
                   2097:   (set-mark (point))
                   2098:   (re-search-forward "[a-z][a-z]*")
                   2099:   (setq ex-token-type "command")
                   2100:   (setq ex-token (buffer-substring (point) (mark)))
                   2101:   (exchange-point-and-mark)
                   2102:   (cond ((looking-at "a")
                   2103:         (cond ((looking-at "ab") (vip-check-sub "abbreviate"))
                   2104:               ((looking-at "ar") (vip-check-sub "args"))
                   2105:               (t (vip-check-sub "append"))))
                   2106:        ((looking-at "[bh]") (setq ex-token-type "non-command"))
                   2107:        ((looking-at "c")
                   2108:         (if (looking-at "co") (vip-check-sub "copy")
                   2109:           (vip-check-sub "change")))
                   2110:        ((looking-at "d") (vip-check-sub "delete"))
                   2111:        ((looking-at "e")
                   2112:         (if (looking-at "ex") (vip-check-sub "ex")
                   2113:           (vip-check-sub "edit")))
                   2114:        ((looking-at "f") (vip-check-sub "file"))
                   2115:        ((looking-at "g") (vip-check-sub "global"))
                   2116:        ((looking-at "i") (vip-check-sub "insert"))
                   2117:        ((looking-at "j") (vip-check-sub "join"))
                   2118:        ((looking-at "l") (vip-check-sub "list"))
                   2119:        ((looking-at "m")
                   2120:         (cond ((looking-at "map") (vip-check-sub "map"))
                   2121:               ((looking-at "mar") (vip-check-sub "mark"))
                   2122:               (t (vip-check-sub "move"))))
                   2123:        ((looking-at "n")
                   2124:         (if (looking-at "nu") (vip-check-sub "number")
                   2125:           (vip-check-sub "next")))
                   2126:        ((looking-at "o") (vip-check-sub "open"))
                   2127:        ((looking-at "p")
                   2128:         (cond ((looking-at "pre") (vip-check-sub "preserve"))
                   2129:               ((looking-at "pu") (vip-check-sub "put"))
                   2130:               (t (vip-check-sub "print"))))
                   2131:        ((looking-at "q") (vip-check-sub "quit"))
                   2132:        ((looking-at "r")
                   2133:         (cond ((looking-at "rec") (vip-check-sub "recover"))
                   2134:               ((looking-at "rew") (vip-check-sub "rewind"))
                   2135:               (t (vip-check-sub "read"))))
                   2136:        ((looking-at "s")
                   2137:         (cond ((looking-at "se") (vip-check-sub "set"))
                   2138:               ((looking-at "sh") (vip-check-sub "shell"))
                   2139:               ((looking-at "so") (vip-check-sub "source"))
                   2140:               ((looking-at "st") (vip-check-sub "stop"))
                   2141:               (t (vip-check-sub "substitute"))))
                   2142:        ((looking-at "t")
                   2143:         (if (looking-at "ta") (vip-check-sub "tag")
                   2144:           (vip-check-sub "t")))
                   2145:        ((looking-at "u")
                   2146:         (cond ((looking-at "una") (vip-check-sub "unabbreviate"))
                   2147:               ((looking-at "unm") (vip-check-sub "unmap"))
                   2148:               (t (vip-check-sub "undo"))))
                   2149:        ((looking-at "v")
                   2150:         (cond ((looking-at "ve") (vip-check-sub "version"))
                   2151:               ((looking-at "vi") (vip-check-sub "visual"))
                   2152:               (t (vip-check-sub "v"))))
                   2153:        ((looking-at "w")
                   2154:         (if (looking-at "wq") (vip-check-sub "wq")
                   2155:           (vip-check-sub "write")))
                   2156:        ((looking-at "x") (vip-check-sub "xit"))
                   2157:        ((looking-at "y") (vip-check-sub "yank"))
                   2158:        ((looking-at "z") (vip-check-sub "z")))
                   2159:   (exchange-point-and-mark))
                   2160: 
                   2161: (defun vip-get-ex-token ()
                   2162:   "get an ex-token which is either an address or a command.
                   2163: a token has type \(command, address, end-mark\) and value."
                   2164:   (save-window-excursion
                   2165:     (set-buffer " *ex-working-space*")
                   2166:     (skip-chars-forward " \t")
                   2167:     (cond ((looking-at "[k#]")
                   2168:           (setq ex-token-type "command")
                   2169:           (setq ex-token (char-to-string (following-char)))
                   2170:           (forward-char 1))
                   2171:          ((looking-at "[a-z]") (vip-get-ex-com-subr))
                   2172:          ((looking-at "\\.")
                   2173:           (forward-char 1)
                   2174:           (setq ex-token-type "dot"))
                   2175:          ((looking-at "[0-9]")
                   2176:           (set-mark (point))
                   2177:           (re-search-forward "[0-9]*")
                   2178:           (setq ex-token-type
                   2179:                 (cond ((string= ex-token-type "plus") "add-number")
                   2180:                       ((string= ex-token-type "minus") "sub-number")
                   2181:                       (t "abs-number")))
                   2182:           (setq ex-token (string-to-int (buffer-substring (point) (mark)))))
                   2183:          ((looking-at "\\$")
                   2184:           (forward-char 1)
                   2185:           (setq ex-token-type "end"))
                   2186:          ((looking-at "%")
                   2187:           (forward-char 1)
                   2188:           (setq ex-token-type "whole"))
                   2189:          ((looking-at "+")
                   2190:           (cond ((or (looking-at "+[-+]") (looking-at "+[\n|]"))
                   2191:                  (forward-char 1)
                   2192:                  (insert "1")
                   2193:                  (backward-char 1)
                   2194:                  (setq ex-token-type "plus"))
                   2195:                 ((looking-at "+[0-9]")
                   2196:                  (forward-char 1)
                   2197:                  (setq ex-token-type "plus"))
                   2198:                 (t
                   2199:                  (error "Badly formed address"))))
                   2200:          ((looking-at "-")
                   2201:           (cond ((or (looking-at "-[-+]") (looking-at "-[\n|]"))
                   2202:                  (forward-char 1)
                   2203:                  (insert "1")
                   2204:                  (backward-char 1)
                   2205:                  (setq ex-token-type "minus"))
                   2206:                 ((looking-at "-[0-9]")
                   2207:                  (forward-char 1)
                   2208:                  (setq ex-token-type "minus"))
                   2209:                 (t
                   2210:                  (error "Badly formed address"))))
                   2211:          ((looking-at "/")
                   2212:           (forward-char 1)
                   2213:           (set-mark (point))
                   2214:           (let ((cont t))
                   2215:             (while (and (not (eolp)) cont)
                   2216:               ;;(re-search-forward "[^/]*/")
                   2217:               (re-search-forward "[^/]*\\(/\\|\n\\)")
                   2218:               (if (not (vip-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/"))
                   2219:                   (setq cont nil))))
                   2220:           (backward-char 1)
                   2221:           (setq ex-token (buffer-substring (point) (mark)))
                   2222:           (if (looking-at "/") (forward-char 1))
                   2223:           (setq ex-token-type "search-forward"))
                   2224:          ((looking-at "\\?")
                   2225:           (forward-char 1)
                   2226:           (set-mark (point))
                   2227:           (let ((cont t))
                   2228:             (while (and (not (eolp)) cont)
                   2229:               ;;(re-search-forward "[^\\?]*\\?")
                   2230:               (re-search-forward "[^\\?]*\\(\\?\\|\n\\)")
                   2231:               (if (not (vip-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\\\?"))
                   2232:                   (setq cont nil))
                   2233:               (backward-char 1)
                   2234:               (if (not (looking-at "\n")) (forward-char 1))))
                   2235:           (setq ex-token-type "search-backward")
                   2236:           (setq ex-token (buffer-substring (1- (point)) (mark))))
                   2237:          ((looking-at ",")
                   2238:           (forward-char 1)
                   2239:           (setq ex-token-type "comma"))
                   2240:          ((looking-at ";")
                   2241:           (forward-char 1)
                   2242:           (setq ex-token-type "semi-colon"))
                   2243:          ((looking-at "[!=><&~]")
                   2244:           (setq ex-token-type "command")
                   2245:           (setq ex-token (char-to-string (following-char)))
                   2246:           (forward-char 1))
                   2247:          ((looking-at "'")
                   2248:           (setq ex-token-type "goto-mark")
                   2249:           (forward-char 1)
                   2250:           (cond ((looking-at "'") (setq ex-token nil))
                   2251:                 ((looking-at "[a-z]") (setq ex-token (following-char)))
                   2252:                 (t (error "Marks are ' and a-z")))
                   2253:           (forward-char 1))
                   2254:          ((looking-at "\n")
                   2255:           (setq ex-token-type "end-mark")
                   2256:           (setq ex-token "goto"))
                   2257:          (t
                   2258:           (error "illegal token")))))
                   2259: 
                   2260: (defun vip-ex (&optional string)
                   2261:   "ex commands within VIP."
                   2262:   (interactive)
                   2263:   (or string
                   2264:       (setq ex-g-flag nil
                   2265:            ex-g-variant nil))
                   2266:   (let ((com-str (or string (vip-read-string ":")))
                   2267:        (address nil) (cont t) (dot (point)))
                   2268:     (save-window-excursion
                   2269:       (set-buffer (get-buffer-create " *ex-working-space*"))
                   2270:       (delete-region (point-min) (point-max))
                   2271:       (insert com-str "\n")
                   2272:       (goto-char (point-min)))
                   2273:     (setq ex-token-type "")
                   2274:     (setq ex-addresses nil)
                   2275:     (while cont
                   2276:       (vip-get-ex-token)
                   2277:       (cond ((or (string= ex-token-type "command")
                   2278:                 (string= ex-token-type "end-mark"))
                   2279:             (if address (setq ex-addresses (cons address ex-addresses)))
                   2280:             (cond ((string= ex-token "global")
                   2281:                    (ex-global nil)
                   2282:                    (setq cont nil))
                   2283:                   ((string= ex-token "v")
                   2284:                    (ex-global t)
                   2285:                    (setq cont nil))
                   2286:                   (t
                   2287:                    (vip-execute-ex-command)
                   2288:                    (save-window-excursion
                   2289:                      (set-buffer " *ex-working-space*")
                   2290:                      (skip-chars-forward " \t")
                   2291:                      (cond ((looking-at "|")
                   2292:                             (forward-char 1))
                   2293:                            ((looking-at "\n")
                   2294:                             (setq cont nil))
                   2295:                            (t (error "Extra character at end of a command")))))))
                   2296:            ((string= ex-token-type "non-command")
                   2297:             (error (format "%s: Not an editor command" ex-token)))
                   2298:            ((string= ex-token-type "whole")
                   2299:             (setq ex-addresses
                   2300:                   (cons (point-max) (cons (point-min) ex-addresses))))
                   2301:            ((string= ex-token-type "comma")
                   2302:             (setq ex-addresses
                   2303:                   (cons (if (null address) (point) address) ex-addresses)))
                   2304:            ((string= ex-token-type "semi-colon")
                   2305:             (if address (setq dot address))
                   2306:             (setq ex-addresses
                   2307:                   (cons (if (null address) (point) address) ex-addresses)))
                   2308:            (t (let ((ans (vip-get-ex-address-subr address dot)))
                   2309:                 (if ans (setq address ans))))))))
                   2310: 
                   2311: (defun vip-get-ex-pat ()
                   2312:   "get a regular expression and set ex-variant if found"
                   2313:   (save-window-excursion
                   2314:     (set-buffer " *ex-working-space*")
                   2315:     (skip-chars-forward " \t")
                   2316:     (if (looking-at "!")
                   2317:        (progn
                   2318:          (setq ex-g-variant (not ex-g-variant)
                   2319:                ex-g-flag (not ex-g-flag))
                   2320:          (forward-char 1)
                   2321:          (skip-chars-forward " \t")))
                   2322:     (if (looking-at "/")
                   2323:        (progn
                   2324:          (forward-char 1)
                   2325:          (set-mark (point))
                   2326:          (let ((cont t))
                   2327:            (while (and (not (eolp)) cont)
                   2328:              (re-search-forward "[^/]*\\(/\\|\n\\)")
                   2329:              ;;(re-search-forward "[^/]*/")
                   2330:              (if (not (vip-looking-back "[^\\\\]\\(\\\\\\\\\\)*\\\\/"))
                   2331:                  (setq cont nil))))
                   2332:          (setq ex-token
                   2333:                (if (= (mark) (point)) ""
                   2334:                  (buffer-substring (1- (point)) (mark))))
                   2335:          (backward-char 1))
                   2336:       (setq ex-token nil))))
                   2337: 
                   2338: (defun vip-get-ex-command ()
                   2339:   "get an ex command"
                   2340:   (save-window-excursion
                   2341:     (set-buffer " *ex-working-space*")
                   2342:     (if (looking-at "/") (forward-char 1))
                   2343:     (skip-chars-forward " \t")
                   2344:     (cond ((looking-at "[a-z]")
                   2345:           (vip-get-ex-com-subr)
                   2346:           (if (string= ex-token-type "non-command")
                   2347:               (error "%s: not an editor command" ex-token)))
                   2348:          ((looking-at "[!=><&~]")
                   2349:           (setq ex-token (char-to-string (following-char)))
                   2350:           (forward-char 1))
                   2351:          (t (error "Could not find an ex command")))))
                   2352: 
                   2353: (defun vip-get-ex-opt-gc ()
                   2354:   "get an ex option g or c"
                   2355:   (save-window-excursion
                   2356:     (set-buffer " *ex-working-space*")
                   2357:     (if (looking-at "/") (forward-char 1))
                   2358:     (skip-chars-forward " \t")
                   2359:     (cond ((looking-at "g")
                   2360:           (setq ex-token "g")
                   2361:           (forward-char 1)
                   2362:           t)
                   2363:          ((looking-at "c")
                   2364:           (setq ex-token "c")
                   2365:           (forward-char 1)
                   2366:           t)
                   2367:          (t nil))))
                   2368: 
                   2369: (defun vip-default-ex-addresses (&optional whole-flag)
                   2370:   "compute default addresses.  whole-flag means whole buffer."
                   2371:   (cond ((null ex-addresses)
                   2372:         (setq ex-addresses
                   2373:               (if whole-flag
                   2374:                   (cons (point-max) (cons (point-min) nil))
                   2375:                 (cons (point) (cons (point) nil)))))
                   2376:        ((null (cdr ex-addresses))
                   2377:         (setq ex-addresses
                   2378:               (cons (car ex-addresses) ex-addresses)))))
                   2379: 
                   2380: (defun vip-get-ex-address ()
                   2381:   "get an ex-address as a marker and set ex-flag if a flag is found"
                   2382:   (let ((address (point-marker)) (cont t))
                   2383:     (setq ex-token "")
                   2384:     (setq ex-flag nil)
                   2385:     (while cont
                   2386:       (vip-get-ex-token)
                   2387:       (cond ((string= ex-token-type "command")
                   2388:             (if (or (string= ex-token "print") (string= ex-token "list")
                   2389:                     (string= ex-token "#"))
                   2390:                 (progn
                   2391:                   (setq ex-flag t)
                   2392:                   (setq cont nil))
                   2393:             (error "address expected")))
                   2394:            ((string= ex-token-type "end-mark")
                   2395:             (setq cont nil))
                   2396:            ((string= ex-token-type "whole")
                   2397:             (error "a trailing address is expected"))
                   2398:            ((string= ex-token-type "comma")
                   2399:             (error "Extra characters after an address"))
                   2400:            (t (let ((ans (vip-get-ex-address-subr address (point-marker))))
                   2401:                 (if ans (setq address ans))))))
                   2402:     address))
                   2403: 
                   2404: (defun vip-get-ex-address-subr (old-address dot)
                   2405:   "returns an address as a point"
                   2406:   (let ((address nil))
                   2407:     (if (null old-address) (setq old-address dot))
                   2408:     (cond ((string= ex-token-type "dot")
                   2409:           (setq address dot))
                   2410:          ((string= ex-token-type "add-number")
                   2411:           (save-excursion
                   2412:             (goto-char old-address)
                   2413:             (forward-line (if (= old-address 0) (1- ex-token) ex-token))
                   2414:             (setq address (point-marker))))
                   2415:          ((string= ex-token-type "sub-number")
                   2416:           (save-excursion
                   2417:             (goto-char old-address)
                   2418:             (forward-line (- ex-token))
                   2419:             (setq address (point-marker))))
                   2420:          ((string= ex-token-type "abs-number")
                   2421:           (save-excursion
                   2422:             (goto-char (point-min))
                   2423:             (if (= ex-token 0) (setq address 0)
                   2424:               (forward-line (1- ex-token))
                   2425:               (setq address (point-marker)))))
                   2426:          ((string= ex-token-type "end")
                   2427:           (setq address (point-max-marker)))
                   2428:          ((string= ex-token-type "plus") t);; do nothing
                   2429:          ((string= ex-token-type "minus") t);; do nothing
                   2430:          ((string= ex-token-type "search-forward")
                   2431:           (save-excursion
                   2432:             (ex-search-address t)
                   2433:             (setq address (point-marker))))
                   2434:          ((string= ex-token-type "search-backward")
                   2435:           (save-excursion
                   2436:             (ex-search-address nil)
                   2437:             (setq address (point-marker))))
                   2438:          ((string= ex-token-type "goto-mark")
                   2439:           (save-excursion
                   2440:             (if (null ex-token)
                   2441:                 (exchange-point-and-mark)
                   2442:               (goto-char (register-to-point (- ex-token (- ?a ?\C-a)))))
                   2443:             (setq address (point-marker)))))
                   2444:     address))
                   2445: 
                   2446: (defun ex-search-address (forward)
                   2447:   "search pattern and set address"
                   2448:   (if (string= ex-token "")
                   2449:       (if (null vip-s-string) (error "No previous search string")
                   2450:        (setq ex-token vip-s-string))
                   2451:     (setq vip-s-string ex-token))
                   2452:   (if forward
                   2453:       (progn
                   2454:        (forward-line 1)
                   2455:        (re-search-forward ex-token))
                   2456:     (forward-line -1)
                   2457:     (re-search-backward ex-token)))
                   2458: 
                   2459: (defun vip-get-ex-buffer ()
                   2460:   "get a buffer name and set ex-count and ex-flag if found"
                   2461:   (setq ex-buffer nil)
                   2462:   (setq ex-count nil)
                   2463:   (setq ex-flag nil)
                   2464:   (save-window-excursion
                   2465:     (set-buffer " *ex-working-space*")
                   2466:     (skip-chars-forward " \t")
                   2467:     (if (looking-at "[a-zA-Z]")
                   2468:        (progn
                   2469:          (setq ex-buffer (following-char))
                   2470:          (forward-char 1)
                   2471:          (skip-chars-forward " \t")))
                   2472:     (if (looking-at "[0-9]")
                   2473:        (progn
                   2474:          (set-mark (point))
                   2475:          (re-search-forward "[0-9][0-9]*")
                   2476:          (setq ex-count (string-to-int (buffer-substring (point) (mark))))
                   2477:          (skip-chars-forward " \t")))
                   2478:     (if (looking-at "[pl#]")
                   2479:        (progn
                   2480:          (setq ex-flag t)
                   2481:          (forward-char 1)))
                   2482:     (if (not (looking-at "[\n|]"))
                   2483:        (error "Illegal extra characters"))))
                   2484: 
                   2485: (defun vip-get-ex-count ()
                   2486:   (setq ex-variant nil
                   2487:        ex-count nil
                   2488:        ex-flag nil)
                   2489:   (save-window-excursion
                   2490:     (set-buffer " *ex-working-space*")
                   2491:     (skip-chars-forward " \t")
                   2492:     (if (looking-at "!")
                   2493:        (progn
                   2494:          (setq ex-variant t)
                   2495:          (forward-char 1)))
                   2496:     (skip-chars-forward " \t")
                   2497:     (if (looking-at "[0-9]")
                   2498:        (progn
                   2499:          (set-mark (point))
                   2500:          (re-search-forward "[0-9][0-9]*")
                   2501:          (setq ex-count (string-to-int (buffer-substring (point) (mark))))
                   2502:          (skip-chars-forward " \t")))
                   2503:     (if (looking-at "[pl#]")
                   2504:        (progn
                   2505:          (setq ex-flag t)
                   2506:          (forward-char 1)))
                   2507:     (if (not (looking-at "[\n|]"))
                   2508:        (error "Illegal extra characters"))))
                   2509: 
                   2510: (defun vip-get-ex-file ()
                   2511:   "get a file name and set ex-variant, ex-append and ex-offset if found"
                   2512:   (setq ex-file nil
                   2513:        ex-variant nil
                   2514:        ex-append nil
                   2515:        ex-offset nil)
                   2516:   (save-window-excursion
                   2517:     (set-buffer " *ex-working-space*")
                   2518:     (skip-chars-forward " \t")
                   2519:     (if (looking-at "!")
                   2520:        (progn
                   2521:          (setq ex-variant t)
                   2522:          (forward-char 1)
                   2523:          (skip-chars-forward " \t")))
                   2524:     (if (looking-at ">>")
                   2525:        (progn
                   2526:          (setq ex-append t
                   2527:                ex-variant t)
                   2528:          (forward-char 2)
                   2529:          (skip-chars-forward " \t")))
                   2530:     (if (looking-at "+")
                   2531:        (progn
                   2532:          (forward-char 1)
                   2533:          (set-mark (point))
                   2534:          (re-search-forward "[ \t\n]")
                   2535:          (backward-char 1)
                   2536:          (setq ex-offset (buffer-substring (point) (mark)))
                   2537:          (forward-char 1)
                   2538:          (skip-chars-forward " \t")))
                   2539:     (set-mark (point))
                   2540:     (re-search-forward "[ \t\n]")
                   2541:     (backward-char 1)
                   2542:     (setq ex-file (buffer-substring (point) (mark)))))
                   2543: 
                   2544: (defun vip-execute-ex-command ()
                   2545:   "execute ex command using the value of addresses."
                   2546:   (cond ((string= ex-token "goto") (ex-goto))
                   2547:        ((string= ex-token "copy") (ex-copy nil))
                   2548:        ((string= ex-token "delete") (ex-delete))
                   2549:        ((string= ex-token "edit") (ex-edit))
                   2550:        ((string= ex-token "file") (vip-info-on-file))
                   2551:        ;((string= ex-token "global") (ex-global nil))
                   2552:        ((string= ex-token "join") (ex-line "join"))
                   2553:        ((string= ex-token "k") (ex-mark))
                   2554:        ((string= ex-token "mark") (ex-mark))
                   2555:        ((string= ex-token "map") (ex-map))
                   2556:        ((string= ex-token "move") (ex-copy t))
                   2557:        ((string= ex-token "put") (ex-put))
                   2558:        ((string= ex-token "quit") (ex-quit))
                   2559:        ((string= ex-token "read") (ex-read))
                   2560:        ((string= ex-token "set") (ex-set))
                   2561:        ((string= ex-token "shell") (ex-shell))
                   2562:        ((string= ex-token "substitute") (ex-substitute))
                   2563:        ((string= ex-token "stop") (suspend-emacs))
                   2564:        ((string= ex-token "t") (ex-copy nil))
                   2565:        ((string= ex-token "tag") (ex-tag))
                   2566:        ((string= ex-token "undo") (vip-undo))
                   2567:        ((string= ex-token "unmap") (ex-unmap))
                   2568:        ;((string= ex-token "v") (ex-global t))
                   2569:        ((string= ex-token "version") (vip-version))
                   2570:        ((string= ex-token "visual") (ex-edit))
                   2571:        ((string= ex-token "write") (ex-write nil))
                   2572:        ((string= ex-token "wq") (ex-write t))
                   2573:        ((string= ex-token "yank") (ex-yank))
                   2574:        ((string= ex-token "!") (ex-command))
                   2575:        ((string= ex-token "=") (ex-line-no))
                   2576:        ((string= ex-token ">") (ex-line "right"))
                   2577:        ((string= ex-token "<") (ex-line "left"))
                   2578:        ((string= ex-token "&") (ex-substitute t))
                   2579:        ((string= ex-token "~") (ex-substitute t t))
                   2580:        ((or (string= ex-token "append")
                   2581:             (string= ex-token "args")
                   2582:             (string= ex-token "change")
                   2583:             (string= ex-token "insert")
                   2584:             (string= ex-token "open")
                   2585:             )
                   2586:         (error (format "%s: no such command from VIP" ex-token)))
                   2587:        ((or (string= ex-token "abbreviate")
                   2588:             (string= ex-token "list")
                   2589:             (string= ex-token "next")
                   2590:             (string= ex-token "print")
                   2591:             (string= ex-token "preserve")
                   2592:             (string= ex-token "recover")
                   2593:             (string= ex-token "rewind")
                   2594:             (string= ex-token "source")
                   2595:             (string= ex-token "unabbreviate")
                   2596:             (string= ex-token "xit")
                   2597:             (string= ex-token "z")
                   2598:             )
                   2599:         (error (format "%s: not implemented in VIP" ex-token)))
                   2600:        (t (error (format "%s: Not an editor command" ex-token)))))
                   2601: 
                   2602: (defun ex-goto ()
                   2603:   "ex goto command"
                   2604:   (if (null ex-addresses)
                   2605:       (setq ex-addresses (cons (dot) nil)))
                   2606:   (push-mark (point))
                   2607:   (goto-char (car ex-addresses))
                   2608:   (beginning-of-line))
                   2609: 
                   2610: (defun ex-copy (del-flag)
                   2611:   "ex copy and move command.  DEL-FLAG means delete."
                   2612:   (vip-default-ex-addresses)
                   2613:   (let ((address (vip-get-ex-address))
                   2614:        (end (car ex-addresses)) (beg (car (cdr ex-addresses))))
                   2615:     (goto-char end)
                   2616:     (save-excursion
                   2617:       (set-mark beg)
                   2618:       (vip-enlarge-region (mark) (point))
                   2619:       (if del-flag (kill-region (point) (mark))
                   2620:        (copy-region-as-kill (point) (mark)))
                   2621:       (if ex-flag
                   2622:          (progn
                   2623:            (with-output-to-temp-buffer "*copy text*"
                   2624:              (princ
                   2625:               (if (or del-flag ex-g-flag ex-g-variant)
                   2626:                   (car kill-ring-yank-pointer)
                   2627:                 (buffer-substring (point) (mark)))))
                   2628:            (condition-case nil
                   2629:                (progn
                   2630:                  (vip-read-string "[Hit return to continue] ")
                   2631:                  (save-excursion (kill-buffer "*copy text*")))
                   2632:              (quit
                   2633:               (save-excursion (kill-buffer "*copy text*"))
                   2634:               (signal 'quit nil))))))
                   2635:       (if (= address 0)
                   2636:          (goto-char (point-min))
                   2637:        (goto-char address)
                   2638:        (forward-line 1))
                   2639:       (insert (car kill-ring-yank-pointer))))
                   2640: 
                   2641: (defun ex-delete ()
                   2642:   "ex delete"
                   2643:   (vip-default-ex-addresses)
                   2644:   (vip-get-ex-buffer)
                   2645:   (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
                   2646:     (if (> beg end) (error "First address exceeds second"))
                   2647:     (save-excursion
                   2648:       (vip-enlarge-region beg end)
                   2649:       (exchange-point-and-mark)
                   2650:       (if ex-count
                   2651:          (progn
                   2652:            (set-mark (point))
                   2653:            (forward-line (1- ex-count)))
                   2654:        (set-mark end))
                   2655:       (vip-enlarge-region (point) (mark))
                   2656:       (if ex-flag
                   2657:          ;; show text to be deleted and ask for confirmation
                   2658:          (progn
                   2659:            (with-output-to-temp-buffer " *delete text*"
                   2660:              (princ (buffer-substring (point) (mark))))
                   2661:            (condition-case conditions
                   2662:                (vip-read-string "[Hit return to continue] ")
                   2663:              (quit
                   2664:               (save-excursion (kill-buffer " *delete text*"))
                   2665:               (error "")))
                   2666:            (save-excursion (kill-buffer " *delete text*")))
                   2667:        (if ex-buffer
                   2668:            (if (and (<= ?A ex-buffer) (<= ex-buffer ?Z))
                   2669:                (vip-append-to-register
                   2670:                 (+ ex-buffer 32) (point) (mark) nil)
                   2671:              (copy-to-register ex-buffer (point) (mark) nil)))
                   2672:        (delete-region (point) (mark))))))
                   2673: 
                   2674: (defun ex-edit ()
                   2675:   "ex-edit"
                   2676:   (vip-get-ex-file)
                   2677:   (if (and (not ex-variant) (buffer-modified-p) buffer-file-name)
                   2678:       (error "No write since last change \(:e! overrides\)"))
                   2679:   (vip-change-mode-to-emacs)
                   2680:   (set-buffer
                   2681:    (find-file-noselect (concat default-directory ex-file)))
                   2682:   (vip-change-mode-to-vi)
                   2683:   (goto-char (point-min))
                   2684:   (if ex-offset
                   2685:       (progn
                   2686:        (save-window-excursion
                   2687:          (set-buffer " *ex-working-space*")
                   2688:          (delete-region (point-min) (point-max))
                   2689:          (insert ex-offset "\n")
                   2690:          (goto-char (point-min)))
                   2691:        (goto-char (vip-get-ex-address))
                   2692:        (beginning-of-line))))
                   2693: 
                   2694: (defun ex-global (variant)
                   2695:   "ex global command"
                   2696:   (if (or ex-g-flag ex-g-variant)
                   2697:       (error "Global within global not allowed")
                   2698:     (if variant
                   2699:        (setq ex-g-flag nil
                   2700:              ex-g-variant t)
                   2701:       (setq ex-g-flag t
                   2702:            ex-g-variant nil)))
                   2703:   (vip-get-ex-pat)
                   2704:   (if (null ex-token)
                   2705:       (error "Missing regular expression for global command"))
                   2706:   (if (string= ex-token "")
                   2707:       (if (null vip-s-string) (error "No previous search string")
                   2708:        (setq ex-g-pat vip-s-string))
                   2709:     (setq ex-g-pat ex-token
                   2710:          vip-s-string ex-token))
                   2711:   (if (null ex-addresses)
                   2712:       (setq ex-addresses (list (point-max) (point-min))))
                   2713:   (let ((marks nil) (mark-count 0)
                   2714:        com-str (end (car ex-addresses)) (beg (car (cdr ex-addresses))))
                   2715:     (if (> beg end) (error "First address exceeds second"))
                   2716:     (save-excursion
                   2717:       (vip-enlarge-region beg end)
                   2718:       (exchange-point-and-mark)
                   2719:       (let ((cont t) (limit (point-marker)))
                   2720:        (exchange-point-and-mark)
                   2721:        ;; skip the last line if empty
                   2722:        (beginning-of-line)
                   2723:        (if (and (eobp) (not (bobp))) (backward-char 1))
                   2724:        (while (and cont (not (bobp)) (>= (point) limit))
                   2725:          (beginning-of-line)
                   2726:          (set-mark (point))
                   2727:          (end-of-line)
                   2728:          (let ((found (re-search-backward ex-g-pat (mark) t)))
                   2729:            (if (or (and ex-g-flag found)
                   2730:                    (and ex-g-variant (not found)))
                   2731:                (progn
                   2732:                  (end-of-line)
                   2733:                  (setq mark-count (1+ mark-count))
                   2734:                  (setq marks (cons (point-marker) marks)))))
                   2735:          (beginning-of-line)
                   2736:          (if (bobp) (setq cont nil)
                   2737:            (forward-line -1)
                   2738:            (end-of-line)))))
                   2739:   (save-window-excursion
                   2740:     (set-buffer " *ex-working-space*")
                   2741:     (setq com-str (buffer-substring (1+ (point)) (1- (point-max)))))
                   2742:   (while marks
                   2743:     (goto-char (car marks))
                   2744:     ; report progress of execution on a slow machine.
                   2745:     ;(message "Executing global command...")
                   2746:     ;(if (zerop (% mark-count 10))
                   2747:        ;(message "Executing global command...%d" mark-count))
                   2748:     (vip-ex com-str)
                   2749:     (setq mark-count (1- mark-count))
                   2750:     (setq marks (cdr marks)))))
                   2751:   ;(message "Executing global command...done")))
                   2752: 
                   2753: (defun ex-line (com)
                   2754:   "ex line commands.  COM is join, shift-right or shift-left."
                   2755:   (vip-default-ex-addresses)
                   2756:   (vip-get-ex-count)
                   2757:   (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))) point)
                   2758:     (if (> beg end) (error "First address exceeds second"))
                   2759:     (save-excursion
                   2760:       (vip-enlarge-region beg end)
                   2761:       (exchange-point-and-mark)
                   2762:       (if ex-count
                   2763:          (progn
                   2764:            (set-mark (point))
                   2765:            (forward-line ex-count)))
                   2766:       (if ex-flag
                   2767:          ;; show text to be joined and ask for confirmation
                   2768:          (progn
                   2769:            (with-output-to-temp-buffer " *text*"
                   2770:              (princ (buffer-substring (point) (mark))))
                   2771:            (condition-case conditions
                   2772:                (progn
                   2773:                  (vip-read-string "[Hit return to continue] ")
                   2774:                  (ex-line-subr com (point) (mark)))
                   2775:              (quit
                   2776:               (ding)))
                   2777:            (save-excursion (kill-buffer " *text*")))
                   2778:        (ex-line-subr com (point) (mark)))
                   2779:       (setq point (point)))
                   2780:     (goto-char (1- point))
                   2781:     (beginning-of-line)))
                   2782: 
                   2783: (defun ex-line-subr (com beg end)
                   2784:   (cond ((string= com "join")
                   2785:         (goto-char (min beg end))
                   2786:         (while (and (not (eobp)) (< (point) (max beg end)))
                   2787:           (end-of-line)
                   2788:           (if (and (<= (point) (max beg end)) (not (eobp)))
                   2789:               (progn
                   2790:                 (forward-line 1)
                   2791:                 (delete-region (point) (1- (point)))
                   2792:                 (if (not ex-variant) (fixup-whitespace))))))
                   2793:        ((or (string= com "right") (string= com "left"))
                   2794:         (indent-rigidly
                   2795:          (min beg end) (max beg end)
                   2796:          (if (string= com "right") vip-shift-width (- vip-shift-width)))
                   2797:         (goto-char (max beg end))
                   2798:         (end-of-line)
                   2799:         (forward-char 1))))
                   2800: 
                   2801: (defun ex-mark ()
                   2802:   "ex mark"
                   2803:   (let (char)
                   2804:     (if (null ex-addresses)
                   2805:        (setq ex-addresses
                   2806:              (cons (point) nil)))
                   2807:     (save-window-excursion
                   2808:       (set-buffer " *ex-working-space*")
                   2809:       (skip-chars-forward " \t")
                   2810:       (if (looking-at "[a-z]")
                   2811:          (progn
                   2812:            (setq char (following-char))
                   2813:            (forward-char 1)
                   2814:            (skip-chars-forward " \t")
                   2815:            (if (not (looking-at "[\n|]"))
                   2816:                (error "Extra characters at end of \"k\" command")))
                   2817:        (if (looking-at "[\n|]")
                   2818:            (error "\"k\" requires a following letter")
                   2819:          (error "Mark must specify a letter"))))
                   2820:     (save-excursion
                   2821:       (goto-char (car ex-addresses))
                   2822:       (point-to-register (- char (- ?a ?\C-a))))))
                   2823: 
                   2824: (defun ex-map ()
                   2825:   "ex map"
                   2826:   (let (char string)
                   2827:     (save-window-excursion
                   2828:       (set-buffer " *ex-working-space*")
                   2829:       (skip-chars-forward " \t")
                   2830:       (setq char (char-to-string (following-char)))
                   2831:       (forward-char 1)
                   2832:       (skip-chars-forward " \t")
                   2833:       (if (looking-at "[\n|]") (error "Missing rhs"))
                   2834:       (set-mark (point))
                   2835:       (end-of-buffer)
                   2836:       (backward-char 1)
                   2837:       (setq string (buffer-substring (mark) (point))))
                   2838:     (if (not (lookup-key ex-map char))
                   2839:        (define-key ex-map char
                   2840:          (or (lookup-key vip-mode-map char) 'vip-nil)))
                   2841:     (define-key vip-mode-map char
                   2842:       (eval
                   2843:        (list 'quote
                   2844:             (cons 'lambda
                   2845:                   (list '(count)
                   2846:                         '(interactive "p")
                   2847:                         (list 'execute-kbd-macro string 'count))))))))
                   2848: 
                   2849: (defun ex-unmap ()
                   2850:   "ex unmap"
                   2851:   (let (char)
                   2852:     (save-window-excursion
                   2853:       (set-buffer " *ex-working-space*")
                   2854:       (skip-chars-forward " \t")
                   2855:       (setq char (char-to-string (following-char)))
                   2856:       (forward-char 1)
                   2857:       (skip-chars-forward " \t")
                   2858:       (if (not (looking-at "[\n|]")) (error "Macro must be a character")))
                   2859:     (if (not (lookup-key ex-map char))
                   2860:        (error "That macro wasn't mapped"))
                   2861:     (define-key vip-mode-map char (lookup-key ex-map char))
                   2862:     (define-key ex-map char nil)))
                   2863: 
                   2864: (defun ex-put ()
                   2865:   "ex put"
                   2866:   (let ((point (if (null ex-addresses) (point) (car ex-addresses))))
                   2867:     (vip-get-ex-buffer)
                   2868:     (setq vip-use-register ex-buffer)
                   2869:     (goto-char point)
                   2870:     (if (= point 0) (vip-Put-back 1) (vip-put-back 1))))
                   2871: 
                   2872: (defun ex-quit ()
                   2873:   "ex quit"
                   2874:   (let (char)
                   2875:     (save-window-excursion
                   2876:       (set-buffer " *ex-working-space*")
                   2877:       (skip-chars-forward " \t")
                   2878:       (setq char (following-char)))
                   2879:     (if (= char ?!) (kill-emacs t) (save-buffers-kill-emacs))))
                   2880: 
                   2881: (defun ex-read ()
                   2882:   "ex read"
                   2883:   (let ((point (if (null ex-addresses) (point) (car ex-addresses)))
                   2884:        (variant nil) command file)
                   2885:     (goto-char point)
                   2886:     (if (not (= point 0)) (next-line 1))
                   2887:     (beginning-of-line)
                   2888:     (save-window-excursion
                   2889:       (set-buffer " *ex-working-space*")
                   2890:       (skip-chars-forward " \t")
                   2891:       (if (looking-at "!")
                   2892:          (progn
                   2893:            (setq variant t)
                   2894:            (forward-char 1)
                   2895:            (skip-chars-forward " \t")
                   2896:            (set-mark (point))
                   2897:            (end-of-line)
                   2898:            (setq command (buffer-substring (mark) (point))))
                   2899:        (set-mark (point))
                   2900:        (re-search-forward "[ \t\n]")
                   2901:        (backward-char 1)
                   2902:        (setq file (buffer-substring (point) (mark)))))
                   2903:       (if variant
                   2904:          (shell-command command t)
                   2905:        (insert-file file))))
                   2906: 
                   2907: (defun ex-set ()
                   2908:   (eval (list 'setq
                   2909:              (read-variable "Variable: ")
                   2910:              (eval (read-minibuffer "Value: ")))))
                   2911: 
                   2912: (defun ex-shell ()
                   2913:   "ex shell"
                   2914:   (vip-change-mode-to-emacs)
                   2915:   (shell))
                   2916: 
                   2917: (defun ex-substitute (&optional repeat r-flag) 
                   2918:   "ex substitute. if REPEAT use previous reg-exp which is ex-reg-exp or
                   2919: vip-s-string"
                   2920:   (let (pat repl (opt-g nil) (opt-c nil) (matched-pos nil))
                   2921:     (if repeat (setq ex-token nil) (vip-get-ex-pat))
                   2922:     (if (null ex-token)
                   2923:        (setq pat (if r-flag vip-s-string ex-reg-exp)
                   2924:              repl ex-repl)
                   2925:       (setq pat (if (string= ex-token "") vip-s-string ex-token))
                   2926:       (setq vip-s-string pat
                   2927:            ex-reg-exp pat)
                   2928:       (vip-get-ex-pat)
                   2929:       (if (null ex-token)
                   2930:          (setq ex-token ""
                   2931:                ex-repl "")
                   2932:        (setq repl ex-token
                   2933:              ex-repl ex-token)))
                   2934:     (while (vip-get-ex-opt-gc)
                   2935:       (if (string= ex-token "g") (setq opt-g t) (setq opt-c t)))
                   2936:     (vip-get-ex-count)
                   2937:     (if ex-count
                   2938:        (save-excursion
                   2939:          (if ex-addresses (goto-char (car ex-addresses)))
                   2940:          (set-mark (point))
                   2941:          (forward-line (1- ex-count))
                   2942:          (setq ex-addresses (cons (point) (cons (mark) nil))))
                   2943:       (if (null ex-addresses)
                   2944:          (setq ex-addresses (cons (point) (cons (point) nil)))
                   2945:        (if (null (cdr ex-addresses))
                   2946:            (setq ex-addresses (cons (car ex-addresses) ex-addresses)))))
                   2947:     ;(setq G opt-g)
                   2948:     (let ((beg (car ex-addresses)) (end (car (cdr ex-addresses)))
                   2949:          (cont t) eol-mark)
                   2950:       (save-excursion
                   2951:        (vip-enlarge-region beg end)
                   2952:        (let ((limit (save-excursion
                   2953:                       (goto-char (max (point) (mark)))
                   2954:                       (point-marker))))
                   2955:          (goto-char (min (point) (mark)))
                   2956:          (while (< (point) limit)
                   2957:            (end-of-line)
                   2958:            (setq eol-mark (dot-marker))
                   2959:            (beginning-of-line)
                   2960:            (if opt-g
                   2961:                (progn
                   2962:                  (while (and (not (eolp))
                   2963:                              (re-search-forward pat eol-mark t))
                   2964:                    (if (or (not opt-c) (y-or-n-p "Replace? "))
                   2965:                        (progn
                   2966:                          (setq matched-pos (point))
                   2967:                          (replace-match repl))))
                   2968:                  (end-of-line)
                   2969:                  (forward-char))
                   2970:              (if (and (re-search-forward pat eol-mark t)
                   2971:                       (or (not opt-c) (y-or-n-p "Replace? ")))
                   2972:                  (progn
                   2973:                    (setq matched-pos (point))
                   2974:                    (replace-match repl)))
                   2975:              (end-of-line)
                   2976:              (forward-char))))))
                   2977:     (if matched-pos (goto-char matched-pos))
                   2978:     (beginning-of-line)
                   2979:     (if opt-c (message "done"))))
                   2980: 
                   2981: (defun ex-tag ()
                   2982:   "ex tag"
                   2983:   (let (tag)
                   2984:     (save-window-excursion
                   2985:       (set-buffer " *ex-working-space*")
                   2986:       (skip-chars-forward " \t")
                   2987:       (set-mark (point))
                   2988:       (skip-chars-forward "^ |\t\n")
                   2989:       (setq tag (buffer-substring (mark) (point))))
                   2990:     (if (not (string= tag "")) (setq ex-tag tag))
                   2991:     (vip-change-mode-to-emacs)
                   2992:     (condition-case conditions
                   2993:        (progn
                   2994:          (if (string= tag "")
                   2995:              (find-tag ex-tag t)
                   2996:            (find-tag-other-window ex-tag))
                   2997:          (vip-change-mode-to-vi))
                   2998:       (error
                   2999:        (vip-change-mode-to-vi)
                   3000:        (vip-message-conditions conditions)))))
                   3001: 
                   3002: (defun ex-write (q-flag)
                   3003:   "ex write"
                   3004:   (vip-default-ex-addresses t)
                   3005:   (vip-get-ex-file)
                   3006:   (if (string= ex-file "")
                   3007:       (progn
                   3008:        (if (null buffer-file-name)
                   3009:            (error "No file associated with this buffer"))
                   3010:        (setq ex-file buffer-file-name))
                   3011:     (setq ex-file (expand-file-name ex-file)))
                   3012:   (if (and (not (string= ex-file (buffer-file-name)))
                   3013:           (file-exists-p ex-file)
                   3014:           (not ex-variant))
                   3015:       (error (format "\"%s\" File exists - use w! to override" ex-file)))
                   3016:   (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
                   3017:     (if (> beg end) (error "First address exceeds second"))
                   3018:     (save-excursion
                   3019:       (vip-enlarge-region beg end)
                   3020:       (write-region (point) (mark) ex-file ex-append t)))
                   3021:   (if (null buffer-file-name) (setq buffer-file-name ex-file))
                   3022:   (if q-flag (save-buffers-kill-emacs)))
                   3023: 
                   3024: (defun ex-yank ()
                   3025:   "ex yank"
                   3026:   (vip-default-ex-addresses)
                   3027:   (vip-get-ex-buffer)
                   3028:   (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
                   3029:     (if (> beg end) (error "First address exceeds second"))
                   3030:     (save-excursion
                   3031:       (vip-enlarge-region beg end)
                   3032:       (exchange-point-and-mark)
                   3033:       (if (or ex-g-flag ex-g-variant) (error "Can't yank within global"))
                   3034:       (if ex-count
                   3035:          (progn
                   3036:            (set-mark (point))
                   3037:            (forward-line (1- ex-count)))
                   3038:        (set-mark end))
                   3039:       (vip-enlarge-region (point) (mark))
                   3040:       (if ex-flag (error "Extra chacters at end of command"))
                   3041:       (if ex-buffer
                   3042:          (copy-to-register ex-buffer (point) (mark) nil))
                   3043:       (copy-region-as-kill (point) (mark)))))
                   3044: 
                   3045: (defun ex-command ()
                   3046:   "execute shell command"
                   3047:   (let (command)
                   3048:     (save-window-excursion
                   3049:       (set-buffer " *ex-working-space*")
                   3050:       (skip-chars-forward " \t")
                   3051:       (set-mark (point))
                   3052:       (end-of-line)
                   3053:       (setq command (buffer-substring (mark) (point))))
                   3054:     (if (null ex-addresses)
                   3055:        (shell-command command)
                   3056:       (let ((end (car ex-addresses)) (beg (car (cdr ex-addresses))))
                   3057:        (if (null beg) (setq beg end))
                   3058:        (save-excursion
                   3059:          (goto-char beg)
                   3060:          (set-mark end)
                   3061:          (vip-enlarge-region (point) (mark))
                   3062:          (shell-command-on-region (point) (mark) command t))
                   3063:        (goto-char beg)))))
                   3064: 
                   3065: (defun ex-line-no ()
                   3066:   "print line number"
                   3067:   (message "%d"
                   3068:           (1+ (count-lines
                   3069:                (point-min)
                   3070:                (if (null ex-addresses) (point-max) (car ex-addresses))))))
                   3071: 
                   3072: (if (file-exists-p "~/.vip") (load "~/.vip"))
                   3073: 
                   3074: ;; End of VIP

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.