X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9b70a748edea012ecad578c42495ffa01e9eb80b..1e70790f2f4826c646d5640a9f6162aa78ea682b:/lisp/emulation/viper-ex.el diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el index 8e35403e57..4b29dc1465 100644 --- a/lisp/emulation/viper-ex.el +++ b/lisp/emulation/viper-ex.el @@ -31,23 +31,33 @@ (defvar vip-ex-history) (defvar vip-related-files-and-buffers-ring) (defvar vip-local-search-start-marker) -(defvar vip-expert-level) +(defvar viper-expert-level) (defvar vip-custom-file-name) (defvar vip-case-fold-search) - -(eval-when-compile - (let ((load-path (cons (expand-file-name ".") load-path))) - (or (featurep 'viper-util) - (load "viper-util.el" nil nil 'nosuffix)) - (or (featurep 'viper-keym) - (load "viper-keym.el" nil nil 'nosuffix)) - (or (featurep 'viper) - (load "viper.el" nil nil 'nosuffix)) - )) +(defvar explicit-shell-file-name) + +;; loading happens only in non-interactive compilation +;; in order to spare non-viperized emacs from being viperized +(if noninteractive + (eval-when-compile + (let ((load-path (cons (expand-file-name ".") load-path))) + (or (featurep 'viper-util) + (load "viper-util.el" nil nil 'nosuffix)) + (or (featurep 'viper-keym) + (load "viper-keym.el" nil nil 'nosuffix)) + (or (featurep 'viper-cmd) + (load "viper-cmd.el" nil nil 'nosuffix)) + ))) ;; end pacifier (require 'viper-util) +(defgroup viper-ex nil + "Viper support for Ex commands" + :prefix "ex-" + :group 'viper) + + ;;; Variables @@ -73,15 +83,16 @@ ;; A-list of Ex variables that can be set using the :set command. (defconst ex-variable-alist '(("wrapscan") ("ws") ("wrapmargin") ("wm") - ("global-tabstop") ("gts") ("tabstop") ("ts") + ("tabstop-global") ("ts-g") ("tabstop") ("ts") ("showmatch") ("sm") ("shiftwidth") ("sw") ("shell") ("sh") ("readonly") ("ro") ("nowrapscan") ("nows") ("noshowmatch") ("nosm") ("noreadonly") ("noro") ("nomagic") ("noma") ("noignorecase") ("noic") - ("global-noautoindent") ("gnoai") ("noautoindent") ("noai") + ("noautoindent-global") ("noai-g") ("noautoindent") ("noai") ("magic") ("ma") ("ignorecase") ("ic") - ("global-autoindent") ("gai") ("autoindent") ("ai") + ("autoindent-global") ("ai-g") ("autoindent") ("ai") + ("all") )) @@ -107,10 +118,9 @@ ;; Value of ex count. (defvar ex-count nil) -;; Flag for global command. +;; Flag indicating that :global Ex command is being executed. (defvar ex-g-flag nil) - -;; If t, global command is executed on lines not matching ex-g-pat. +;; Flag indicating that :vglobal Ex command is being executed. (defvar ex-g-variant nil) ;; Save reg-exp used in substitute. @@ -123,8 +133,7 @@ ;; Pattern for global command. (defvar ex-g-pat nil) - -(defvar ex-unix-type-shell +(defcustom ex-unix-type-shell (let ((case-fold-search t)) (and (stringp shell-file-name) (string-match @@ -141,9 +150,11 @@ "bash$\\|bash.exe$" "\\)") shell-file-name))) - "Is the user using a unix-type shell?") + "Is the user using a unix-type shell under a non-OS?" + :type 'string + :group 'viper-ex) -(defvar ex-unix-type-shell-options +(defcustom ex-unix-type-shell-options (let ((case-fold-search t)) (if ex-unix-type-shell (cond ((string-match "\\(csh$\\|csh.exe$\\)" shell-file-name) @@ -152,7 +163,9 @@ "-noprofile") ; bash: ignore .profile ))) "Options to pass to the Unix-style shell. -Don't put `-c' here, as it is added automatically.") +Don't put `-c' here, as it is added automatically." + :type 'string + :group 'viper-ex) (defvar ex-nontrivial-find-file-function (cond (ex-unix-type-shell 'vip-ex-nontrivial-find-file-unix) @@ -185,13 +198,17 @@ Don't put `-c' here, as it is added automatically.") ;; multiple file names. Used for :edit and :next (defvar vip-keep-reading-filename nil) -(defconst ex-cycle-other-window t +(defcustom ex-cycle-other-window t "*If t, :n and :b cycles through files and buffers in other window. Then :N and :B cycles in the current window. If nil, this behavior is -reversed.") +reversed." + :type 'boolean + :group 'viper-ex) -(defconst ex-cycle-through-non-files nil - "*Cycle through *scratch* and other buffers that don't visit any file.") +(defcustom ex-cycle-through-non-files nil + "*Cycle through *scratch* and other buffers that don't visit any file." + :type 'boolean + :group 'viper-ex) ;; Last shell command executed with :! command. (defvar vip-ex-last-shell-com nil) @@ -422,7 +439,7 @@ reversed.") "*[ \t]*$")) (stay-regex (concat "\\(" "^[ \t]*$" - "\\|" "[?/].*[?/].*" + "\\|" "[?/].*" "\\|" "[ktgjmsz][ \t]*$" "\\|" "^[ \t]*ab.*" "\\|" "tr[ansfer \t]*" @@ -498,7 +515,6 @@ reversed.") ;; Read Ex commands -;; Ex commands themselves are implemented in viper-ex.el (defun vip-ex (&optional string) (interactive) (or string @@ -608,7 +624,15 @@ reversed.") (setq ex-token (if (= (mark t) (point)) "" (buffer-substring (1- (point)) (mark t)))) - (backward-char 1)) + (backward-char 1) + ;; if the user doesn't specify the final pattern delimiter, we're + ;; at newline now. In this case, insert the initial delimiter + ;; specified in variable c + (if (looking-at "\n") + (progn + (insert c) + (backward-char 1))) + ) (setq ex-token nil)) c))) @@ -1228,6 +1252,14 @@ reversed.") ;; Ex global command +;; This is executed in response to: +;; :global "pattern" ex-command +;; :vglobal "pattern" ex-command +;; :global executes ex-command on all lines matching +;; :vglobal executes ex-command on all lines that don't match +;; +;; With VARIANT nil, this functions executes :global +;; With VARIANT t, executes :vglobal (defun ex-global (variant) (let ((gcommand ex-token)) (if (or ex-g-flag ex-g-variant) @@ -1250,8 +1282,11 @@ reversed.") (if (null ex-addresses) (setq ex-addresses (list (point-max) (point-min))) (vip-default-ex-addresses)) - (let ((marks nil) (mark-count 0) - com-str (end (car ex-addresses)) (beg (car (cdr ex-addresses)))) + (let ((marks nil) + (mark-count 0) + (end (car ex-addresses)) + (beg (car (cdr ex-addresses))) + com-str) (if (> beg end) (error vip-FirstAddrExceedsSecond)) (save-excursion (vip-enlarge-region beg end) @@ -1487,7 +1522,7 @@ reversed.") (setq vip-ex-work-buf (get-buffer-create vip-ex-work-buf-name)) (set-buffer vip-ex-work-buf) (if (looking-at "!") (forward-char 1))) - (if (< vip-expert-level 3) + (if (< viper-expert-level 3) (save-buffers-kill-emacs) (kill-buffer (current-buffer)))) @@ -1561,7 +1596,7 @@ reversed.") (while (string-match "^[ \\t\\n]*$" (setq str (completing-read ":set " ex-variable-alist))) - (message ":set ") + (message ":set [= ]") ;; if there are unread events, don't wait (or (vip-set-unread-command-events "") (sit-for 2)) ) ; while @@ -1579,12 +1614,15 @@ reversed.") actual-lisp-cmd lisp-cmd-del-pattern val2 orig-var) (setq orig-var var) - (cond ((member var '("ai" "autoindent")) + (cond ((string= var "all") + (setq ask-if-save nil + set-cmd nil)) + ((member var '("ai" "autoindent")) (setq var "vip-auto-indent" set-cmd "setq" ask-if-save nil val "t")) - ((member var '("gai" "global-autoindent")) + ((member var '("ai-g" "autoindent-global")) (kill-local-variable 'vip-auto-indent) (setq var "vip-auto-indent" set-cmd "setq-default" @@ -1593,7 +1631,7 @@ reversed.") (setq var "vip-auto-indent" ask-if-save nil val "nil")) - ((member var '("gnoai" "global-noautoindent")) + ((member var '("noai-g" "noautoindent-global")) (kill-local-variable 'vip-auto-indent) (setq var "vip-auto-indent" set-cmd "setq-default" @@ -1607,7 +1645,7 @@ reversed.") ((member var '("ma" "magic")) (setq var "vip-re-search" val "t")) - ((member var '("noma" "nomagic")) + ((member var '("noma" "nomagic")) (setq var "vip-re-search" val "nil")) ((member var '("ro" "readonly")) @@ -1628,7 +1666,7 @@ reversed.") ((member var '("nows" "nowrapscan")) (setq var "vip-search-wrap-around-t" val "nil"))) - (if (eq val 0) ; value must be set by the user + (if (and set-cmd (eq val 0)) ; value must be set by the user (let ((cursor-in-echo-area t)) (message ":set %s = " var) ;; if there are unread events, don't wait @@ -1640,7 +1678,7 @@ reversed.") (if (member var '("sw" "shiftwidth" "ts" "tabstop" - "gts" "global-tabstop" + "ts-g" "tabstop-global" "wm" "wrapmargin")) (condition-case nil (or (numberp (setq val2 (car (read-from-string val)))) @@ -1656,7 +1694,7 @@ reversed.") (setq var "tab-width" set-cmd "setq" ask-if-save nil)) - ((member var '("gts" "global-tabstop")) + ((member var '("ts-g" "tabstop-global")) (kill-local-variable 'tab-width) (setq var "tab-width" set-cmd "setq-default")) @@ -1671,11 +1709,12 @@ reversed.") val (format "\"%s\"" val))))) (ex-fixup-history "set" orig-var)) - (setq actual-lisp-cmd (format "\n(%s %s %s) %s" - set-cmd var val auto-cmd-label)) - (setq lisp-cmd-del-pattern - (format "^\n?[ \t]*([ \t]*%s[ \t]+%s[ \t].*)[ \t]*%s" - set-cmd var auto-cmd-label)) + (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 " @@ -1702,15 +1741,19 @@ reversed.") )) )) - (message "%s %s %s" set-cmd var (if (string-match "^[ \t]*$" val) - (format "%S" val) - val)) - (eval (car (read-from-string actual-lisp-cmd))) - (if (string= var "fill-column") - (if (> val2 0) - (auto-fill-mode 1) - (auto-fill-mode -1))) - + (if set-cmd + (message "%s %s %s" + set-cmd var + (if (string-match "^[ \t]*$" val) + (format "%S" val) + val))) + (if actual-lisp-cmd + (eval (car (read-from-string actual-lisp-cmd)))) + (if (string= var "fill-column") + (if (> val2 0) + (auto-fill-mode 1) + (auto-fill-mode -1))) + (if (string= var "all") (ex-show-vars)) )) ;; In inline args, skip regex-forw and (optionally) chars-back. @@ -1971,7 +2014,7 @@ Please contact your system administrator. " (not writing-same-file) (set-buffer-modified-p t)) (if q-flag - (if (< vip-expert-level 2) + (if (< viper-expert-level 2) (save-buffers-kill-emacs) (kill-buffer (current-buffer)))) ))) @@ -2074,5 +2117,32 @@ Please contact your system administrator. " (kill-buffer " *vip-info*"))) )) +;; display all variables set through :set +(defun ex-show-vars () + (with-output-to-temp-buffer " *vip-info*" + (princ (if vip-auto-indent + "autoindent (local)\n" "noautoindent (local)\n")) + (princ (if (default-value 'vip-auto-indent) + "autoindent (global) \n" "noautoindent (global) \n")) + (princ (if vip-case-fold-search "ignorecase\n" "noignorecase\n")) + (princ (if vip-re-search "magic\n" "nomagic\n")) + (princ (if buffer-read-only "readonly\n" "noreadonly\n")) + (princ (if blink-matching-paren "showmatch\n" "noshowmatch\n")) + (princ (if vip-search-wrap-around-t "wrapscan\n" "nowrapscan\n")) + (princ (format "shiftwidth \t\t= %S\n" vip-shift-width)) + (princ (format "tabstop (local) \t= %S\n" tab-width)) + (princ (format "tabstop (global) \t= %S\n" (default-value 'tab-width))) + (princ (format "wrapmargin (local) \t= %S\n" + (- (window-width) fill-column))) + (princ (format "wrapmargin (global) \t= %S\n" + (- (window-width) (default-value 'fill-column)))) + (princ (format "shell \t\t\t= %S\n" (if (boundp 'explicit-shell-file-name) + explicit-shell-file-name + 'none))) + )) + + + + ;;; viper-ex.el ends here