Mercurial > emacs
comparison lisp/progmodes/sh-script.el @ 90428:a8190f7e546e
Merge from emacs--devo--0
Patches applied:
* emacs--devo--0 (patch 285-296)
- Update from CVS
- Merge from gnus--rel--5.10
- Update from CVS: admin/FOR-RELEASE: Update refcard section.
* gnus--rel--5.10 (patch 102-104)
- Update from CVS
Revision: emacs@sv.gnu.org/emacs--unicode--0--patch-64
author | Miles Bader <miles@gnu.org> |
---|---|
date | Wed, 07 Jun 2006 18:05:10 +0000 |
parents | 72dea2ff0142 44d77343c9ac |
children | 8a8e69664178 |
comparison
equal
deleted
inserted
replaced
90427:ddb25860d044 | 90428:a8190f7e546e |
---|---|
812 (:foreground "tan" )) | 812 (:foreground "tan" )) |
813 (t | 813 (t |
814 (:weight bold))) | 814 (:weight bold))) |
815 "Face to show a here-document" | 815 "Face to show a here-document" |
816 :group 'sh-indentation) | 816 :group 'sh-indentation) |
817 | |
818 ;; These colours are probably icky. It's just a placeholder though. | |
819 (defface sh-quoted-exec | |
820 '((((class color) (background dark)) | |
821 (:foreground "salmon")) | |
822 (((class color) (background light)) | |
823 (:foreground "magenta")) | |
824 (t | |
825 (:weight bold))) | |
826 "Face to show quoted execs like ``" | |
827 :group 'sh-indentation) | |
828 | |
817 ;; backward-compatibility alias | 829 ;; backward-compatibility alias |
818 (put 'sh-heredoc-face 'face-alias 'sh-heredoc) | 830 (put 'sh-heredoc-face 'face-alias 'sh-heredoc) |
819 (defvar sh-heredoc-face 'sh-heredoc) | 831 (defvar sh-heredoc-face 'sh-heredoc) |
820 | 832 |
821 (defface sh-escaped-newline '((t :inherit font-lock-string-face)) | 833 (defface sh-escaped-newline '((t :inherit font-lock-string-face)) |
831 (es sh-append executable-font-lock-keywords | 843 (es sh-append executable-font-lock-keywords |
832 ("\\$#?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\)" 1 | 844 ("\\$#?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\)" 1 |
833 font-lock-variable-name-face)) | 845 font-lock-variable-name-face)) |
834 | 846 |
835 (rc sh-append es) | 847 (rc sh-append es) |
836 | 848 (bash sh-append shell ("\\$(\\(\\sw+\\)" (1 'sh-quoted-exec t) )) |
837 (sh sh-append shell | 849 (sh sh-append shell |
838 ;; Variable names. | 850 ;; Variable names. |
839 ("\\$\\({#?\\)?\\([A-Za-z_][A-Za-z0-9_]*\\|[-#?@!]\\)" 2 | 851 ("\\$\\({#?\\)?\\([A-Za-z_][A-Za-z0-9_]*\\|[-#?@!]\\)" 2 |
840 font-lock-variable-name-face) | 852 font-lock-variable-name-face) |
841 ;; Function names. | 853 ;; Function names. |
965 (defun sh-font-lock-here-doc (limit) | 977 (defun sh-font-lock-here-doc (limit) |
966 "Search for a heredoc marker." | 978 "Search for a heredoc marker." |
967 ;; This looks silly, but it's because `sh-here-doc-re' keeps changing. | 979 ;; This looks silly, but it's because `sh-here-doc-re' keeps changing. |
968 (re-search-forward sh-here-doc-re limit t)) | 980 (re-search-forward sh-here-doc-re limit t)) |
969 | 981 |
982 (defun sh-quoted-subshell (limit) | |
983 "Search for a subshell embedded in a string. Find all the unescaped | |
984 \" characters within said subshell, remembering that subshells can nest." | |
985 (if (re-search-forward "\"\\(?:.\\|\n\\)*?\\(\\$(\\|`\\)" limit t) | |
986 ;; bingo we have a $( or a ` inside a "" | |
987 (let ((char (char-after (point))) | |
988 (continue t) | |
989 (pos (point)) | |
990 (data nil) ;; value to put into match-data (and return) | |
991 (last nil) ;; last char seen | |
992 (bq (equal (match-string 1) "`")) ;; ` state flip-flop | |
993 (seen nil) ;; list of important positions | |
994 (nest 1)) ;; subshell nesting level | |
995 (while (and continue char (<= pos limit)) | |
996 ;; unescaped " inside a $( ... ) construct. | |
997 ;; state machine time... | |
998 ;; \ => ignore next char; | |
999 ;; ` => increase or decrease nesting level based on bq flag | |
1000 ;; ) [where nesting > 0] => decrease nesting | |
1001 ;; ( [where nesting > 0] => increase nesting | |
1002 ;; ( [preceeded by $ ] => increase nesting | |
1003 ;; " [nesting <= 0 ] => terminate, we're done. | |
1004 ;; " [nesting > 0 ] => remember this, it's not a proper " | |
1005 (if (eq ?\\ last) nil | |
1006 (if (eq ?\` char) (setq nest (+ nest (if bq -1 1)) bq (not bq)) | |
1007 (if (and (> nest 0) (eq ?\) char)) (setq nest (1- nest)) | |
1008 (if (and (eq ?$ last) (eq ?\( char)) (setq nest (1+ nest)) | |
1009 (if (and (> nest 0) (eq ?\( char)) (setq nest (1+ nest)) | |
1010 (if (eq char ?\") | |
1011 (if (>= 0 nest) (setq continue nil) | |
1012 (setq seen (cons pos seen)) ) )))))) | |
1013 ;;(message "POS: %d [%d]" pos nest) | |
1014 (setq last char | |
1015 pos (1+ pos) | |
1016 char (char-after pos)) ) | |
1017 (when seen | |
1018 ;;(message "SEEN: %S" seen) | |
1019 (setq data (list (current-buffer))) | |
1020 (mapc (lambda (P) | |
1021 (setq data (cons P (cons (1+ P) data)) ) ) seen) | |
1022 (store-match-data data)) | |
1023 data) )) | |
1024 | |
970 (defun sh-is-quoted-p (pos) | 1025 (defun sh-is-quoted-p (pos) |
971 (and (eq (char-before pos) ?\\) | 1026 (and (eq (char-before pos) ?\\) |
972 (not (sh-is-quoted-p (1- pos))))) | 1027 (not (sh-is-quoted-p (1- pos))))) |
973 | 1028 |
974 (defun sh-font-lock-paren (start) | 1029 (defun sh-font-lock-paren (start) |
995 (when (eq (char-before) ?|) | 1050 (when (eq (char-before) ?|) |
996 (backward-char 1) t))) | 1051 (backward-char 1) t))) |
997 (when (save-excursion (backward-char 2) (looking-at ";;\\|in")) | 1052 (when (save-excursion (backward-char 2) (looking-at ";;\\|in")) |
998 sh-st-punc))) | 1053 sh-st-punc))) |
999 | 1054 |
1055 (defun sh-apply-quoted-subshell () | |
1056 "Apply the `sh-st-punc' syntax to all the matches in `match-data'. | |
1057 This is used to flag quote characters in subshell constructs inside strings | |
1058 \(which should therefore not be treated as normal quote characters\)" | |
1059 (let ((m (match-data)) a b) | |
1060 (while m | |
1061 (setq a (car m) | |
1062 b (cadr m) | |
1063 m (cddr m)) | |
1064 (put-text-property a b 'syntax-table sh-st-punc))) sh-st-punc) | |
1065 | |
1000 (defconst sh-font-lock-syntactic-keywords | 1066 (defconst sh-font-lock-syntactic-keywords |
1001 ;; A `#' begins a comment when it is unquoted and at the beginning of a | 1067 ;; A `#' begins a comment when it is unquoted and at the beginning of a |
1002 ;; word. In the shell, words are separated by metacharacters. | 1068 ;; word. In the shell, words are separated by metacharacters. |
1003 ;; The list of special chars is taken from the single-unix spec | 1069 ;; The list of special chars is taken from the single-unix spec |
1004 ;; of the shell command language (under `quoting') but with `$' removed. | 1070 ;; of the shell command language (under `quoting') but with `$' removed. |
1005 `(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 ,sh-st-symbol) | 1071 `(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 ,sh-st-symbol) |
1006 ;; In a '...' the backslash is not escaping. | 1072 ;; In a '...' the backslash is not escaping. |
1007 ("\\(\\\\\\)'" 1 ,sh-st-punc) | 1073 ("\\(\\\\\\)'" 1 ,sh-st-punc) |
1008 ;; Make sure $@ and @? are correctly recognized as sexps. | 1074 ;; Make sure $@ and @? are correctly recognized as sexps. |
1009 ("\\$\\([?@]\\)" 1 ,sh-st-symbol) | 1075 ("\\$\\([?@]\\)" 1 ,sh-st-symbol) |
1076 ;; highlight (possibly nested) subshells inside "" quoted regions correctly. | |
1077 (sh-quoted-subshell | |
1078 (1 (sh-apply-quoted-subshell) t t)) | |
1010 ;; Find HEREDOC starters and add a corresponding rule for the ender. | 1079 ;; Find HEREDOC starters and add a corresponding rule for the ender. |
1011 (sh-font-lock-here-doc | 1080 (sh-font-lock-here-doc |
1012 (2 (sh-font-lock-open-heredoc | 1081 (2 (sh-font-lock-open-heredoc |
1013 (match-beginning 0) (match-string 1)) nil t) | 1082 (match-beginning 0) (match-string 1)) nil t) |
1014 (5 (sh-font-lock-close-heredoc | 1083 (5 (sh-font-lock-close-heredoc |
1017 nil t)) | 1086 nil t)) |
1018 ;; Distinguish the special close-paren in `case'. | 1087 ;; Distinguish the special close-paren in `case'. |
1019 (")" 0 (sh-font-lock-paren (match-beginning 0))))) | 1088 (")" 0 (sh-font-lock-paren (match-beginning 0))))) |
1020 | 1089 |
1021 (defun sh-font-lock-syntactic-face-function (state) | 1090 (defun sh-font-lock-syntactic-face-function (state) |
1022 (if (nth 3 state) | 1091 (let ((q (nth 3 state))) |
1023 (if (characterp (nth 3 state)) | 1092 (if q |
1024 font-lock-string-face | 1093 (if (characterp q) |
1025 sh-heredoc-face) | 1094 (if (eq q ?\`) 'sh-quoted-exec font-lock-string-face) |
1026 font-lock-comment-face)) | 1095 sh-heredoc-face) |
1096 font-lock-comment-face))) | |
1027 | 1097 |
1028 (defgroup sh-indentation nil | 1098 (defgroup sh-indentation nil |
1029 "Variables controlling indentation in shell scripts. | 1099 "Variables controlling indentation in shell scripts. |
1030 | 1100 |
1031 Note: customizing these variables will not affect existing buffers if | 1101 Note: customizing these variables will not affect existing buffers if |
1388 (make-local-variable 'require-final-newline) | 1458 (make-local-variable 'require-final-newline) |
1389 (make-local-variable 'sh-header-marker) | 1459 (make-local-variable 'sh-header-marker) |
1390 (make-local-variable 'sh-shell-file) | 1460 (make-local-variable 'sh-shell-file) |
1391 (make-local-variable 'sh-shell) | 1461 (make-local-variable 'sh-shell) |
1392 (make-local-variable 'skeleton-pair-alist) | 1462 (make-local-variable 'skeleton-pair-alist) |
1393 (make-local-variable 'skeleton-pair-filter) | 1463 (make-local-variable 'skeleton-pair-filter-function) |
1394 (make-local-variable 'comint-dynamic-complete-functions) | 1464 (make-local-variable 'comint-dynamic-complete-functions) |
1395 (make-local-variable 'comint-prompt-regexp) | 1465 (make-local-variable 'comint-prompt-regexp) |
1396 (make-local-variable 'font-lock-defaults) | 1466 (make-local-variable 'font-lock-defaults) |
1397 (make-local-variable 'skeleton-filter) | 1467 (make-local-variable 'skeleton-filter-function) |
1398 (make-local-variable 'skeleton-newline-indent-rigidly) | 1468 (make-local-variable 'skeleton-newline-indent-rigidly) |
1399 (make-local-variable 'sh-shell-variables) | 1469 (make-local-variable 'sh-shell-variables) |
1400 (make-local-variable 'sh-shell-variables-initialized) | 1470 (make-local-variable 'sh-shell-variables-initialized) |
1401 (make-local-variable 'imenu-generic-expression) | 1471 (make-local-variable 'imenu-generic-expression) |
1402 (make-local-variable 'sh-indent-supported-here) | 1472 (make-local-variable 'sh-indent-supported-here) |
1420 ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil | 1490 ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil |
1421 (font-lock-syntactic-keywords . sh-font-lock-syntactic-keywords) | 1491 (font-lock-syntactic-keywords . sh-font-lock-syntactic-keywords) |
1422 (font-lock-syntactic-face-function | 1492 (font-lock-syntactic-face-function |
1423 . sh-font-lock-syntactic-face-function)) | 1493 . sh-font-lock-syntactic-face-function)) |
1424 skeleton-pair-alist '((?` _ ?`)) | 1494 skeleton-pair-alist '((?` _ ?`)) |
1425 skeleton-pair-filter 'sh-quoted-p | 1495 skeleton-pair-filter-function 'sh-quoted-p |
1426 skeleton-further-elements '((< '(- (min sh-indentation | 1496 skeleton-further-elements '((< '(- (min sh-indentation |
1427 (current-column))))) | 1497 (current-column))))) |
1428 skeleton-filter 'sh-feature | 1498 skeleton-filter-function 'sh-feature |
1429 skeleton-newline-indent-rigidly t | 1499 skeleton-newline-indent-rigidly t |
1430 sh-indent-supported-here nil) | 1500 sh-indent-supported-here nil) |
1431 (set (make-local-variable 'parse-sexp-ignore-comments) t) | 1501 (set (make-local-variable 'parse-sexp-ignore-comments) t) |
1432 ;; Parse or insert magic number for exec, and set all variables depending | 1502 ;; Parse or insert magic number for exec, and set all variables depending |
1433 ;; on the shell thus determined. | 1503 ;; on the shell thus determined. |