[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 22.0.95.1 (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)
Indeed.
> 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 ...
Exactly.
> 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 \'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'\'.
Stefan
--- 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"))
sh-st-punc)))
+(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.