aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2000-10-15 04:38:24 +0000
committerStefan Monnier2000-10-15 04:38:24 +0000
commit6c5bcbc1b1444cc4a4160ada897301099b00f802 (patch)
tree50a07772c5ccc15e7b2bbe3ddf34e9a66e021dea
parentea590e1c631c1c68e0ce6c0a7aaff9ece7566bf3 (diff)
downloademacs-6c5bcbc1b1444cc4a4160ada897301099b00f802.tar.gz
emacs-6c5bcbc1b1444cc4a4160ada897301099b00f802.zip
(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.
-rw-r--r--lisp/progmodes/sh-script.el885
1 files changed, 328 insertions, 557 deletions
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 08e0e1eec48..fd225cd164a 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -113,7 +113,7 @@
113;; would make this unnecessary; simply learn the values when you visit 113;; would make this unnecessary; simply learn the values when you visit
114;; the buffer. 114;; the buffer.
115;; You can do this automatically like this: 115;; You can do this automatically like this:
116; (add-hook 'sh-set-shell-hook 'sh-learn-buffer-indent) 116;; (add-hook 'sh-set-shell-hook 'sh-learn-buffer-indent)
117;; 117;;
118;; However... `sh-learn-buffer-indent' is extremely slow, 118;; However... `sh-learn-buffer-indent' is extremely slow,
119;; especially on large-ish buffer. Also, if there are conflicts the 119;; especially on large-ish buffer. Also, if there are conflicts the
@@ -332,12 +332,8 @@ shell it really is."
332 :group 'sh-script) 332 :group 'sh-script)
333 333
334(defcustom sh-imenu-generic-expression 334(defcustom sh-imenu-generic-expression
335 (list 335 `((sh
336 (cons 'sh 336 . ((nil "^\\s-*\\(function\\s-+\\)?\\([A-Za-z_][A-Za-z_0-9]+\\)\\s-*()" 2))))
337 (concat
338 "\\(^\\s-*function\\s-+[A-Za-z_][A-Za-z_0-9]*\\)"
339 "\\|"
340 "\\(^\\s-*[A-Za-z_][A-Za-z_0-9]*\\s-*()\\)")))
341 "*Regular expression for recognizing shell function definitions. 337 "*Regular expression for recognizing shell function definitions.
342See `sh-feature'." 338See `sh-feature'."
343 :type '(repeat (cons (symbol :tag "Shell") 339 :type '(repeat (cons (symbol :tag "Shell")
@@ -417,7 +413,9 @@ the car and cdr are the same symbol.")
417 ?: "_" 413 ?: "_"
418 ?. "_" 414 ?. "_"
419 ?^ "_" 415 ?^ "_"
420 ?~ "_") 416 ?~ "_"
417 ?< "."
418 ?> ".")
421 (csh eval identity sh) 419 (csh eval identity sh)
422 (rc eval identity sh)) 420 (rc eval identity sh))
423 "Syntax-table used in Shell-Script mode. See `sh-feature'.") 421 "Syntax-table used in Shell-Script mode. See `sh-feature'.")
@@ -479,10 +477,8 @@ the car and cdr are the same symbol.")
479 (define-key menu-map [sh-tmp-file] '("Temporary File" . sh-tmp-file)) 477 (define-key menu-map [sh-tmp-file] '("Temporary File" . sh-tmp-file))
480 (define-key menu-map [sh-select] '("Select Statement" . sh-select)) 478 (define-key menu-map [sh-select] '("Select Statement" . sh-select))
481 (define-key menu-map [sh-repeat] '("Repeat Loop" . sh-repeat)) 479 (define-key menu-map [sh-repeat] '("Repeat Loop" . sh-repeat))
482 (define-key menu-map [sh-while-getopts] 480 (define-key menu-map [sh-getopts] '("Options Loop" . sh-while-getopts))
483 '("Options Loop" . sh-while-getopts)) 481 (define-key menu-map [sh-indexed-loop] '("Indexed Loop" . sh-indexed-loop))
484 (define-key menu-map [sh-indexed-loop]
485 '("Indexed Loop" . sh-indexed-loop))
486 (define-key menu-map [sh-if] '("If Statement" . sh-if)) 482 (define-key menu-map [sh-if] '("If Statement" . sh-if))
487 (define-key menu-map [sh-for] '("For Loop" . sh-for)) 483 (define-key menu-map [sh-for] '("For Loop" . sh-for))
488 (define-key menu-map [sh-case] '("Case Statement" . sh-case)) 484 (define-key menu-map [sh-case] '("Case Statement" . sh-case))
@@ -601,7 +597,7 @@ The actual command ends at the end of the first \\(grouping\\)."
601 "bg" "fg" "jobs" "kill" "stop" "suspend") 597 "bg" "fg" "jobs" "kill" "stop" "suspend")
602 598
603 (jcsh eval sh-append csh 599 (jcsh eval sh-append csh
604 "bg" "fg" "jobs" "kill" "notify" "stop" "suspend") 600 "bg" "fg" "jobs" "kill" "notify" "stop" "suspend")
605 601
606 (ksh88 eval sh-append bourne 602 (ksh88 eval sh-append bourne
607 "alias" "bg" "false" "fc" "fg" "jobs" "kill" "let" "print" "time" 603 "alias" "bg" "false" "fc" "fg" "jobs" "kill" "let" "print" "time"
@@ -731,7 +727,7 @@ See `sh-feature'."
731 "pid" "prompt" "signals") 727 "pid" "prompt" "signals")
732 728
733 (jcsh eval sh-append csh 729 (jcsh eval sh-append csh
734 "notify") 730 "notify")
735 731
736 (ksh88 eval sh-append sh 732 (ksh88 eval sh-append sh
737 "ENV" "ERRNO" "FCEDIT" "FPATH" "HISTFILE" "HISTSIZE" "LINENO" 733 "ENV" "ERRNO" "FCEDIT" "FPATH" "HISTFILE" "HISTSIZE" "LINENO"
@@ -839,12 +835,12 @@ and command `sh-reset-indent-vars-to-global-values'."
839 835
840(defcustom sh-set-shell-hook nil 836(defcustom sh-set-shell-hook nil
841 "*Hook run by `sh-set-shell'." 837 "*Hook run by `sh-set-shell'."
842 :type 'hook 838 :type 'hook
843 :group 'sh-script) 839 :group 'sh-script)
844 840
845(defcustom sh-mode-hook nil 841(defcustom sh-mode-hook nil
846 "*Hook run by `sh-mode'." 842 "*Hook run by `sh-mode'."
847 :type 'hook 843 :type 'hook
848 :group 'sh-script) 844 :group 'sh-script)
849 845
850(defcustom sh-learn-basic-offset nil 846(defcustom sh-learn-basic-offset nil
@@ -903,7 +899,7 @@ a number means align to that column, e.g. 0 means fist column."
903 (const :tag "Leave as is." nil) 899 (const :tag "Leave as is." nil)
904 (const :tag "Indent as a normal line." t) 900 (const :tag "Indent as a normal line." t)
905 (integer :menu-tag "Indent to this col (0 means first col)." 901 (integer :menu-tag "Indent to this col (0 means first col)."
906 :tag "Indent to column number.") ) 902 :tag "Indent to column number.") )
907 :group 'sh-indentation) 903 :group 'sh-indentation)
908 904
909 905
@@ -943,9 +939,9 @@ a number means align to that column, e.g. 0 means fist column."
943 :group 'sh-indentation) 939 :group 'sh-indentation)
944 940
945(defconst sh-number-or-symbol-list 941(defconst sh-number-or-symbol-list
946 (append (list '(integer :menu-tag "A number (positive=>indent right)" 942 (append '((integer :menu-tag "A number (positive=>indent right)"
947 :tag "A number") 943 :tag "A number")
948 '(const :tag "--")) ; separator 944 (const :tag "--")) ; separator
949 sh-symbol-list)) 945 sh-symbol-list))
950 946
951(defcustom sh-indent-for-fi 0 947(defcustom sh-indent-for-fi 0
@@ -983,7 +979,7 @@ while until or for statement."
983 :group 'sh-indentation) 979 :group 'sh-indentation)
984 980
985(defcustom sh-indent-after-do '* 981(defcustom sh-indent-after-do '*
986"*How much to indent a line after a do statement. 982 "*How much to indent a line after a do statement.
987This is used when the do is the first word of the line. 983This is used when the do is the first word of the line.
988This is relative to the statement before the do, e.g. a 984This is relative to the statement before the do, e.g. a
989while for repeat or select statement." 985while for repeat or select statement."
@@ -1217,8 +1213,6 @@ with your script for an edit-interpret-debug cycle."
1217 (interactive) 1213 (interactive)
1218 (kill-all-local-variables) 1214 (kill-all-local-variables)
1219 (use-local-map sh-mode-map) 1215 (use-local-map sh-mode-map)
1220 (make-local-variable 'indent-line-function)
1221 (make-local-variable 'indent-region-function)
1222 (make-local-variable 'skeleton-end-hook) 1216 (make-local-variable 'skeleton-end-hook)
1223 (make-local-variable 'paragraph-start) 1217 (make-local-variable 'paragraph-start)
1224 (make-local-variable 'paragraph-separate) 1218 (make-local-variable 'paragraph-separate)
@@ -1238,7 +1232,6 @@ with your script for an edit-interpret-debug cycle."
1238 (make-local-variable 'sh-shell-variables) 1232 (make-local-variable 'sh-shell-variables)
1239 (make-local-variable 'sh-shell-variables-initialized) 1233 (make-local-variable 'sh-shell-variables-initialized)
1240 (make-local-variable 'imenu-generic-expression) 1234 (make-local-variable 'imenu-generic-expression)
1241 (make-local-variable 'sh-electric-rparen-needed-here)
1242 (make-local-variable 'sh-indent-supported-here) 1235 (make-local-variable 'sh-indent-supported-here)
1243 (make-local-variable 'font-lock-unfontify-region-function) 1236 (make-local-variable 'font-lock-unfontify-region-function)
1244 (setq major-mode 'sh-mode 1237 (setq major-mode 'sh-mode
@@ -1266,7 +1259,7 @@ with your script for an edit-interpret-debug cycle."
1266 nil nil 1259 nil nil
1267 ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil 1260 ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil
1268 (font-lock-syntactic-keywords . sh-font-lock-syntactic-keywords)) 1261 (font-lock-syntactic-keywords . sh-font-lock-syntactic-keywords))
1269 font-lock-unfontify-region-function 1262 font-lock-unfontify-region-function
1270 'sh-font-lock-unfontify-region-function 1263 'sh-font-lock-unfontify-region-function
1271 skeleton-pair-alist '((?` _ ?`)) 1264 skeleton-pair-alist '((?` _ ?`))
1272 skeleton-pair-filter 'sh-quoted-p 1265 skeleton-pair-filter 'sh-quoted-p
@@ -1274,10 +1267,8 @@ with your script for an edit-interpret-debug cycle."
1274 (current-column))))) 1267 (current-column)))))
1275 skeleton-filter 'sh-feature 1268 skeleton-filter 'sh-feature
1276 skeleton-newline-indent-rigidly t 1269 skeleton-newline-indent-rigidly t
1277 sh-electric-rparen-needed-here nil
1278 sh-indent-supported-here nil) 1270 sh-indent-supported-here nil)
1279 (make-local-variable 'parse-sexp-ignore-comments) 1271 (set (make-local-variable 'parse-sexp-ignore-comments) t)
1280 (setq parse-sexp-ignore-comments t)
1281 ;; Parse or insert magic number for exec, and set all variables depending 1272 ;; Parse or insert magic number for exec, and set all variables depending
1282 ;; on the shell thus determined. 1273 ;; on the shell thus determined.
1283 (let ((interpreter 1274 (let ((interpreter
@@ -1363,77 +1354,32 @@ This adds rules for comments and assignments."
1363;; for both. 1354;; for both.
1364;; 1355;;
1365(defconst sh-kw 1356(defconst sh-kw
1366 '( 1357 '((sh
1367 (sh 1358 ("if" nil sh-handle-prev-if)
1368 ( "if" 1359 ("elif" sh-handle-this-else sh-handle-prev-else)
1369 nil 1360 ("else" sh-handle-this-else sh-handle-prev-else)
1370 sh-handle-prev-if ) 1361 ("fi" sh-handle-this-fi sh-handle-prev-fi)
1371 ( "elif" 1362 ("then" sh-handle-this-then sh-handle-prev-then)
1372 sh-handle-this-else 1363 ("(" nil sh-handle-prev-open)
1373 sh-handle-prev-else ) 1364 ("{" nil sh-handle-prev-open)
1374 ( "else" 1365 ("[" nil sh-handle-prev-open)
1375 sh-handle-this-else 1366 ("}" sh-handle-this-close nil)
1376 sh-handle-prev-else ) 1367 (")" sh-handle-this-close nil)
1377 ( "fi" 1368 ("]" sh-handle-this-close nil)
1378 sh-handle-this-fi 1369 ("case" nil sh-handle-prev-case)
1379 sh-handle-prev-fi ) 1370 ("esac" sh-handle-this-esac sh-handle-prev-esac)
1380 ( "then" 1371 (case-label nil sh-handle-after-case-label) ;; ???
1381 sh-handle-this-then 1372 (";;" nil sh-handle-prev-case-alt-end) ;; ???
1382 sh-handle-prev-then ) 1373 ("done" sh-handle-this-done sh-handle-prev-done)
1383 ( "(" 1374 ("do" sh-handle-this-do sh-handle-prev-do))
1384 nil
1385 sh-handle-prev-open )
1386 ( "{"
1387 nil
1388 sh-handle-prev-open )
1389 ( "["
1390 nil
1391 sh-handle-prev-open )
1392 ( "}"
1393 sh-handle-this-close
1394 nil )
1395 ( ")"
1396 sh-handle-this-close
1397 nil )
1398 ( "]"
1399 sh-handle-this-close
1400 nil )
1401 ( "case"
1402 nil
1403 sh-handle-prev-case )
1404 ( "esac"
1405 sh-handle-this-esac
1406 sh-handle-prev-esac )
1407 ( case-label
1408 nil ;; ???
1409 sh-handle-after-case-label )
1410 ( ";;"
1411 nil ;; ???
1412 sh-handle-prev-case-alt-end ;; ??
1413 )
1414 ( "done"
1415 sh-handle-this-done
1416 sh-handle-prev-done )
1417 ( "do"
1418 sh-handle-this-do
1419 sh-handle-prev-do )
1420 ) ;; end of sh
1421 1375
1422 ;; Note: we don't need specific stuff for bash and zsh shells; 1376 ;; Note: we don't need specific stuff for bash and zsh shells;
1423 ;; the regexp `sh-regexp-for-done' handles the extra keywords 1377 ;; the regexp `sh-regexp-for-done' handles the extra keywords
1424 ;; these shells use. 1378 ;; these shells use.
1425 (rc 1379 (rc
1426 ( "{" 1380 ("{" nil sh-handle-prev-open)
1427 nil 1381 ("}" sh-handle-this-close nil)
1428 sh-handle-prev-open ) 1382 ("case" sh-handle-this-rc-case sh-handle-prev-rc-case))))
1429 ( "}"
1430 sh-handle-this-close
1431 nil )
1432 ( "case"
1433 sh-handle-this-rc-case
1434 sh-handle-prev-rc-case )
1435 ) ;; end of rc
1436 ))
1437 1383
1438 1384
1439(defun sh-set-shell (shell &optional no-query-flag insert-flag) 1385(defun sh-set-shell (shell &optional no-query-flag insert-flag)
@@ -1457,9 +1403,6 @@ Calls the value of `sh-set-shell-hook' if set."
1457 no-query-flag insert-flag))) 1403 no-query-flag insert-flag)))
1458 (setq require-final-newline (sh-feature sh-require-final-newline) 1404 (setq require-final-newline (sh-feature sh-require-final-newline)
1459;;; local-abbrev-table (sh-feature sh-abbrevs) 1405;;; local-abbrev-table (sh-feature sh-abbrevs)
1460;; Packages should not need to set these variables directly. sm.
1461; font-lock-keywords nil ; force resetting
1462; font-lock-syntax-table nil
1463 comment-start-skip "#+[\t ]*" 1406 comment-start-skip "#+[\t ]*"
1464 mode-line-process (format "[%s]" sh-shell) 1407 mode-line-process (format "[%s]" sh-shell)
1465 sh-shell-variables nil 1408 sh-shell-variables nil
@@ -1468,37 +1411,25 @@ Calls the value of `sh-set-shell-hook' if set."
1468 imenu-case-fold-search nil) 1411 imenu-case-fold-search nil)
1469 (set-syntax-table (or (sh-feature sh-mode-syntax-table) 1412 (set-syntax-table (or (sh-feature sh-mode-syntax-table)
1470 (standard-syntax-table))) 1413 (standard-syntax-table)))
1471 (let ((vars (sh-feature sh-variables))) 1414 (dolist (var (sh-feature sh-variables))
1472 (while vars 1415 (sh-remember-variable var))
1473 (sh-remember-variable (car vars)) 1416 (make-local-variable 'indent-line-function)
1474 (setq vars (cdr vars))))
1475;; Packages should not need to toggle Font Lock mode. sm.
1476; (and (boundp 'font-lock-mode)
1477; font-lock-mode
1478; (font-lock-mode (font-lock-mode 0)))
1479 (if (setq sh-indent-supported-here (sh-feature sh-indent-supported)) 1417 (if (setq sh-indent-supported-here (sh-feature sh-indent-supported))
1480 (progn 1418 (progn
1481 (message "Setting up indent for shell type %s" sh-shell) 1419 (message "Setting up indent for shell type %s" sh-shell)
1482 (make-local-variable 'sh-kw-alist) 1420 (set (make-local-variable 'sh-electric-rparen-needed-here)
1483 (make-local-variable 'sh-regexp-for-done) 1421 (sh-feature sh-electric-rparen-needed))
1484 (make-local-variable 'parse-sexp-lookup-properties) 1422 (set (make-local-variable 'parse-sexp-lookup-properties) t)
1485 (setq sh-electric-rparen-needed-here
1486 (sh-feature sh-electric-rparen-needed))
1487 (setq parse-sexp-lookup-properties t)
1488 (sh-scan-buffer) 1423 (sh-scan-buffer)
1489 (setq sh-kw-alist (sh-feature sh-kw)) 1424 (set (make-local-variable 'sh-kw-alist) (sh-feature sh-kw))
1490 (let ((regexp (sh-feature sh-kws-for-done))) 1425 (let ((regexp (sh-feature sh-kws-for-done)))
1491 (if regexp 1426 (if regexp
1492 (setq sh-regexp-for-done 1427 (set (make-local-variable 'sh-regexp-for-done)
1493 (sh-mkword-regexpr (regexp-opt regexp t))))) 1428 (sh-mkword-regexpr (regexp-opt regexp t)))))
1494 (message "setting up indent stuff") 1429 (message "setting up indent stuff")
1495 ;; sh-mode has already made indent-line-function local 1430 ;; sh-mode has already made indent-line-function local
1496 ;; but do it in case this is called before that. 1431 ;; but do it in case this is called before that.
1497 (make-local-variable 'indent-line-function)
1498 (setq indent-line-function 'sh-indent-line) 1432 (setq indent-line-function 'sh-indent-line)
1499 ;; This is very inefficient, but this at least makes indent-region work:
1500 (make-local-variable 'indent-region-function)
1501 (setq indent-region-function nil)
1502 (if sh-make-vars-local 1433 (if sh-make-vars-local
1503 (sh-make-vars-local)) 1434 (sh-make-vars-local))
1504 (message "Indentation setup for shell type %s" sh-shell)) 1435 (message "Indentation setup for shell type %s" sh-shell))
@@ -1601,8 +1532,7 @@ in ALIST."
1601 "Copy TABLE and set syntax for successive CHARs according to strings S." 1532 "Copy TABLE and set syntax for successive CHARs according to strings S."
1602 (setq table (copy-syntax-table table)) 1533 (setq table (copy-syntax-table table))
1603 (while list 1534 (while list
1604 (modify-syntax-entry (car list) (car (cdr list)) table) 1535 (modify-syntax-entry (pop list) (pop list) table))
1605 (setq list (cdr (cdr list))))
1606 table) 1536 table)
1607 1537
1608 1538
@@ -1684,7 +1614,7 @@ region, clear header."
1684 (or (< (length var) sh-remember-variable-min) 1614 (or (< (length var) sh-remember-variable-min)
1685 (getenv var) 1615 (getenv var)
1686 (assoc var sh-shell-variables) 1616 (assoc var sh-shell-variables)
1687 (setq sh-shell-variables (cons (cons var var) sh-shell-variables))) 1617 (push (cons var var) sh-shell-variables))
1688 var) 1618 var)
1689 1619
1690 1620
@@ -1736,9 +1666,7 @@ Then, if variable `sh-make-vars-local' is non-nil, make them local."
1736 "Construct a string for `sh-read-variable' when changing variable VAR ." 1666 "Construct a string for `sh-read-variable' when changing variable VAR ."
1737 (let ((msg (documentation-property var 'variable-documentation)) 1667 (let ((msg (documentation-property var 'variable-documentation))
1738 (msg2 "")) 1668 (msg2 ""))
1739 (unless (or 1669 (unless (memq var '(sh-first-lines-indent sh-indent-comment))
1740 (eq var 'sh-first-lines-indent)
1741 (eq var 'sh-indent-comment))
1742 (setq msg2 1670 (setq msg2
1743 (format "\n 1671 (format "\n
1744You can enter a number (positive to increase indentation, 1672You can enter a number (positive to increase indentation,
@@ -1751,10 +1679,8 @@ which in this buffer is currently %s.
1751\t%s." 1679\t%s."
1752 sh-basic-offset 1680 sh-basic-offset
1753 (mapconcat (lambda (x) 1681 (mapconcat (lambda (x)
1754 (nth (1- (length x)) x) ) 1682 (nth (1- (length x)) x))
1755 sh-symbol-list "\n\t") 1683 sh-symbol-list "\n\t"))))
1756 )))
1757
1758 (concat 1684 (concat
1759 ;; The following shows the global not the local value! 1685 ;; The following shows the global not the local value!
1760 ;; (format "Current value of %s is %s\n\n" var (symbol-value var)) 1686 ;; (format "Current value of %s is %s\n\n" var (symbol-value var))
@@ -1767,10 +1693,10 @@ which in this buffer is currently %s.
1767 (quote ,var))) 1693 (quote ,var)))
1768 val) 1694 val)
1769 (setq val (read-from-minibuffer 1695 (setq val (read-from-minibuffer
1770 (format "New value for %s (press %s for help): " 1696 (format "New value for %s (press %s for help): "
1771 var (single-key-description help-char)) 1697 var (single-key-description help-char))
1772 (format "%s" (symbol-value var)) 1698 (format "%s" (symbol-value var))
1773 nil t)) 1699 nil t))
1774 val)) 1700 val))
1775 1701
1776 1702
@@ -1853,79 +1779,46 @@ This handles nested if..fi pairs."
1853 1779
1854(defun sh-handle-this-close () 1780(defun sh-handle-this-close ()
1855 (forward-char 1) ;; move over ")" 1781 (forward-char 1) ;; move over ")"
1856 (let ((p (sh-safe-backward-sexp))) 1782 (if (sh-safe-forward-sexp -1)
1857 (if p 1783 (list "aligned to opening paren")))
1858 (list "aligned to opening paren")
1859 nil
1860 )))
1861 1784
1862(defun sh-goto-matching-case () 1785(defun sh-goto-matching-case ()
1863 (let ((found (sh-find-prev-matching "\\bcase\\b" "\\besac\\b" 1))) 1786 (let ((found (sh-find-prev-matching "\\bcase\\b" "\\besac\\b" 1)))
1864 (if found 1787 (if found (goto-char found))))
1865 (goto-char found))))
1866 1788
1867(defun sh-handle-prev-case () 1789(defun sh-handle-prev-case ()
1868 ;; This is typically called when point is on same line as a case 1790 ;; This is typically called when point is on same line as a case
1869 ;; we shouldn't -- and can't find prev-case 1791 ;; we shouldn't -- and can't find prev-case
1870 (if (looking-at ".*\\bcase\\b") 1792 (if (looking-at ".*\\<case\\>")
1871 (list '(+ sh-indent-for-case-label)) 1793 (list '(+ sh-indent-for-case-label))
1872 (error "We don't seem to be on a line with a case") ;; debug 1794 (error "We don't seem to be on a line with a case"))) ;; debug
1873 ))
1874 1795
1875(defun sh-handle-this-esac () 1796(defun sh-handle-this-esac ()
1876 (let ((p (sh-goto-matching-case))) 1797 (if (sh-goto-matching-case)
1877 (if p 1798 (list "aligned to matching case")))
1878 (list "aligned to matching case")
1879 nil
1880 )))
1881
1882 1799
1883(defun sh-handle-prev-esac () 1800(defun sh-handle-prev-esac ()
1884 (let ((p (sh-goto-matching-case))) 1801 (if (sh-goto-matching-case)
1885 (if p 1802 (list "matching case")))
1886 (list "matching case")
1887 nil
1888 )))
1889 1803
1890(defun sh-handle-after-case-label () 1804(defun sh-handle-after-case-label ()
1891 (let ((p (sh-goto-matching-case))) 1805 (if (sh-goto-matching-case)
1892 (if p 1806 (list '(+ sh-indent-for-case-alt))))
1893 (list '( + sh-indent-for-case-alt ))
1894 nil
1895 )))
1896 1807
1897(defun sh-handle-prev-case-alt-end () 1808(defun sh-handle-prev-case-alt-end ()
1898 (let ((p (sh-goto-matching-case))) 1809 (if (sh-goto-matching-case)
1899 (if p 1810 (list '(+ sh-indent-for-case-label))))
1900 (list '( + sh-indent-for-case-label ))
1901 nil
1902 )))
1903 1811
1904(defun sh-safe-backward-sexp () 1812(defun sh-safe-forward-sexp (&optional arg)
1905 "Try and do a `backward-sexp', but do not error.
1906Return new point if successful, nil if an error occurred."
1907 (condition-case nil
1908 (progn
1909 (backward-sexp 1)
1910 (point) ;; return point if successful
1911 )
1912 (error
1913 (sh-debug "oops!(0) %d" (point))
1914 nil ;; return nil if fail
1915 )))
1916
1917(defun sh-safe-forward-sexp ()
1918 "Try and do a `forward-sexp', but do not error. 1813 "Try and do a `forward-sexp', but do not error.
1919Return new point if successful, nil if an error occurred." 1814Return new point if successful, nil if an error occurred."
1920 (condition-case nil 1815 (condition-case nil
1921 (progn 1816 (progn
1922 (forward-sexp 1) 1817 (forward-sexp (or arg 1))
1923 (point) ;; return point if successful 1818 (point)) ;; return point if successful
1924 )
1925 (error 1819 (error
1926 (sh-debug "oops!(1) %d" (point)) 1820 (sh-debug "oops!(1) %d" (point))
1927 nil ;; return nil if fail 1821 nil))) ;; return nil if fail
1928 )))
1929 1822
1930(defun sh-goto-match-for-done () 1823(defun sh-goto-match-for-done ()
1931 (let ((found (sh-find-prev-matching sh-regexp-for-done sh-re-done 1))) 1824 (let ((found (sh-find-prev-matching sh-regexp-for-done sh-re-done 1)))
@@ -1934,41 +1827,33 @@ Return new point if successful, nil if an error occurred."
1934 1827
1935(defun sh-handle-this-done () 1828(defun sh-handle-this-done ()
1936 (if (sh-goto-match-for-done) 1829 (if (sh-goto-match-for-done)
1937 (list "aligned to do stmt" '(+ sh-indent-for-done)) 1830 (list "aligned to do stmt" '(+ sh-indent-for-done))))
1938 nil
1939 ))
1940 1831
1941(defun sh-handle-prev-done () 1832(defun sh-handle-prev-done ()
1942 (if (sh-goto-match-for-done) 1833 (if (sh-goto-match-for-done)
1943 (list "previous done") 1834 (list "previous done")))
1944 nil
1945 ))
1946 1835
1947(defun sh-handle-this-do () 1836(defun sh-handle-this-do ()
1948 (let ( (p (sh-goto-match-for-done)) ) 1837 (if (sh-goto-match-for-done)
1949 (if p 1838 (list '(+ sh-indent-for-do))))
1950 (list '(+ sh-indent-for-do))
1951 nil
1952 )))
1953 1839
1954(defun sh-handle-prev-do () 1840(defun sh-handle-prev-do ()
1955 (let ( (p) ) 1841 (cond
1956 (cond 1842 ((save-restriction
1957 ((save-restriction 1843 (narrow-to-region
1958 (narrow-to-region 1844 (point)
1959 (point) 1845 (save-excursion
1960 (save-excursion 1846 (beginning-of-line)
1961 (beginning-of-line) 1847 (point)))
1962 (point))) 1848 (sh-goto-match-for-done))
1963 (sh-goto-match-for-done)) 1849 (sh-debug "match for done found on THIS line")
1964 (sh-debug "match for done found on THIS line") 1850 (list '(+ sh-indent-after-loop-construct)))
1965 (list '(+ sh-indent-after-loop-construct))) 1851 ((sh-goto-match-for-done)
1966 ((sh-goto-match-for-done) 1852 (sh-debug "match for done found on PREV line")
1967 (sh-debug "match for done found on PREV line") 1853 (list '(+ sh-indent-after-do)))
1968 (list '(+ sh-indent-after-do))) 1854 (t
1969 (t 1855 (message "match for done NOT found")
1970 (message "match for done NOT found") 1856 nil)))
1971 nil))))
1972 1857
1973;; for rc: 1858;; for rc:
1974(defun sh-find-prev-switch () 1859(defun sh-find-prev-switch ()
@@ -1978,7 +1863,7 @@ Return new point if successful, nil if an error occurred."
1978(defun sh-handle-this-rc-case () 1863(defun sh-handle-this-rc-case ()
1979 (if (sh-find-prev-switch) 1864 (if (sh-find-prev-switch)
1980 (list '(+ sh-indent-after-switch)) 1865 (list '(+ sh-indent-after-switch))
1981 ;; (list '(+ sh-indent-for-case-label)) 1866 ;; (list '(+ sh-indent-for-case-label))
1982 nil)) 1867 nil))
1983 1868
1984(defun sh-handle-prev-rc-case () 1869(defun sh-handle-prev-rc-case ()
@@ -2033,21 +1918,21 @@ STRING This is ignored for the purposes of calculating
2033 prev-line-end x) 1918 prev-line-end x)
2034 (beginning-of-line) 1919 (beginning-of-line)
2035 ;; Note: setting result to t means we are done and will return nil. 1920 ;; Note: setting result to t means we are done and will return nil.
2036 ;;( This function never returns just t.) 1921 ;;(This function never returns just t.)
2037 (cond 1922 (cond
2038 ((equal (get-text-property (point) 'syntax-table) sh-here-doc-syntax) 1923 ((equal (get-text-property (point) 'syntax-table) sh-here-doc-syntax)
2039 (setq result t) 1924 (setq result t)
2040 (setq have-result t)) 1925 (setq have-result t))
2041 ((looking-at "\\s-*#") ; was (equal this-kw "#") 1926 ((looking-at "\\s-*#") ; was (equal this-kw "#")
2042 (if (bobp) 1927 (if (bobp)
2043 (setq result t);; return nil if 1st line! 1928 (setq result t) ;; return nil if 1st line!
2044 (setq result (list '(= sh-indent-comment))) 1929 (setq result (list '(= sh-indent-comment)))
2045 ;; we still need to get previous line in case 1930 ;; we still need to get previous line in case
2046 ;; sh-indent-comment is t (indent as normal) 1931 ;; sh-indent-comment is t (indent as normal)
2047 (setq align-point (sh-prev-line nil)) 1932 (setq align-point (sh-prev-line nil))
2048 (setq have-result nil) 1933 (setq have-result nil)
2049 )) 1934 ))
2050 );; cond 1935 ) ;; cond
2051 1936
2052 (unless have-result 1937 (unless have-result
2053 ;; Continuation lines are handled specially 1938 ;; Continuation lines are handled specially
@@ -2086,7 +1971,7 @@ STRING This is ignored for the purposes of calculating
2086 ;; We start off at beginning of this line. 1971 ;; We start off at beginning of this line.
2087 ;; Scan previous statements while this is <= 1972 ;; Scan previous statements while this is <=
2088 ;; start of previous line. 1973 ;; start of previous line.
2089 (setq start (point));; for debug only 1974 (setq start (point)) ;; for debug only
2090 (goto-char prev-line-end) 1975 (goto-char prev-line-end)
2091 (setq x t) 1976 (setq x t)
2092 (while (and x (setq x (sh-prev-thing))) 1977 (while (and x (setq x (sh-prev-thing)))
@@ -2105,7 +1990,7 @@ STRING This is ignored for the purposes of calculating
2105 (skip-chars-forward "[a-z0-9]*?") 1990 (skip-chars-forward "[a-z0-9]*?")
2106 ) 1991 )
2107 ((string-match "[])}]" x) 1992 ((string-match "[])}]" x)
2108 (setq x (sh-safe-backward-sexp)) 1993 (setq x (sh-safe-forward-sexp -1))
2109 (if x 1994 (if x
2110 (progn 1995 (progn
2111 (setq align-point (point)) 1996 (setq align-point (point))
@@ -2121,7 +2006,7 @@ STRING This is ignored for the purposes of calculating
2121 ((string-match "[\"'`]" x) 2006 ((string-match "[\"'`]" x)
2122 (sh-debug "Skipping back for %s" x) 2007 (sh-debug "Skipping back for %s" x)
2123 ;; this was oops-2 2008 ;; this was oops-2
2124 (setq x (sh-safe-backward-sexp))) 2009 (setq x (sh-safe-forward-sexp -1)))
2125 ((stringp x) 2010 ((stringp x)
2126 (sh-debug "Checking string %s at %s" x (point)) 2011 (sh-debug "Checking string %s at %s" x (point))
2127 (if (setq val (sh-check-rule 2 x)) 2012 (if (setq val (sh-check-rule 2 x))
@@ -2135,7 +2020,7 @@ STRING This is ignored for the purposes of calculating
2135 (t 2020 (t
2136 (error "Don't know what to do with %s" x)) 2021 (error "Don't know what to do with %s" x))
2137 ) 2022 )
2138 );; while 2023 ) ;; while
2139 (sh-debug "result is %s" result) 2024 (sh-debug "result is %s" result)
2140 ) 2025 )
2141 (sh-debug "No prev line!") 2026 (sh-debug "No prev line!")
@@ -2158,7 +2043,7 @@ STRING This is ignored for the purposes of calculating
2158 (setq result nil)) 2043 (setq result nil))
2159 (sh-debug "result is: %s" result) 2044 (sh-debug "result is: %s" result)
2160 result 2045 result
2161 );; let 2046 ) ;; let
2162 )) 2047 ))
2163 2048
2164 2049
@@ -2185,7 +2070,7 @@ If INFO is supplied it is used, else it is calculated."
2185 (error "sh-get-indent-var-for-line invalid elt: %s" elt)) 2070 (error "sh-get-indent-var-for-line invalid elt: %s" elt))
2186 ;; so it is a list 2071 ;; so it is a list
2187 ((eq t (car elt)) 2072 ((eq t (car elt))
2188 );; nothing 2073 ) ;; nothing
2189 ((symbolp (setq sym (nth 1 elt))) 2074 ((symbolp (setq sym (nth 1 elt)))
2190 ;; A bit of a kludge - when we see the sh-indent-comment 2075 ;; A bit of a kludge - when we see the sh-indent-comment
2191 ;; ignore other variables. Otherwise it is tricky to 2076 ;; ignore other variables. Otherwise it is tricky to
@@ -2219,75 +2104,34 @@ If INFO is supplied it is used, else it is calculated."
2219;; because we may want to a align to the beginning of it. 2104;; because we may want to a align to the beginning of it.
2220;; 2105;;
2221;; What we do: 2106;; What we do:
2222;; - go back a line, if empty repeat 2107;; - go back to previous non-empty line
2223;; - (we are now at a previous non empty line)
2224;; - save this
2225;; - if this is in a here-document, go to the beginning of it 2108;; - if this is in a here-document, go to the beginning of it
2226;; and save that 2109;; - while previous line is continued, go back one line
2227;; - go back one more physical line and see if it is a continuation line
2228;; - if yes, save it and repeat
2229;; - if no, go back to where we last saved.
2230(defun sh-prev-line (&optional end) 2110(defun sh-prev-line (&optional end)
2231 "Back to end of previous non-comment non-empty line. 2111 "Back to end of previous non-comment non-empty line.
2232Go to beginning of logical line unless END is non-nil, in which case 2112Go to beginning of logical line unless END is non-nil, in which case
2233we go to the end of the previous line and do not check for continuations." 2113we go to the end of the previous line and do not check for continuations."
2234 (sh-must-be-shell-mode) 2114 (sh-must-be-shell-mode)
2235 (let ((going t) 2115 (save-excursion
2236 (last-contin-line nil) 2116 (beginning-of-line)
2237 (result nil) 2117 (forward-comment (- (point-max)))
2238 bol eol state) 2118 (unless end (beginning-of-line))
2239 (save-excursion 2119 (when (and (not (bobp))
2120 (equal (get-text-property (1- (point)) 'syntax-table)
2121 sh-here-doc-syntax))
2122 (let ((p1 (previous-single-property-change (1- (point)) 'syntax-table)))
2123 (when p1
2124 (goto-char p1)
2125 (forward-line -1)
2126 (if end (end-of-line)))))
2127 (unless end
2128 ;; we must check previous lines to see if they are continuation lines
2129 ;; if so, we must return position of first of them
2130 (while (and (sh-this-is-a-continuation)
2131 (>= 0 (forward-line -1))))
2240 (beginning-of-line) 2132 (beginning-of-line)
2241 (while (and going 2133 (skip-chars-forward " \t"))
2242 (not (bobp)) 2134 (point)))
2243 (>= 0 (forward-line -1))
2244 )
2245 (setq bol (point))
2246 (end-of-line)
2247 (setq eol (point))
2248 (save-restriction
2249 (setq state (parse-partial-sexp bol eol nil nil nil t))
2250 (if (nth 4 state)
2251 (setq eol (nth 8 state)))
2252 (narrow-to-region bol eol)
2253 (goto-char bol)
2254 (cond
2255 ((looking-at "\\s-*$"))
2256 (t
2257 (if end
2258 (setq result eol)
2259 (setq result bol))
2260 (setq going nil))
2261 )))
2262 (if (and result
2263 (equal (get-text-property (1- result) 'syntax-table)
2264 sh-here-doc-syntax))
2265 (let ((p1 (previous-single-property-change
2266 (1- result) 'syntax-table)))
2267 (if p1
2268 (progn
2269 (goto-char p1)
2270 (forward-line -1)
2271 (if end
2272 (end-of-line))
2273 (setq result (point)))
2274 )))
2275 (unless end
2276 ;; we must check previous lines to see if they are continuation lines
2277 ;; if so, we must return position of first of them
2278 (while (and (sh-this-is-a-continuation)
2279 (>= 0 (forward-line -1)))
2280 (setq result (point)))
2281 (if result
2282 (progn
2283 (goto-char result)
2284 (beginning-of-line)
2285 (skip-chars-forward " \t")
2286 (setq result (point))
2287 )))
2288 ) ;; save-excursion
2289 result
2290 ))
2291 2135
2292 2136
2293(defun sh-prev-stmt () 2137(defun sh-prev-stmt ()
@@ -2307,7 +2151,7 @@ we go to the end of the previous line and do not check for continuations."
2307 (not (bobp)) 2151 (not (bobp))
2308 going) 2152 going)
2309 ;; Do a backward-sexp if possible, else backup bit by bit... 2153 ;; Do a backward-sexp if possible, else backup bit by bit...
2310 (if (sh-safe-backward-sexp) 2154 (if (sh-safe-forward-sexp -1)
2311 (progn 2155 (progn
2312 (if (looking-at sh-special-keywords) 2156 (if (looking-at sh-special-keywords)
2313 (progn 2157 (progn
@@ -2380,59 +2224,51 @@ we go to the end of the previous line and do not check for continuations."
2380 (found nil)) 2224 (found nil))
2381 (save-restriction 2225 (save-restriction
2382 (narrow-to-region 2226 (narrow-to-region
2383 (if (sh-this-is-a-continuation) 2227 (if (sh-this-is-a-continuation)
2384 (setq min-point (sh-prev-line nil)) 2228 (setq min-point (sh-prev-line nil))
2385 (save-excursion 2229 (save-excursion
2386 (beginning-of-line) 2230 (beginning-of-line)
2387 (setq min-point (point)))) 2231 (setq min-point (point))))
2388 (point)) 2232 (point))
2389 (skip-chars-backward " \t;") 2233 (skip-chars-backward " \t;")
2390 (unless (looking-at "\\s-*;;") 2234 (unless (looking-at "\\s-*;;")
2391 (skip-chars-backward "^)}];\"'`({[") 2235 (skip-chars-backward "^)}];\"'`({[")
2392 (setq c (char-before)))) 2236 (setq c (char-before))))
2393 (sh-debug "stopping at %d c is %s start=%d min-point=%d" 2237 (sh-debug "stopping at %d c is %s start=%d min-point=%d"
2394 (point) c start min-point) 2238 (point) c start min-point)
2395 (if (< (point) min-point) 2239 (if (< (point) min-point)
2396 (error "point %d < min-point %d" (point) min-point)) 2240 (error "point %d < min-point %d" (point) min-point))
2397 (cond 2241 (cond
2398 ((looking-at "\\s-*;;") 2242 ((looking-at "\\s-*;;")
2399 ;; (message "Found ;; !") 2243 ;; (message "Found ;; !")
2400 ";;") 2244 ";;")
2401 ((or (eq c ?\n) 2245 ((or (eq c ?\n)
2402 (eq c nil) 2246 (eq c nil)
2403 (eq c ?\;)) 2247 (eq c ?\;))
2404 (save-excursion 2248 (save-excursion
2405 ;; skip forward over white space newline and \ at eol 2249 ;; skip forward over white space newline and \ at eol
2406 (skip-chars-forward " \t\n\\\\") 2250 (skip-chars-forward " \t\n\\\\")
2407 (sh-debug "Now at %d start=%d" (point) start) 2251 (sh-debug "Now at %d start=%d" (point) start)
2408 (if (>= (point) start) 2252 (if (>= (point) start)
2409 (progn 2253 (progn
2410 (sh-debug "point: %d >= start: %d" (point) start) 2254 (sh-debug "point: %d >= start: %d" (point) start)
2411 nil) 2255 nil)
2412 (sh-get-word)) 2256 (sh-get-word))
2413 )) 2257 ))
2414 (t 2258 (t
2415 ;; c -- return a string 2259 ;; c -- return a string
2416 (char-to-string c) 2260 (char-to-string c)
2417 )) 2261 ))
2418 ))) 2262 )))
2419 2263
2420 2264
2421(defun sh-this-is-a-continuation () 2265(defun sh-this-is-a-continuation ()
2422 "Return non-nil if current line is a continuation of previous line." 2266 "Return non-nil if current line is a continuation of previous line."
2423 (let ((result nil) 2267 (save-excursion
2424 bol eol state) 2268 (and (zerop (forward-line -1))
2425 (save-excursion 2269 (looking-at ".*\\\\$")
2426 (if (and (zerop (forward-line -1)) 2270 (not (nth 4 (parse-partial-sexp (match-beginning 0) (match-end 0)
2427 (looking-at ".*\\\\$")) 2271 nil nil nil t))))))
2428 (progn
2429 (setq bol (point))
2430 (end-of-line)
2431 (setq eol (point))
2432 (setq state (parse-partial-sexp bol eol nil nil nil t))
2433 (unless (nth 4 state)
2434 (setq result t))
2435 )))))
2436 2272
2437(defun sh-get-kw (&optional where and-move) 2273(defun sh-get-kw (&optional where and-move)
2438 "Return first word of line from WHERE. 2274 "Return first word of line from WHERE.
@@ -2442,7 +2278,7 @@ If AND-MOVE is non-nil then move to end of word."
2442 (goto-char where)) 2278 (goto-char where))
2443 (prog1 2279 (prog1
2444 (buffer-substring (point) 2280 (buffer-substring (point)
2445 (progn (skip-chars-forward "^ \t\n;")(point))) 2281 (progn (skip-chars-forward "^ \t\n;")(point)))
2446 (unless and-move 2282 (unless and-move
2447 (goto-char start))) 2283 (goto-char start)))
2448 )) 2284 ))
@@ -2476,7 +2312,7 @@ Optional parameter DEPTH (usually 1) says how many to look for."
2476 (sh-debug "found close - depth = %d" depth)) 2312 (sh-debug "found close - depth = %d" depth))
2477 (t 2313 (t
2478 )))) 2314 ))))
2479 (error nil)) 2315 (error nil))
2480 (if (eq depth 0) 2316 (if (eq depth 0)
2481 prev ;; (point) 2317 prev ;; (point)
2482 nil) 2318 nil)
@@ -2510,10 +2346,10 @@ IGNORE-ERROR is non-nil."
2510 (/ (- sh-basic-offset) 2)) 2346 (/ (- sh-basic-offset) 2))
2511 (t 2347 (t
2512 (if ignore-error 2348 (if ignore-error
2513 (progn 2349 (progn
2514 (message "Don't know how to handle %s's value of %s" var val) 2350 (message "Don't know how to handle %s's value of %s" var val)
2515 0) 2351 0)
2516 (error "Don't know how to handle %s's value of %s" var val)) 2352 (error "Don't know how to handle %s's value of %s" var val))
2517 )))) 2353 ))))
2518 2354
2519(defun sh-set-var-value (var value &optional no-symbol) 2355(defun sh-set-var-value (var value &optional no-symbol)
@@ -2543,21 +2379,17 @@ can be represented by a symbol then do so."
2543(defun sh-calculate-indent (&optional info) 2379(defun sh-calculate-indent (&optional info)
2544 "Return the indentation for the current line. 2380 "Return the indentation for the current line.
2545If INFO is supplied it is used, else it is calculated from current line." 2381If INFO is supplied it is used, else it is calculated from current line."
2546 (let ( 2382 (let ((ofs 0)
2547 (ofs 0)
2548 (base-value 0) 2383 (base-value 0)
2549 elt a b var val) 2384 elt a b var val)
2550 (or info 2385 (or info
2551 (setq info (sh-get-indent-info))) 2386 (setq info (sh-get-indent-info)))
2552 (if (null info) 2387 (when info
2553 nil
2554 (while info 2388 (while info
2555 (sh-debug "info: %s ofs=%s" info ofs) 2389 (sh-debug "info: %s ofs=%s" info ofs)
2556 (setq elt (car info)) 2390 (setq elt (car info))
2557 (cond 2391 (cond
2558 ((stringp elt) 2392 ((stringp elt)) ;; do nothing?
2559 ;; do nothing?
2560 )
2561 ((listp elt) 2393 ((listp elt)
2562 (setq a (car (car info))) 2394 (setq a (car (car info)))
2563 (setq b (nth 1 (car info))) 2395 (setq b (nth 1 (car info)))
@@ -2576,31 +2408,22 @@ If INFO is supplied it is used, else it is calculated from current line."
2576 ;; no indentation 2408 ;; no indentation
2577 ;; set info to nil so we stop immediately 2409 ;; set info to nil so we stop immediately
2578 (setq base-value nil ofs nil info nil)) 2410 (setq base-value nil ofs nil info nil))
2579 ((eq val t) 2411 ((eq val t) (setq ofs 0)) ;; indent as normal line
2580 ;; indent as normal line
2581 (setq ofs 0))
2582 (t 2412 (t
2583 ;; The following assume the (t POS) come first! 2413 ;; The following assume the (t POS) come first!
2584 (setq ofs val base-value 0) 2414 (setq ofs val base-value 0)
2585 (setq info nil) ;; ? stop now 2415 (setq info nil)))) ;; ? stop now
2586 )) 2416 ((eq a '+) (setq ofs (+ ofs val)))
2587 ) 2417 ((eq a '-) (setq ofs (- ofs val)))
2588 ((eq a '+)
2589 (setq ofs (+ ofs val)))
2590 ((eq a '-)
2591 (setq ofs (- ofs val)))
2592 (t 2418 (t
2593 (error "sh-calculate-indent invalid a a=%s b=%s" a b)))) 2419 (error "sh-calculate-indent invalid a a=%s b=%s" a b))))
2594 (t 2420 (t
2595 (error "sh-calculate-indent invalid elt: a=%s b=%s" a b))) 2421 (error "sh-calculate-indent invalid elt: a=%s b=%s" a b))))
2596 )
2597 (t 2422 (t
2598 (error "sh-calculate-indent invalid elt %s" elt)) 2423 (error "sh-calculate-indent invalid elt %s" elt)))
2599 ) 2424 (sh-debug "a=%s b=%s val=%s base-value=%s ofs=%s"
2600 (sh-debug "a=%s b=%s val=%s base-value=%s ofs=%s" 2425 a b val base-value ofs)
2601 a b val base-value ofs) 2426 (setq info (cdr info)))
2602 (setq info (cdr info))
2603 )
2604 ;; return value: 2427 ;; return value:
2605 (sh-debug "at end: base-value: %s ofs: %s" base-value ofs) 2428 (sh-debug "at end: base-value: %s ofs: %s" base-value ofs)
2606 2429
@@ -2609,13 +2432,12 @@ If INFO is supplied it is used, else it is calculated from current line."
2609 nil) 2432 nil)
2610 ((and (numberp base-value)(numberp ofs)) 2433 ((and (numberp base-value)(numberp ofs))
2611 (sh-debug "base (%d) + ofs (%d) = %d" 2434 (sh-debug "base (%d) + ofs (%d) = %d"
2612 base-value ofs (+ base-value ofs)) 2435 base-value ofs (+ base-value ofs))
2613 (+ base-value ofs)) ;; return value 2436 (+ base-value ofs)) ;; return value
2614 (t 2437 (t
2615 (error "sh-calculate-indent: Help. base-value=%s ofs=%s" 2438 (error "sh-calculate-indent: Help. base-value=%s ofs=%s"
2616 base-value ofs) 2439 base-value ofs)
2617 nil)) 2440 nil)))))
2618 )))
2619 2441
2620 2442
2621(defun sh-indent-line () 2443(defun sh-indent-line ()
@@ -2624,21 +2446,18 @@ If INFO is supplied it is used, else it is calculated from current line."
2624 (sh-must-be-shell-mode) 2446 (sh-must-be-shell-mode)
2625 (let ((indent (sh-calculate-indent)) shift-amt beg end 2447 (let ((indent (sh-calculate-indent)) shift-amt beg end
2626 (pos (- (point-max) (point)))) 2448 (pos (- (point-max) (point))))
2627 (if indent 2449 (when indent
2628 (progn 2450 (beginning-of-line)
2629 (beginning-of-line) 2451 (setq beg (point))
2630 (setq beg (point)) 2452 (skip-chars-forward " \t")
2631 (skip-chars-forward " \t") 2453 (setq shift-amt (- indent (current-column)))
2632 (setq shift-amt (- indent (current-column))) 2454 (unless (zerop shift-amt)
2633 (if (zerop shift-amt) 2455 (delete-region beg (point))
2634 nil 2456 (indent-to indent))
2635 (delete-region beg (point)) 2457 ;; If initial point was within line's indentation,
2636 (indent-to indent)) 2458 ;; position after the indentation. Else stay at same point in text.
2637 ;; If initial point was within line's indentation, 2459 (if (> (- (point-max) pos) (point))
2638 ;; position after the indentation. Else stay at same point in text. 2460 (goto-char (- (point-max) pos))))))
2639 (if (> (- (point-max) pos) (point))
2640 (goto-char (- (point-max) pos)))
2641 ))))
2642 2461
2643 2462
2644(defun sh-blink (blinkpos &optional msg) 2463(defun sh-blink (blinkpos &optional msg)
@@ -2649,8 +2468,7 @@ If INFO is supplied it is used, else it is calculated from current line."
2649 (goto-char blinkpos) 2468 (goto-char blinkpos)
2650 (message msg) 2469 (message msg)
2651 (sit-for blink-matching-delay)) 2470 (sit-for blink-matching-delay))
2652 (message msg) 2471 (message msg)))
2653 ))
2654 2472
2655(defun sh-show-indent (arg) 2473(defun sh-show-indent (arg)
2656 "Show the how the currently line would be indented. 2474 "Show the how the currently line would be indented.
@@ -2664,9 +2482,8 @@ we are indenting relative to, if applicable."
2664 (sh-must-support-indent) 2482 (sh-must-support-indent)
2665 (let* ((info (sh-get-indent-info)) 2483 (let* ((info (sh-get-indent-info))
2666 (var (sh-get-indent-var-for-line info)) 2484 (var (sh-get-indent-var-for-line info))
2667 val msg 2485 (curr-indent (current-indentation))
2668 (curr-indent (current-indentation)) 2486 val msg)
2669 )
2670 (if (stringp var) 2487 (if (stringp var)
2671 (message (setq msg var)) 2488 (message (setq msg var))
2672 (setq val (sh-calculate-indent info)) 2489 (setq val (sh-calculate-indent info))
@@ -2750,44 +2567,43 @@ unless optional argument ARG (the prefix when interactive) is non-nil."
2750 ival sval diff new-val 2567 ival sval diff new-val
2751 (no-symbol arg) 2568 (no-symbol arg)
2752 (curr-indent (current-indentation))) 2569 (curr-indent (current-indentation)))
2753 (cond 2570 (cond
2754 ((stringp var) 2571 ((stringp var)
2755 (message (format "Cannot learn line - %s" var))) 2572 (message (format "Cannot learn line - %s" var)))
2756 ((eq var 'sh-indent-comment) 2573 ((eq var 'sh-indent-comment)
2757 ;; This is arbitrary... 2574 ;; This is arbitrary...
2758 ;; - if curr-indent is 0, set to curr-indent 2575 ;; - if curr-indent is 0, set to curr-indent
2759 ;; - else if it has the indentation of a "normal" line, 2576 ;; - else if it has the indentation of a "normal" line,
2760 ;; then set to t 2577 ;; then set to t
2761 ;; - else set to curr-indent. 2578 ;; - else set to curr-indent.
2762 (setq sh-indent-comment 2579 (setq sh-indent-comment
2763 (if (= curr-indent 0) 2580 (if (= curr-indent 0)
2764 0 2581 0
2765 (let* ((sh-indent-comment t) 2582 (let* ((sh-indent-comment t)
2766 (val2 (sh-calculate-indent info))) 2583 (val2 (sh-calculate-indent info)))
2767 (if (= val2 curr-indent) 2584 (if (= val2 curr-indent)
2768 t 2585 t
2769 curr-indent)))) 2586 curr-indent))))
2770 (message "%s set to %s" var (symbol-value var)) 2587 (message "%s set to %s" var (symbol-value var))
2771 ) 2588 )
2772 ((numberp (setq sval (sh-var-value var))) 2589 ((numberp (setq sval (sh-var-value var)))
2773 (setq ival (sh-calculate-indent info)) 2590 (setq ival (sh-calculate-indent info))
2774 (setq diff (- curr-indent ival)) 2591 (setq diff (- curr-indent ival))
2775 2592
2776 (sh-debug "curr-indent: %d ival: %d diff: %d var:%s sval %s" 2593 (sh-debug "curr-indent: %d ival: %d diff: %d var:%s sval %s"
2777 curr-indent ival diff var sval) 2594 curr-indent ival diff var sval)
2778 (setq new-val (+ sval diff)) 2595 (setq new-val (+ sval diff))
2779;;; I commented out this because someone might want to replace 2596;;; I commented out this because someone might want to replace
2780;;; a value of `+' with the current value of sh-basic-offset 2597;;; a value of `+' with the current value of sh-basic-offset
2781;;; or vice-versa. 2598;;; or vice-versa.
2782;;; (if (= 0 diff) 2599;;; (if (= 0 diff)
2783;;; (message "No change needed!") 2600;;; (message "No change needed!")
2784 (sh-set-var-value var new-val no-symbol) 2601 (sh-set-var-value var new-val no-symbol)
2785 (message "%s set to %s" var (symbol-value var)) 2602 (message "%s set to %s" var (symbol-value var))
2786 ) 2603 )
2787 (t 2604 (t
2788 (debug) 2605 (debug)
2789 (message "Cannot change %s" var)) 2606 (message "Cannot change %s" var))))))
2790 ))))
2791 2607
2792 2608
2793 2609
@@ -2811,12 +2627,11 @@ so that `occur-next' and `occur-prev' will work."
2811 (let ((m1 (make-marker)) 2627 (let ((m1 (make-marker))
2812 (main-buffer (current-buffer)) 2628 (main-buffer (current-buffer))
2813 start 2629 start
2814 (line "") ) 2630 (line ""))
2815 (if point 2631 (when point
2816 (progn 2632 (set-marker m1 point (current-buffer))
2817 (set-marker m1 point (current-buffer)) 2633 (if add-linenum
2818 (if add-linenum 2634 (setq line (format "%d: " (1+ (count-lines 1 point))))))
2819 (setq line (format "%d: " (1+ (count-lines 1 point)))))))
2820 (save-excursion 2635 (save-excursion
2821 (if (get-buffer buffer) 2636 (if (get-buffer buffer)
2822 (set-buffer (get-buffer buffer)) 2637 (set-buffer (get-buffer buffer))
@@ -2924,9 +2739,9 @@ This command can often take a long time to run."
2924 2739
2925 (while (< (point) (point-max)) 2740 (while (< (point) (point-max))
2926 (setq linenum (1+ linenum)) 2741 (setq linenum (1+ linenum))
2927;; (if (zerop (% linenum 10)) 2742 ;; (if (zerop (% linenum 10))
2928 (message "line %d" linenum) 2743 (message "line %d" linenum)
2929;; ) 2744 ;; )
2930 (unless (looking-at "\\s-*$") ;; ignore empty lines! 2745 (unless (looking-at "\\s-*$") ;; ignore empty lines!
2931 (let* ((sh-indent-comment t) ;; info must return default indent 2746 (let* ((sh-indent-comment t) ;; info must return default indent
2932 (info (sh-get-indent-info)) 2747 (info (sh-get-indent-info))
@@ -2944,7 +2759,7 @@ This command can often take a long time to run."
2944 (setq diff (- curr-indent ival)) 2759 (setq diff (- curr-indent ival))
2945 (setq new-val (+ sval diff)) 2760 (setq new-val (+ sval diff))
2946 (sh-set-var-value var new-val 'no-symbol) 2761 (sh-set-var-value var new-val 'no-symbol)
2947 (unless (looking-at "\\s-*#");; don't learn from comments 2762 (unless (looking-at "\\s-*#") ;; don't learn from comments
2948 (if (setq previous-set-info (assoc var learned-var-list)) 2763 (if (setq previous-set-info (assoc var learned-var-list))
2949 (progn 2764 (progn
2950 ;; it was already there, is it same value ? 2765 ;; it was already there, is it same value ?
@@ -2981,16 +2796,16 @@ This command can often take a long time to run."
2981 (unless (= curr-indent (sh-calculate-indent info)) 2796 (unless (= curr-indent (sh-calculate-indent info))
2982 ;; this is not the default indentation 2797 ;; this is not the default indentation
2983 (setq comments-always-default nil) 2798 (setq comments-always-default nil)
2984 (if comment-col;; then we have see one before 2799 (if comment-col ;; then we have see one before
2985 (or (eq comment-col curr-indent) 2800 (or (eq comment-col curr-indent)
2986 (setq comment-col t));; seen a different one 2801 (setq comment-col t)) ;; seen a different one
2987 (setq comment-col curr-indent)) 2802 (setq comment-col curr-indent))
2988 )) 2803 ))
2989 (t 2804 (t
2990 (sh-debug "Cannot learn this line!!!") 2805 (sh-debug "Cannot learn this line!!!")
2991 )) 2806 ))
2992 (sh-debug 2807 (sh-debug
2993 "at %s learned-var-list is %s" (point) learned-var-list) 2808 "at %s learned-var-list is %s" (point) learned-var-list)
2994 )) 2809 ))
2995 (forward-line 1) 2810 (forward-line 1)
2996 ) ;; while 2811 ) ;; while
@@ -3056,54 +2871,42 @@ This command can often take a long time to run."
3056 2871
3057 (setq learned-var-list 2872 (setq learned-var-list
3058 (append (list (list 'sh-indent-comment comment-col (point-max))) 2873 (append (list (list 'sh-indent-comment comment-col (point-max)))
3059 learned-var-list)) 2874 learned-var-list))
3060 (setq sh-indent-comment comment-col) 2875 (setq sh-indent-comment comment-col)
3061 (let ((name (buffer-name)) 2876 (let ((name (buffer-name))
3062 (lines (if (and (eq (point-min) 1) 2877 (lines (if (and (eq (point-min) 1)
3063 (eq (point-max) (1+ (buffer-size)))) 2878 (eq (point-max) (1+ (buffer-size))))
3064 "" 2879 ""
3065 (format "lines %d to %d of " 2880 (format "lines %d to %d of "
3066 (1+ (count-lines 1 (point-min))) 2881 (1+ (count-lines 1 (point-min)))
3067 (1+ (count-lines 1 (point-max)))))) 2882 (1+ (count-lines 1 (point-max))))))
3068 ) 2883 )
3069 (sh-mark-line "\nLearned variable settings:" nil out-buffer) 2884 (sh-mark-line "\nLearned variable settings:" nil out-buffer)
3070 (if arg 2885 (if arg
3071 ;; Set learned variables to symbolic rather than numeric 2886 ;; Set learned variables to symbolic rather than numeric
3072 ;; values where possible. 2887 ;; values where possible.
3073 (progn 2888 (dolist (learned-var (reverse learned-var-list))
3074 (let ((p (reverse learned-var-list)) 2889 (let ((var (car learned-var))
3075 var val) 2890 (val (nth 1 learned-var)))
3076 (while p 2891 (when (and (not (eq var 'sh-basic-offset))
3077 (setq var (car (car p))) 2892 (numberp val))
3078 (setq val (nth 1 (car p))) 2893 (sh-set-var-value var val)))))
3079 (cond 2894 (dolist (learned-var (reverse learned-var-list))
3080 ((eq var 'sh-basic-offset) 2895 (let ((var (car learned-var)))
3081 )
3082 ((numberp val)
3083 (sh-set-var-value var val))
3084 (t
3085 ))
3086 (setq p (cdr p))
3087 ))))
3088 (let ((p (reverse learned-var-list))
3089 var)
3090 (while p
3091 (setq var (car (car p)))
3092 (sh-mark-line (format " %s %s" var (symbol-value var)) 2896 (sh-mark-line (format " %s %s" var (symbol-value var))
3093 (nth 2 (car p)) out-buffer) 2897 (nth 2 learned-var) out-buffer)))
3094 (setq p (cdr p))))
3095 (save-excursion 2898 (save-excursion
3096 (set-buffer out-buffer) 2899 (set-buffer out-buffer)
3097 (goto-char (point-min)) 2900 (goto-char (point-min))
3098 (insert 2901 (insert
3099 (format "Indentation values for buffer %s.\n" name) 2902 (format "Indentation values for buffer %s.\n" name)
3100 (format "%d indentation variable%s different values%s\n\n" 2903 (format "%d indentation variable%s different values%s\n\n"
3101 num-diffs 2904 num-diffs
3102 (if (= num-diffs 1) 2905 (if (= num-diffs 1)
3103 " has" "s have") 2906 " has" "s have")
3104 (if (zerop num-diffs) 2907 (if (zerop num-diffs)
3105 "." ":")) 2908 "." ":"))
3106 ))) 2909 )))
3107 ;; Are abnormal hooks considered bad form? 2910 ;; Are abnormal hooks considered bad form?
3108 (run-hook-with-args 'sh-learned-buffer-hook learned-var-list) 2911 (run-hook-with-args 'sh-learned-buffer-hook learned-var-list)
3109 (if (or sh-popup-occur-buffer (> num-diffs 0)) 2912 (if (or sh-popup-occur-buffer (> num-diffs 0))
@@ -3121,10 +2924,10 @@ Return values:
3121 reasonable choices 2924 reasonable choices
3122 nil - we couldn't find a reasonable one." 2925 nil - we couldn't find a reasonable one."
3123 (let* ((max (1- (length vec))) 2926 (let* ((max (1- (length vec)))
3124 (i 1) 2927 (i 1)
3125 (totals (make-vector max 0)) 2928 (totals (make-vector max 0))
3126 (return nil) 2929 (return nil)
3127 j) 2930 j)
3128 (while (< i max) 2931 (while (< i max)
3129 (aset totals i (+ (aref totals i) (* 4 (aref vec i)))) 2932 (aset totals i (+ (aref totals i) (* 4 (aref vec i))))
3130 (setq j (/ i 2)) 2933 (setq j (/ i 2))
@@ -3132,8 +2935,8 @@ Return values:
3132 (aset totals i (+ (aref totals i) (aref vec (/ i 2))))) 2935 (aset totals i (+ (aref totals i) (aref vec (/ i 2)))))
3133 (if (< (* i 2) max) 2936 (if (< (* i 2) max)
3134 (aset totals i (+ (aref totals i) (aref vec (* i 2))))) 2937 (aset totals i (+ (aref totals i) (aref vec (* i 2)))))
3135 (setq i (1+ i)) 2938 (setq i (1+ i)))
3136 ) 2939
3137 (let ((x nil) 2940 (let ((x nil)
3138 (result nil) 2941 (result nil)
3139 tot sum p) 2942 tot sum p)
@@ -3143,17 +2946,16 @@ Return values:
3143 (setq x (append x (list (cons i (aref totals i)))))) 2946 (setq x (append x (list (cons i (aref totals i))))))
3144 (setq i (1+ i))) 2947 (setq i (1+ i)))
3145 2948
3146 (setq x (sort x (lambda (a b) 2949 (setq x (sort x (lambda (a b) (> (cdr a) (cdr b)))))
3147 (> (cdr a)(cdr b)))))
3148 (setq tot (apply '+ (append totals nil))) 2950 (setq tot (apply '+ (append totals nil)))
3149 (sh-debug (format "vec: %s\ntotals: %s\ntot: %d" 2951 (sh-debug (format "vec: %s\ntotals: %s\ntot: %d"
3150 vec totals tot)) 2952 vec totals tot))
3151 (cond 2953 (cond
3152 ((zerop (length x)) 2954 ((zerop (length x))
3153 (message "no values!")) ;; we return nil 2955 (message "no values!")) ;; we return nil
3154 ((= (length x) 1) 2956 ((= (length x) 1)
3155 (message "only value is %d" (car (car x))) 2957 (message "only value is %d" (car (car x)))
3156 (setq result (car (car x)))) ;; return single value 2958 (setq result (car (car x)))) ;; return single value
3157 ((> (cdr (car x)) (/ tot 2)) 2959 ((> (cdr (car x)) (/ tot 2))
3158 ;; 1st is > 50% 2960 ;; 1st is > 50%
3159 (message "basic-offset is probably %d" (car (car x))) 2961 (message "basic-offset is probably %d" (car (car x)))
@@ -3180,12 +2982,6 @@ Return values:
3180 ))) 2982 )))
3181 2983
3182 2984
3183(defun sh-do-nothing (a b c)
3184 ;; checkdoc-params: (a b c)
3185 "A dummy function to prevent font-lock from re-fontifying a change.
3186Otherwise, we fontify something and font-lock overwrites it."
3187 )
3188
3189;; The default font-lock-unfontify-region-function removes 2985;; The default font-lock-unfontify-region-function removes
3190;; syntax-table properties, and so removes our information. 2986;; syntax-table properties, and so removes our information.
3191(defun sh-font-lock-unfontify-region-function (beg end) 2987(defun sh-font-lock-unfontify-region-function (beg end)
@@ -3201,7 +2997,7 @@ Otherwise, we fontify something and font-lock overwrites it."
3201 "Set the character's syntax table property at WHERE to be NEW-PROP." 2997 "Set the character's syntax table property at WHERE to be NEW-PROP."
3202 (or where 2998 (or where
3203 (setq where (point))) 2999 (setq where (point)))
3204 (let ((font-lock-fontify-region-function 'sh-do-nothing)) 3000 (let ((inhibit-modification-hooks t))
3205 (put-text-property where (1+ where) 'syntax-table new-prop) 3001 (put-text-property where (1+ where) 'syntax-table new-prop)
3206 (add-text-properties where (1+ where) 3002 (add-text-properties where (1+ where)
3207 '(face sh-st-face rear-nonsticky t)) 3003 '(face sh-st-face rear-nonsticky t))
@@ -3275,7 +3071,7 @@ Argument ARG if non-nil disables this test."
3275 ;; That way sexp movement doens't worry about any parentheses. 3071 ;; That way sexp movement doens't worry about any parentheses.
3276 ;; A disadvantage of this is we can't use forward-word within a 3072 ;; A disadvantage of this is we can't use forward-word within a
3277 ;; here-doc, which is annoying. 3073 ;; here-doc, which is annoying.
3278 (let ((font-lock-fontify-region-function 'sh-do-nothing)) 3074 (let ((inhibit-modification-hooks t))
3279 (put-text-property start end 'syntax-table sh-here-doc-syntax) 3075 (put-text-property start end 'syntax-table sh-here-doc-syntax)
3280 (put-text-property start end 'face 'sh-heredoc-face) 3076 (put-text-property start end 'face 'sh-heredoc-face)
3281 (put-text-property (1- end) end 'rear-nonsticky t) 3077 (put-text-property (1- end) end 'rear-nonsticky t)
@@ -3532,24 +3328,18 @@ overwritten if
3532 (list 3328 (list
3533 (read-from-minibuffer "Name for this style? " ) 3329 (read-from-minibuffer "Name for this style? " )
3534 (not current-prefix-arg))) 3330 (not current-prefix-arg)))
3535 (let ((slist (list name)) 3331 (let ((slist (cons name
3536 (p sh-var-list) 3332 (mapcar (lambda (var) (cons var (symbol-value var)))
3537 var style) 3333 sh-var-list)))
3538 (while p 3334 (style (assoc name sh-styles-alist)))
3539 (setq var (car p)) 3335 (if style
3540 (setq slist (append slist (list (cons var (symbol-value var))))) 3336 (if (and confirm-overwrite
3541 (setq p (cdr p))) 3337 (not (y-or-n-p "This style exists. Overwrite it? ")))
3542 (if (setq style (assoc name sh-styles-alist)) 3338 (message "Not changing style %s" name)
3543 (if (or (not confirm-overwrite) 3339 (message "Updating style %s" name)
3544 (y-or-n-p "This style exists. Overwrite it? ")) 3340 (setcdr style (cdr slist)))
3545 (progn
3546 (message "Updating style %s" name)
3547 (setcdr style (cdr slist)))
3548 (message "Not changing style %s" name))
3549 (message "Creating new style %s" name) 3341 (message "Creating new style %s" name)
3550 (setq sh-styles-alist (append sh-styles-alist 3342 (push slist sh-styles-alist))))
3551 (list slist)))
3552 )))
3553 3343
3554(defun sh-load-style (name) 3344(defun sh-load-style (name)
3555 "Set shell indentation values for this buffer from those in style NAME." 3345 "Set shell indentation values for this buffer from those in style NAME."
@@ -3559,37 +3349,18 @@ overwritten if
3559 (let ((sl (assoc name sh-styles-alist))) 3349 (let ((sl (assoc name sh-styles-alist)))
3560 (if (null sl) 3350 (if (null sl)
3561 (error "sh-load-style - style %s not known" name) 3351 (error "sh-load-style - style %s not known" name)
3562 (setq sl (cdr sl)) 3352 (dolist (var (cdr sl))
3563 (while sl 3353 (set (car var) (cdr var))))))
3564 (set (car (car sl)) (cdr (car sl)))
3565 (setq sl (cdr sl))
3566 ))))
3567 3354
3568(defun sh-save-styles-to-buffer (buff) 3355(defun sh-save-styles-to-buffer (buff)
3569 "Save all current styles in elisp to buffer BUFF. 3356 "Save all current styles in elisp to buffer BUFF.
3570This is always added to the end of the buffer." 3357This is always added to the end of the buffer."
3571 (interactive (list 3358 (interactive (list
3572 (read-from-minibuffer "Buffer to save styles in? " "*scratch*"))) 3359 (read-from-minibuffer "Buffer to save styles in? " "*scratch*")))
3573 ;; This is an attempt to sort of pretty print it... 3360 (with-current-buffer (get-buffer-create buff)
3574 (save-excursion
3575 (set-buffer (get-buffer-create buff))
3576 (goto-char (point-max)) 3361 (goto-char (point-max))
3577 (insert "\n") 3362 (insert "\n")
3578 (let ((p sh-styles-alist) q) 3363 (pp `(setq sh-styles-alist ',sh-styles-alist) (current-buffer))))
3579 (insert "(setq sh-styles-alist '(\n")
3580 (while p
3581 (setq q (car p))
3582 (insert " ( " (prin1-to-string (car q)) "\n")
3583 (setq q (cdr q))
3584 (while q
3585 (insert " "(prin1-to-string (car q)) "\n")
3586 (setq q (cdr q)))
3587 (insert " )\n")
3588 (setq p (cdr p))
3589 )
3590 (insert "))\n")
3591 )))
3592
3593 3364
3594 3365
3595 3366
@@ -3624,19 +3395,19 @@ This is always added to the end of the buffer."
3624 "case *" > \n 3395 "case *" > \n
3625 > _ \n 3396 > _ \n
3626 resume: 3397 resume:
3627 ?} > ) 3398 ?} > )
3628 (sh "expression: " 3399 (sh "expression: "
3629 > "case " str " in" \n 3400 > "case " str " in" \n
3630 > (read-string "pattern: ") 3401 > (read-string "pattern: ")
3631 '(sh-electric-rparen) 3402 (propertize ")" 'syntax-table sh-st-punc)
3632 \n 3403 \n
3633 > _ \n 3404 > _ \n
3634 ";;" \n 3405 ";;" \n
3635 ( "other pattern, %s: " 3406 ( "other pattern, %s: "
3636 > str '(sh-electric-rparen) \n 3407 > str (propertize ")" 'syntax-table sh-st-punc) \n
3637 > _ \n 3408 > _ \n
3638 ";;" \n) 3409 ";;" \n)
3639 > "*" '(sh-electric-rparen) \n 3410 > "*" (propertize ")" 'syntax-table sh-st-punc) \n
3640 > _ \n 3411 > _ \n
3641 resume: 3412 resume:
3642 "esac" > )) 3413 "esac" > ))
@@ -3695,7 +3466,7 @@ This is always added to the end of the buffer."
3695 (read-string "upper limit: ") 3466 (read-string "upper limit: ")
3696 "; i++ ) print i }'`}) {" \n 3467 "; i++ ) print i }'`}) {" \n
3697 > _ ?$ (sh-remember-variable str) \n 3468 > _ ?$ (sh-remember-variable str) \n
3698 ?} >) 3469 ?} >)
3699 (sh "Index variable: " 3470 (sh "Index variable: "
3700 > "for " str " in `awk 'BEGIN { for( i=1; i<=" 3471 > "for " str " in `awk 'BEGIN { for( i=1; i<="
3701 (read-string "upper limit: ") 3472 (read-string "upper limit: ")
@@ -3780,7 +3551,7 @@ t means to return a list of all possible completions of STRING.
3780 > _ \n 3551 > _ \n
3781 < "}") 3552 < "}")
3782 (rc eval sh-modify ksh88 3553 (rc eval sh-modify ksh88
3783 1 "fn ") 3554 1 "fn ")
3784 (sh () 3555 (sh ()
3785 "() {" \n 3556 "() {" \n
3786 > _ \n 3557 > _ \n
@@ -3801,34 +3572,34 @@ t means to return a list of all possible completions of STRING.
3801 resume: 3572 resume:
3802 < "endif") 3573 < "endif")
3803 (es "condition: " 3574 (es "condition: "
3804 > "if { " str " } {" \n 3575 > "if { " str " } {" \n
3805 > _ \n 3576 > _ \n
3806 ( "other condition, %s: " 3577 ( "other condition, %s: "
3807 "} { " str " } {" > \n 3578 "} { " str " } {" > \n
3808 > _ \n) 3579 > _ \n)
3809 "} {" > \n 3580 "} {" > \n
3810 > _ \n 3581 > _ \n
3811 resume: 3582 resume:
3812 ?} > ) 3583 ?} > )
3813 (rc "condition: " 3584 (rc "condition: "
3814 > "if( " str " ) {" \n 3585 > "if( " str " ) {" \n
3815 > _ \n 3586 > _ \n
3816 ( "other condition, %s: " 3587 ( "other condition, %s: "
3817 "} else if( " str " ) {" > \n 3588 "} else if( " str " ) {" > \n
3818 > _ \n) 3589 > _ \n)
3819 "} else {" > \n 3590 "} else {" > \n
3820 > _ \n 3591 > _ \n
3821 resume: 3592 resume:
3822 ?} > 3593 ?} >
3823 ) 3594 )
3824 (sh "condition: " 3595 (sh "condition: "
3825 '(setq input (sh-feature sh-test)) 3596 '(setq input (sh-feature sh-test))
3826 > "if " str "; then" \n 3597 > "if " str "; then" \n
3827 > _ \n 3598 > _ \n
3828 ( "other condition, %s: " 3599 ( "other condition, %s: "
3829 > "elif " str "; then" > \n 3600 > "elif " str "; then" > \n
3830 > \n) 3601 > \n)
3831 "else" > \n 3602 "else" > \n
3832 > \n 3603 > \n
3833 resume: 3604 resume:
3834 "fi" > )) 3605 "fi" > ))
@@ -3840,10 +3611,10 @@ t means to return a list of all possible completions of STRING.
3840 (es nil 3611 (es nil
3841 > "forever {" \n 3612 > "forever {" \n
3842 > _ \n 3613 > _ \n
3843 ?} > ) 3614 ?} > )
3844 (zsh "factor: " 3615 (zsh "factor: "
3845 > "repeat " str "; do" > \n 3616 > "repeat " str "; do" > \n
3846 > \n 3617 > \n
3847 "done" > )) 3618 "done" > ))
3848 3619
3849;;;(put 'sh-repeat 'menu-enable '(sh-feature sh-repeat)) 3620;;;(put 'sh-repeat 'menu-enable '(sh-feature sh-repeat))
@@ -3880,14 +3651,14 @@ t means to return a list of all possible completions of STRING.
3880 > "rm $tmp^* >[2]/dev/null" \n 3651 > "rm $tmp^* >[2]/dev/null" \n
3881 "throw $e" \n 3652 "throw $e" \n
3882 "} {" > \n 3653 "} {" > \n
3883 _ \n 3654 _ \n
3884 ?} > \n 3655 ?} > \n
3885 ?} > ) 3656 ?} > )
3886 (ksh88 eval sh-modify sh 3657 (ksh88 eval sh-modify sh
3887 7 "EXIT") 3658 7 "EXIT")
3888 (rc (file-name-nondirectory (buffer-file-name)) 3659 (rc (file-name-nondirectory (buffer-file-name))
3889 > "tmp = /tmp/" str ".$pid" \n 3660 > "tmp = /tmp/" str ".$pid" \n
3890 "fn sigexit { rm $tmp^* >[2]/dev/null }") 3661 "fn sigexit { rm $tmp^* >[2]/dev/null }")
3891 (sh (file-name-nondirectory (buffer-file-name)) 3662 (sh (file-name-nondirectory (buffer-file-name))
3892 > "TMP=${TMPDIR:-/tmp}/" str ".$$" \n 3663 > "TMP=${TMPDIR:-/tmp}/" str ".$$" \n
3893 "trap \"rm $TMP* 2>/dev/null\" " ?0)) 3664 "trap \"rm $TMP* 2>/dev/null\" " ?0))
@@ -3900,7 +3671,7 @@ t means to return a list of all possible completions of STRING.
3900 '(setq input (sh-feature sh-test)) 3671 '(setq input (sh-feature sh-test))
3901 > "until " str "; do" \n 3672 > "until " str "; do" \n
3902 > _ \n 3673 > _ \n
3903 "done" > )) 3674 "done" > ))
3904;;;(put 'sh-until 'menu-enable '(sh-feature sh-until)) 3675;;;(put 'sh-until 'menu-enable '(sh-feature sh-until))
3905 3676
3906 3677
@@ -3974,10 +3745,10 @@ option followed by a colon `:' if the option accepts an argument."
3974 v2 "\"$OPTARG\"") 3745 v2 "\"$OPTARG\"")
3975 (setq v1 (cdr v1) 3746 (setq v1 (cdr v1)
3976 v2 nil))) 3747 v2 nil)))
3977 > str "|+" str '(sh-electric-rparen) \n 3748 > str "|+" str (propertize ")" 'syntax-table sh-st-punc) \n
3978 > _ v2 \n 3749 > _ v2 \n
3979 > ";;" \n) 3750 > ";;" \n)
3980 > "*" '(sh-electric-rparen) \n 3751 > "*" (propertize ")" 'syntax-table sh-st-punc) \n
3981 > "echo" " \"usage: " "`basename $0`" 3752 > "echo" " \"usage: " "`basename $0`"
3982 " [+-" '(setq v1 (point)) str 3753 " [+-" '(setq v1 (point)) str
3983 '(save-excursion 3754 '(save-excursion
@@ -3987,9 +3758,9 @@ option followed by a colon `:' if the option accepts an argument."
3987 (if (and (sequencep v1) (length v1)) "] " "} ") 3758 (if (and (sequencep v1) (length v1)) "] " "} ")
3988 "[--] ARGS...\"" \n 3759 "[--] ARGS...\"" \n
3989 "exit 2" > \n 3760 "exit 2" > \n
3990 "esac" > 3761 "esac" >
3991 \n "done" 3762 \n "done"
3992 > \n 3763 > \n
3993 "shift " (sh-add "OPTIND" -1))) 3764 "shift " (sh-add "OPTIND" -1)))
3994 3765
3995 3766
@@ -4010,7 +3781,7 @@ option followed by a colon `:' if the option accepts an argument."
4010 3781
4011 3782
4012(defun sh-maybe-here-document (arg) 3783(defun sh-maybe-here-document (arg)
4013 "Inserts self. Without prefix, following unquoted `<' inserts here document. 3784 "Insert self. Without prefix, following unquoted `<' inserts here document.
4014The document is bounded by `sh-here-document-word'." 3785The document is bounded by `sh-here-document-word'."
4015 (interactive "*P") 3786 (interactive "*P")
4016 (self-insert-command (prefix-numeric-value arg)) 3787 (self-insert-command (prefix-numeric-value arg))