[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: shell-script mode vs. quoted apostrophe

From: Stefan Monnier
Subject: Re: shell-script mode vs. quoted apostrophe
Date: Wed, 30 May 2007 20:04:14 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux)

>> shell-script mode thinks everything after the quoted apostrophe is
>> quoted at least judging from the color.
>> GNU Emacs (i486-pc-linux-gnu, X toolkit, Xaw3d scroll bars) of 
>> 2007-03-03 on pacem, modified by Debian
>> #!/bin/sh -ex
>> test $# -eq 3 ||{ echo $0: couldn\'t look it up in $f 1>&2; exit 55;}
>> exec pppd user $1 $extra_opts connect \
>> "chat -v -f /etc/chatscripts/generic -T $2"

The patch below may fix it.

> Most shell scripts require that within single quotes _all_ characters
> get quoted, including the backslash.  Emacs resolves this by removing
> the escape property for a backslash whenever it appears before a single
> quote due to the following (inherently wrong) specification within
> `sh-font-lock-syntactic-keywords':

>     ;; In a '...' the backslash is not escaping.
>     ("\\(\\\\\\)'" 1 ,sh-st-punc)


> This strips the escape property from _any_ backslash preceding a single
> quote (since it does not render backslashes non-escaping when they are
> followed by any other character within single quotes the specification
> is obviously wrong, without visible consequences, though).  In your case
> things go wrong outside a single quote environment: The backslash in
> couldn\'t gets punctuation syntax, doesn't escape the subsequent quote,
> which consequently starts quoting everything after it ...


> I'm afraid that solving this is non-trivial.  It could be done by
> calling the parser in font-lock's syntactic keyword pass

Yup, that's what the patch does.

> but this would render font-lock unbearably slow.

It shouldn't be a problem except maybe for very unusual cases such as with
long lines of \'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'.


--- orig/lisp/progmodes/sh-script.el
+++ mod/lisp/progmodes/sh-script.el
@@ -1062,6 +1062,19 @@
     (when (save-excursion (backward-char 2) (looking-at ";;\\|in"))
+(defun sh-font-lock-backslash-quote ()
+  (if (eq (save-excursion (nth 3 (syntax-ppss (match-beginning 0)))) ?\')
+      ;; In a '...' the backslash is not escaping.
+      sh-st-punc
+    nil))
+(defun sh-font-lock-flush-syntax-ppss-cache (limit)
+  ;; This should probably be a standard function provided by font-lock.el
+  ;; (or syntax.el).
+  (syntax-ppss-flush-cache (point))
+  (goto-char limit)
+  nil)
 (defun sh-apply-quoted-subshell ()
   "Apply the `sh-st-punc' syntax to all the matches in `match-data'.
 This is used to flag quote characters in subshell constructs inside strings
@@ -1080,7 +1093,11 @@
   ;; of the shell command language (under `quoting') but with `$' removed.
   `(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 ,sh-st-symbol)
     ;; In a '...' the backslash is not escaping.
-    ("\\(\\\\\\)'" 1 ,sh-st-punc)
+    ("\\(\\\\\\)'" (1 (sh-font-lock-backslash-quote)))
+    ;; The previous rule uses syntax-ppss, but the subsequent rules may
+    ;; change the syntax, so we have to tell syntax-ppss that the states it
+    ;; has just computed will need to be recomputed.
+    (sh-font-lock-flush-syntax-ppss-cache)
     ;; Make sure $@ and @? are correctly recognized as sexps.
     ("\\$\\(address@hidden)" 1 ,sh-st-symbol)
     ;; Find HEREDOC starters and add a corresponding rule for the ender.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]