Mercurial > emacs
comparison lisp/progmodes/sh-script.el @ 78197:f942a5cc0de4
(sh-font-lock-backslash-quote, sh-font-lock-flush-syntax-ppss-cache): New funs.
(sh-font-lock-syntactic-keywords): Use them to distinguish the
different possible cases for \'.
(sh-font-lock-paren): Mark the relevant text with font-lock-multiline.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Mon, 23 Jul 2007 13:07:29 +0000 |
parents | dac1de8103f2 |
children | c1ec1c8a8d2e |
comparison
equal
deleted
inserted
replaced
78196:2e0600da7d6a | 78197:f942a5cc0de4 |
---|---|
169 ;; To try and address points 2 3 and 5 I used a feature that cperl mode | 169 ;; To try and address points 2 3 and 5 I used a feature that cperl mode |
170 ;; uses, that of a text's syntax property. This, however, has 2 | 170 ;; uses, that of a text's syntax property. This, however, has 2 |
171 ;; disadvantages: | 171 ;; disadvantages: |
172 ;; 1. We need to scan the buffer to find which ")" symbols belong to a | 172 ;; 1. We need to scan the buffer to find which ")" symbols belong to a |
173 ;; case alternative, to find any here documents, and handle "$#". | 173 ;; case alternative, to find any here documents, and handle "$#". |
174 ;; 2. Setting the text property makes the buffer modified. If the | |
175 ;; buffer is read-only buffer we have to cheat and bypass the read-only | |
176 ;; status. This is for cases where the buffer started read-only buffer | |
177 ;; but the user issued `toggle-read-only'. | |
178 ;; | 174 ;; |
179 ;; Bugs | 175 ;; Bugs |
180 ;; ---- | 176 ;; ---- |
181 ;; - Indenting many lines is slow. It currently does each line | 177 ;; - Indenting many lines is slow. It currently does each line |
182 ;; independently, rather than saving state information. | 178 ;; independently, rather than saving state information. |
183 ;; | 179 ;; |
184 ;; - `sh-learn-buffer-indent' is extremely slow. | 180 ;; - `sh-learn-buffer-indent' is extremely slow. |
181 ;; | |
182 ;; - "case $x in y) echo ;; esac)" the last ) is mis-identified as being | |
183 ;; part of a case-pattern. You need to add a semi-colon after "esac" to | |
184 ;; coerce sh-script into doing the right thing. | |
185 ;; | |
186 ;; - "echo $z in ps | head)" the last ) is mis-identified as being part of | |
187 ;; a case-pattern. You need to put the "in" between quotes to coerce | |
188 ;; sh-script into doing the right thing. | |
189 ;; | |
190 ;; - A line starting with "}>foo" is not indented like "} >foo". | |
185 ;; | 191 ;; |
186 ;; Richard Sharman <rsharman@pobox.com> June 1999. | 192 ;; Richard Sharman <rsharman@pobox.com> June 1999. |
187 | 193 |
188 ;;; Code: | 194 ;;; Code: |
189 | 195 |
882 (defconst sh-st-punc (string-to-syntax ".")) | 888 (defconst sh-st-punc (string-to-syntax ".")) |
883 (defconst sh-st-symbol (string-to-syntax "_")) | 889 (defconst sh-st-symbol (string-to-syntax "_")) |
884 (defconst sh-here-doc-syntax (string-to-syntax "|")) ;; generic string | 890 (defconst sh-here-doc-syntax (string-to-syntax "|")) ;; generic string |
885 | 891 |
886 (defconst sh-escaped-line-re | 892 (defconst sh-escaped-line-re |
887 ;; Should match until the real end-of-continued line, but if that is not | 893 ;; Should match until the real end-of-continued-line, but if that is not |
888 ;; possible (because we bump into EOB or the search bound), then we should | 894 ;; possible (because we bump into EOB or the search bound), then we should |
889 ;; match until the search bound. | 895 ;; match until the search bound. |
890 "\\(?:\\(?:.*[^\\\n]\\)?\\(?:\\\\\\\\\\)*\\\\\n\\)*.*") | 896 "\\(?:\\(?:.*[^\\\n]\\)?\\(?:\\\\\\\\\\)*\\\\\n\\)*.*") |
891 | 897 |
892 (defconst sh-here-doc-open-re | 898 (defconst sh-here-doc-open-re |
1057 ;; Maybe we've bumped into an escaped newline. | 1063 ;; Maybe we've bumped into an escaped newline. |
1058 (sh-is-quoted-p (point))) | 1064 (sh-is-quoted-p (point))) |
1059 (backward-char 1)) | 1065 (backward-char 1)) |
1060 (when (eq (char-before) ?|) | 1066 (when (eq (char-before) ?|) |
1061 (backward-char 1) t))) | 1067 (backward-char 1) t))) |
1062 (when (save-excursion (backward-char 2) (looking-at ";;\\|in")) | 1068 ;; FIXME: ";; esac )" is a case that looks like a case-pattern but it's |
1069 ;; really just a close paren after a case statement. I.e. if we skipped | |
1070 ;; over `esac' just now, we're not looking at a case-pattern. | |
1071 (when (progn (backward-char 2) | |
1072 (if (> start (line-end-position)) | |
1073 (put-text-property (point) (1+ start) | |
1074 'font-lock-multiline t)) | |
1075 ;; FIXME: The `in' may just be a random argument to | |
1076 ;; a normal command rather than the real `in' keyword. | |
1077 ;; I.e. we should look back to try and find the | |
1078 ;; corresponding `case'. | |
1079 (looking-at ";;\\|in")) | |
1063 sh-st-punc))) | 1080 sh-st-punc))) |
1081 | |
1082 (defun sh-font-lock-backslash-quote () | |
1083 (if (eq (save-excursion (nth 3 (syntax-ppss (match-beginning 0)))) ?\') | |
1084 ;; In a '...' the backslash is not escaping. | |
1085 sh-st-punc | |
1086 nil)) | |
1087 | |
1088 (defun sh-font-lock-flush-syntax-ppss-cache (limit) | |
1089 ;; This should probably be a standard function provided by font-lock.el | |
1090 ;; (or syntax.el). | |
1091 (syntax-ppss-flush-cache (point)) | |
1092 (goto-char limit) | |
1093 nil) | |
1064 | 1094 |
1065 (defun sh-apply-quoted-subshell () | 1095 (defun sh-apply-quoted-subshell () |
1066 "Apply the `sh-st-punc' syntax to all the matches in `match-data'. | 1096 "Apply the `sh-st-punc' syntax to all the matches in `match-data'. |
1067 This is used to flag quote characters in subshell constructs inside strings | 1097 This is used to flag quote characters in subshell constructs inside strings |
1068 \(which should therefore not be treated as normal quote characters\)" | 1098 \(which should therefore not be treated as normal quote characters\)" |
1078 ;; word. In the shell, words are separated by metacharacters. | 1108 ;; word. In the shell, words are separated by metacharacters. |
1079 ;; The list of special chars is taken from the single-unix spec | 1109 ;; The list of special chars is taken from the single-unix spec |
1080 ;; of the shell command language (under `quoting') but with `$' removed. | 1110 ;; of the shell command language (under `quoting') but with `$' removed. |
1081 `(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 ,sh-st-symbol) | 1111 `(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 ,sh-st-symbol) |
1082 ;; In a '...' the backslash is not escaping. | 1112 ;; In a '...' the backslash is not escaping. |
1083 ("\\(\\\\\\)'" 1 ,sh-st-punc) | 1113 ("\\(\\\\\\)'" (1 (sh-font-lock-backslash-quote))) |
1114 ;; The previous rule uses syntax-ppss, but the subsequent rules may | |
1115 ;; change the syntax, so we have to tell syntax-ppss that the states it | |
1116 ;; has just computed will need to be recomputed. | |
1117 (sh-font-lock-flush-syntax-ppss-cache) | |
1084 ;; Make sure $@ and @? are correctly recognized as sexps. | 1118 ;; Make sure $@ and @? are correctly recognized as sexps. |
1085 ("\\$\\([?@]\\)" 1 ,sh-st-symbol) | 1119 ("\\$\\([?@]\\)" 1 ,sh-st-symbol) |
1086 ;; Find HEREDOC starters and add a corresponding rule for the ender. | 1120 ;; Find HEREDOC starters and add a corresponding rule for the ender. |
1087 (sh-font-lock-here-doc | 1121 (sh-font-lock-here-doc |
1088 (2 (sh-font-lock-open-heredoc | 1122 (2 (sh-font-lock-open-heredoc |