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