comparison lisp/progmodes/perl-mode.el @ 66638:4ac8c6441408

(perl-font-lock-special-syntactic-constructs): Rename from perl-font-lock-syntactic-face-function. Change the calling convention so it can be used as a font-lock MATCHER. Do the parse-partial-sexp loop outselves. (perl-font-lock-syntactic-keywords): Use it. (perl-mode): Don't set font-lock-syntactic-face-function any more.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 02 Nov 2005 17:33:28 +0000
parents c136332c98dd
children a11fdee52c05
comparison
equal deleted inserted replaced
66637:7567f8b4780e 66638:4ac8c6441408
250 ;; tr /.../.../ 250 ;; tr /.../.../
251 ;; y /.../.../ 251 ;; y /.../.../
252 ;; 252 ;;
253 ;; <file*glob> 253 ;; <file*glob>
254 (defvar perl-font-lock-syntactic-keywords 254 (defvar perl-font-lock-syntactic-keywords
255 ;; Turn POD into b-style comments 255 ;; TODO: here-documents ("<<\\(\\sw\\|['\"]\\)")
256 '(("^\\(=\\)\\sw" (1 "< b")) 256 '(;; Turn POD into b-style comments
257 ("^\\(=\\)\\sw" (1 "< b"))
257 ("^=cut[ \t]*\\(\n\\)" (1 "> b")) 258 ("^=cut[ \t]*\\(\n\\)" (1 "> b"))
258 ;; Catch ${ so that ${var} doesn't screw up indentation. 259 ;; Catch ${ so that ${var} doesn't screw up indentation.
259 ;; This also catches $' to handle 'foo$', although it should really 260 ;; This also catches $' to handle 'foo$', although it should really
260 ;; check that it occurs inside a '..' string. 261 ;; check that it occurs inside a '..' string.
261 ("\\(\\$\\)[{']" (1 ". p")) 262 ("\\(\\$\\)[{']" (1 ". p"))
273 ;; \s (appears often in regexps). 274 ;; \s (appears often in regexps).
274 ;; -s file 275 ;; -s file
275 (3 (if (assoc (char-after (match-beginning 3)) 276 (3 (if (assoc (char-after (match-beginning 3))
276 perl-quote-like-pairs) 277 perl-quote-like-pairs)
277 '(15) '(7)))) 278 '(15) '(7))))
278 ;; TODO: here-documents ("<<\\(\\sw\\|['\"]\\)") 279 ;; Find and mark the end of funny quotes and format statements.
280 (perl-font-lock-special-syntactic-constructs)
279 )) 281 ))
280 282
281 (defvar perl-empty-syntax-table 283 (defvar perl-empty-syntax-table
282 (let ((st (copy-syntax-table))) 284 (let ((st (copy-syntax-table)))
283 ;; Make all chars be of punctuation syntax. 285 ;; Make all chars be of punctuation syntax.
293 (modify-syntax-entry char "\"" st) 295 (modify-syntax-entry char "\"" st)
294 (modify-syntax-entry char "(" st) 296 (modify-syntax-entry char "(" st)
295 (modify-syntax-entry close ")" st)) 297 (modify-syntax-entry close ")" st))
296 st)) 298 st))
297 299
298 (defun perl-font-lock-syntactic-face-function (state) 300 (defun perl-font-lock-special-syntactic-constructs (limit)
299 (let ((char (nth 3 state))) 301 ;; We used to do all this in a font-lock-syntactic-face-function, which
300 (cond 302 ;; did not work correctly because sometimes some parts of the buffer are
301 ((not char) 303 ;; treated with font-lock-syntactic-keywords but not with
302 ;; Comment or docstring. 304 ;; font-lock-syntactic-face-function (mostly because of
303 (if (nth 7 state) font-lock-doc-face font-lock-comment-face)) 305 ;; font-lock-syntactically-fontified). That meant that some syntax-table
304 ((and (char-valid-p char) (eq (char-syntax (nth 3 state)) ?\")) 306 ;; properties were missing. So now we do the parse-partial-sexp loop
305 ;; Normal string. 307 ;; ourselves directly from font-lock-syntactic-keywords, so we're sure
306 font-lock-string-face) 308 ;; it's done when necessary.
307 ((eq (nth 3 state) ?\n) 309 (let ((state (syntax-ppss))
308 ;; A `format' command. 310 char)
309 (save-excursion 311 (while (< (point) limit)
310 (when (and (re-search-forward "^\\s *\\.\\s *$" nil t) 312 (cond
311 (not (eobp))) 313 ((or (null (setq char (nth 3 state)))
312 (put-text-property (point) (1+ (point)) 'syntax-table '(7))) 314 (and (char-valid-p char) (eq (char-syntax (nth 3 state)) ?\")))
313 font-lock-string-face)) 315 ;; Normal text, or comment, or docstring, or normal string.
314 (t 316 nil)
315 ;; This is regexp like quote thingy. 317 ((eq (nth 3 state) ?\n)
316 (setq char (char-after (nth 8 state))) 318 ;; A `format' command.
317 (save-excursion 319 (save-excursion
318 (let ((twoargs (save-excursion 320 (when (and (re-search-forward "^\\s *\\.\\s *$" nil t)
319 (goto-char (nth 8 state)) 321 (not (eobp)))
320 (skip-syntax-backward " ") 322 (put-text-property (point) (1+ (point)) 'syntax-table '(7)))))
321 (skip-syntax-backward "w") 323 (t
322 (member (buffer-substring 324 ;; This is regexp like quote thingy.
323 (point) (progn (forward-word 1) (point))) 325 (setq char (char-after (nth 8 state)))
324 '("tr" "s" "y")))) 326 (save-excursion
325 (close (cdr (assq char perl-quote-like-pairs))) 327 (let ((twoargs (save-excursion
326 (pos (point)) 328 (goto-char (nth 8 state))
327 (st (perl-quote-syntax-table char))) 329 (skip-syntax-backward " ")
328 (if (not close) 330 (skip-syntax-backward "w")
329 ;; The closing char is the same as the opening char. 331 (member (buffer-substring
330 (with-syntax-table st 332 (point) (progn (forward-word 1) (point)))
331 (parse-partial-sexp (point) (point-max) 333 '("tr" "s" "y"))))
332 nil nil state 'syntax-table) 334 (close (cdr (assq char perl-quote-like-pairs)))
333 (when twoargs 335 (pos (point))
334 (parse-partial-sexp (point) (point-max) 336 (st (perl-quote-syntax-table char)))
335 nil nil state 'syntax-table))) 337 (if (not close)
336 ;; The open/close chars are matched like () [] {} and <>. 338 ;; The closing char is the same as the opening char.
337 (let ((parse-sexp-lookup-properties nil)) 339 (with-syntax-table st
338 (condition-case err 340 (parse-partial-sexp (point) (point-max)
339 (progn 341 nil nil state 'syntax-table)
340 (with-syntax-table st 342 (when twoargs
341 (goto-char (nth 8 state)) (forward-sexp 1)) 343 (parse-partial-sexp (point) (point-max)
342 (when twoargs 344 nil nil state 'syntax-table)))
343 (save-excursion 345 ;; The open/close chars are matched like () [] {} and <>.
344 ;; Skip whitespace and make sure that font-lock will 346 (let ((parse-sexp-lookup-properties nil))
345 ;; refontify the second part in the proper context. 347 (condition-case err
346 (put-text-property 348 (progn
347 (point) (progn (forward-comment (point-max)) (point)) 349 (with-syntax-table st
348 'font-lock-multiline t) 350 (goto-char (nth 8 state)) (forward-sexp 1))
349 ;; 351 (when twoargs
350 (unless 352 (save-excursion
351 (save-excursion 353 ;; Skip whitespace and make sure that font-lock will
352 (with-syntax-table 354 ;; refontify the second part in the proper context.
353 (perl-quote-syntax-table (char-after)) 355 (put-text-property
354 (forward-sexp 1)) 356 (point) (progn (forward-comment (point-max)) (point))
355 (put-text-property pos (line-end-position) 357 'font-lock-multiline t)
356 'jit-lock-defer-multiline t) 358 ;;
357 (looking-at "\\s-*\\sw*e")) 359 (unless
358 (put-text-property (point) (1+ (point)) 360 (save-excursion
359 'syntax-table 361 (with-syntax-table
360 (if (assoc (char-after) 362 (perl-quote-syntax-table (char-after))
361 perl-quote-like-pairs) 363 (forward-sexp 1))
362 '(15) '(7))))))) 364 (put-text-property pos (line-end-position)
363 ;; The arg(s) is not terminated, so it extends until EOB. 365 'jit-lock-defer-multiline t)
364 (scan-error (goto-char (point-max)))))) 366 (looking-at "\\s-*\\sw*e"))
365 ;; Point is now right after the arg(s). 367 (put-text-property (point) (1+ (point))
366 ;; Erase any syntactic marks within the quoted text. 368 'syntax-table
367 (put-text-property pos (1- (point)) 'syntax-table nil) 369 (if (assoc (char-after)
368 (when (eq (char-before (1- (point))) ?$) 370 perl-quote-like-pairs)
369 (put-text-property (- (point) 2) (1- (point)) 371 '(15) '(7)))))))
370 'syntax-table '(1))) 372 ;; The arg(s) is not terminated, so it extends until EOB.
371 (put-text-property (1- (point)) (point) 373 (scan-error (goto-char (point-max))))))
372 'syntax-table (if close '(15) '(7))) 374 ;; Point is now right after the arg(s).
373 font-lock-string-face)))))) 375 ;; Erase any syntactic marks within the quoted text.
374 ;; (if (or twoargs (not (looking-at "\\s-*\\sw*e"))) 376 (put-text-property pos (1- (point)) 'syntax-table nil)
375 ;; font-lock-string-face 377 (when (eq (char-before (1- (point))) ?$)
376 ;; (font-lock-fontify-syntactically-region 378 (put-text-property (- (point) 2) (1- (point))
377 ;; ;; FIXME: `end' is accessed via dyn-scoping. 379 'syntax-table '(1)))
378 ;; pos (min end (1- (point))) nil '(nil)) 380 (put-text-property (1- (point)) (point)
379 ;; nil))))))) 381 'syntax-table (if close '(15) '(7)))))))
382
383 (setq state (parse-partial-sexp (point) limit nil nil state
384 'syntax-table))))
385 ;; Tell font-lock that this needs not further processing.
386 nil)
380 387
381 388
382 (defcustom perl-indent-level 4 389 (defcustom perl-indent-level 4
383 "*Indentation of Perl statements with respect to containing block." 390 "*Indentation of Perl statements with respect to containing block."
384 :type 'integer 391 :type 'integer
529 perl-font-lock-keywords-1 536 perl-font-lock-keywords-1
530 perl-font-lock-keywords-2) 537 perl-font-lock-keywords-2)
531 nil nil ((?\_ . "w")) nil 538 nil nil ((?\_ . "w")) nil
532 (font-lock-syntactic-keywords 539 (font-lock-syntactic-keywords
533 . perl-font-lock-syntactic-keywords) 540 . perl-font-lock-syntactic-keywords)
534 (font-lock-syntactic-face-function
535 . perl-font-lock-syntactic-face-function)
536 (parse-sexp-lookup-properties . t))) 541 (parse-sexp-lookup-properties . t)))
537 ;; Tell imenu how to handle Perl. 542 ;; Tell imenu how to handle Perl.
538 (set (make-local-variable 'imenu-generic-expression) 543 (set (make-local-variable 'imenu-generic-expression)
539 perl-imenu-generic-expression) 544 perl-imenu-generic-expression)
540 (setq imenu-case-fold-search nil) 545 (setq imenu-case-fold-search nil)