aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2001-10-13 19:08:30 +0000
committerStefan Monnier2001-10-13 19:08:30 +0000
commit3e2dd647b766091c075b6a49be0ca36b0f80f5d6 (patch)
tree0d80b722fe94936072d290d2e0ac8f1554e59770
parent71f343138c2c459e02f23908a79083fb0478a9e9 (diff)
downloademacs-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.el330
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
237csh C Shell 237csh 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
241rc Plan 9 Shell 241rc Plan 9 Shell
242 es Extensible Shell 242 es Extensible Shell
243sh Bourne Shell 243sh 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'."
758See `sh-feature'.") 758See `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.
830If 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.
870START is the position of <<.
871STRING is the actual word used as delimiter (f.ex. \"EOF\").
872INDENTED is non-nil if the here document's content (and the EOF mark) can
873be 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