aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2015-06-15 17:10:06 -0400
committerStefan Monnier2015-06-15 17:10:06 -0400
commitf784272f7381dfd1fc1e6ba2c3c79cd1b7a9c5cd (patch)
tree5a0ff1dcff3763633edc0ff586dab519554bad5b
parente58a815339fe77f184da8e71e3b932a46b2c0433 (diff)
downloademacs-f784272f7381dfd1fc1e6ba2c3c79cd1b7a9c5cd.tar.gz
emacs-f784272f7381dfd1fc1e6ba2c3c79cd1b7a9c5cd.zip
* lisp/progmodes/perl-mode.el: Refine handling of /re/ and y/abc/def/
(perl--syntax-exp-intro-keywords): New var. (perl--syntax-exp-intro-regexp, perl-syntax-propertize-function): Use it. (bug#20800).
-rw-r--r--lisp/progmodes/perl-mode.el36
-rwxr-xr-xtest/indent/perl.perl8
2 files changed, 33 insertions, 11 deletions
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index a64944f0dc5..3521a139809 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -204,10 +204,13 @@
204 '((?\( . ?\)) (?\[ . ?\]) (?\{ . ?\}) (?\< . ?\>))) 204 '((?\( . ?\)) (?\[ . ?\]) (?\{ . ?\}) (?\< . ?\>)))
205 205
206(eval-and-compile 206(eval-and-compile
207 (defconst perl--syntax-exp-intro-keywords
208 '("split" "if" "unless" "until" "while" "print"
209 "grep" "map" "not" "or" "and" "for" "foreach"))
210
207 (defconst perl--syntax-exp-intro-regexp 211 (defconst perl--syntax-exp-intro-regexp
208 (concat "\\(?:\\(?:^\\|[^$@&%[:word:]]\\)" 212 (concat "\\(?:\\(?:^\\|[^$@&%[:word:]]\\)"
209 (regexp-opt '("split" "if" "unless" "until" "while" "print" 213 (regexp-opt perl--syntax-exp-intro-keywords)
210 "grep" "map" "not" "or" "and" "for" "foreach"))
211 "\\|[-?:.,;|&+*=!~({[]\\|\\(^\\)\\)[ \t\n]*"))) 214 "\\|[-?:.,;|&+*=!~({[]\\|\\(^\\)\\)[ \t\n]*")))
212 215
213;; FIXME: handle here-docs and regexps. 216;; FIXME: handle here-docs and regexps.
@@ -278,8 +281,13 @@
278 (forward-comment (- (point-max))) 281 (forward-comment (- (point-max)))
279 (put-text-property (point) (match-end 2) 282 (put-text-property (point) (match-end 2)
280 'syntax-multiline t) 283 'syntax-multiline t)
281 (not (memq (char-before) 284 (not (or (and (eq ?w (char-syntax (preceding-char)))
282 '(?? ?: ?. ?, ?\; ?= ?! ?~ ?\( ?\[))))) 285 (let ((end (point)))
286 (backward-sexp 1)
287 (member (buffer-substring (point) end)
288 perl--syntax-exp-intro-keywords)))
289 (memq (char-before)
290 '(?? ?: ?. ?, ?\; ?= ?! ?~ ?\( ?\[))))))
283 nil ;; A division sign instead of a regexp-match. 291 nil ;; A division sign instead of a regexp-match.
284 (put-text-property (match-beginning 2) (match-end 2) 292 (put-text-property (match-beginning 2) (match-end 2)
285 'syntax-table (string-to-syntax "\"")) 293 'syntax-table (string-to-syntax "\""))
@@ -297,13 +305,19 @@
297 (looking-at-p "sub[ \t\n]")) 305 (looking-at-p "sub[ \t\n]"))
298 ;; This is defining a function. 306 ;; This is defining a function.
299 nil 307 nil
300 (put-text-property (match-beginning 3) (match-end 3) 308 (unless (nth 8 (save-excursion (syntax-ppss (match-beginning 1))))
301 'syntax-table 309 ;; Don't add this syntax-table property if
302 (if (assoc (char-after (match-beginning 3)) 310 ;; within a string, which would misbehave in cases such as
303 perl-quote-like-pairs) 311 ;; $a = "foo y \"toto\" bar" where we'd end up changing the
304 (string-to-syntax "|") 312 ;; syntax of the backslash and hence de-escaping the embedded
305 (string-to-syntax "\""))) 313 ;; double quote.
306 (perl-syntax-propertize-special-constructs end))))) 314 (put-text-property (match-beginning 3) (match-end 3)
315 'syntax-table
316 (if (assoc (char-after (match-beginning 3))
317 perl-quote-like-pairs)
318 (string-to-syntax "|")
319 (string-to-syntax "\"")))
320 (perl-syntax-propertize-special-constructs end))))))
307 ;; Here documents. 321 ;; Here documents.
308 ((concat 322 ((concat
309 "\\(?:" 323 "\\(?:"
diff --git a/test/indent/perl.perl b/test/indent/perl.perl
index ea487543219..f86a09b2733 100755
--- a/test/indent/perl.perl
+++ b/test/indent/perl.perl
@@ -59,3 +59,11 @@ print "hello" for /./;
59 59
60$fileType_filesButNot # bug#12373? 60$fileType_filesButNot # bug#12373?
61 = join( '|', map { quotemeta($_).'$' } @{$fileType->{filesButNot}} ); 61 = join( '|', map { quotemeta($_).'$' } @{$fileType->{filesButNot}} );
62
63# There can be a comment between an if/when/while and a /<re>/ matcher!
64return 'W' if #/^Not Available on Mobile/m; #W=Web only
65 /This video is not available on mobile devices./m; #bug#20800
66
67# A "y|abc|def|" shouldn't interfere when inside a string!
68$toto = " x \" string\"";
69$toto = " y \" string\""; # This is not the `y' operator!