> #!/bin/bash > cat << EOF | \ > tee -a bug.txt > This is a test case for a bug in bash shell mode text highlighting > EOF
If people who hack on SH scripts with lots of heredoc thingies could try the patch below, it would help. It's relative to the Emacs-CVS code. It seems "safe" and appears to do the right thing with the above example, but I'd like to get some positive feedback before installing it, Stefan --- orig/lisp/progmodes/sh-script.el +++ mod/lisp/progmodes/sh-script.el @@ -869,7 +869,18 @@ (defconst sh-st-symbol (string-to-syntax "_")) (defconst sh-here-doc-syntax (string-to-syntax "|")) ;; generic string -(defconst sh-here-doc-open-re "<<-?\\s-*\\\\?\\(\\(?:['\"][^'\"]+['\"]\\|\\sw\\)+\\).*\\(\n\\)") +(defconst sh-escaped-line-re + (concat + "\\(?:" + ;; First the real regexp. + "\\(?:.*[^\\\n]\\)?\\(?:\\(?:\\\\\\\\\\)*\\\\\n\\(?:.*[^\\\n]\\)?\\)*" + ;; Then a failsafe fallback: in case the search boundary prevents us from + ;; finding the actual end of line. + "\\|.*\\)")) + +(defconst sh-here-doc-open-re + (concat "<<-?\\s-*\\\\?\\(\\(?:['\"][^'\"]+['\"]\\|\\sw\\)+\\)" + sh-escaped-line-re "\\(\n\\)")) (defvar sh-here-doc-markers nil) (make-variable-buffer-local 'sh-here-doc-markers) @@ -883,7 +894,9 @@ ;; A rough regexp that should find the opening <<EOF back. (sre (concat "<<\\(-?\\)\\s-*['\"\\]?" ;; Use \s| to cheaply check it's an open-heredoc. - eof-re "['\"]?\\([ \t|;&)<>].*\\)?\\s|")) + eof-re "['\"]?\\([ \t|;&)<>]" + sh-escaped-line-re + "\\)?\\s|")) ;; A regexp that will find other EOFs. (ere (concat "^" (if indented "[ \t]*") eof-re "\n")) (start (save-excursion @@ -922,7 +935,8 @@ START is the position of <<. STRING is the actual word used as delimiter (f.ex. \"EOF\"). INDENTED is non-nil if the here document's content (and the EOF mark) can -be indented (i.e. a <<- was used rather than just <<)." +be indented (i.e. a <<- was used rather than just <<). +Point is at the beginning of the next line." (unless (or (memq (char-before start) '(?< ?>)) (sh-in-comment-or-string start)) ;; We're looking at <<STRING, so we add "^STRING$" to the syntactic @@ -933,6 +947,20 @@ (setq sh-here-doc-re (concat sh-here-doc-open-re "\\|^\\([ \t]*\\)" (regexp-opt sh-here-doc-markers t) "\\(\n\\)")))) + (let ((ppss (save-excursion (syntax-ppss (1- (point)))))) + (if (nth 4 ppss) + ;; The \n not only starts the heredoc but also closes a comment. + ;; Let's close the comment just before the \n. + (put-text-property (1- (point)) (point) 'syntax-table '(12))) ;">" + (if (or (> (count-lines start (point)) 1) (nth 5 ppss)) + ;; If the sh-escaped-line-re part of sh-here-doc-re has matched + ;; several lines, make sure we refontify them together. + ;; Furthermore, if (nth 5 ppss) is non-nil (i.e. the \n is + ;; escaped), it means we haven't actually found the right \n. + ;; Don't bother fixing it now, but place a multiline property so + ;; that when jit-lock-context-* refontifies the rest of the + ;; buffer, it also refontifies the current line with it. + (put-text-property start (point) 'font-lock-multiline t))) sh-here-doc-syntax)) (defun sh-font-lock-here-doc (limit) _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel