Mercurial > emacs
changeset 32480:261dcd5e9f0a
(sh-imenu-generic-expression): Fix.
(sh-mode-syntax-table): Add punctuation syntax for < and >.
(sh-mode): Don't make all vars local here.
(sh-kw): Reformat.
(sh-set-shell): Use dolist. Don't set indent-region-function.
(sh-mode-syntax-table): Use pop.
(sh-remember-variable): Use push.
(sh-help-string-for-variable): Use memq.
(sh-safe-backward-sexp): Remove.
(sh-safe-forward-sexp): Add ARG.
(sh-get-indent-info, sh-prev-stmt): Use it.
(sh-prev-line): Simplify by using forward-comment.
(sh-this-is-a-continuation): Simplify.
(sh-learn-buffer-indent): Use dolist.
(sh-do-nothing): Remove.
(sh-set-char-syntax, sh-set-here-doc-region):
Use inhibit-modification-hooks.
(sh-name-style): Use mapcar and push.
(sh-load-style): Use dolist.
(sh-save-styles-to-buffer): Use with-current-buffer and pp.
(sh-case, sh-while-getopts): Use propertize directly rather
than sh-electric-rparen.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sun, 15 Oct 2000 04:38:24 +0000 |
parents | 783ed0889617 |
children | 4372fcfffc7f |
files | lisp/progmodes/sh-script.el |
diffstat | 1 files changed, 329 insertions(+), 558 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/progmodes/sh-script.el Sun Oct 15 03:48:17 2000 +0000 +++ b/lisp/progmodes/sh-script.el Sun Oct 15 04:38:24 2000 +0000 @@ -113,7 +113,7 @@ ;; would make this unnecessary; simply learn the values when you visit ;; the buffer. ;; You can do this automatically like this: -; (add-hook 'sh-set-shell-hook 'sh-learn-buffer-indent) +;; (add-hook 'sh-set-shell-hook 'sh-learn-buffer-indent) ;; ;; However... `sh-learn-buffer-indent' is extremely slow, ;; especially on large-ish buffer. Also, if there are conflicts the @@ -332,12 +332,8 @@ :group 'sh-script) (defcustom sh-imenu-generic-expression - (list - (cons 'sh - (concat - "\\(^\\s-*function\\s-+[A-Za-z_][A-Za-z_0-9]*\\)" - "\\|" - "\\(^\\s-*[A-Za-z_][A-Za-z_0-9]*\\s-*()\\)"))) + `((sh + . ((nil "^\\s-*\\(function\\s-+\\)?\\([A-Za-z_][A-Za-z_0-9]+\\)\\s-*()" 2)))) "*Regular expression for recognizing shell function definitions. See `sh-feature'." :type '(repeat (cons (symbol :tag "Shell") @@ -417,7 +413,9 @@ ?: "_" ?. "_" ?^ "_" - ?~ "_") + ?~ "_" + ?< "." + ?> ".") (csh eval identity sh) (rc eval identity sh)) "Syntax-table used in Shell-Script mode. See `sh-feature'.") @@ -479,10 +477,8 @@ (define-key menu-map [sh-tmp-file] '("Temporary File" . sh-tmp-file)) (define-key menu-map [sh-select] '("Select Statement" . sh-select)) (define-key menu-map [sh-repeat] '("Repeat Loop" . sh-repeat)) - (define-key menu-map [sh-while-getopts] - '("Options Loop" . sh-while-getopts)) - (define-key menu-map [sh-indexed-loop] - '("Indexed Loop" . sh-indexed-loop)) + (define-key menu-map [sh-getopts] '("Options Loop" . sh-while-getopts)) + (define-key menu-map [sh-indexed-loop] '("Indexed Loop" . sh-indexed-loop)) (define-key menu-map [sh-if] '("If Statement" . sh-if)) (define-key menu-map [sh-for] '("For Loop" . sh-for)) (define-key menu-map [sh-case] '("Case Statement" . sh-case)) @@ -601,7 +597,7 @@ "bg" "fg" "jobs" "kill" "stop" "suspend") (jcsh eval sh-append csh - "bg" "fg" "jobs" "kill" "notify" "stop" "suspend") + "bg" "fg" "jobs" "kill" "notify" "stop" "suspend") (ksh88 eval sh-append bourne "alias" "bg" "false" "fc" "fg" "jobs" "kill" "let" "print" "time" @@ -731,7 +727,7 @@ "pid" "prompt" "signals") (jcsh eval sh-append csh - "notify") + "notify") (ksh88 eval sh-append sh "ENV" "ERRNO" "FCEDIT" "FPATH" "HISTFILE" "HISTSIZE" "LINENO" @@ -839,12 +835,12 @@ (defcustom sh-set-shell-hook nil "*Hook run by `sh-set-shell'." - :type 'hook + :type 'hook :group 'sh-script) (defcustom sh-mode-hook nil "*Hook run by `sh-mode'." - :type 'hook + :type 'hook :group 'sh-script) (defcustom sh-learn-basic-offset nil @@ -903,7 +899,7 @@ (const :tag "Leave as is." nil) (const :tag "Indent as a normal line." t) (integer :menu-tag "Indent to this col (0 means first col)." - :tag "Indent to column number.") ) + :tag "Indent to column number.") ) :group 'sh-indentation) @@ -943,9 +939,9 @@ :group 'sh-indentation) (defconst sh-number-or-symbol-list - (append (list '(integer :menu-tag "A number (positive=>indent right)" - :tag "A number") - '(const :tag "--")) ; separator + (append '((integer :menu-tag "A number (positive=>indent right)" + :tag "A number") + (const :tag "--")) ; separator sh-symbol-list)) (defcustom sh-indent-for-fi 0 @@ -983,7 +979,7 @@ :group 'sh-indentation) (defcustom sh-indent-after-do '* -"*How much to indent a line after a do statement. + "*How much to indent a line after a do statement. This is used when the do is the first word of the line. This is relative to the statement before the do, e.g. a while for repeat or select statement." @@ -1217,8 +1213,6 @@ (interactive) (kill-all-local-variables) (use-local-map sh-mode-map) - (make-local-variable 'indent-line-function) - (make-local-variable 'indent-region-function) (make-local-variable 'skeleton-end-hook) (make-local-variable 'paragraph-start) (make-local-variable 'paragraph-separate) @@ -1238,7 +1232,6 @@ (make-local-variable 'sh-shell-variables) (make-local-variable 'sh-shell-variables-initialized) (make-local-variable 'imenu-generic-expression) - (make-local-variable 'sh-electric-rparen-needed-here) (make-local-variable 'sh-indent-supported-here) (make-local-variable 'font-lock-unfontify-region-function) (setq major-mode 'sh-mode @@ -1266,7 +1259,7 @@ nil nil ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil (font-lock-syntactic-keywords . sh-font-lock-syntactic-keywords)) - font-lock-unfontify-region-function + font-lock-unfontify-region-function 'sh-font-lock-unfontify-region-function skeleton-pair-alist '((?` _ ?`)) skeleton-pair-filter 'sh-quoted-p @@ -1274,10 +1267,8 @@ (current-column))))) skeleton-filter 'sh-feature skeleton-newline-indent-rigidly t - sh-electric-rparen-needed-here nil sh-indent-supported-here nil) - (make-local-variable 'parse-sexp-ignore-comments) - (setq parse-sexp-ignore-comments t) + (set (make-local-variable 'parse-sexp-ignore-comments) t) ;; Parse or insert magic number for exec, and set all variables depending ;; on the shell thus determined. (let ((interpreter @@ -1363,77 +1354,32 @@ ;; for both. ;; (defconst sh-kw - '( - (sh - ( "if" - nil - sh-handle-prev-if ) - ( "elif" - sh-handle-this-else - sh-handle-prev-else ) - ( "else" - sh-handle-this-else - sh-handle-prev-else ) - ( "fi" - sh-handle-this-fi - sh-handle-prev-fi ) - ( "then" - sh-handle-this-then - sh-handle-prev-then ) - ( "(" - nil - sh-handle-prev-open ) - ( "{" - nil - sh-handle-prev-open ) - ( "[" - nil - sh-handle-prev-open ) - ( "}" - sh-handle-this-close - nil ) - ( ")" - sh-handle-this-close - nil ) - ( "]" - sh-handle-this-close - nil ) - ( "case" - nil - sh-handle-prev-case ) - ( "esac" - sh-handle-this-esac - sh-handle-prev-esac ) - ( case-label - nil ;; ??? - sh-handle-after-case-label ) - ( ";;" - nil ;; ??? - sh-handle-prev-case-alt-end ;; ?? - ) - ( "done" - sh-handle-this-done - sh-handle-prev-done ) - ( "do" - sh-handle-this-do - sh-handle-prev-do ) - ) ;; end of sh + '((sh + ("if" nil sh-handle-prev-if) + ("elif" sh-handle-this-else sh-handle-prev-else) + ("else" sh-handle-this-else sh-handle-prev-else) + ("fi" sh-handle-this-fi sh-handle-prev-fi) + ("then" sh-handle-this-then sh-handle-prev-then) + ("(" nil sh-handle-prev-open) + ("{" nil sh-handle-prev-open) + ("[" nil sh-handle-prev-open) + ("}" sh-handle-this-close nil) + (")" sh-handle-this-close nil) + ("]" sh-handle-this-close nil) + ("case" nil sh-handle-prev-case) + ("esac" sh-handle-this-esac sh-handle-prev-esac) + (case-label nil sh-handle-after-case-label) ;; ??? + (";;" nil sh-handle-prev-case-alt-end) ;; ??? + ("done" sh-handle-this-done sh-handle-prev-done) + ("do" sh-handle-this-do sh-handle-prev-do)) ;; Note: we don't need specific stuff for bash and zsh shells; ;; the regexp `sh-regexp-for-done' handles the extra keywords ;; these shells use. (rc - ( "{" - nil - sh-handle-prev-open ) - ( "}" - sh-handle-this-close - nil ) - ( "case" - sh-handle-this-rc-case - sh-handle-prev-rc-case ) - ) ;; end of rc - )) + ("{" nil sh-handle-prev-open) + ("}" sh-handle-this-close nil) + ("case" sh-handle-this-rc-case sh-handle-prev-rc-case)))) (defun sh-set-shell (shell &optional no-query-flag insert-flag) @@ -1457,9 +1403,6 @@ no-query-flag insert-flag))) (setq require-final-newline (sh-feature sh-require-final-newline) ;;; local-abbrev-table (sh-feature sh-abbrevs) -;; Packages should not need to set these variables directly. sm. -; font-lock-keywords nil ; force resetting -; font-lock-syntax-table nil comment-start-skip "#+[\t ]*" mode-line-process (format "[%s]" sh-shell) sh-shell-variables nil @@ -1468,37 +1411,25 @@ imenu-case-fold-search nil) (set-syntax-table (or (sh-feature sh-mode-syntax-table) (standard-syntax-table))) - (let ((vars (sh-feature sh-variables))) - (while vars - (sh-remember-variable (car vars)) - (setq vars (cdr vars)))) -;; Packages should not need to toggle Font Lock mode. sm. -; (and (boundp 'font-lock-mode) -; font-lock-mode -; (font-lock-mode (font-lock-mode 0))) + (dolist (var (sh-feature sh-variables)) + (sh-remember-variable var)) + (make-local-variable 'indent-line-function) (if (setq sh-indent-supported-here (sh-feature sh-indent-supported)) (progn (message "Setting up indent for shell type %s" sh-shell) - (make-local-variable 'sh-kw-alist) - (make-local-variable 'sh-regexp-for-done) - (make-local-variable 'parse-sexp-lookup-properties) - (setq sh-electric-rparen-needed-here - (sh-feature sh-electric-rparen-needed)) - (setq parse-sexp-lookup-properties t) + (set (make-local-variable 'sh-electric-rparen-needed-here) + (sh-feature sh-electric-rparen-needed)) + (set (make-local-variable 'parse-sexp-lookup-properties) t) (sh-scan-buffer) - (setq sh-kw-alist (sh-feature sh-kw)) + (set (make-local-variable 'sh-kw-alist) (sh-feature sh-kw)) (let ((regexp (sh-feature sh-kws-for-done))) (if regexp - (setq sh-regexp-for-done - (sh-mkword-regexpr (regexp-opt regexp t))))) + (set (make-local-variable 'sh-regexp-for-done) + (sh-mkword-regexpr (regexp-opt regexp t))))) (message "setting up indent stuff") ;; sh-mode has already made indent-line-function local ;; but do it in case this is called before that. - (make-local-variable 'indent-line-function) (setq indent-line-function 'sh-indent-line) - ;; This is very inefficient, but this at least makes indent-region work: - (make-local-variable 'indent-region-function) - (setq indent-region-function nil) (if sh-make-vars-local (sh-make-vars-local)) (message "Indentation setup for shell type %s" sh-shell)) @@ -1601,8 +1532,7 @@ "Copy TABLE and set syntax for successive CHARs according to strings S." (setq table (copy-syntax-table table)) (while list - (modify-syntax-entry (car list) (car (cdr list)) table) - (setq list (cdr (cdr list)))) + (modify-syntax-entry (pop list) (pop list) table)) table) @@ -1684,7 +1614,7 @@ (or (< (length var) sh-remember-variable-min) (getenv var) (assoc var sh-shell-variables) - (setq sh-shell-variables (cons (cons var var) sh-shell-variables))) + (push (cons var var) sh-shell-variables)) var) @@ -1736,9 +1666,7 @@ "Construct a string for `sh-read-variable' when changing variable VAR ." (let ((msg (documentation-property var 'variable-documentation)) (msg2 "")) - (unless (or - (eq var 'sh-first-lines-indent) - (eq var 'sh-indent-comment)) + (unless (memq var '(sh-first-lines-indent sh-indent-comment)) (setq msg2 (format "\n You can enter a number (positive to increase indentation, @@ -1751,10 +1679,8 @@ \t%s." sh-basic-offset (mapconcat (lambda (x) - (nth (1- (length x)) x) ) - sh-symbol-list "\n\t") - ))) - + (nth (1- (length x)) x)) + sh-symbol-list "\n\t")))) (concat ;; The following shows the global not the local value! ;; (format "Current value of %s is %s\n\n" var (symbol-value var)) @@ -1767,10 +1693,10 @@ (quote ,var))) val) (setq val (read-from-minibuffer - (format "New value for %s (press %s for help): " - var (single-key-description help-char)) - (format "%s" (symbol-value var)) - nil t)) + (format "New value for %s (press %s for help): " + var (single-key-description help-char)) + (format "%s" (symbol-value var)) + nil t)) val)) @@ -1853,79 +1779,46 @@ (defun sh-handle-this-close () (forward-char 1) ;; move over ")" - (let ((p (sh-safe-backward-sexp))) - (if p - (list "aligned to opening paren") - nil - ))) + (if (sh-safe-forward-sexp -1) + (list "aligned to opening paren"))) (defun sh-goto-matching-case () (let ((found (sh-find-prev-matching "\\bcase\\b" "\\besac\\b" 1))) - (if found - (goto-char found)))) + (if found (goto-char found)))) (defun sh-handle-prev-case () ;; This is typically called when point is on same line as a case ;; we shouldn't -- and can't find prev-case - (if (looking-at ".*\\bcase\\b") + (if (looking-at ".*\\<case\\>") (list '(+ sh-indent-for-case-label)) - (error "We don't seem to be on a line with a case") ;; debug - )) + (error "We don't seem to be on a line with a case"))) ;; debug (defun sh-handle-this-esac () - (let ((p (sh-goto-matching-case))) - (if p - (list "aligned to matching case") - nil - ))) - + (if (sh-goto-matching-case) + (list "aligned to matching case"))) (defun sh-handle-prev-esac () - (let ((p (sh-goto-matching-case))) - (if p - (list "matching case") - nil - ))) + (if (sh-goto-matching-case) + (list "matching case"))) (defun sh-handle-after-case-label () - (let ((p (sh-goto-matching-case))) - (if p - (list '( + sh-indent-for-case-alt )) - nil - ))) + (if (sh-goto-matching-case) + (list '(+ sh-indent-for-case-alt)))) (defun sh-handle-prev-case-alt-end () - (let ((p (sh-goto-matching-case))) - (if p - (list '( + sh-indent-for-case-label )) - nil - ))) - -(defun sh-safe-backward-sexp () - "Try and do a `backward-sexp', but do not error. -Return new point if successful, nil if an error occurred." - (condition-case nil - (progn - (backward-sexp 1) - (point) ;; return point if successful - ) - (error - (sh-debug "oops!(0) %d" (point)) - nil ;; return nil if fail - ))) - -(defun sh-safe-forward-sexp () + (if (sh-goto-matching-case) + (list '(+ sh-indent-for-case-label)))) + +(defun sh-safe-forward-sexp (&optional arg) "Try and do a `forward-sexp', but do not error. Return new point if successful, nil if an error occurred." (condition-case nil (progn - (forward-sexp 1) - (point) ;; return point if successful - ) + (forward-sexp (or arg 1)) + (point)) ;; return point if successful (error (sh-debug "oops!(1) %d" (point)) - nil ;; return nil if fail - ))) + nil))) ;; return nil if fail (defun sh-goto-match-for-done () (let ((found (sh-find-prev-matching sh-regexp-for-done sh-re-done 1))) @@ -1934,41 +1827,33 @@ (defun sh-handle-this-done () (if (sh-goto-match-for-done) - (list "aligned to do stmt" '(+ sh-indent-for-done)) - nil - )) + (list "aligned to do stmt" '(+ sh-indent-for-done)))) (defun sh-handle-prev-done () (if (sh-goto-match-for-done) - (list "previous done") - nil - )) + (list "previous done"))) (defun sh-handle-this-do () - (let ( (p (sh-goto-match-for-done)) ) - (if p - (list '(+ sh-indent-for-do)) - nil - ))) + (if (sh-goto-match-for-done) + (list '(+ sh-indent-for-do)))) (defun sh-handle-prev-do () - (let ( (p) ) - (cond - ((save-restriction - (narrow-to-region - (point) - (save-excursion - (beginning-of-line) - (point))) - (sh-goto-match-for-done)) - (sh-debug "match for done found on THIS line") - (list '(+ sh-indent-after-loop-construct))) - ((sh-goto-match-for-done) - (sh-debug "match for done found on PREV line") - (list '(+ sh-indent-after-do))) - (t - (message "match for done NOT found") - nil)))) + (cond + ((save-restriction + (narrow-to-region + (point) + (save-excursion + (beginning-of-line) + (point))) + (sh-goto-match-for-done)) + (sh-debug "match for done found on THIS line") + (list '(+ sh-indent-after-loop-construct))) + ((sh-goto-match-for-done) + (sh-debug "match for done found on PREV line") + (list '(+ sh-indent-after-do))) + (t + (message "match for done NOT found") + nil))) ;; for rc: (defun sh-find-prev-switch () @@ -1978,7 +1863,7 @@ (defun sh-handle-this-rc-case () (if (sh-find-prev-switch) (list '(+ sh-indent-after-switch)) - ;; (list '(+ sh-indent-for-case-label)) + ;; (list '(+ sh-indent-for-case-label)) nil)) (defun sh-handle-prev-rc-case () @@ -2033,21 +1918,21 @@ prev-line-end x) (beginning-of-line) ;; Note: setting result to t means we are done and will return nil. - ;;( This function never returns just t.) + ;;(This function never returns just t.) (cond ((equal (get-text-property (point) 'syntax-table) sh-here-doc-syntax) (setq result t) (setq have-result t)) ((looking-at "\\s-*#") ; was (equal this-kw "#") (if (bobp) - (setq result t);; return nil if 1st line! + (setq result t) ;; return nil if 1st line! (setq result (list '(= sh-indent-comment))) ;; we still need to get previous line in case ;; sh-indent-comment is t (indent as normal) (setq align-point (sh-prev-line nil)) (setq have-result nil) )) - );; cond + ) ;; cond (unless have-result ;; Continuation lines are handled specially @@ -2086,7 +1971,7 @@ ;; We start off at beginning of this line. ;; Scan previous statements while this is <= ;; start of previous line. - (setq start (point));; for debug only + (setq start (point)) ;; for debug only (goto-char prev-line-end) (setq x t) (while (and x (setq x (sh-prev-thing))) @@ -2105,7 +1990,7 @@ (skip-chars-forward "[a-z0-9]*?") ) ((string-match "[])}]" x) - (setq x (sh-safe-backward-sexp)) + (setq x (sh-safe-forward-sexp -1)) (if x (progn (setq align-point (point)) @@ -2121,7 +2006,7 @@ ((string-match "[\"'`]" x) (sh-debug "Skipping back for %s" x) ;; this was oops-2 - (setq x (sh-safe-backward-sexp))) + (setq x (sh-safe-forward-sexp -1))) ((stringp x) (sh-debug "Checking string %s at %s" x (point)) (if (setq val (sh-check-rule 2 x)) @@ -2135,7 +2020,7 @@ (t (error "Don't know what to do with %s" x)) ) - );; while + ) ;; while (sh-debug "result is %s" result) ) (sh-debug "No prev line!") @@ -2158,7 +2043,7 @@ (setq result nil)) (sh-debug "result is: %s" result) result - );; let + ) ;; let )) @@ -2185,7 +2070,7 @@ (error "sh-get-indent-var-for-line invalid elt: %s" elt)) ;; so it is a list ((eq t (car elt)) - );; nothing + ) ;; nothing ((symbolp (setq sym (nth 1 elt))) ;; A bit of a kludge - when we see the sh-indent-comment ;; ignore other variables. Otherwise it is tricky to @@ -2219,75 +2104,34 @@ ;; because we may want to a align to the beginning of it. ;; ;; What we do: -;; - go back a line, if empty repeat -;; - (we are now at a previous non empty line) -;; - save this +;; - go back to previous non-empty line ;; - if this is in a here-document, go to the beginning of it -;; and save that -;; - go back one more physical line and see if it is a continuation line -;; - if yes, save it and repeat -;; - if no, go back to where we last saved. +;; - while previous line is continued, go back one line (defun sh-prev-line (&optional end) "Back to end of previous non-comment non-empty line. Go to beginning of logical line unless END is non-nil, in which case we go to the end of the previous line and do not check for continuations." (sh-must-be-shell-mode) - (let ((going t) - (last-contin-line nil) - (result nil) - bol eol state) - (save-excursion + (save-excursion + (beginning-of-line) + (forward-comment (- (point-max))) + (unless end (beginning-of-line)) + (when (and (not (bobp)) + (equal (get-text-property (1- (point)) 'syntax-table) + sh-here-doc-syntax)) + (let ((p1 (previous-single-property-change (1- (point)) 'syntax-table))) + (when p1 + (goto-char p1) + (forward-line -1) + (if end (end-of-line))))) + (unless end + ;; we must check previous lines to see if they are continuation lines + ;; if so, we must return position of first of them + (while (and (sh-this-is-a-continuation) + (>= 0 (forward-line -1)))) (beginning-of-line) - (while (and going - (not (bobp)) - (>= 0 (forward-line -1)) - ) - (setq bol (point)) - (end-of-line) - (setq eol (point)) - (save-restriction - (setq state (parse-partial-sexp bol eol nil nil nil t)) - (if (nth 4 state) - (setq eol (nth 8 state))) - (narrow-to-region bol eol) - (goto-char bol) - (cond - ((looking-at "\\s-*$")) - (t - (if end - (setq result eol) - (setq result bol)) - (setq going nil)) - ))) - (if (and result - (equal (get-text-property (1- result) 'syntax-table) - sh-here-doc-syntax)) - (let ((p1 (previous-single-property-change - (1- result) 'syntax-table))) - (if p1 - (progn - (goto-char p1) - (forward-line -1) - (if end - (end-of-line)) - (setq result (point))) - ))) - (unless end - ;; we must check previous lines to see if they are continuation lines - ;; if so, we must return position of first of them - (while (and (sh-this-is-a-continuation) - (>= 0 (forward-line -1))) - (setq result (point))) - (if result - (progn - (goto-char result) - (beginning-of-line) - (skip-chars-forward " \t") - (setq result (point)) - ))) - ) ;; save-excursion - result - )) + (skip-chars-forward " \t")) + (point))) (defun sh-prev-stmt () @@ -2307,7 +2151,7 @@ (not (bobp)) going) ;; Do a backward-sexp if possible, else backup bit by bit... - (if (sh-safe-backward-sexp) + (if (sh-safe-forward-sexp -1) (progn (if (looking-at sh-special-keywords) (progn @@ -2380,59 +2224,51 @@ (found nil)) (save-restriction (narrow-to-region - (if (sh-this-is-a-continuation) - (setq min-point (sh-prev-line nil)) - (save-excursion - (beginning-of-line) - (setq min-point (point)))) - (point)) + (if (sh-this-is-a-continuation) + (setq min-point (sh-prev-line nil)) + (save-excursion + (beginning-of-line) + (setq min-point (point)))) + (point)) (skip-chars-backward " \t;") (unless (looking-at "\\s-*;;") - (skip-chars-backward "^)}];\"'`({[") - (setq c (char-before)))) + (skip-chars-backward "^)}];\"'`({[") + (setq c (char-before)))) (sh-debug "stopping at %d c is %s start=%d min-point=%d" - (point) c start min-point) + (point) c start min-point) (if (< (point) min-point) (error "point %d < min-point %d" (point) min-point)) (cond ((looking-at "\\s-*;;") ;; (message "Found ;; !") - ";;") + ";;") ((or (eq c ?\n) (eq c nil) (eq c ?\;)) - (save-excursion - ;; skip forward over white space newline and \ at eol - (skip-chars-forward " \t\n\\\\") - (sh-debug "Now at %d start=%d" (point) start) - (if (>= (point) start) - (progn - (sh-debug "point: %d >= start: %d" (point) start) - nil) - (sh-get-word)) - )) + (save-excursion + ;; skip forward over white space newline and \ at eol + (skip-chars-forward " \t\n\\\\") + (sh-debug "Now at %d start=%d" (point) start) + (if (>= (point) start) + (progn + (sh-debug "point: %d >= start: %d" (point) start) + nil) + (sh-get-word)) + )) (t ;; c -- return a string - (char-to-string c) - )) + (char-to-string c) + )) ))) (defun sh-this-is-a-continuation () "Return non-nil if current line is a continuation of previous line." - (let ((result nil) - bol eol state) - (save-excursion - (if (and (zerop (forward-line -1)) - (looking-at ".*\\\\$")) - (progn - (setq bol (point)) - (end-of-line) - (setq eol (point)) - (setq state (parse-partial-sexp bol eol nil nil nil t)) - (unless (nth 4 state) - (setq result t)) - ))))) + (save-excursion + (and (zerop (forward-line -1)) + (looking-at ".*\\\\$") + (not (nth 4 (parse-partial-sexp (match-beginning 0) (match-end 0) + nil nil nil t)))))) (defun sh-get-kw (&optional where and-move) "Return first word of line from WHERE. @@ -2442,7 +2278,7 @@ (goto-char where)) (prog1 (buffer-substring (point) - (progn (skip-chars-forward "^ \t\n;")(point))) + (progn (skip-chars-forward "^ \t\n;")(point))) (unless and-move (goto-char start))) )) @@ -2476,7 +2312,7 @@ (sh-debug "found close - depth = %d" depth)) (t )))) - (error nil)) + (error nil)) (if (eq depth 0) prev ;; (point) nil) @@ -2510,10 +2346,10 @@ (/ (- sh-basic-offset) 2)) (t (if ignore-error - (progn - (message "Don't know how to handle %s's value of %s" var val) - 0) - (error "Don't know how to handle %s's value of %s" var val)) + (progn + (message "Don't know how to handle %s's value of %s" var val) + 0) + (error "Don't know how to handle %s's value of %s" var val)) )))) (defun sh-set-var-value (var value &optional no-symbol) @@ -2543,21 +2379,17 @@ (defun sh-calculate-indent (&optional info) "Return the indentation for the current line. If INFO is supplied it is used, else it is calculated from current line." - (let ( - (ofs 0) + (let ((ofs 0) (base-value 0) elt a b var val) (or info (setq info (sh-get-indent-info))) - (if (null info) - nil + (when info (while info (sh-debug "info: %s ofs=%s" info ofs) (setq elt (car info)) (cond - ((stringp elt) - ;; do nothing? - ) + ((stringp elt)) ;; do nothing? ((listp elt) (setq a (car (car info))) (setq b (nth 1 (car info))) @@ -2576,31 +2408,22 @@ ;; no indentation ;; set info to nil so we stop immediately (setq base-value nil ofs nil info nil)) - ((eq val t) - ;; indent as normal line - (setq ofs 0)) + ((eq val t) (setq ofs 0)) ;; indent as normal line (t ;; The following assume the (t POS) come first! (setq ofs val base-value 0) - (setq info nil) ;; ? stop now - )) - ) - ((eq a '+) - (setq ofs (+ ofs val))) - ((eq a '-) - (setq ofs (- ofs val))) + (setq info nil)))) ;; ? stop now + ((eq a '+) (setq ofs (+ ofs val))) + ((eq a '-) (setq ofs (- ofs val))) (t (error "sh-calculate-indent invalid a a=%s b=%s" a b)))) (t - (error "sh-calculate-indent invalid elt: a=%s b=%s" a b))) - ) + (error "sh-calculate-indent invalid elt: a=%s b=%s" a b)))) (t - (error "sh-calculate-indent invalid elt %s" elt)) - ) - (sh-debug "a=%s b=%s val=%s base-value=%s ofs=%s" - a b val base-value ofs) - (setq info (cdr info)) - ) + (error "sh-calculate-indent invalid elt %s" elt))) + (sh-debug "a=%s b=%s val=%s base-value=%s ofs=%s" + a b val base-value ofs) + (setq info (cdr info))) ;; return value: (sh-debug "at end: base-value: %s ofs: %s" base-value ofs) @@ -2609,13 +2432,12 @@ nil) ((and (numberp base-value)(numberp ofs)) (sh-debug "base (%d) + ofs (%d) = %d" - base-value ofs (+ base-value ofs)) + base-value ofs (+ base-value ofs)) (+ base-value ofs)) ;; return value (t (error "sh-calculate-indent: Help. base-value=%s ofs=%s" base-value ofs) - nil)) - ))) + nil))))) (defun sh-indent-line () @@ -2624,21 +2446,18 @@ (sh-must-be-shell-mode) (let ((indent (sh-calculate-indent)) shift-amt beg end (pos (- (point-max) (point)))) - (if indent - (progn - (beginning-of-line) - (setq beg (point)) - (skip-chars-forward " \t") - (setq shift-amt (- indent (current-column))) - (if (zerop shift-amt) - nil - (delete-region beg (point)) - (indent-to indent)) - ;; If initial point was within line's indentation, - ;; position after the indentation. Else stay at same point in text. - (if (> (- (point-max) pos) (point)) - (goto-char (- (point-max) pos))) - )))) + (when indent + (beginning-of-line) + (setq beg (point)) + (skip-chars-forward " \t") + (setq shift-amt (- indent (current-column))) + (unless (zerop shift-amt) + (delete-region beg (point)) + (indent-to indent)) + ;; If initial point was within line's indentation, + ;; position after the indentation. Else stay at same point in text. + (if (> (- (point-max) pos) (point)) + (goto-char (- (point-max) pos)))))) (defun sh-blink (blinkpos &optional msg) @@ -2649,8 +2468,7 @@ (goto-char blinkpos) (message msg) (sit-for blink-matching-delay)) - (message msg) - )) + (message msg))) (defun sh-show-indent (arg) "Show the how the currently line would be indented. @@ -2664,9 +2482,8 @@ (sh-must-support-indent) (let* ((info (sh-get-indent-info)) (var (sh-get-indent-var-for-line info)) - val msg - (curr-indent (current-indentation)) - ) + (curr-indent (current-indentation)) + val msg) (if (stringp var) (message (setq msg var)) (setq val (sh-calculate-indent info)) @@ -2750,44 +2567,43 @@ ival sval diff new-val (no-symbol arg) (curr-indent (current-indentation))) - (cond - ((stringp var) - (message (format "Cannot learn line - %s" var))) - ((eq var 'sh-indent-comment) - ;; This is arbitrary... - ;; - if curr-indent is 0, set to curr-indent - ;; - else if it has the indentation of a "normal" line, - ;; then set to t - ;; - else set to curr-indent. - (setq sh-indent-comment - (if (= curr-indent 0) - 0 - (let* ((sh-indent-comment t) - (val2 (sh-calculate-indent info))) - (if (= val2 curr-indent) - t - curr-indent)))) - (message "%s set to %s" var (symbol-value var)) - ) - ((numberp (setq sval (sh-var-value var))) - (setq ival (sh-calculate-indent info)) - (setq diff (- curr-indent ival)) + (cond + ((stringp var) + (message (format "Cannot learn line - %s" var))) + ((eq var 'sh-indent-comment) + ;; This is arbitrary... + ;; - if curr-indent is 0, set to curr-indent + ;; - else if it has the indentation of a "normal" line, + ;; then set to t + ;; - else set to curr-indent. + (setq sh-indent-comment + (if (= curr-indent 0) + 0 + (let* ((sh-indent-comment t) + (val2 (sh-calculate-indent info))) + (if (= val2 curr-indent) + t + curr-indent)))) + (message "%s set to %s" var (symbol-value var)) + ) + ((numberp (setq sval (sh-var-value var))) + (setq ival (sh-calculate-indent info)) + (setq diff (- curr-indent ival)) - (sh-debug "curr-indent: %d ival: %d diff: %d var:%s sval %s" - curr-indent ival diff var sval) - (setq new-val (+ sval diff)) + (sh-debug "curr-indent: %d ival: %d diff: %d var:%s sval %s" + curr-indent ival diff var sval) + (setq new-val (+ sval diff)) ;;; I commented out this because someone might want to replace ;;; a value of `+' with the current value of sh-basic-offset ;;; or vice-versa. ;;; (if (= 0 diff) ;;; (message "No change needed!") - (sh-set-var-value var new-val no-symbol) - (message "%s set to %s" var (symbol-value var)) - ) - (t - (debug) - (message "Cannot change %s" var)) - )))) + (sh-set-var-value var new-val no-symbol) + (message "%s set to %s" var (symbol-value var)) + ) + (t + (debug) + (message "Cannot change %s" var)))))) @@ -2811,12 +2627,11 @@ (let ((m1 (make-marker)) (main-buffer (current-buffer)) start - (line "") ) - (if point - (progn - (set-marker m1 point (current-buffer)) - (if add-linenum - (setq line (format "%d: " (1+ (count-lines 1 point))))))) + (line "")) + (when point + (set-marker m1 point (current-buffer)) + (if add-linenum + (setq line (format "%d: " (1+ (count-lines 1 point)))))) (save-excursion (if (get-buffer buffer) (set-buffer (get-buffer buffer)) @@ -2924,9 +2739,9 @@ (while (< (point) (point-max)) (setq linenum (1+ linenum)) -;; (if (zerop (% linenum 10)) - (message "line %d" linenum) -;; ) + ;; (if (zerop (% linenum 10)) + (message "line %d" linenum) + ;; ) (unless (looking-at "\\s-*$") ;; ignore empty lines! (let* ((sh-indent-comment t) ;; info must return default indent (info (sh-get-indent-info)) @@ -2944,7 +2759,7 @@ (setq diff (- curr-indent ival)) (setq new-val (+ sval diff)) (sh-set-var-value var new-val 'no-symbol) - (unless (looking-at "\\s-*#");; don't learn from comments + (unless (looking-at "\\s-*#") ;; don't learn from comments (if (setq previous-set-info (assoc var learned-var-list)) (progn ;; it was already there, is it same value ? @@ -2981,16 +2796,16 @@ (unless (= curr-indent (sh-calculate-indent info)) ;; this is not the default indentation (setq comments-always-default nil) - (if comment-col;; then we have see one before + (if comment-col ;; then we have see one before (or (eq comment-col curr-indent) - (setq comment-col t));; seen a different one + (setq comment-col t)) ;; seen a different one (setq comment-col curr-indent)) - )) - (t + )) + (t (sh-debug "Cannot learn this line!!!") )) (sh-debug - "at %s learned-var-list is %s" (point) learned-var-list) + "at %s learned-var-list is %s" (point) learned-var-list) )) (forward-line 1) ) ;; while @@ -3056,54 +2871,42 @@ (setq learned-var-list (append (list (list 'sh-indent-comment comment-col (point-max))) - learned-var-list)) + learned-var-list)) (setq sh-indent-comment comment-col) (let ((name (buffer-name)) - (lines (if (and (eq (point-min) 1) - (eq (point-max) (1+ (buffer-size)))) - "" - (format "lines %d to %d of " - (1+ (count-lines 1 (point-min))) - (1+ (count-lines 1 (point-max)))))) - ) + (lines (if (and (eq (point-min) 1) + (eq (point-max) (1+ (buffer-size)))) + "" + (format "lines %d to %d of " + (1+ (count-lines 1 (point-min))) + (1+ (count-lines 1 (point-max)))))) + ) (sh-mark-line "\nLearned variable settings:" nil out-buffer) (if arg ;; Set learned variables to symbolic rather than numeric ;; values where possible. - (progn - (let ((p (reverse learned-var-list)) - var val) - (while p - (setq var (car (car p))) - (setq val (nth 1 (car p))) - (cond - ((eq var 'sh-basic-offset) - ) - ((numberp val) - (sh-set-var-value var val)) - (t - )) - (setq p (cdr p)) - )))) - (let ((p (reverse learned-var-list)) - var) - (while p - (setq var (car (car p))) + (dolist (learned-var (reverse learned-var-list)) + (let ((var (car learned-var)) + (val (nth 1 learned-var))) + (when (and (not (eq var 'sh-basic-offset)) + (numberp val)) + (sh-set-var-value var val))))) + (dolist (learned-var (reverse learned-var-list)) + (let ((var (car learned-var))) (sh-mark-line (format " %s %s" var (symbol-value var)) - (nth 2 (car p)) out-buffer) - (setq p (cdr p)))) + (nth 2 learned-var) out-buffer))) (save-excursion - (set-buffer out-buffer) - (goto-char (point-min)) - (insert - (format "Indentation values for buffer %s.\n" name) - (format "%d indentation variable%s different values%s\n\n" - num-diffs - (if (= num-diffs 1) - " has" "s have") - (if (zerop num-diffs) - "." ":")) - ))) + (set-buffer out-buffer) + (goto-char (point-min)) + (insert + (format "Indentation values for buffer %s.\n" name) + (format "%d indentation variable%s different values%s\n\n" + num-diffs + (if (= num-diffs 1) + " has" "s have") + (if (zerop num-diffs) + "." ":")) + ))) ;; Are abnormal hooks considered bad form? (run-hook-with-args 'sh-learned-buffer-hook learned-var-list) (if (or sh-popup-occur-buffer (> num-diffs 0)) @@ -3121,10 +2924,10 @@ reasonable choices nil - we couldn't find a reasonable one." (let* ((max (1- (length vec))) - (i 1) - (totals (make-vector max 0)) - (return nil) - j) + (i 1) + (totals (make-vector max 0)) + (return nil) + j) (while (< i max) (aset totals i (+ (aref totals i) (* 4 (aref vec i)))) (setq j (/ i 2)) @@ -3132,8 +2935,8 @@ (aset totals i (+ (aref totals i) (aref vec (/ i 2))))) (if (< (* i 2) max) (aset totals i (+ (aref totals i) (aref vec (* i 2))))) - (setq i (1+ i)) - ) + (setq i (1+ i))) + (let ((x nil) (result nil) tot sum p) @@ -3143,17 +2946,16 @@ (setq x (append x (list (cons i (aref totals i)))))) (setq i (1+ i))) - (setq x (sort x (lambda (a b) - (> (cdr a)(cdr b))))) + (setq x (sort x (lambda (a b) (> (cdr a) (cdr b))))) (setq tot (apply '+ (append totals nil))) (sh-debug (format "vec: %s\ntotals: %s\ntot: %d" - vec totals tot)) + vec totals tot)) (cond ((zerop (length x)) (message "no values!")) ;; we return nil ((= (length x) 1) (message "only value is %d" (car (car x))) - (setq result (car (car x)))) ;; return single value + (setq result (car (car x)))) ;; return single value ((> (cdr (car x)) (/ tot 2)) ;; 1st is > 50% (message "basic-offset is probably %d" (car (car x))) @@ -3180,12 +2982,6 @@ ))) -(defun sh-do-nothing (a b c) - ;; checkdoc-params: (a b c) - "A dummy function to prevent font-lock from re-fontifying a change. -Otherwise, we fontify something and font-lock overwrites it." - ) - ;; The default font-lock-unfontify-region-function removes ;; syntax-table properties, and so removes our information. (defun sh-font-lock-unfontify-region-function (beg end) @@ -3201,7 +2997,7 @@ "Set the character's syntax table property at WHERE to be NEW-PROP." (or where (setq where (point))) - (let ((font-lock-fontify-region-function 'sh-do-nothing)) + (let ((inhibit-modification-hooks t)) (put-text-property where (1+ where) 'syntax-table new-prop) (add-text-properties where (1+ where) '(face sh-st-face rear-nonsticky t)) @@ -3275,7 +3071,7 @@ ;; That way sexp movement doens't worry about any parentheses. ;; A disadvantage of this is we can't use forward-word within a ;; here-doc, which is annoying. - (let ((font-lock-fontify-region-function 'sh-do-nothing)) + (let ((inhibit-modification-hooks t)) (put-text-property start end 'syntax-table sh-here-doc-syntax) (put-text-property start end 'face 'sh-heredoc-face) (put-text-property (1- end) end 'rear-nonsticky t) @@ -3532,24 +3328,18 @@ (list (read-from-minibuffer "Name for this style? " ) (not current-prefix-arg))) - (let ((slist (list name)) - (p sh-var-list) - var style) - (while p - (setq var (car p)) - (setq slist (append slist (list (cons var (symbol-value var))))) - (setq p (cdr p))) - (if (setq style (assoc name sh-styles-alist)) - (if (or (not confirm-overwrite) - (y-or-n-p "This style exists. Overwrite it? ")) - (progn - (message "Updating style %s" name) - (setcdr style (cdr slist))) - (message "Not changing style %s" name)) + (let ((slist (cons name + (mapcar (lambda (var) (cons var (symbol-value var))) + sh-var-list))) + (style (assoc name sh-styles-alist))) + (if style + (if (and confirm-overwrite + (not (y-or-n-p "This style exists. Overwrite it? "))) + (message "Not changing style %s" name) + (message "Updating style %s" name) + (setcdr style (cdr slist))) (message "Creating new style %s" name) - (setq sh-styles-alist (append sh-styles-alist - (list slist))) - ))) + (push slist sh-styles-alist)))) (defun sh-load-style (name) "Set shell indentation values for this buffer from those in style NAME." @@ -3559,37 +3349,18 @@ (let ((sl (assoc name sh-styles-alist))) (if (null sl) (error "sh-load-style - style %s not known" name) - (setq sl (cdr sl)) - (while sl - (set (car (car sl)) (cdr (car sl))) - (setq sl (cdr sl)) - )))) + (dolist (var (cdr sl)) + (set (car var) (cdr var)))))) (defun sh-save-styles-to-buffer (buff) "Save all current styles in elisp to buffer BUFF. This is always added to the end of the buffer." (interactive (list - (read-from-minibuffer "Buffer to save styles in? " "*scratch*"))) - ;; This is an attempt to sort of pretty print it... - (save-excursion - (set-buffer (get-buffer-create buff)) + (read-from-minibuffer "Buffer to save styles in? " "*scratch*"))) + (with-current-buffer (get-buffer-create buff) (goto-char (point-max)) (insert "\n") - (let ((p sh-styles-alist) q) - (insert "(setq sh-styles-alist '(\n") - (while p - (setq q (car p)) - (insert " ( " (prin1-to-string (car q)) "\n") - (setq q (cdr q)) - (while q - (insert " "(prin1-to-string (car q)) "\n") - (setq q (cdr q))) - (insert " )\n") - (setq p (cdr p)) - ) - (insert "))\n") - ))) - + (pp `(setq sh-styles-alist ',sh-styles-alist) (current-buffer)))) @@ -3624,19 +3395,19 @@ "case *" > \n > _ \n resume: - ?} > ) + ?} > ) (sh "expression: " > "case " str " in" \n > (read-string "pattern: ") - '(sh-electric-rparen) + (propertize ")" 'syntax-table sh-st-punc) \n > _ \n ";;" \n ( "other pattern, %s: " - > str '(sh-electric-rparen) \n + > str (propertize ")" 'syntax-table sh-st-punc) \n > _ \n ";;" \n) - > "*" '(sh-electric-rparen) \n + > "*" (propertize ")" 'syntax-table sh-st-punc) \n > _ \n resume: "esac" > )) @@ -3695,7 +3466,7 @@ (read-string "upper limit: ") "; i++ ) print i }'`}) {" \n > _ ?$ (sh-remember-variable str) \n - ?} >) + ?} >) (sh "Index variable: " > "for " str " in `awk 'BEGIN { for( i=1; i<=" (read-string "upper limit: ") @@ -3780,7 +3551,7 @@ > _ \n < "}") (rc eval sh-modify ksh88 - 1 "fn ") + 1 "fn ") (sh () "() {" \n > _ \n @@ -3801,34 +3572,34 @@ resume: < "endif") (es "condition: " - > "if { " str " } {" \n - > _ \n - ( "other condition, %s: " - "} { " str " } {" > \n - > _ \n) - "} {" > \n - > _ \n - resume: - ?} > ) + > "if { " str " } {" \n + > _ \n + ( "other condition, %s: " + "} { " str " } {" > \n + > _ \n) + "} {" > \n + > _ \n + resume: + ?} > ) (rc "condition: " - > "if( " str " ) {" \n - > _ \n - ( "other condition, %s: " - "} else if( " str " ) {" > \n - > _ \n) - "} else {" > \n - > _ \n - resume: - ?} > - ) + > "if( " str " ) {" \n + > _ \n + ( "other condition, %s: " + "} else if( " str " ) {" > \n + > _ \n) + "} else {" > \n + > _ \n + resume: + ?} > + ) (sh "condition: " '(setq input (sh-feature sh-test)) > "if " str "; then" \n > _ \n ( "other condition, %s: " - > "elif " str "; then" > \n - > \n) - "else" > \n + > "elif " str "; then" > \n + > \n) + "else" > \n > \n resume: "fi" > )) @@ -3840,10 +3611,10 @@ (es nil > "forever {" \n > _ \n - ?} > ) + ?} > ) (zsh "factor: " > "repeat " str "; do" > \n - > \n + > \n "done" > )) ;;;(put 'sh-repeat 'menu-enable '(sh-feature sh-repeat)) @@ -3880,14 +3651,14 @@ > "rm $tmp^* >[2]/dev/null" \n "throw $e" \n "} {" > \n - _ \n + _ \n ?} > \n ?} > ) (ksh88 eval sh-modify sh 7 "EXIT") (rc (file-name-nondirectory (buffer-file-name)) > "tmp = /tmp/" str ".$pid" \n - "fn sigexit { rm $tmp^* >[2]/dev/null }") + "fn sigexit { rm $tmp^* >[2]/dev/null }") (sh (file-name-nondirectory (buffer-file-name)) > "TMP=${TMPDIR:-/tmp}/" str ".$$" \n "trap \"rm $TMP* 2>/dev/null\" " ?0)) @@ -3900,7 +3671,7 @@ '(setq input (sh-feature sh-test)) > "until " str "; do" \n > _ \n - "done" > )) + "done" > )) ;;;(put 'sh-until 'menu-enable '(sh-feature sh-until)) @@ -3974,10 +3745,10 @@ v2 "\"$OPTARG\"") (setq v1 (cdr v1) v2 nil))) - > str "|+" str '(sh-electric-rparen) \n + > str "|+" str (propertize ")" 'syntax-table sh-st-punc) \n > _ v2 \n > ";;" \n) - > "*" '(sh-electric-rparen) \n + > "*" (propertize ")" 'syntax-table sh-st-punc) \n > "echo" " \"usage: " "`basename $0`" " [+-" '(setq v1 (point)) str '(save-excursion @@ -3987,9 +3758,9 @@ (if (and (sequencep v1) (length v1)) "] " "} ") "[--] ARGS...\"" \n "exit 2" > \n - "esac" > - \n "done" - > \n + "esac" > + \n "done" + > \n "shift " (sh-add "OPTIND" -1))) @@ -4010,7 +3781,7 @@ (defun sh-maybe-here-document (arg) - "Inserts self. Without prefix, following unquoted `<' inserts here document. + "Insert self. Without prefix, following unquoted `<' inserts here document. The document is bounded by `sh-here-document-word'." (interactive "*P") (self-insert-command (prefix-numeric-value arg))