;;; viper-ex.el --- functions implementing the Ex commands for Viper
-;; Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003,
+;; 2004, 2005, 2006 Free Software Foundation, Inc.
+
+;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
;; This file is part of GNU Emacs.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
-;; Code
+;;; Code:
(provide 'viper-ex)
(defvar viper-custom-file-name)
(defvar viper-case-fold-search)
(defvar explicit-shell-file-name)
+(defvar compile-command)
;; loading happens only in non-interactive compilation
;; in order to spare non-viperized emacs from being viperized
(require 'viper-util)
(defgroup viper-ex nil
- "Viper support for Ex commands"
+ "Viper support for Ex commands."
:prefix "ex-"
:group 'viper)
;;; Variables
(defconst viper-ex-work-buf-name " *ex-working-space*")
-(defconst viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+(defvar viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(defconst viper-ex-tmp-buf-name " *ex-tmp*")
+(defconst viper-ex-print-buf-name " *ex-print*")
+(defvar viper-ex-print-buf (get-buffer-create viper-ex-print-buf-name))
+
+
+;;; ex-commands...
+
+(defun ex-cmd-obsolete (name)
+ (error "`%s': Obsolete command, not supported by Viper" name))
+
+(defun ex-cmd-not-yet (name)
+ (error "`%s': Command not implemented in Viper" name))
+
+;; alist entries: name (in any order), command, cont(??)
+;; If command is a string, then that is an alias to the real command
+;; to execute (for instance, ":m" -> ":move").
+;; command attributes:
+;; is-mashed: the command's args may be jammed right up against the command
+;; one-letter: this is a one-letter token. Any text appearing after
+;; the name gets appended as an argument for the command
+;; i.e. ":kabc" gets turned into (ex-mark "abc")
+(defconst ex-token-alist '(
+ ("!" (ex-command))
+ ("&" (ex-substitute t))
+ ("=" (ex-line-no))
+ (">" (ex-line "right"))
+ ("<" (ex-line "left"))
+ ("Buffer" (if ex-cycle-other-window
+ (viper-switch-to-buffer)
+ (viper-switch-to-buffer-other-window)))
+ ("Next" (ex-next (not ex-cycle-other-window)))
+ ("PreviousRelatedFile" (ex-next-related-buffer -1))
+ ("RelatedFile" (ex-next-related-buffer 1))
+ ("W" "Write")
+ ("WWrite" (save-some-buffers t))
+ ("Write" (save-some-buffers))
+ ("a" "append")
+ ("args" (ex-args))
+ ("buffer" (if ex-cycle-other-window
+ (viper-switch-to-buffer-other-window)
+ (viper-switch-to-buffer)))
+ ("c" "change")
+ ;; ch should be "change" but maintain old viper compatibility
+ ("ch" "chdir")
+ ("cd" (ex-cd))
+ ("chdir" (ex-cd))
+ ("copy" (ex-copy nil))
+ ("customize" (customize-group "viper"))
+ ("delete" (ex-delete))
+ ("edit" (ex-edit))
+ ("file" (ex-set-visited-file-name))
+ ("g" "global")
+ ("global" (ex-global nil) is-mashed)
+ ("goto" (ex-goto))
+ ("help" (ex-help))
+ ("join" (ex-line "join"))
+ ("k" (ex-mark) one-letter)
+ ("kmark" (ex-mark))
+ ("m" "move")
+ ("make" (ex-compile))
+ ; old viper doesn't specify a default for "ma" so leave it undefined
+ ("map" (ex-map))
+ ("mark" (ex-mark))
+ ("move" (ex-copy t))
+ ("next" (ex-next ex-cycle-other-window))
+ ("p" "print")
+ ("preserve" (ex-preserve))
+ ("print" (ex-print))
+ ("put" (ex-put))
+ ("pwd" (ex-pwd))
+ ("quit" (ex-quit))
+ ("r" "read")
+ ("re" "read")
+ ("read" (ex-read))
+ ("recover" (ex-recover))
+ ("rewind" (ex-rewind))
+ ("s" "substitute")
+ ("su" "substitute")
+ ("sub" "substitute")
+ ("set" (ex-set))
+ ("shell" (ex-shell))
+ ("source" (ex-source))
+ ("stop" (suspend-emacs))
+ ("sr" (ex-substitute t t))
+ ("submitReport" (viper-submit-report))
+ ("substitute" (ex-substitute) is-mashed)
+ ("suspend" (suspend-emacs))
+ ("t" "transfer")
+ ("tag" (ex-tag))
+ ("transfer" (ex-copy nil))
+ ("u" "undo")
+ ("un" "undo")
+ ("undo" (viper-undo))
+ ("unmap" (ex-unmap))
+ ("v" "vglobal")
+ ("version" (viper-version))
+ ("vglobal" (ex-global t) is-mashed)
+ ("visual" (ex-edit))
+ ("w" "write")
+ ("wq" (ex-write t))
+ ("write" (ex-write nil))
+ ("xit" (ex-write t))
+ ("yank" (ex-yank))
+ ("~" (ex-substitute t t))
+
+ ("append" (ex-cmd-obsolete "append"))
+ ("change" (ex-cmd-obsolete "change"))
+ ("insert" (ex-cmd-obsolete "insert"))
+ ("open" (ex-cmd-obsolete "open"))
+
+ ("list" (ex-cmd-not-yet "list"))
+ ("z" (ex-cmd-not-yet "z"))
+ ("#" (ex-cmd-not-yet "#"))
+
+ ("abbreviate" (error "`%s': Vi abbreviations are obsolete. Use the more powerful Emacs abbrevs" ex-token))
+ ("unabbreviate" (error "`%s': Vi abbreviations are obsolete. Use the more powerful Emacs abbrevs" ex-token))
+ ))
+;; No code should touch anything in the alist entry! (other than the name,
+;; "car entry", of course) This way, changing this data structure
+;; requires changing only the following ex-cmd functions...
+
+;; Returns cmd if the command may be jammed right up against its
+;; arguments, nil if there must be a space.
+;; examples of mashable commands: g// g!// v// s// sno// sm//
+(defun ex-cmd-is-mashed-with-args (cmd)
+ (if (eq 'is-mashed (car (nthcdr 2 cmd))) cmd))
+
+;; Returns true if this is a one-letter command that may be followed
+;; by anything, no whitespace needed. This is a special-case for ":k".
+(defun ex-cmd-is-one-letter (cmd)
+ (if (eq 'one-letter (car (nthcdr 2 cmd))) cmd))
+
+;; Executes the function associated with the command
+(defun ex-cmd-execute (cmd)
+ (eval (cadr cmd)))
+
+;; If this is a one-letter magic command, splice in args.
+(defun ex-splice-args-in-1-letr-cmd (key list)
+ (let ((oneletter (ex-cmd-is-one-letter (assoc (substring key 0 1) list))))
+ (if oneletter
+ (list key
+ (append (cadr oneletter)
+ (if (< 1 (length key)) (list (substring key 1))))
+ (car (cdr (cdr oneletter))) ))
+ ))
+
+
+;; Returns the alist entry for the appropriate key.
+;; Tries to complete the key before using it in the alist.
+;; If there is no appropriate key (no match or duplicate matches) return nil
+(defun ex-cmd-assoc (key list)
+ (let ((entry (try-completion key list))
+ result)
+ (setq result (cond
+ ((eq entry t) (assoc key list))
+ ((stringp entry) (or (ex-splice-args-in-1-letr-cmd key list)
+ (assoc entry list)))
+ ((eq entry nil) (ex-splice-args-in-1-letr-cmd key list))
+ (t nil)
+ ))
+ ;; If we end up with an alias, look up the alias...
+ (if (stringp (cadr result))
+ (setq result (ex-cmd-assoc (cadr result) list)))
+ ;; and return the corresponding alist entry
+ result
+ ))
-;;; Variable completion in :set command
-
-;; The list of Ex commands. Used for completing command names.
-(defconst ex-token-alist
- '(("!") ("=") (">") ("&") ("~")
- ("yank") ("xit") ("WWrite") ("Write") ("write") ("wq") ("visual")
- ("version") ("vglobal") ("unmap") ("undo") ("tag") ("transfer") ("suspend")
- ("substitute") ("submitReport") ("stop") ("sr") ("source") ("shell")
- ("set") ("rewind") ("recover") ("read") ("quit") ("pwd")
- ("put") ("preserve") ("PreviousRelatedFile") ("RelatedFile")
- ("next") ("Next") ("move") ("mark") ("map") ("kmark") ("join")
- ("help") ("goto") ("global") ("file") ("edit") ("delete") ("customize")
- ("copy") ("chdir") ("cd") ("Buffer") ("buffer") ("args")) )
;; A-list of Ex variables that can be set using the :set command.
-(defconst ex-variable-alist
+(defconst ex-variable-alist
'(("wrapscan") ("ws") ("wrapmargin") ("wm")
("tabstop-global") ("ts-g") ("tabstop") ("ts")
("showmatch") ("sm") ("shiftwidth") ("sw") ("shell") ("sh")
- ("readonly") ("ro")
+ ("readonly") ("ro")
("nowrapscan") ("nows") ("noshowmatch") ("nosm")
("noreadonly") ("noro") ("nomagic") ("noma")
("noignorecase") ("noic")
("noautoindent-global") ("noai-g") ("noautoindent") ("noai")
("magic") ("ma") ("ignorecase") ("ic")
- ("autoindent-global") ("ai-g") ("autoindent") ("ai")
- ("all")
+ ("autoindent-global") ("ai-g") ("autoindent") ("ai")
+ ("all")
))
-
+
;; Token recognized during parsing of Ex commands (e.g., "read", "comma")
(defvar ex-token nil)
-;; Type of token.
+;; Type of token.
;; If non-nil, gives type of address; if nil, it is a command.
(defvar ex-token-type nil)
(defvar ex-g-flag nil)
;; Flag indicating that :vglobal Ex command is being executed.
(defvar ex-g-variant nil)
+;; Marks to operate on during a :global Ex command.
+(defvar ex-g-marks nil)
;; Save reg-exp used in substitute.
(defvar ex-reg-exp nil)
((string-match "\\(bash$\\|bash.exe$\\)" shell-file-name)
"-noprofile") ; bash: ignore .profile
)))
- "Options to pass to the Unix-style shell.
+ "Options to pass to the Unix-style shell.
Don't put `-c' here, as it is added automatically."
:type '(choice (const nil) string)
:group 'viper-ex)
+(defcustom ex-compile-command "make"
+ "The command to run when the user types :make."
+ :type 'string
+ :group 'viper-ex)
+
(defcustom viper-glob-function
(cond (ex-unix-type-shell 'viper-glob-unix-files)
((eq system-type 'emx) 'viper-glob-mswindows-files) ; OS/2
The default tries to set this variable to work with Unix, Windows,
OS/2, and VMS.
-However, if it doesn't work right for some types of Unix shells or some OS,
+However, if it doesn't work right for some types of Unix shells or some OS,
the user should supply the appropriate function and set this variable to the
corresponding function symbol."
:type 'symbol
;; e.g., :r !date
(defvar ex-cmdfile nil)
(defvar ex-cmdfile-args "")
-
+
;; flag used in viper-ex-read-file-name to indicate that we may be reading
;; multiple file names. Used for :edit and :next
(defvar viper-keep-reading-filename nil)
;; Last shell command executed with :! command.
(defvar viper-ex-last-shell-com nil)
-
+
;; Indicates if Minibuffer was exited temporarily in Ex-command.
(defvar viper-incomplete-ex-cmd nil)
-
+
;; Remembers the last ex-command prompt.
(defvar viper-last-ex-prompt "")
-;;; Code
-
-;; Check if ex-token is an initial segment of STR
-(defun viper-check-sub (str)
- (let ((length (length ex-token)))
- (if (and (<= length (length str))
- (string= ex-token (substring str 0 length)))
- (setq ex-token str)
- (setq ex-token-type 'non-command))))
-
;; Get a complete ex command
(defun viper-get-ex-com-subr ()
- (let (case-fold-search)
+ (let (cmd case-fold-search)
(set-mark (point))
(re-search-forward "[a-zA-Z][a-zA-Z]*")
(setq ex-token-type 'command)
(setq ex-token (buffer-substring (point) (mark t)))
- (exchange-point-and-mark)
- (cond ((looking-at "a")
- (cond ((looking-at "ab") (viper-check-sub "abbreviate"))
- ((looking-at "ar") (viper-check-sub "args"))
- (t (viper-check-sub "append"))))
- ((looking-at "h") (viper-check-sub "help"))
- ((looking-at "c")
- (cond ((looking-at "cd") (viper-check-sub "cd"))
- ((looking-at "ch") (viper-check-sub "chdir"))
- ((looking-at "co") (viper-check-sub "copy"))
- ((looking-at "cu") (viper-check-sub "customize"))
- (t (viper-check-sub "change"))))
- ((looking-at "d") (viper-check-sub "delete"))
- ((looking-at "b") (viper-check-sub "buffer"))
- ((looking-at "B") (viper-check-sub "Buffer"))
- ((looking-at "e")
- (if (looking-at "ex") (viper-check-sub "ex")
- (viper-check-sub "edit")))
- ((looking-at "f") (viper-check-sub "file"))
- ((looking-at "g") (viper-check-sub "global"))
- ((looking-at "i") (viper-check-sub "insert"))
- ((looking-at "j") (viper-check-sub "join"))
- ((looking-at "l") (viper-check-sub "list"))
- ((looking-at "m")
- (cond ((looking-at "map") (viper-check-sub "map"))
- ((looking-at "mar") (viper-check-sub "mark"))
- (t (viper-check-sub "move"))))
- ((looking-at "k[a-z][^a-z]")
- (setq ex-token "kmark")
- (forward-char 1)
- (exchange-point-and-mark)) ; this is canceled out by another
- ; exchange-point-and-mark at the end
- ((looking-at "k") (viper-check-sub "kmark"))
- ((looking-at "n") (if (looking-at "nu")
- (viper-check-sub "number")
- (viper-check-sub "next")))
- ((looking-at "N") (viper-check-sub "Next"))
- ((looking-at "o") (viper-check-sub "open"))
- ((looking-at "p")
- (cond ((looking-at "pre") (viper-check-sub "preserve"))
- ((looking-at "pu") (viper-check-sub "put"))
- ((looking-at "pw") (viper-check-sub "pwd"))
- (t (viper-check-sub "print"))))
- ((looking-at "P") (viper-check-sub "PreviousRelatedFile"))
- ((looking-at "R") (viper-check-sub "RelatedFile"))
- ((looking-at "q") (viper-check-sub "quit"))
- ((looking-at "r")
- (cond ((looking-at "rec") (viper-check-sub "recover"))
- ((looking-at "rew") (viper-check-sub "rewind"))
- (t (viper-check-sub "read"))))
- ((looking-at "s")
- (cond ((looking-at "se") (viper-check-sub "set"))
- ((looking-at "sh") (viper-check-sub "shell"))
- ((looking-at "so") (viper-check-sub "source"))
- ((looking-at "sr") (viper-check-sub "sr"))
- ((looking-at "st") (viper-check-sub "stop"))
- ((looking-at "sus") (viper-check-sub "suspend"))
- ((looking-at "subm") (viper-check-sub "submitReport"))
- (t (viper-check-sub "substitute"))))
- ((looking-at "t")
- (if (looking-at "ta") (viper-check-sub "tag")
- (viper-check-sub "transfer")))
- ((looking-at "u")
- (cond ((looking-at "una") (viper-check-sub "unabbreviate"))
- ((looking-at "unm") (viper-check-sub "unmap"))
- (t (viper-check-sub "undo"))))
- ((looking-at "v")
- (cond ((looking-at "ve") (viper-check-sub "version"))
- ((looking-at "vi") (viper-check-sub "visual"))
- (t (viper-check-sub "vglobal"))))
- ((looking-at "w")
- (if (looking-at "wq") (viper-check-sub "wq")
- (viper-check-sub "write")))
- ((looking-at "W")
- (if (looking-at "WW")
- (viper-check-sub "WWrite")
- (viper-check-sub "Write")))
- ((looking-at "x") (viper-check-sub "xit"))
- ((looking-at "y") (viper-check-sub "yank"))
- ((looking-at "z") (viper-check-sub "z")))
- (exchange-point-and-mark)
+ (setq cmd (ex-cmd-assoc ex-token ex-token-alist))
+ (if cmd
+ (setq ex-token (car cmd))
+ (setq ex-token-type 'non-command))
))
;; Get an ex-token which is either an address or a command.
;; A token has a type, \(command, address, end-mark\), and a value
(defun viper-get-ex-token ()
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t|")
(let ((case-fold-search t))
((eq ex-token-type 'minus) 'sub-number)
(t 'abs-number)))
(setq ex-token
- (string-to-int (buffer-substring (point) (mark t)))))
+ (string-to-number (buffer-substring (point) (mark t)))))
((looking-at "\\$")
(forward-char 1)
(setq ex-token-type 'end))
"\\|" "![ \t]*[a-zA-Z].*"
"\\)"
"!*")))
-
+
(save-window-excursion ;; put cursor at the end of the Ex working buffer
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(goto-char (point-max)))
(cond ((viper-looking-back quit-regex1) (exit-minibuffer))
((viper-looking-back stay-regex) (insert " "))
((viper-looking-back quit-regex2) (exit-minibuffer))
(t (insert " ")))))
-
+
;; complete Ex command
(defun ex-cmd-complete ()
(interactive)
(let (save-pos dist compl-list string-to-complete completion-result)
-
+
(save-excursion
(setq dist (skip-chars-backward "[a-zA-Z!=>&~]")
save-pos (point)))
-
+
(if (or (= dist 0)
(viper-looking-back "\\([ \t]*['`][ \t]*[a-z]*\\)")
(viper-looking-back
(viper-looking-back "\\([ \t]*['`][ \t]*[a-z]*\\)")
(looking-at "[^ \t\n\C-m]"))
nil
- (with-output-to-temp-buffer "*Completions*"
+ (with-output-to-temp-buffer "*Completions*"
(display-completion-list
(viper-alist-to-list ex-token-alist))))
;; Preceding chars may be part of a command name
(setq string-to-complete (buffer-substring save-pos (point)))
(setq completion-result
(try-completion string-to-complete ex-token-alist))
-
+
(cond ((eq completion-result t) ; exact match--do nothing
(viper-tmp-insert-at-eob " (Sole completion)"))
((eq completion-result nil)
(viper-filter-alist (concat "^" completion-result)
ex-token-alist)))
(if (> (length compl-list) 1)
- (with-output-to-temp-buffer "*Completions*"
+ (with-output-to-temp-buffer "*Completions*"
(display-completion-list
(viper-alist-to-list (reverse compl-list)))))))
)))
-
-;; Read Ex commands
+
+;; Read Ex commands
;; ARG is a prefix argument. If given, the ex command runs on the region
;;(without the user having to specify the address :a,b
;; STRING is the command to execute. If nil, then Viper asks you to enter the
-;; command.
+;; command.
(defun viper-ex (arg &optional string)
(interactive "P")
(or string
(+ reg-beg-line (count-lines reg-beg reg-end) -1)))))
(if reg-beg-line
(setq initial-str (format "%d,%d" reg-beg-line reg-end-line)))
-
- (setq com-str
+
+ (setq com-str
(or string (viper-read-string-with-history
- ":"
+ ":"
initial-str
'viper-ex-history
;; no default when working on region
(if initial-str
- "none"
+ nil
(car viper-ex-history))
map
(if initial-str
" [Type command to execute on current region]"))))
(save-window-excursion
;; just a precaution
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(delete-region (point-min) (point-max))
(insert com-str "\n")
(viper-get-ex-token)
(cond ((memq ex-token-type '(command end-mark))
(if address (setq ex-addresses (cons address ex-addresses)))
- (cond ((string= ex-token "global")
- (ex-global nil)
- (setq cont nil))
- ((string= ex-token "vglobal")
- (ex-global t)
- (setq cont nil))
- (t
- (viper-execute-ex-command)
- (save-excursion
- (save-window-excursion
- (setq viper-ex-work-buf
- (get-buffer-create viper-ex-work-buf-name))
- (set-buffer viper-ex-work-buf)
- (skip-chars-forward " \t")
- (cond ((looking-at "|")
- (forward-char 1))
- ((looking-at "\n")
- (setq cont nil))
- (t (error
- "`%s': %s" ex-token viper-SpuriousText)))
- )))
- ))
+ (viper-deactivate-mark)
+ (let ((cmd (ex-cmd-assoc ex-token ex-token-alist)))
+ (if (null cmd)
+ (error "`%s': %s" ex-token viper-BadExCommand))
+ (ex-cmd-execute cmd)
+ (if (or (ex-cmd-is-mashed-with-args cmd)
+ (ex-cmd-is-one-letter cmd))
+ (setq cont nil)
+ (save-excursion
+ (save-window-excursion
+ (setq viper-ex-work-buf
+ (get-buffer-create viper-ex-work-buf-name))
+ (set-buffer viper-ex-work-buf)
+ (skip-chars-forward " \t")
+ (cond ((looking-at "|")
+ (forward-char 1))
+ ((looking-at "\n")
+ (setq cont nil))
+ (t (error
+ "`%s': %s" ex-token viper-SpuriousText)))
+ )))
+ ))
((eq ex-token-type 'non-command)
(error "`%s': %s" ex-token viper-BadExCommand))
((eq ex-token-type 'whole)
(t (let ((ans (viper-get-ex-address-subr address dot)))
(if ans (setq address ans)))))
(setq prev-token-type ex-token-type))))
-
+
;; Get a regular expression and set `ex-variant', if found
+;; Viper doesn't parse the substitution or search patterns.
+;; In particular, it doesn't expand ~ into the last substitution.
(defun viper-get-ex-pat ()
(save-window-excursion
(setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(setq ex-token nil))
c)))
-;; get an ex command
-(defun viper-get-ex-command ()
- (save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
- (set-buffer viper-ex-work-buf)
- (if (looking-at "/") (forward-char 1))
- (skip-chars-forward " \t")
- (cond ((looking-at "[a-z]")
- (viper-get-ex-com-subr)
- (if (eq ex-token-type 'non-command)
- (error "`%s': %s" ex-token viper-BadExCommand)))
- ((looking-at "[!=><&~]")
- (setq ex-token (char-to-string (following-char)))
- (forward-char 1))
- (t (error viper-BadExCommand)))))
-
;; Get an Ex option g or c
(defun viper-get-ex-opt-gc (c)
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(if (looking-at (format "%c" c)) (forward-char 1))
(skip-chars-forward " \t")
(forward-line (1- ex-token))
(setq address (point-marker)))))
((eq ex-token-type 'end)
- (setq address (point-max-marker)))
+ (save-excursion
+ (goto-char (1- (point-max)))
+ (setq address (point-marker))))
((eq ex-token-type 'plus) t) ; do nothing
((eq ex-token-type 'minus) t) ; do nothing
((eq ex-token-type 'search-forward)
(save-excursion
(if (null ex-token)
(exchange-point-and-mark)
- (goto-char (viper-register-to-point
- (1+ (- ex-token ?a)) 'enforce-buffer)))
+ (goto-char
+ (viper-register-to-point
+ (viper-int-to-char (1+ (- ex-token ?a))) 'enforce-buffer)))
(setq address (point-marker)))))
address))
;; Search pattern and set address
+;; Doesn't wrap around. Should it?
(defun ex-search-address (forward)
(if (string= ex-token "")
(if (null viper-s-string)
(setq ex-count nil)
(setq ex-flag nil)
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t")
(if (looking-at "[a-zA-Z]")
(progn
(set-mark (point))
(re-search-forward "[0-9][0-9]*")
- (setq ex-count (string-to-int (buffer-substring (point) (mark t))))
+ (setq ex-count (string-to-number (buffer-substring (point) (mark t))))
(skip-chars-forward " \t")))
(if (looking-at "[pl#]")
(progn
ex-count nil
ex-flag nil)
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t")
(if (looking-at "!")
(progn
(set-mark (point))
(re-search-forward "[0-9][0-9]*")
- (setq ex-count (string-to-int (buffer-substring (point) (mark t))))
+ (setq ex-count (string-to-number (buffer-substring (point) (mark t))))
(skip-chars-forward " \t")))
(if (looking-at "[pl#]")
(progn
;; Expand \% and \# in ex command
(defun ex-expand-filsyms (cmd buf)
(let (cf pf ret)
- (save-excursion
+ (save-excursion
(set-buffer buf)
(setq cf buffer-file-name)
(setq pf (ex-next nil t))) ; this finds alternative file name
(insert cmd)
(goto-char (point-min))
(while (re-search-forward "%\\|#" nil t)
- (let ((data (match-data))
+ (let ((data (match-data))
(char (buffer-substring (match-beginning 0) (match-end 0))))
(if (viper-looking-back (concat "\\\\" char))
(replace-match char)
ex-cmdfile-args "")
(save-excursion
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t")
(if (looking-at "!")
(skip-chars-backward " \t\n")
(setq prompt (buffer-substring (point-min) (point)))
))
-
+
(setq viper-last-ex-prompt prompt)
-
+
;; If we just finished reading command, redisplay prompt
(if viper-incomplete-ex-cmd
(setq ex-file (viper-ex-read-file-name (format ":%s " prompt)))
;; file names, arranges to re-enter the minibuffer.
(defun viper-complete-filename-or-exit ()
(interactive)
- (setq viper-keep-reading-filename t)
- ;; don't exit if directory---ex-commands don't
+ (setq viper-keep-reading-filename t)
+ ;; don't exit if directory---ex-commands don't
(cond ((ex-cmd-accepts-multiple-files-p ex-token) (exit-minibuffer))
;; apparently the argument to an Ex command is
;; supposed to be a shell command
(minibuffer-local-completion-map
(copy-keymap minibuffer-local-completion-map))
beg end cont val)
-
+
(viper-add-keymap ex-read-filename-map
- (if viper-emacs-p
+ (if viper-emacs-p
minibuffer-local-completion-map
- read-file-name-map))
-
+ read-file-name-map))
+
(setq cont (setq viper-keep-reading-filename t))
(while cont
(setq viper-keep-reading-filename nil
(setq val (concat "\"" val "\"")))
(setq str (concat str (if (equal val "") "" " ")
val (if (equal val "") "" " ")))
-
+
;; Only edit, next, and Next commands accept multiple files.
;; viper-keep-reading-filename is set in the anonymous function that is
;; bound to " " in ex-read-filename-map.
(setq cont (and viper-keep-reading-filename
(ex-cmd-accepts-multiple-files-p ex-token)))
)
-
+
(setq beg (string-match "[^ \t]" str) ; delete leading blanks
end (string-match "[ \t]*$" str)) ; delete trailing blanks
(if (member ex-token '("read" "write"))
(concat viper-last-ex-prompt " !")))))
(substring str (or beg 0) end)))
-;; Execute ex command using the value of addresses
-(defun viper-execute-ex-command ()
- (viper-deactivate-mark)
- (cond ((string= ex-token "args") (ex-args))
- ((string= ex-token "copy") (ex-copy nil))
- ((string= ex-token "cd") (ex-cd))
- ((string= ex-token "customize") (customize-group "viper"))
- ((string= ex-token "chdir") (ex-cd))
- ((string= ex-token "delete") (ex-delete))
- ((string= ex-token "edit") (ex-edit))
- ((string= ex-token "file") (viper-info-on-file))
- ((string= ex-token "goto") (ex-goto))
- ((string= ex-token "help") (ex-help))
- ((string= ex-token "join") (ex-line "join"))
- ((string= ex-token "kmark") (ex-mark))
- ((string= ex-token "mark") (ex-mark))
- ((string= ex-token "map") (ex-map))
- ((string= ex-token "move") (ex-copy t))
- ((string= ex-token "next") (ex-next ex-cycle-other-window))
- ((string= ex-token "Next") (ex-next (not ex-cycle-other-window)))
- ((string= ex-token "RelatedFile") (ex-next-related-buffer 1))
- ((string= ex-token "put") (ex-put))
- ((string= ex-token "pwd") (ex-pwd))
- ((string= ex-token "preserve") (ex-preserve))
- ((string= ex-token "PreviousRelatedFile") (ex-next-related-buffer -1))
- ((string= ex-token "quit") (ex-quit))
- ((string= ex-token "read") (ex-read))
- ((string= ex-token "recover") (ex-recover))
- ((string= ex-token "rewind") (ex-rewind))
- ((string= ex-token "submitReport") (viper-submit-report))
- ((string= ex-token "set") (ex-set))
- ((string= ex-token "shell") (ex-shell))
- ((string= ex-token "source") (ex-source))
- ((string= ex-token "sr") (ex-substitute t t))
- ((string= ex-token "substitute") (ex-substitute))
- ((string= ex-token "suspend") (suspend-emacs))
- ((string= ex-token "stop") (suspend-emacs))
- ((string= ex-token "transfer") (ex-copy nil))
- ((string= ex-token "buffer") (if ex-cycle-other-window
- (viper-switch-to-buffer-other-window)
- (viper-switch-to-buffer)))
- ((string= ex-token "Buffer") (if ex-cycle-other-window
- (viper-switch-to-buffer)
- (viper-switch-to-buffer-other-window)))
- ((string= ex-token "tag") (ex-tag))
- ((string= ex-token "undo") (viper-undo))
- ((string= ex-token "unmap") (ex-unmap))
- ((string= ex-token "version") (viper-version))
- ((string= ex-token "visual") (ex-edit))
- ((string= ex-token "write") (ex-write nil))
- ((string= ex-token "Write") (save-some-buffers))
- ((string= ex-token "wq") (ex-write t))
- ((string= ex-token "WWrite") (save-some-buffers t)) ; don't ask
- ((string= ex-token "xit") (ex-write t))
- ((string= ex-token "yank") (ex-yank))
- ((string= ex-token "!") (ex-command))
- ((string= ex-token "=") (ex-line-no))
- ((string= ex-token ">") (ex-line "right"))
- ((string= ex-token "<") (ex-line "left"))
- ((string= ex-token "&") (ex-substitute t))
- ((string= ex-token "~") (ex-substitute t t))
- ((or (string= ex-token "append")
- (string= ex-token "change")
- (string= ex-token "insert")
- (string= ex-token "open"))
- (error "`%s': Obsolete command, not supported by Viper" ex-token))
- ((or (string= ex-token "abbreviate")
- (string= ex-token "unabbreviate"))
- (error
- "`%s': Vi abbrevs are obsolete. Use the more powerful Emacs abbrevs"
- ex-token))
- ((or (string= ex-token "list")
- (string= ex-token "print")
- (string= ex-token "z")
- (string= ex-token "#"))
- (error "`%s': Command not implemented in Viper" ex-token))
- (t (error "`%s': %s" ex-token viper-BadExCommand))))
(defun viper-undisplayed-files ()
(mapcar
- (lambda (b)
+ (lambda (b)
(if (null (get-buffer-window b))
(let ((f (buffer-file-name b)))
(if f f
- (if ex-cycle-through-non-files
+ (if ex-cycle-through-non-files
(let ((s (buffer-name b)))
(if (string= " " (substring s 0 1))
nil
(args "")
(file-count 1))
(while (not (null l))
- (if (car l)
+ (if (car l)
(setq args (format "%s %d) %s\n" args file-count (car l))
file-count (1+ file-count)))
(setq l (cdr l)))
(setq ex-file (viper-abbreviate-file-name (buffer-file-name))))
((string= ex-file "")
(error viper-NoFileSpecified)))
-
-;;; (let (msg do-edit)
-;;; (if buffer-file-name
-;;; (cond ((buffer-modified-p)
-;;; (setq msg
-;;; (format "Buffer %s is modified. Discard changes? "
-;;; (buffer-name))
-;;; do-edit t))
-;;; ((not (verify-visited-file-modtime (current-buffer)))
-;;; (setq msg
-;;; (format "File %s changed on disk. Reread from disk? "
-;;; buffer-file-name)
-;;; do-edit t))
-;;; (t (setq do-edit nil))))
-;;;
-;;; (if do-edit
-;;; (if (yes-or-no-p msg)
-;;; (progn
-;;; (set-buffer-modified-p nil)
-;;; (kill-buffer (current-buffer)))
-;;; (message "Buffer %s was left intact" (buffer-name))))
-;;; ) ; let
-
+
+ (let (msg do-edit)
+ (if buffer-file-name
+ (cond ((buffer-modified-p)
+ (setq msg
+ (format "Buffer %s is modified. Discard changes? "
+ (buffer-name))
+ do-edit t))
+ ((not (verify-visited-file-modtime (current-buffer)))
+ (setq msg
+ (format "File %s changed on disk. Reread from disk? "
+ buffer-file-name)
+ do-edit t))
+ (t (setq do-edit nil))))
+
+ (if do-edit
+ (if (yes-or-no-p msg)
+ (progn
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer)))
+ (message "Buffer %s was left intact" (buffer-name))))
+ ) ; let
+
(if (null (setq file (get-file-buffer ex-file)))
- (progn
+ (progn
;; this also does shell-style globbing
(ex-find-file
;; replace # and % with the previous/current file
(if ex-offset
(progn
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(delete-region (point-min) (point-max))
(insert ex-offset "\n")
(viper-get-ex-pat)
(if (null ex-token)
(error "`%s': Missing regular expression" gcommand)))
-
+
(if (string= ex-token "")
(if (null viper-s-string)
(error viper-NoPrevSearch)
(if (null ex-addresses)
(setq ex-addresses (list (point-max) (point-min)))
(viper-default-ex-addresses))
- (let ((marks nil)
- (mark-count 0)
+ (setq ex-g-marks nil)
+ (let ((mark-count 0)
(end (car ex-addresses))
(beg (car (cdr ex-addresses)))
com-str)
(progn
(end-of-line)
(setq mark-count (1+ mark-count))
- (setq marks (cons (point-marker) marks)))))
+ (setq ex-g-marks (cons (point-marker) ex-g-marks)))))
(beginning-of-line)
(if (bobp) (setq cont nil)
(forward-line -1)
(end-of-line)))))
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
;; com-str is the command string, i.e., g/pattern/ or v/pattern'
(setq com-str (buffer-substring (1+ (point)) (1- (point-max)))))
- (while marks
- (goto-char (car marks))
+ (while ex-g-marks
+ (goto-char (car ex-g-marks))
(viper-ex nil com-str)
(setq mark-count (1- mark-count))
- (setq marks (cdr marks)))))
+ (setq ex-g-marks (cdr ex-g-marks)))))
;; Ex goto command
(defun ex-goto ()
;; Ex mark command
-(defun ex-mark ()
+;; Sets the mark to the current point.
+;; If name is omitted, get the name straight from the work buffer."
+(defun ex-mark (&optional name)
(let (char)
(if (null ex-addresses)
(setq ex-addresses
(cons (point) nil)))
+ (if name
+ (if (eq 1 (length name))
+ (setq char (string-to-char name))
+ (error "`%s': Spurious text \"%s\" after mark name"
+ name (substring name 1)))
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t")
(if (looking-at "[a-z]")
(skip-chars-forward " \t")
(if (not (looking-at "[\n|]"))
(error "`%s': %s" ex-token viper-SpuriousText)))
- (error "`%s' requires a following letter" ex-token)))
+ (error "`%s' requires a following letter" ex-token))))
(save-excursion
(goto-char (car ex-addresses))
- (point-to-register (1+ (- char ?a))))))
+ (point-to-register (viper-int-to-char (1+ (- char ?a)))))))
+
+
-
-
;; Alternate file is the file next to the first one in the buffer ring
(defun ex-next (cycle-other-window &optional find-alt-file)
(catch 'ex-edit
(let (count l)
- (if (not find-alt-file)
+ (if (not find-alt-file)
(progn
(viper-get-ex-file)
(if (or (char-or-string-p ex-offset)
- (and (not (string= "" ex-file))
+ (and (not (string= "" ex-file))
(not (string-match "^[0-9]+$" ex-file))))
(progn
(ex-edit t)
(throw 'ex-edit nil))
- (setq count (string-to-int ex-file))
+ (setq count (string-to-number ex-file))
(if (= count 0) (setq count 1))
(if (< count 0) (error "Usage: `next <count>' (count >= 0)"))))
(setq count 1))
(defun ex-next-related-buffer (direction &optional no-recursion)
-
+
(viper-ring-rotate1 viper-related-files-and-buffers-ring direction)
-
- (let ((file-or-buffer-name
+
+ (let ((file-or-buffer-name
(viper-current-ring-item viper-related-files-and-buffers-ring))
(old-ring viper-related-files-and-buffers-ring)
(old-win (selected-window))
skip-rest buf wind)
-
+
(or (and (ring-p viper-related-files-and-buffers-ring)
(> (ring-length viper-related-files-and-buffers-ring) 0))
(error "This buffer has no related files or buffers"))
-
+
(or (stringp file-or-buffer-name)
(error
"File and buffer names must be strings, %S" file-or-buffer-name))
-
+
(setq buf (cond ((get-buffer file-or-buffer-name))
((file-exists-p file-or-buffer-name)
(find-file-noselect file-or-buffer-name))
))
-
+
(if (not (viper-buffer-live-p buf))
(error "Didn't find buffer %S or file %S"
file-or-buffer-name
(viper-abbreviate-file-name
(expand-file-name file-or-buffer-name))))
-
+
(if (equal buf (current-buffer))
(or no-recursion
;; try again
(progn
(setq skip-rest t)
(ex-next-related-buffer direction 'norecursion))))
-
+
(if skip-rest
()
;; setup buffer
()
(setq wind (get-lru-window (if viper-xemacs-p nil 'visible)))
(set-window-buffer wind buf))
-
+
(if (viper-window-display-p)
(progn
(raise-frame (window-frame wind))
(save-window-excursion (select-window wind) (sit-for 1))
(select-window wind)))
(save-window-excursion (select-window wind) (sit-for 1)))
-
+
(save-excursion
(set-buffer buf)
(setq viper-related-files-and-buffers-ring old-ring))
-
+
(setq viper-local-search-start-marker (point-marker))
)))
-
-
+
+
;; Force auto save
(defun ex-preserve ()
(message "Autosaving all buffers that need to be saved...")
;; Ex print working directory
(defun ex-pwd ()
- (message default-directory))
+ (message "%s" default-directory))
;; Ex quit command
(defun ex-quit ()
;; skip "!", if it is q!. In Viper q!, w!, etc., behave as q, w, etc.
(save-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(if (looking-at "!") (forward-char 1)))
(if (< viper-expert-level 3)
(setq ex-file buffer-file-name)))
(if ex-cmdfile
(progn
- (setq command
+ (setq command
;; replace # and % with the previous/current file
(ex-expand-filsyms (concat ex-file ex-cmdfile-args)
(current-buffer)))
(shell-command command t))
(insert-file-contents ex-file)))
(ex-fixup-history viper-last-ex-prompt ex-file ex-cmdfile-args))
-
+
;; this function fixes ex-history for some commands like ex-read, ex-edit
-(defun ex-fixup-history (&rest args)
+(defun ex-fixup-history (&rest args)
(setq viper-ex-history
(cons (mapconcat 'identity args " ") (cdr viper-ex-history))))
-
+
;; Ex recover from emacs \#file\#
(defun ex-recover ()
(viper-set-unread-command-events ?\C-m)))
(message ":set <Variable> [= <Value>]")
(or batch (sit-for 2))
-
+
(while (string-match "^[ \\t\\n]*$"
(setq str
(completing-read ":set " ex-variable-alist)))
(or (viper-set-unread-command-events "") (sit-for 2))
(setq val (read-string (format ":set %s = " var)))
(ex-fixup-history "set" orig-var val)
-
+
;; check numerical values
(if (member var
'("sw" "shiftwidth"
"ts" "tabstop"
"ts-g" "tabstop-global"
- "wm" "wrapmargin"))
+ "wm" "wrapmargin"))
(condition-case nil
(or (numberp (setq val2 (car (read-from-string val))))
(error "%s: Invalid value, numberp, %S" var val))
(error
(error "%s: Invalid value, numberp, %S" var val))))
-
+
(cond
((member var '("sw" "shiftwidth"))
(setq var "viper-shift-width"))
set-cmd "setq-default"))
((member var '("wm" "wrapmargin"))
;; make it take effect in curr buff and new bufs
- (kill-local-variable 'fill-column)
- (setq var "fill-column"
+ (kill-local-variable 'fill-column)
+ (setq var "fill-column"
val (format "(- (window-width) %s)" val)
set-cmd "setq-default"))
((member var '("sh" "shell"))
(setq var "explicit-shell-file-name"
val (format "\"%s\"" val)))))
(ex-fixup-history "set" orig-var))
-
+
(if set-cmd
(setq actual-lisp-cmd
(format "\n(%s %s %s) %s" set-cmd var val auto-cmd-label)
lisp-cmd-del-pattern
(format "^\n?[ \t]*([ \t]*%s[ \t]+%s[ \t].*)[ \t]*%s"
set-cmd var auto-cmd-label)))
-
+
(if (and ask-if-save
(y-or-n-p (format "Do you want to save this setting in %s "
viper-custom-file-name)))
(progn
- (viper-save-string-in-file
+ (viper-save-string-in-file
actual-lisp-cmd viper-custom-file-name
;; del pattern
lisp-cmd-del-pattern)
lisp-cmd-del-pattern)
))
))
-
+
(if set-cmd
(message "%s %s %s"
set-cmd var
;; special meaning
(defun ex-get-inline-cmd-args (regex-forw &optional chars-back replace-str)
(save-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(goto-char (point-min))
(re-search-forward regex-forw nil t)
;; Ex shell command
(defun ex-shell ()
(shell))
-
+
;; Viper help. Invokes Info
(defun ex-help ()
(condition-case nil
;; Ex substitute command
;; If REPEAT use previous regexp which is ex-reg-exp or viper-s-string
-(defun ex-substitute (&optional repeat r-flag)
+(defun ex-substitute (&optional repeat r-flag)
(let ((opt-g nil)
(opt-c nil)
(matched-pos nil)
(defun ex-tag ()
(let (tag)
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t")
(set-mark (point))
;; Ex write command
;; ex-write doesn't support wildcards, because file completion is a better
-;; mechanism. We also don't support # and %
+;; mechanism. We also don't support # and %
;; because file history is a better mechanism.
(defun ex-write (q-flag)
(viper-default-ex-addresses t)
(viper-get-ex-file)
(let ((end (car ex-addresses))
- (beg (car (cdr ex-addresses)))
+ (beg (car (cdr ex-addresses)))
(orig-buf (current-buffer))
- (orig-buf-file-name (buffer-file-name))
- (orig-buf-name (buffer-name))
- (buff-changed-p (buffer-modified-p))
+ ;;(orig-buf-file-name (buffer-file-name))
+ ;;(orig-buf-name (buffer-name))
+ ;;(buff-changed-p (buffer-modified-p))
temp-buf writing-same-file region
file-exists writing-whole-file)
(if (> beg end) (error viper-FirstAddrExceedsSecond))
(if ex-cmdfile
(progn
(viper-enlarge-region beg end)
- (shell-command-on-region (point) (mark t)
+ (shell-command-on-region (point) (mark t)
(concat ex-file ex-cmdfile-args)))
(if (and (string= ex-file "") (not (buffer-file-name)))
(setq ex-file
(read-file-name
(format "Buffer %s isn't visiting any file. File to save in: "
(buffer-name)))))
-
+
(setq writing-whole-file (and (= (point-min) beg) (= (point-max) end))
ex-file (if (string= ex-file "")
(buffer-file-name)
(setq ex-file
(concat (file-name-as-directory ex-file)
(file-name-nondirectory buffer-file-name))))
-
+
(setq file-exists (file-exists-p ex-file)
writing-same-file (string= ex-file (buffer-file-name)))
(format "File %s exists. Overwrite? " ex-file))))
(error "Quit"))
;; writing a region or whole buffer to non-visited file
- (unwind-protect
+ (unwind-protect
(save-excursion
(viper-enlarge-region beg end)
(setq region (buffer-substring (point) (mark t)))
;; create temp buffer for the region
(setq temp-buf (get-buffer-create " *ex-write*"))
(set-buffer temp-buf)
- (if viper-xemacs-p
- (set-visited-file-name ex-file)
- (set-visited-file-name ex-file 'noquerry))
+ (viper-cond-compile-for-xemacs-or-emacs
+ (set-visited-file-name ex-file) ; xemacs
+ (set-visited-file-name ex-file 'noquerry) ; emacs
+ )
(erase-buffer)
(if (and file-exists ex-append)
(insert-file-contents ex-file))
(if (and (buffer-file-name) writing-same-file)
(set-visited-file-modtime))
;; prevent loss of data if saving part of the buffer in visited file
- (or writing-whole-file
+ (or writing-whole-file
(not writing-same-file)
(progn
(sit-for 2)
(save-buffers-kill-emacs)
(kill-buffer (current-buffer))))
)))
-
+
(defun ex-write-info (exists file-name beg end)
(message "`%s'%s %d lines, %d characters"
(defun ex-command ()
(let (command)
(save-window-excursion
- (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t")
(setq command (buffer-substring (point) (point-max)))
(shell-command-on-region (point) (mark t) command t))
(goto-char beg)))))
+(defun ex-compile ()
+ "Reads args from the command line, then runs make with the args.
+If no args are given, then it runs the last compile command.
+Type 'mak ' (including the space) to run make with no args."
+ (let (args)
+ (save-window-excursion
+ (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
+ (set-buffer viper-ex-work-buf)
+ (setq args (buffer-substring (point) (point-max)))
+ (end-of-line))
+ ;; Remove the newline that may (will?) be at the end of the args
+ (if (string= "\n" (substring args (1- (length args))))
+ (setq args (substring args 0 (1- (length args)))))
+ ;; Run last command if no args given, else construct a new command.
+ (setq args
+ (if (string= "" args)
+ (if (boundp 'compile-command)
+ compile-command
+ ex-compile-command)
+ (concat ex-compile-command " " args)))
+ (compile args)
+ ))
+
;; Print line number
(defun ex-line-no ()
(message "%d"
(if (buffer-modified-p) "[Modified]" "[Unchanged]")))
(if (< (+ 1 (length info) (length file))
(window-width (minibuffer-window)))
- (message (concat file " " info))
+ (message "%s" (concat file " " info))
(save-window-excursion
(with-output-to-temp-buffer " *viper-info*"
(princ (concat "\n" file "\n\n\t" info "\n\n")))
(kill-buffer " *viper-info*")))
))
+
+;; Without arguments displays info on file. With an arg, sets the visited file
+;; name to that arg
+(defun ex-set-visited-file-name ()
+ (viper-get-ex-file)
+ (if (string= ex-file "")
+ (viper-info-on-file)
+ ;; If ex-file is a directory, use the file portion of the buffer
+ ;; file name (like ex-write). Do this even if ex-file is a
+ ;; non-existent directory, since set-visited-file-name signals an
+ ;; error on this condition, too.
+ (if (and (string= (file-name-nondirectory ex-file) "")
+ buffer-file-name
+ (not (file-directory-p buffer-file-name)))
+ (setq ex-file (concat (file-name-as-directory ex-file)
+ (file-name-nondirectory buffer-file-name))))
+ (set-visited-file-name ex-file)))
+
+
;; display all variables set through :set
(defun ex-show-vars ()
(with-output-to-temp-buffer " *viper-info*"
(princ (if viper-auto-indent
"autoindent (local)\n" "noautoindent (local)\n"))
- (princ (if (default-value 'viper-auto-indent)
+ (princ (if (default-value 'viper-auto-indent)
"autoindent (global) \n" "noautoindent (global) \n"))
(princ (if viper-case-fold-search "ignorecase\n" "noignorecase\n"))
(princ (if viper-re-search "magic\n" "nomagic\n"))
'none)))
))
-
-
-
-
-;;; viper-ex.el ends here
+(defun ex-print ()
+ (viper-default-ex-addresses)
+ (let ((end (car ex-addresses))
+ (beg (car (cdr ex-addresses))))
+ (if (> beg end) (error viper-FirstAddrExceedsSecond))
+ (save-excursion
+ (viper-enlarge-region beg end)
+ (if (or ex-g-flag ex-g-variant)
+ ;; When executing a global command, collect output of each
+ ;; print in viper-ex-print-buf.
+ (progn
+ (append-to-buffer viper-ex-print-buf (point) (mark t))
+ ;; Is this the last mark for the global command?
+ (unless (cdr ex-g-marks)
+ (with-current-buffer viper-ex-print-buf
+ (ex-print-display-lines (buffer-string))
+ (erase-buffer))))
+ (ex-print-display-lines (buffer-substring (point) (mark t)))))))
+
+(defun ex-print-display-lines (lines)
+ (cond
+ ;; String doesn't contain a newline.
+ ((not (string-match "\n" lines))
+ (message "%s" lines))
+ ;; String contains only one newline at the end. Strip it off.
+ ((= (string-match "\n" lines) (1- (length lines)))
+ (message "%s" (substring lines 0 -1)))
+ ;; String spans more than one line. Use a temporary buffer.
+ (t
+ (save-current-buffer
+ (with-output-to-temp-buffer " *viper-info*"
+ (princ lines))))))
+
+
+
+
+
+;;; arch-tag: 56b80d36-f880-4d10-bd66-85ad91a295db
+;;; viper-ex.el ends here