diff options
| author | Stefan Monnier | 2001-10-13 19:08:30 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2001-10-13 19:08:30 +0000 |
| commit | 3e2dd647b766091c075b6a49be0ca36b0f80f5d6 (patch) | |
| tree | 0d80b722fe94936072d290d2e0ac8f1554e59770 | |
| parent | 71f343138c2c459e02f23908a79083fb0478a9e9 (diff) | |
| download | emacs-3e2dd647b766091c075b6a49be0ca36b0f80f5d6.tar.gz emacs-3e2dd647b766091c075b6a49be0ca36b0f80f5d6.zip | |
(sh-font-lock-syntactic-keywords): Handle here-docs differently.
(sh-font-lock-heredoc): Remove.
(sh-here-doc-open-re, sh-here-doc-markers, sh-here-doc-re): New vars.
(sh-font-lock-here-doc, sh-font-lock-close-heredoc)
(sh-font-lock-open-heredoc): New functions.
(sh-mode): Don't copy sh-font-lock-syntactic-keywords any more.
(sh-font-lock-keywords-1): Use regexp-opt.
(sh-in-comment-or-string): Use syntax-ppss.
(sh-case, sh-for, sh-indexed-loop, sh-function, sh-if, sh-repeat)
(sh-select, sh-tmp-file): Add explicit terminating \n.
| -rw-r--r-- | lisp/progmodes/sh-script.el | 330 |
1 files changed, 182 insertions, 148 deletions
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 6755fe0e8de..9392c3da2d8 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el | |||
| @@ -236,8 +236,8 @@ By default we have the following three hierarchies: | |||
| 236 | 236 | ||
| 237 | csh C Shell | 237 | csh C Shell |
| 238 | jcsh C Shell with Job Control | 238 | jcsh C Shell with Job Control |
| 239 | tcsh Toronto C Shell | 239 | tcsh Turbo C Shell |
| 240 | itcsh ? Toronto C Shell | 240 | itcsh ? Turbo C Shell |
| 241 | rc Plan 9 Shell | 241 | rc Plan 9 Shell |
| 242 | es Extensible Shell | 242 | es Extensible Shell |
| 243 | sh Bourne Shell | 243 | sh Bourne Shell |
| @@ -354,39 +354,39 @@ the car and cdr are the same symbol.") | |||
| 354 | (defvar sh-shell (sh-canonicalize-shell (file-name-nondirectory sh-shell-file)) | 354 | (defvar sh-shell (sh-canonicalize-shell (file-name-nondirectory sh-shell-file)) |
| 355 | "The shell being programmed. This is set by \\[sh-set-shell].") | 355 | "The shell being programmed. This is set by \\[sh-set-shell].") |
| 356 | 356 | ||
| 357 | ;;; I turned off this feature because it doesn't permit typing commands | 357 | ;; I turned off this feature because it doesn't permit typing commands |
| 358 | ;;; in the usual way without help. | 358 | ;; in the usual way without help. |
| 359 | ;;;(defvar sh-abbrevs | 359 | ;;(defvar sh-abbrevs |
| 360 | ;;; '((csh eval sh-abbrevs shell | 360 | ;; '((csh eval sh-abbrevs shell |
| 361 | ;;; "switch" 'sh-case | 361 | ;; "switch" 'sh-case |
| 362 | ;;; "getopts" 'sh-while-getopts) | 362 | ;; "getopts" 'sh-while-getopts) |
| 363 | 363 | ||
| 364 | ;;; (es eval sh-abbrevs shell | 364 | ;; (es eval sh-abbrevs shell |
| 365 | ;;; "function" 'sh-function) | 365 | ;; "function" 'sh-function) |
| 366 | 366 | ||
| 367 | ;;; (ksh88 eval sh-abbrevs sh | 367 | ;; (ksh88 eval sh-abbrevs sh |
| 368 | ;;; "select" 'sh-select) | 368 | ;; "select" 'sh-select) |
| 369 | 369 | ||
| 370 | ;;; (rc eval sh-abbrevs shell | 370 | ;; (rc eval sh-abbrevs shell |
| 371 | ;;; "case" 'sh-case | 371 | ;; "case" 'sh-case |
| 372 | ;;; "function" 'sh-function) | 372 | ;; "function" 'sh-function) |
| 373 | 373 | ||
| 374 | ;;; (sh eval sh-abbrevs shell | 374 | ;; (sh eval sh-abbrevs shell |
| 375 | ;;; "case" 'sh-case | 375 | ;; "case" 'sh-case |
| 376 | ;;; "function" 'sh-function | 376 | ;; "function" 'sh-function |
| 377 | ;;; "until" 'sh-until | 377 | ;; "until" 'sh-until |
| 378 | ;;; "getopts" 'sh-while-getopts) | 378 | ;; "getopts" 'sh-while-getopts) |
| 379 | 379 | ||
| 380 | ;;; ;; The next entry is only used for defining the others | 380 | ;; ;; The next entry is only used for defining the others |
| 381 | ;;; (shell "for" sh-for | 381 | ;; (shell "for" sh-for |
| 382 | ;;; "loop" sh-indexed-loop | 382 | ;; "loop" sh-indexed-loop |
| 383 | ;;; "if" sh-if | 383 | ;; "if" sh-if |
| 384 | ;;; "tmpfile" sh-tmp-file | 384 | ;; "tmpfile" sh-tmp-file |
| 385 | ;;; "while" sh-while) | 385 | ;; "while" sh-while) |
| 386 | 386 | ||
| 387 | ;;; (zsh eval sh-abbrevs ksh88 | 387 | ;; (zsh eval sh-abbrevs ksh88 |
| 388 | ;;; "repeat" 'sh-repeat)) | 388 | ;; "repeat" 'sh-repeat)) |
| 389 | ;;; "Abbrev-table used in Shell-Script mode. See `sh-feature'. | 389 | ;; "Abbrev-table used in Shell-Script mode. See `sh-feature'. |
| 390 | ;;;Due to the internal workings of abbrev tables, the shell name symbol is | 390 | ;;;Due to the internal workings of abbrev tables, the shell name symbol is |
| 391 | ;;;actually defined as the table for the like of \\[edit-abbrevs].") | 391 | ;;;actually defined as the table for the like of \\[edit-abbrevs].") |
| 392 | 392 | ||
| @@ -758,7 +758,7 @@ See `sh-feature'." | |||
| 758 | See `sh-feature'.") | 758 | See `sh-feature'.") |
| 759 | 759 | ||
| 760 | 760 | ||
| 761 | ;;; Font-Lock support | 761 | ;; Font-Lock support |
| 762 | 762 | ||
| 763 | (defface sh-heredoc-face | 763 | (defface sh-heredoc-face |
| 764 | '((((class color) | 764 | '((((class color) |
| @@ -818,36 +818,76 @@ See `sh-feature'.") | |||
| 818 | (defconst sh-st-symbol (string-to-syntax "_")) | 818 | (defconst sh-st-symbol (string-to-syntax "_")) |
| 819 | (defconst sh-here-doc-syntax (string-to-syntax "|")) ;; generic string | 819 | (defconst sh-here-doc-syntax (string-to-syntax "|")) ;; generic string |
| 820 | 820 | ||
| 821 | (defun sh-font-lock-heredoc (start string quoted) | 821 | (defconst sh-here-doc-open-re "<<-?\\s-*\\\\?\\(\\(?:['\"][^'\"]+['\"]\\|\\sw\\|\\s_\\)+\\).*\\(\n\\)") |
| 822 | "Determine the syntax of the \\n after a <<HEREDOC." | 822 | |
| 823 | (unless (sh-in-comment-or-string start) | 823 | (defvar sh-here-doc-markers nil) |
| 824 | (make-variable-buffer-local 'sh-here-doc-markers) | ||
| 825 | (defvar sh-here-doc-re sh-here-doc-open-re) | ||
| 826 | (make-variable-buffer-local 'sh-here-doc-re) | ||
| 827 | |||
| 828 | (defun sh-font-lock-close-heredoc (bol eof indented) | ||
| 829 | "Determine the syntax of the \\n after an EOF. | ||
| 830 | If non-nil INDENTED indicates that the EOF was indented." | ||
| 831 | (let* (;; A rough regexp that should find the opening <<EOF back. | ||
| 832 | (sre (concat "<<\\(-?\\)\\s-*['\"\\]?" | ||
| 833 | ;; Use \s| to cheaply check it's an open-heredoc. | ||
| 834 | (regexp-quote eof) "['\"]?\\([ \t|;&)<>].*\\)?\\s|")) | ||
| 835 | ;; A regexp that will find other EOFs. | ||
| 836 | (ere (concat "^" (if indented "[ \t]*") (regexp-quote eof) "\n")) | ||
| 837 | (start (save-excursion | ||
| 838 | (goto-char bol) | ||
| 839 | (re-search-backward (concat sre "\\|" ere) nil t)))) | ||
| 840 | ;; If subgroup 1 matched, we found an open-heredoc, otherwise we first | ||
| 841 | ;; found a close-heredoc which makes the current close-heredoc inoperant. | ||
| 842 | (cond | ||
| 843 | ((when (and start (match-end 1) | ||
| 844 | (not (and indented (= (match-beginning 1) (match-end 1)))) | ||
| 845 | (not (sh-in-comment-or-string (match-beginning 0)))) | ||
| 846 | ;; Make sure our `<<' is not the EOF1 of a `cat <<EOF1 <<EOF2'. | ||
| 847 | (save-excursion | ||
| 848 | (goto-char start) | ||
| 849 | (setq start (line-beginning-position 2)) | ||
| 850 | (while | ||
| 851 | (progn | ||
| 852 | (re-search-forward "<<") ; Skip ourselves. | ||
| 853 | (and (re-search-forward sh-here-doc-open-re start 'move) | ||
| 854 | (goto-char (match-beginning 0)) | ||
| 855 | (sh-in-comment-or-string (point))))) | ||
| 856 | ;; No <<EOF2 found after our <<. | ||
| 857 | (= (point) start))) | ||
| 858 | sh-here-doc-syntax) | ||
| 859 | ((not (or start (save-excursion (re-search-forward sre nil t)))) | ||
| 860 | ;; There's no <<EOF either before or after us, | ||
| 861 | ;; so we should remove ourselves from font-lock's keywords. | ||
| 862 | (setq sh-here-doc-markers (delete eof sh-here-doc-markers)) | ||
| 863 | (setq sh-here-doc-re | ||
| 864 | (concat sh-here-doc-open-re "\\|^\\([ \t]*\\)" | ||
| 865 | (regexp-opt sh-here-doc-markers t) "\\(\n\\)")) | ||
| 866 | nil)))) | ||
| 867 | |||
| 868 | (defun sh-font-lock-open-heredoc (start string) | ||
| 869 | "Determine the syntax of the \\n after a <<EOF. | ||
| 870 | START is the position of <<. | ||
| 871 | STRING is the actual word used as delimiter (f.ex. \"EOF\"). | ||
| 872 | INDENTED is non-nil if the here document's content (and the EOF mark) can | ||
| 873 | be indented (i.e. a <<- was used rather than just <<)." | ||
| 874 | (unless (or (memq (char-before start) '(?< ?>)) | ||
| 875 | (sh-in-comment-or-string start)) | ||
| 824 | ;; We're looking at <<STRING, so we add "^STRING$" to the syntactic | 876 | ;; We're looking at <<STRING, so we add "^STRING$" to the syntactic |
| 825 | ;; font-lock keywords to detect the end of this here document. | 877 | ;; font-lock keywords to detect the end of this here document. |
| 826 | (let ((ere (concat | 878 | (let ((str (replace-regexp-in-string "['\"]" "" string))) |
| 827 | "^" (if quoted "[ \t]*") | 879 | (unless (member str sh-here-doc-markers) |
| 828 | (regexp-quote (replace-regexp-in-string "['\"]" "" string)) | 880 | (push str sh-here-doc-markers) |
| 829 | "\\(\n\\)"))) | 881 | (setq sh-here-doc-re |
| 830 | (unless (assoc ere font-lock-syntactic-keywords) | 882 | (concat sh-here-doc-open-re "\\|^\\([ \t]*\\)" |
| 831 | (let* ( ;; A rough regexp that should find us back. | 883 | (regexp-opt sh-here-doc-markers t) "\\(\n\\)")))) |
| 832 | (sre (concat "<<\\(-\\)?\\s-*\\\\?['\"]?" | ||
| 833 | (regexp-quote string) "['\"]?[ \t\n]")) | ||
| 834 | (code `(cond | ||
| 835 | ((save-excursion (re-search-backward ,sre nil t)) | ||
| 836 | ;; This ^STRING$ is indeed following a <<STRING | ||
| 837 | sh-here-doc-syntax) | ||
| 838 | ((not (save-excursion (re-search-forward ,sre nil t))) | ||
| 839 | ;; There's no <<STRING either before or after us, | ||
| 840 | ;; so we should remove this now obsolete entry. | ||
| 841 | (setq font-lock-syntactic-keywords | ||
| 842 | (delq (assoc ,ere font-lock-syntactic-keywords) | ||
| 843 | font-lock-syntactic-keywords)) | ||
| 844 | nil)))) | ||
| 845 | ;; Use destructive update so the new keyword gets used right away. | ||
| 846 | (setq font-lock-syntactic-keywords | ||
| 847 | (nconc font-lock-syntactic-keywords | ||
| 848 | (list (font-lock-compile-keyword `(,ere 1 ,code)))))))) | ||
| 849 | sh-here-doc-syntax)) | 884 | sh-here-doc-syntax)) |
| 850 | 885 | ||
| 886 | (defun sh-font-lock-here-doc (limit) | ||
| 887 | "Search for a heredoc marker." | ||
| 888 | ;; This looks silly, but it's because `sh-here-doc-re' keeps changing. | ||
| 889 | (re-search-forward sh-here-doc-re limit t)) | ||
| 890 | |||
| 851 | (defun sh-font-lock-paren (start) | 891 | (defun sh-font-lock-paren (start) |
| 852 | (save-excursion | 892 | (save-excursion |
| 853 | (goto-char start) | 893 | (goto-char start) |
| @@ -875,9 +915,12 @@ See `sh-feature'.") | |||
| 875 | ;; of the shell command language (under `quoting') but with `$' removed. | 915 | ;; of the shell command language (under `quoting') but with `$' removed. |
| 876 | `(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 ,sh-st-symbol) | 916 | `(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 ,sh-st-symbol) |
| 877 | ;; Find HEREDOC starters and add a corresponding rule for the ender. | 917 | ;; Find HEREDOC starters and add a corresponding rule for the ender. |
| 878 | ("[^<>]<<\\(-\\)?\\s-*\\\\?\\(\\(['\"][^'\"]+['\"]\\|\\sw\\|\\s_\\)+\\).*\\(\n\\)" | 918 | (sh-font-lock-here-doc |
| 879 | 4 (sh-font-lock-heredoc | 919 | (2 (sh-font-lock-open-heredoc |
| 880 | (match-beginning 0) (match-string 2) (match-end 1))) | 920 | (match-beginning 0) (match-string 1)) nil t) |
| 921 | (5 (sh-font-lock-close-heredoc | ||
| 922 | (match-beginning 0) (match-string 4) | ||
| 923 | (/= (match-beginning 3) (match-end 3))) nil t)) | ||
| 881 | ;; Distinguish the special close-paren in `case'. | 924 | ;; Distinguish the special close-paren in `case'. |
| 882 | (")" 0 (sh-font-lock-paren (match-beginning 0))))) | 925 | (")" 0 (sh-font-lock-paren (match-beginning 0))))) |
| 883 | 926 | ||
| @@ -1268,9 +1311,7 @@ with your script for an edit-interpret-debug cycle." | |||
| 1268 | sh-font-lock-keywords-1 sh-font-lock-keywords-2) | 1311 | sh-font-lock-keywords-1 sh-font-lock-keywords-2) |
| 1269 | nil nil | 1312 | nil nil |
| 1270 | ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil | 1313 | ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil |
| 1271 | (font-lock-syntactic-keywords | 1314 | (font-lock-syntactic-keywords . sh-font-lock-syntactic-keywords) |
| 1272 | ;; Copy so we can use destructive update in `sh-font-lock-heredoc'. | ||
| 1273 | . ,(copy-sequence sh-font-lock-syntactic-keywords)) | ||
| 1274 | (font-lock-syntactic-face-function | 1315 | (font-lock-syntactic-face-function |
| 1275 | . sh-font-lock-syntactic-face-function)) | 1316 | . sh-font-lock-syntactic-face-function)) |
| 1276 | skeleton-pair-alist '((?` _ ?`)) | 1317 | skeleton-pair-alist '((?` _ ?`)) |
| @@ -1310,21 +1351,17 @@ This adds rules for comments and assignments." | |||
| 1310 | 1351 | ||
| 1311 | (defun sh-font-lock-keywords-1 (&optional builtins) | 1352 | (defun sh-font-lock-keywords-1 (&optional builtins) |
| 1312 | "Function to get better fontification including keywords." | 1353 | "Function to get better fontification including keywords." |
| 1313 | (let ((keywords (concat "\\([;(){}`|&]\\|^\\)[ \t]*\\(\\(\\(" | 1354 | (let ((keywords (concat "\\([;(){}`|&]\\|^\\)[ \t]*\\(\\(" |
| 1314 | (mapconcat 'identity | 1355 | (regexp-opt (sh-feature sh-leading-keywords) t) |
| 1315 | (sh-feature sh-leading-keywords) | 1356 | "[ \t]+\\)?" |
| 1316 | "\\|") | 1357 | (regexp-opt (append (sh-feature sh-leading-keywords) |
| 1317 | "\\)[ \t]+\\)?\\(" | 1358 | (sh-feature sh-other-keywords)) |
| 1318 | (mapconcat 'identity | 1359 | t)))) |
| 1319 | (append (sh-feature sh-leading-keywords) | ||
| 1320 | (sh-feature sh-other-keywords)) | ||
| 1321 | "\\|") | ||
| 1322 | "\\)"))) | ||
| 1323 | (sh-font-lock-keywords | 1360 | (sh-font-lock-keywords |
| 1324 | `(,@(if builtins | 1361 | `(,@(if builtins |
| 1325 | `((,(concat keywords "[ \t]+\\)?\\(" | 1362 | `((,(concat keywords "[ \t]+\\)?" |
| 1326 | (mapconcat 'identity (sh-feature sh-builtins) "\\|") | 1363 | (regexp-opt (sh-feature sh-builtins) t) |
| 1327 | "\\)\\>") | 1364 | "\\>") |
| 1328 | (2 font-lock-keyword-face nil t) | 1365 | (2 font-lock-keyword-face nil t) |
| 1329 | (6 font-lock-builtin-face)) | 1366 | (6 font-lock-builtin-face)) |
| 1330 | ,@(sh-feature sh-font-lock-keywords-2))) | 1367 | ,@(sh-feature sh-font-lock-keywords-2))) |
| @@ -1500,37 +1537,37 @@ in ALIST." | |||
| 1500 | 1537 | ||
| 1501 | 1538 | ||
| 1502 | 1539 | ||
| 1503 | ;;; I commented this out because nobody calls it -- rms. | 1540 | ;; I commented this out because nobody calls it -- rms. |
| 1504 | ;;;(defun sh-abbrevs (ancestor &rest list) | 1541 | ;;(defun sh-abbrevs (ancestor &rest list) |
| 1505 | ;;; "Iff it isn't, define the current shell as abbrev table and fill that. | 1542 | ;; "Iff it isn't, define the current shell as abbrev table and fill that. |
| 1506 | ;;;Abbrev table will inherit all abbrevs from ANCESTOR, which is either an abbrev | 1543 | ;;Abbrev table will inherit all abbrevs from ANCESTOR, which is either an abbrev |
| 1507 | ;;;table or a list of (NAME1 EXPANSION1 ...). In addition it will define abbrevs | 1544 | ;;table or a list of (NAME1 EXPANSION1 ...). In addition it will define abbrevs |
| 1508 | ;;;according to the remaining arguments NAMEi EXPANSIONi ... | 1545 | ;;according to the remaining arguments NAMEi EXPANSIONi ... |
| 1509 | ;;;EXPANSION may be either a string or a skeleton command." | 1546 | ;;EXPANSION may be either a string or a skeleton command." |
| 1510 | ;;; (or (if (boundp sh-shell) | 1547 | ;; (or (if (boundp sh-shell) |
| 1511 | ;;; (symbol-value sh-shell)) | 1548 | ;; (symbol-value sh-shell)) |
| 1512 | ;;; (progn | 1549 | ;; (progn |
| 1513 | ;;; (if (listp ancestor) | 1550 | ;; (if (listp ancestor) |
| 1514 | ;;; (nconc list ancestor)) | 1551 | ;; (nconc list ancestor)) |
| 1515 | ;;; (define-abbrev-table sh-shell ()) | 1552 | ;; (define-abbrev-table sh-shell ()) |
| 1516 | ;;; (if (vectorp ancestor) | 1553 | ;; (if (vectorp ancestor) |
| 1517 | ;;; (mapatoms (lambda (atom) | 1554 | ;; (mapatoms (lambda (atom) |
| 1518 | ;;; (or (eq atom 0) | 1555 | ;; (or (eq atom 0) |
| 1519 | ;;; (define-abbrev (symbol-value sh-shell) | 1556 | ;; (define-abbrev (symbol-value sh-shell) |
| 1520 | ;;; (symbol-name atom) | 1557 | ;; (symbol-name atom) |
| 1521 | ;;; (symbol-value atom) | 1558 | ;; (symbol-value atom) |
| 1522 | ;;; (symbol-function atom)))) | 1559 | ;; (symbol-function atom)))) |
| 1523 | ;;; ancestor)) | 1560 | ;; ancestor)) |
| 1524 | ;;; (while list | 1561 | ;; (while list |
| 1525 | ;;; (define-abbrev (symbol-value sh-shell) | 1562 | ;; (define-abbrev (symbol-value sh-shell) |
| 1526 | ;;; (car list) | 1563 | ;; (car list) |
| 1527 | ;;; (if (stringp (car (cdr list))) | 1564 | ;; (if (stringp (car (cdr list))) |
| 1528 | ;;; (car (cdr list)) | 1565 | ;; (car (cdr list)) |
| 1529 | ;;; "") | 1566 | ;; "") |
| 1530 | ;;; (if (symbolp (car (cdr list))) | 1567 | ;; (if (symbolp (car (cdr list))) |
| 1531 | ;;; (car (cdr list)))) | 1568 | ;; (car (cdr list)))) |
| 1532 | ;;; (setq list (cdr (cdr list))))) | 1569 | ;; (setq list (cdr (cdr list))))) |
| 1533 | ;;; (symbol-value sh-shell))) | 1570 | ;; (symbol-value sh-shell))) |
| 1534 | 1571 | ||
| 1535 | 1572 | ||
| 1536 | (defun sh-append (ancestor &rest list) | 1573 | (defun sh-append (ancestor &rest list) |
| @@ -1675,9 +1712,9 @@ which in this buffer is currently %s. | |||
| 1675 | 1712 | ||
| 1676 | \t%s." | 1713 | \t%s." |
| 1677 | sh-basic-offset | 1714 | sh-basic-offset |
| 1678 | (mapconcat (lambda (x) | 1715 | (mapconcat (lambda (x) |
| 1679 | (nth (1- (length x)) x)) | 1716 | (nth (1- (length x)) x)) |
| 1680 | sh-symbol-list "\n\t")))) | 1717 | sh-symbol-list "\n\t")))) |
| 1681 | (concat | 1718 | (concat |
| 1682 | ;; The following shows the global not the local value! | 1719 | ;; The following shows the global not the local value! |
| 1683 | ;; (format "Current value of %s is %s\n\n" var (symbol-value var)) | 1720 | ;; (format "Current value of %s is %s\n\n" var (symbol-value var)) |
| @@ -1701,10 +1738,8 @@ which in this buffer is currently %s. | |||
| 1701 | (defun sh-in-comment-or-string (start) | 1738 | (defun sh-in-comment-or-string (start) |
| 1702 | "Return non-nil if START is in a comment or string." | 1739 | "Return non-nil if START is in a comment or string." |
| 1703 | (save-excursion | 1740 | (save-excursion |
| 1704 | (let (state) | 1741 | (let ((state (syntax-ppss start))) |
| 1705 | (beginning-of-line) | 1742 | (or (nth 3 state) (nth 4 state))))) |
| 1706 | (setq state (parse-partial-sexp (point) start nil nil nil t)) | ||
| 1707 | (or (nth 3 state)(nth 4 state))))) | ||
| 1708 | 1743 | ||
| 1709 | (defun sh-goto-matching-if () | 1744 | (defun sh-goto-matching-if () |
| 1710 | "Go to the matching if for a fi. | 1745 | "Go to the matching if for a fi. |
| @@ -2438,7 +2473,7 @@ If INFO is supplied it is used, else it is calculated from current line." | |||
| 2438 | nil))))) | 2473 | nil))))) |
| 2439 | 2474 | ||
| 2440 | 2475 | ||
| 2441 | (defun sh-indent-line (&optional prefix-arg) | 2476 | (defun sh-indent-line () |
| 2442 | "Indent the current line." | 2477 | "Indent the current line." |
| 2443 | (interactive) | 2478 | (interactive) |
| 2444 | (sh-must-be-shell-mode) | 2479 | (sh-must-be-shell-mode) |
| @@ -2663,7 +2698,7 @@ so that `occur-next' and `occur-prev' will work." | |||
| 2663 | ;; Is this really worth having? | 2698 | ;; Is this really worth having? |
| 2664 | (defvar sh-learned-buffer-hook nil | 2699 | (defvar sh-learned-buffer-hook nil |
| 2665 | "*An abnormal hook, called with an alist of learned variables.") | 2700 | "*An abnormal hook, called with an alist of learned variables.") |
| 2666 | ;;; Example of how to use sh-learned-buffer-hook | 2701 | ;; Example of how to use sh-learned-buffer-hook |
| 2667 | ;; | 2702 | ;; |
| 2668 | ;; (defun what-i-learned (list) | 2703 | ;; (defun what-i-learned (list) |
| 2669 | ;; (let ((p list)) | 2704 | ;; (let ((p list)) |
| @@ -3054,7 +3089,7 @@ This is always added to the end of the buffer." | |||
| 3054 | < "default:" \n | 3089 | < "default:" \n |
| 3055 | > _ \n | 3090 | > _ \n |
| 3056 | resume: | 3091 | resume: |
| 3057 | < < "endsw") | 3092 | < < "endsw" \n) |
| 3058 | (es) | 3093 | (es) |
| 3059 | (rc "expression: " | 3094 | (rc "expression: " |
| 3060 | > "switch( " str " ) {" \n | 3095 | > "switch( " str " ) {" \n |
| @@ -3066,7 +3101,7 @@ This is always added to the end of the buffer." | |||
| 3066 | "case *" > \n | 3101 | "case *" > \n |
| 3067 | > _ \n | 3102 | > _ \n |
| 3068 | resume: | 3103 | resume: |
| 3069 | ?} > ) | 3104 | ?} > \n) |
| 3070 | (sh "expression: " | 3105 | (sh "expression: " |
| 3071 | > "case " str " in" \n | 3106 | > "case " str " in" \n |
| 3072 | > (read-string "pattern: ") | 3107 | > (read-string "pattern: ") |
| @@ -3081,7 +3116,7 @@ This is always added to the end of the buffer." | |||
| 3081 | > "*" (propertize ")" 'syntax-table sh-st-punc) \n | 3116 | > "*" (propertize ")" 'syntax-table sh-st-punc) \n |
| 3082 | > _ \n | 3117 | > _ \n |
| 3083 | resume: | 3118 | resume: |
| 3084 | "esac" > )) | 3119 | "esac" > \n)) |
| 3085 | 3120 | ||
| 3086 | (define-skeleton sh-for | 3121 | (define-skeleton sh-for |
| 3087 | "Insert a for loop. See `sh-feature'." | 3122 | "Insert a for loop. See `sh-feature'." |
| @@ -3101,7 +3136,7 @@ This is always added to the end of the buffer." | |||
| 3101 | (sh "Index variable: " | 3136 | (sh "Index variable: " |
| 3102 | > "for " str " in " _ "; do" \n | 3137 | > "for " str " in " _ "; do" \n |
| 3103 | > _ | ?$ & (sh-remember-variable str) \n | 3138 | > _ | ?$ & (sh-remember-variable str) \n |
| 3104 | "done" > )) | 3139 | "done" > \n)) |
| 3105 | 3140 | ||
| 3106 | 3141 | ||
| 3107 | 3142 | ||
| @@ -3113,7 +3148,7 @@ This is always added to the end of the buffer." | |||
| 3113 | "while( $" str " <= " (read-string "upper limit: ") " )" \n | 3148 | "while( $" str " <= " (read-string "upper limit: ") " )" \n |
| 3114 | > _ ?$ str \n | 3149 | > _ ?$ str \n |
| 3115 | "@ " str "++" \n | 3150 | "@ " str "++" \n |
| 3116 | < "end") | 3151 | < "end" \n) |
| 3117 | (es eval sh-modify rc | 3152 | (es eval sh-modify rc |
| 3118 | 4 " =") | 3153 | 4 " =") |
| 3119 | (ksh88 "Index variable: " | 3154 | (ksh88 "Index variable: " |
| @@ -3122,7 +3157,7 @@ This is always added to the end of the buffer." | |||
| 3122 | (read-string "upper limit: ") | 3157 | (read-string "upper limit: ") |
| 3123 | " )); do" \n | 3158 | " )); do" \n |
| 3124 | > _ ?$ (sh-remember-variable str) > \n | 3159 | > _ ?$ (sh-remember-variable str) > \n |
| 3125 | "done" > ) | 3160 | "done" > \n) |
| 3126 | (posix "Index variable: " | 3161 | (posix "Index variable: " |
| 3127 | > str "=1" \n | 3162 | > str "=1" \n |
| 3128 | "while [ $" str " -le " | 3163 | "while [ $" str " -le " |
| @@ -3130,19 +3165,19 @@ This is always added to the end of the buffer." | |||
| 3130 | " ]; do" \n | 3165 | " ]; do" \n |
| 3131 | > _ ?$ str \n | 3166 | > _ ?$ str \n |
| 3132 | str ?= (sh-add (sh-remember-variable str) 1) \n | 3167 | str ?= (sh-add (sh-remember-variable str) 1) \n |
| 3133 | "done" > ) | 3168 | "done" > \n) |
| 3134 | (rc "Index variable: " | 3169 | (rc "Index variable: " |
| 3135 | > "for( " str " in" " `{awk 'BEGIN { for( i=1; i<=" | 3170 | > "for( " str " in" " `{awk 'BEGIN { for( i=1; i<=" |
| 3136 | (read-string "upper limit: ") | 3171 | (read-string "upper limit: ") |
| 3137 | "; i++ ) print i }'`}) {" \n | 3172 | "; i++ ) print i }'`}) {" \n |
| 3138 | > _ ?$ (sh-remember-variable str) \n | 3173 | > _ ?$ (sh-remember-variable str) \n |
| 3139 | ?} >) | 3174 | ?} > \n) |
| 3140 | (sh "Index variable: " | 3175 | (sh "Index variable: " |
| 3141 | > "for " str " in `awk 'BEGIN { for( i=1; i<=" | 3176 | > "for " str " in `awk 'BEGIN { for( i=1; i<=" |
| 3142 | (read-string "upper limit: ") | 3177 | (read-string "upper limit: ") |
| 3143 | "; i++ ) print i }'`; do" \n | 3178 | "; i++ ) print i }'`; do" \n |
| 3144 | > _ ?$ (sh-remember-variable str) \n | 3179 | > _ ?$ (sh-remember-variable str) \n |
| 3145 | "done" > )) | 3180 | "done" > \n)) |
| 3146 | 3181 | ||
| 3147 | 3182 | ||
| 3148 | (defun sh-shell-initialize-variables () | 3183 | (defun sh-shell-initialize-variables () |
| @@ -3219,13 +3254,13 @@ t means to return a list of all possible completions of STRING. | |||
| 3219 | (ksh88 "name: " | 3254 | (ksh88 "name: " |
| 3220 | "function " str " {" \n | 3255 | "function " str " {" \n |
| 3221 | > _ \n | 3256 | > _ \n |
| 3222 | < "}") | 3257 | < "}" \n) |
| 3223 | (rc eval sh-modify ksh88 | 3258 | (rc eval sh-modify ksh88 |
| 3224 | 1 "fn ") | 3259 | 1 "fn ") |
| 3225 | (sh () | 3260 | (sh () |
| 3226 | "() {" \n | 3261 | "() {" \n |
| 3227 | > _ \n | 3262 | > _ \n |
| 3228 | < "}")) | 3263 | < "}" \n)) |
| 3229 | 3264 | ||
| 3230 | 3265 | ||
| 3231 | 3266 | ||
| @@ -3240,7 +3275,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3240 | < "else" \n | 3275 | < "else" \n |
| 3241 | > _ \n | 3276 | > _ \n |
| 3242 | resume: | 3277 | resume: |
| 3243 | < "endif") | 3278 | < "endif" \n) |
| 3244 | (es "condition: " | 3279 | (es "condition: " |
| 3245 | > "if { " str " } {" \n | 3280 | > "if { " str " } {" \n |
| 3246 | > _ \n | 3281 | > _ \n |
| @@ -3250,7 +3285,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3250 | "} {" > \n | 3285 | "} {" > \n |
| 3251 | > _ \n | 3286 | > _ \n |
| 3252 | resume: | 3287 | resume: |
| 3253 | ?} > ) | 3288 | ?} > \n) |
| 3254 | (rc "condition: " | 3289 | (rc "condition: " |
| 3255 | > "if( " str " ) {" \n | 3290 | > "if( " str " ) {" \n |
| 3256 | > _ \n | 3291 | > _ \n |
| @@ -3260,8 +3295,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3260 | "} else {" > \n | 3295 | "} else {" > \n |
| 3261 | > _ \n | 3296 | > _ \n |
| 3262 | resume: | 3297 | resume: |
| 3263 | ?} > | 3298 | ?} > \n) |
| 3264 | ) | ||
| 3265 | (sh "condition: " | 3299 | (sh "condition: " |
| 3266 | '(setq input (sh-feature sh-test)) | 3300 | '(setq input (sh-feature sh-test)) |
| 3267 | > "if " str "; then" \n | 3301 | > "if " str "; then" \n |
| @@ -3272,7 +3306,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3272 | "else" > \n | 3306 | "else" > \n |
| 3273 | > \n | 3307 | > \n |
| 3274 | resume: | 3308 | resume: |
| 3275 | "fi" > )) | 3309 | "fi" > \n)) |
| 3276 | 3310 | ||
| 3277 | 3311 | ||
| 3278 | 3312 | ||
| @@ -3281,11 +3315,11 @@ t means to return a list of all possible completions of STRING. | |||
| 3281 | (es nil | 3315 | (es nil |
| 3282 | > "forever {" \n | 3316 | > "forever {" \n |
| 3283 | > _ \n | 3317 | > _ \n |
| 3284 | ?} > ) | 3318 | ?} > \n) |
| 3285 | (zsh "factor: " | 3319 | (zsh "factor: " |
| 3286 | > "repeat " str "; do" > \n | 3320 | > "repeat " str "; do" > \n |
| 3287 | > \n | 3321 | > \n |
| 3288 | "done" > )) | 3322 | "done" > \n)) |
| 3289 | 3323 | ||
| 3290 | ;;;(put 'sh-repeat 'menu-enable '(sh-feature sh-repeat)) | 3324 | ;;;(put 'sh-repeat 'menu-enable '(sh-feature sh-repeat)) |
| 3291 | 3325 | ||
| @@ -3296,7 +3330,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3296 | (ksh88 "Index variable: " | 3330 | (ksh88 "Index variable: " |
| 3297 | > "select " str " in " _ "; do" \n | 3331 | > "select " str " in " _ "; do" \n |
| 3298 | > ?$ str \n | 3332 | > ?$ str \n |
| 3299 | "done" > ) | 3333 | "done" > \n) |
| 3300 | (bash eval sh-append ksh88)) | 3334 | (bash eval sh-append ksh88)) |
| 3301 | ;;;(put 'sh-select 'menu-enable '(sh-feature sh-select)) | 3335 | ;;;(put 'sh-select 'menu-enable '(sh-feature sh-select)) |
| 3302 | 3336 | ||
| @@ -3312,7 +3346,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3312 | (not (bolp)) | 3346 | (not (bolp)) |
| 3313 | ?\n) | 3347 | ?\n) |
| 3314 | "exit:\n" | 3348 | "exit:\n" |
| 3315 | "rm $tmp* >&/dev/null" >) | 3349 | "rm $tmp* >&/dev/null" > \n) |
| 3316 | (es (file-name-nondirectory (buffer-file-name)) | 3350 | (es (file-name-nondirectory (buffer-file-name)) |
| 3317 | > "local( signals = $signals sighup sigint; tmp = /tmp/" str | 3351 | > "local( signals = $signals sighup sigint; tmp = /tmp/" str |
| 3318 | ".$pid ) {" \n | 3352 | ".$pid ) {" \n |
| @@ -3322,15 +3356,15 @@ t means to return a list of all possible completions of STRING. | |||
| 3322 | "} {" > \n | 3356 | "} {" > \n |
| 3323 | _ \n | 3357 | _ \n |
| 3324 | ?} > \n | 3358 | ?} > \n |
| 3325 | ?} > ) | 3359 | ?} > \n) |
| 3326 | (ksh88 eval sh-modify sh | 3360 | (ksh88 eval sh-modify sh |
| 3327 | 7 "EXIT") | 3361 | 7 "EXIT") |
| 3328 | (rc (file-name-nondirectory (buffer-file-name)) | 3362 | (rc (file-name-nondirectory (buffer-file-name)) |
| 3329 | > "tmp = /tmp/" str ".$pid" \n | 3363 | > "tmp = /tmp/" str ".$pid" \n |
| 3330 | "fn sigexit { rm $tmp^* >[2]/dev/null }") | 3364 | "fn sigexit { rm $tmp^* >[2]/dev/null }" \n) |
| 3331 | (sh (file-name-nondirectory (buffer-file-name)) | 3365 | (sh (file-name-nondirectory (buffer-file-name)) |
| 3332 | > "TMP=${TMPDIR:-/tmp}/" str ".$$" \n | 3366 | > "TMP=${TMPDIR:-/tmp}/" str ".$$" \n |
| 3333 | "trap \"rm $TMP* 2>/dev/null\" " ?0)) | 3367 | "trap \"rm $TMP* 2>/dev/null\" " ?0 \n)) |
| 3334 | 3368 | ||
| 3335 | 3369 | ||
| 3336 | 3370 | ||
| @@ -3340,7 +3374,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3340 | '(setq input (sh-feature sh-test)) | 3374 | '(setq input (sh-feature sh-test)) |
| 3341 | > "until " str "; do" \n | 3375 | > "until " str "; do" \n |
| 3342 | > _ \n | 3376 | > _ \n |
| 3343 | "done" > )) | 3377 | "done" > \n)) |
| 3344 | ;;;(put 'sh-until 'menu-enable '(sh-feature sh-until)) | 3378 | ;;;(put 'sh-until 'menu-enable '(sh-feature sh-until)) |
| 3345 | 3379 | ||
| 3346 | 3380 | ||
| @@ -3365,7 +3399,7 @@ t means to return a list of all possible completions of STRING. | |||
| 3365 | '(setq input (sh-feature sh-test)) | 3399 | '(setq input (sh-feature sh-test)) |
| 3366 | > "while " str "; do" \n | 3400 | > "while " str "; do" \n |
| 3367 | > _ \n | 3401 | > _ \n |
| 3368 | "done" > )) | 3402 | "done" > \n)) |
| 3369 | 3403 | ||
| 3370 | 3404 | ||
| 3371 | 3405 | ||
| @@ -3397,7 +3431,7 @@ option followed by a colon `:' if the option accepts an argument." | |||
| 3397 | resume: | 3431 | resume: |
| 3398 | < < "endsw" \n | 3432 | < < "endsw" \n |
| 3399 | "shift" \n | 3433 | "shift" \n |
| 3400 | < "end") | 3434 | < "end" \n) |
| 3401 | (ksh88 eval sh-modify sh | 3435 | (ksh88 eval sh-modify sh |
| 3402 | 16 "print" | 3436 | 16 "print" |
| 3403 | 18 "${0##*/}" | 3437 | 18 "${0##*/}" |
| @@ -3430,7 +3464,7 @@ option followed by a colon `:' if the option accepts an argument." | |||
| 3430 | "esac" > | 3464 | "esac" > |
| 3431 | \n "done" | 3465 | \n "done" |
| 3432 | > \n | 3466 | > \n |
| 3433 | "shift " (sh-add "OPTIND" -1))) | 3467 | "shift " (sh-add "OPTIND" -1) \n)) |
| 3434 | 3468 | ||
| 3435 | 3469 | ||
| 3436 | 3470 | ||