summaryrefslogtreecommitdiff
path: root/lisp/emulation/viper-ex.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emulation/viper-ex.el')
-rw-r--r--lisp/emulation/viper-ex.el206
1 files changed, 110 insertions, 96 deletions
diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el
index 849124b5c43..a4d5bea9613 100644
--- a/lisp/emulation/viper-ex.el
+++ b/lisp/emulation/viper-ex.el
@@ -1,6 +1,6 @@
;;; viper-ex.el --- functions implementing the Ex commands for Viper
-;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
;; This file is part of GNU Emacs.
@@ -457,7 +457,9 @@ reversed."
"\\|" "jo.*"
"\\|" "^[ \t]*ta.*"
"\\|" "^[ \t]*una.*"
- "\\|" "^[ \t]*su.*"
+ ;; don't jump up in :s command
+ "\\|" "^[ \t]*\\([`'][a-z]\\|[.,%]\\)*[ \t]*su.*"
+ "\\|" "^[ \t]*\\([`'][a-z]\\|[.,%]\\)*[ \t]*s[^a-z].*"
"\\|" "['`][a-z][ \t]*"
;; r! assumes that the next one is a shell command
"\\|" "\\(r\\|re\\|rea\\|read\\)[ \t]*!"
@@ -631,40 +633,53 @@ reversed."
(set-buffer viper-ex-work-buf)
(skip-chars-forward " \t")
(if (looking-at "!")
+ ;; this is probably a variant command r!
(progn
(setq ex-g-variant (not ex-g-variant)
ex-g-flag (not ex-g-flag))
(forward-char 1)
(skip-chars-forward " \t")))
(let ((c (following-char)))
- (if (string-match "[0-9A-Za-z]" (format "%c" c))
- (error
- "Global regexp must be inside matching non-alphanumeric chars"))
+ (cond ((string-match "[0-9A-Za-z]" (format "%c" c))
+ (error
+ "Global regexp must be inside matching non-alphanumeric chars"))
+ ((= c ??) (error "`?' is not an allowed pattern delimiter here")))
(if (looking-at "[^\\\\\n]")
(progn
(forward-char 1)
(set-mark (point))
(let ((cont t))
- (while (and (not (eolp)) cont)
+ ;; the use of eobp instead of eolp permits the use of newlines in
+ ;; pat2 in s/pat1/pat2/
+ (while (and (not (eobp)) cont)
(if (not (re-search-forward (format "[^%c]*%c" c c) nil t))
(if (member ex-token '("global" "vglobal"))
- (error
- "Missing closing delimiter for global regexp")
+ (error "Missing closing delimiter for global regexp")
(goto-char (point-max))))
(if (not (viper-looking-back
(format "[^\\\\]\\(\\\\\\\\\\)*\\\\%c" c)))
- (setq cont nil))))
+ (setq cont nil)
+ ;; we are at an escaped delimiter: unescape it and continue
+ (delete-backward-char 2)
+ (insert c)
+ (if (eolp)
+ ;; if at eol, exit loop and go to next line
+ ;; later, delim will be inserted at the end
+ (progn
+ (setq cont nil)
+ (forward-char))))
+ ))
(setq ex-token
(if (= (mark t) (point)) ""
(buffer-substring (1- (point)) (mark t))))
(backward-char 1)
- ;; if the user doesn't specify the final pattern delimiter, we're
+ ;; if the user didn't insert the final pattern delimiter, we're
;; at newline now. In this case, insert the initial delimiter
;; specified in variable c
- (if (looking-at "\n")
+ (if (eolp)
(progn
- (insert c)
- (backward-char 1)))
+ (insert c)
+ (backward-char 1)))
)
(setq ex-token nil))
c)))
@@ -707,8 +722,8 @@ reversed."
(cond ((null ex-addresses)
(setq ex-addresses
(if whole-flag
- (cons (point-max) (cons (point-min) nil))
- (cons (point) (cons (point) nil)))))
+ (list (point-max) (point-min))
+ (list (point) (point)))))
((null (cdr ex-addresses))
(setq ex-addresses
(cons (car ex-addresses) ex-addresses)))))
@@ -871,7 +886,7 @@ reversed."
(char (buffer-substring (match-beginning 0) (match-end 0))))
(if (viper-looking-back (concat "\\\\" char))
(replace-match char)
- (set-match-data data)
+ (store-match-data data)
(if (string= char "%")
(replace-match cf)
(replace-match pf)))))
@@ -1009,8 +1024,10 @@ reversed."
(while cont
(setq viper-keep-reading-filename nil
val (read-file-name (concat prompt str) nil default-directory))
- (if (string-match " " val)
- (setq val (concat "\\\"" val "\\\"")))
+ (setq val (expand-file-name val))
+ (if (and (string-match " " val)
+ (ex-cmd-accepts-multiple-files-p ex-token))
+ (setq val (concat "\"" val "\"")))
(setq str (concat str (if (equal val "") "" " ")
val (if (equal val "") "" " ")))
@@ -1237,27 +1254,27 @@ reversed."
((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
@@ -1279,7 +1296,7 @@ reversed."
(ex-fixup-history viper-last-ex-prompt ex-file))
;; Find-file FILESPEC if it appears to specify a single file.
-;; Otherwise, assume that FILES{EC is a wildcard.
+;; Otherwise, assume that FILESPEC is a wildcard.
;; In this case, split it into substrings separated by newlines.
;; Each line is assumed to be a file name. find-file's each file thus obtained.
(defun ex-find-file (filespec)
@@ -1652,7 +1669,7 @@ reversed."
(ask-if-save t)
(auto-cmd-label "; don't touch or else...")
(delete-turn-on-auto-fill-pattern
- "([ \t]*add-hook[ \t]+'viper-insert-state-hooks[ \t]+'turn-on-auto-fill.*)")
+ "([ \t]*add-hook[ \t]+'viper-insert-state-hook[ \t]+'turn-on-auto-fill.*)")
actual-lisp-cmd lisp-cmd-del-pattern
val2 orig-var)
(setq orig-var var)
@@ -1770,7 +1787,7 @@ reversed."
(if (> val2 0)
(viper-save-string-in-file
(concat
- "(add-hook 'viper-insert-state-hooks 'turn-on-auto-fill) "
+ "(add-hook 'viper-insert-state-hook 'turn-on-auto-fill) "
auto-cmd-label)
viper-custom-file-name
delete-turn-on-auto-fill-pattern)
@@ -1902,8 +1919,12 @@ Please contact your system administrator. "
(point-marker))))
(goto-char (min (point) (mark t)))
(while (< (point) limit)
- (end-of-line)
- (setq eol-mark (point-marker))
+ (save-excursion
+ (end-of-line)
+ ;; This move allows the use of newline as the last character in
+ ;; the substitution pattern
+ (viper-forward-char-carefully)
+ (setq eol-mark (point-marker)))
(beginning-of-line)
(if opt-g
(progn
@@ -1927,8 +1948,10 @@ Please contact your system administrator. "
(if (not (stringp repl))
(error "Can't perform Ex substitution: No previous replacement pattern"))
(replace-match repl t)))
- (end-of-line)
- (viper-forward-char-carefully))))))
+ ;;(end-of-line)
+ ;;(viper-forward-char-carefully)
+ (goto-char eol-mark)
+ )))))
(if matched-pos (goto-char matched-pos))
(beginning-of-line)
(if opt-c (message "done"))))
@@ -1994,68 +2017,59 @@ Please contact your system administrator. "
(setq file-exists (file-exists-p ex-file)
writing-same-file (string= ex-file (buffer-file-name)))
+ ;; do actual writing
(if (and writing-whole-file writing-same-file)
+ ;; saving whole buffer in visited file
(if (not (buffer-modified-p))
(message "(No changes need to be saved)")
+ (viper-maybe-checkout (current-buffer))
(save-buffer)
(save-restriction
(widen)
(ex-write-info file-exists ex-file (point-min) (point-max))
))
- ;; writing some other file or portion of the current file
- (cond ((and file-exists
- (not writing-same-file)
- (not (yes-or-no-p
- (format "File %s exists. Overwrite? " ex-file))))
- (error "Quit"))
- ((and writing-whole-file (not ex-append))
- (unwind-protect
- (progn
- (set-visited-file-name ex-file)
- (set-buffer-modified-p t)
- (save-buffer))
- ;; restore the buffer file name
- (set-visited-file-name orig-buf-file-name)
- (set-buffer-modified-p buff-changed-p)
- ;; If the buffer wasn't visiting a file, restore buffer name.
- ;; Name could've been changed by packages such as uniquify.
- (or orig-buf-file-name
- (progn
- (unlock-buffer)
- (rename-buffer orig-buf-name))))
- (save-restriction
- (widen)
- (ex-write-info
- file-exists ex-file (point-min) (point-max))))
- (t ; writing a region
- (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)
- (set-visited-file-name ex-file 'noquerry)
- (erase-buffer)
- (if (and file-exists ex-append)
- (insert-file-contents ex-file))
- (goto-char (point-max))
- (insert region)
- (save-buffer)
- (ex-write-info
- file-exists ex-file (point-min) (point-max))
- ))
- (set-buffer temp-buf)
- (set-buffer-modified-p nil)
- (kill-buffer temp-buf))
- ))
- (set-buffer orig-buf)
- ;; this prevents the loss of data if writing part of the buffer
+ ;; writing to non-visited file and it already exists
+ (if (and file-exists (not writing-same-file)
+ (not (yes-or-no-p
+ (format "File %s exists. Overwrite? " ex-file))))
+ (error "Quit"))
+ ;; writing a region or whole buffer to non-visited file
+ (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)
+ (set-visited-file-name ex-file 'noquerry)
+ (erase-buffer)
+ (if (and file-exists ex-append)
+ (insert-file-contents ex-file))
+ (goto-char (point-max))
+ (insert region)
+ ;; ask user
+ (viper-maybe-checkout (current-buffer))
+ (save-buffer)
+ (ex-write-info
+ file-exists ex-file (point-min) (point-max))
+ )
+ ;; this must be under unwind-protect so that
+ ;; temp-buf will be deleted in case of an error
+ (set-buffer temp-buf)
+ (set-buffer-modified-p nil)
+ (kill-buffer temp-buf)
+ ;; buffer/region has been written, now take care of details
+ (set-buffer orig-buf)))
+ ;; set the right file modification time
(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
(not writing-same-file)
- (set-buffer-modified-p t))
+ (progn
+ (sit-for 2)
+ (message "Warning: you have saved only part of the buffer!")
+ (set-buffer-modified-p t)))
(if q-flag
(if (< viper-expert-level 2)
(save-buffers-kill-emacs)