aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2006-06-03 08:38:43 +0000
committerEli Zaretskii2006-06-03 08:38:43 +0000
commit6d39902f3583e94a67281f0ca15b6f715ade4484 (patch)
treec2432ad5cd29f978b0dbfb0771eddabada411d0f
parente7818a4a1fffbb56db506881771f37d6c92cb59e (diff)
downloademacs-6d39902f3583e94a67281f0ca15b6f715ade4484.tar.gz
emacs-6d39902f3583e94a67281f0ca15b6f715ade4484.zip
(sh-quoted-exec): New face for quoted exec constructs like `foo bar`.
(sh-quoted-subshell): New helper function to search for a possibly nested subshell (like `` or $()) within a "" quoted string. (sh-font-lock-keywords-var): Add sh-quoted-exec for Bash. (sh-apply-quoted-subshell): Flag quote characters inside a subshell, which is itself already in a quoted region, as punctuation, since this is the closest to what they actually are. (sh-font-lock-syntactic-keywords): Add sh-quoted-subshell and sh-apply-quoted-subshell. (sh-font-lock-syntactic-face-function): Apply the new face for text inside `` instead of the old font-lock-string-face.
-rw-r--r--lisp/ChangeLog15
-rw-r--r--lisp/progmodes/sh-script.el82
2 files changed, 91 insertions, 6 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9d4a6d0de47..8f29118a10e 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,18 @@
12006-05-20 Vivek Dasmohapatra <vivek@etla.org>
2
3 * progmodes/sh-script.el (sh-quoted-exec): New face for quoted
4 exec constructs like `foo bar`.
5 (sh-quoted-subshell): New helper function to search for a possibly
6 nested subshell (like `` or $()) within a "" quoted string.
7 (sh-font-lock-keywords-var): Add sh-quoted-exec for Bash.
8 (sh-apply-quoted-subshell): Flag quote characters inside a
9 subshell, which is itself already in a quoted region, as
10 punctuation, since this is the closest to what they actually are.
11 (sh-font-lock-syntactic-keywords): Add sh-quoted-subshell and
12 sh-apply-quoted-subshell.
13 (sh-font-lock-syntactic-face-function): Apply the new face for
14 text inside `` instead of the old font-lock-string-face.
15
12006-06-03 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 162006-06-03 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2 17
3 * term/mac-win.el (mac-ts-active-input-overlay): Add defvar. 18 * term/mac-win.el (mac-ts-active-input-overlay): Add defvar.
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index ab3da050456..ef80d28c578 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -814,6 +814,18 @@ See `sh-feature'.")
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)
@@ -833,7 +845,7 @@ See `sh-feature'.")
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
@@ -967,6 +979,49 @@ Point is at the beginning of the next line."
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)))))
@@ -997,6 +1052,17 @@ Point is at the beginning of the next line."
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'.
1057This 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.
@@ -1007,6 +1073,9 @@ Point is at the beginning of the next line."
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
@@ -1019,11 +1088,12 @@ Point is at the beginning of the next line."
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 (char-valid-p (nth 3 state)) 1092 (if q
1024 font-lock-string-face 1093 (if (char-valid-p 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.