Function: viper-prefix-arg-com

viper-prefix-arg-com is a byte-compiled function defined in viper-cmd.el.gz.

Signature

(viper-prefix-arg-com CHAR VALUE COM)

Source Code

;; Defined in /usr/src/emacs/lisp/emulation/viper-cmd.el.gz
;; Vi operator as prefix argument."
(defun viper-prefix-arg-com (char value com)
  (let ((cont t)
	cmd-info
	cmd-to-exec-at-end)
    (while (and cont
                (memq char
                      (list ?c ?d ?y ?! ?< ?> ?= ?# ?r ?R ?\"
                            viper-buffer-search-char)))
      (if com
	  ;; this means that we already have a command character, so we
	  ;; construct a com list and exit while.  however, if char is "
	  ;; it is an error.
	  (progn
	    ;; new com is (CHAR . OLDCOM)
            (if (memq char '(?# ?\")) (user-error viper-ViperBell))
	    (setq com (cons char com))
	    (setq cont nil))
	;; If com is nil we set com as char, and read more.  Again, if char is
	;; ", we read the name of register and store it in viper-use-register.
	;; if char is !, =, or #, a complete com is formed so we exit the while
	;; loop.
        (cond ((memq char '(?! ?=))
	       (setq com char)
	       (setq char (read-char))
	       (setq cont nil))
	      ((viper= char ?#)
	       ;; read a char and encode it as com
	       (setq com (+ 128 (read-char)))
	       (setq char (read-char)))
	      ((viper= char ?\")
	       (let ((reg (read-char)))
		 (if (viper-valid-register reg)
		     (setq viper-use-register reg)
		   (user-error viper-ViperBell))
		 (setq char (read-char))))
	      (t
	       (setq com char)
	       (setq char (read-char))))))

    (if (atom com)
	;; `com' is a single char, so we construct the command argument
	;; and if `char' is `?', we describe the arg; otherwise
	;; we prepare the command that will be executed at the end.
	(progn
	  (setq cmd-info (cons value com))
	  (while (viper= char ?U)
	    (viper-describe-arg cmd-info)
	    (setq char (read-char)))
	  ;; `char' is a movement cmd, a digit arg cmd, or a register cmd---so
	  ;; we execute it at the very end
	  (or (viper-movement-command-p char)
	      (viper-digit-command-p char)
	      (viper-regsuffix-command-p char)
	      (viper= char ?!) ; bang command
	      (viper= char ?g) ; the gg command (like G0)
	      (user-error viper-ViperBell))
	  (setq cmd-to-exec-at-end
		(viper-exec-form-in-vi
		 `(key-binding (char-to-string ,char)))))

      ;; as com is non-nil, this means that we have a command to execute
      (if (memq (car com) '(?r ?R))
	  ;; execute appropriate region command.
	  (let ((char (car com)) (com (cdr com)))
	    (setq prefix-arg (cons value com))
	    (if (viper= char ?r)
		(viper-region prefix-arg)
	      (viper-Region prefix-arg))
	    ;; reset prefix-arg
	    (setq prefix-arg nil))
	;; otherwise, reset prefix arg and call appropriate command
	(setq value (if (null value) 1 value))
	(setq prefix-arg nil)
	(cond
	 ;; If we change ?C to ?c here, then cc will enter replacement mode
	 ;; rather than deleting lines.  However, it will affect 1 less line
	 ;; than normal.  We decided to not use replacement mode here and
	 ;; follow Vi, since replacement mode on n full lines can be achieved
	 ;; with nC.
	 ((equal com '(?c . ?c)) (viper-line (cons value ?C)))
	 ((equal com '(?d . ?d)) (viper-line (cons value ?D)))
	 ((equal com '(?d . ?y)) (viper-yank-defun))
	 ((equal com '(?y . ?y)) (viper-line (cons value ?Y)))
	 ((equal com '(?< . ?<)) (viper-line (cons value ?<)))
	 ((equal com '(?> . ?>)) (viper-line (cons value ?>)))
	 ((equal com '(?! . ?!)) (viper-line (cons value ?!)))
	 ((equal com '(?= . ?=)) (viper-line (cons value ?=)))
	 ;; gg  acts as G0
	 ((equal (car com) ?g)   (viper-goto-line 0))
	 (t (user-error viper-ViperBell)))))

    (if cmd-to-exec-at-end
	(progn
	  (setq last-command-event char)
	  (condition-case err
	      (funcall cmd-to-exec-at-end cmd-info)
	    (error
	     (error "%s" (error-message-string err))))))
    ))