Mercurial > emacs
comparison lisp/progmodes/cperl-mode.el @ 78750:c727abfbb05e
Merge upstream 5.23.
(cperl-where-am-i): Remove function.
(cperl-backward-to-noncomment): Don't go too far when skipping POD/HEREs
(cperl-sniff-for-indent): De-invert [string] and [comment].
When looking for label, skip s:m:y:tr.
(cperl-indent-line): Likewise.
(cperl-mode): Don't assume `font-lock-multiline' is auto-local.
(cperl-windowed-init): Wrong `ps-print' handling.
Both thanks to Chong Yidong.
(cperl-look-at-leading-count): Could fail with unfinished RExen.
(cperl-find-pods-heres): If the second part of s()[] is missing,
don't try to highlight delimiters...
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 07 Sep 2007 04:37:28 +0000 |
parents | ccfc1f1f4817 |
children | f81c00b9c0ff 5039706521c9 |
comparison
equal
deleted
inserted
replaced
78749:4256a2145ba2 | 78750:c727abfbb05e |
---|---|
2633 ;;((looking-at "[ \t]*#") | 2633 ;;((looking-at "[ \t]*#") |
2634 ;; (setq indent 0)) | 2634 ;; (setq indent 0)) |
2635 (t | 2635 (t |
2636 (skip-chars-forward " \t") | 2636 (skip-chars-forward " \t") |
2637 (if (listp indent) (setq indent (car indent))) | 2637 (if (listp indent) (setq indent (car indent))) |
2638 (cond ((looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]") | 2638 (cond ((and (looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]") |
2639 (not (looking-at "[smy]:\\|tr:"))) | |
2639 (and (> indent 0) | 2640 (and (> indent 0) |
2640 (setq indent (max cperl-min-label-indent | 2641 (setq indent (max cperl-min-label-indent |
2641 (+ indent cperl-label-offset))))) | 2642 (+ indent cperl-label-offset))))) |
2642 ((= (following-char) ?}) | 2643 ((= (following-char) ?}) |
2643 (setq indent (- indent cperl-indent-level))) | 2644 (setq indent (- indent cperl-indent-level))) |
2808 is-block char-after p)) | 2809 is-block char-after p)) |
2809 (t ; No preceeding line... | 2810 (t ; No preceeding line... |
2810 (vector 'indentable 'first-line p)))) | 2811 (vector 'indentable 'first-line p)))) |
2811 ((get-text-property char-after-pos 'REx-part2) | 2812 ((get-text-property char-after-pos 'REx-part2) |
2812 (vector 'REx-part2 (point))) | 2813 (vector 'REx-part2 (point))) |
2814 ((nth 4 state) | |
2815 [comment]) | |
2813 ((nth 3 state) | 2816 ((nth 3 state) |
2814 [comment]) | |
2815 ((nth 4 state) | |
2816 [string]) | 2817 [string]) |
2817 ;; XXXX Do we need to special-case this? | 2818 ;; XXXX Do we need to special-case this? |
2818 ((null containing-sexp) | 2819 ((null containing-sexp) |
2819 ;; Line is at top level. May be data or function definition, | 2820 ;; Line is at top level. May be data or function definition, |
2820 ;; or may be function argument declaration. | 2821 ;; or may be function argument declaration. |
2916 (save-excursion | 2917 (save-excursion |
2917 (forward-char 1) | 2918 (forward-char 1) |
2918 (let ((colon-line-end 0)) | 2919 (let ((colon-line-end 0)) |
2919 (while | 2920 (while |
2920 (progn (skip-chars-forward " \t\n") | 2921 (progn (skip-chars-forward " \t\n") |
2921 (looking-at "#\\|[a-zA-Z0-9_$]*:[^:]\\|=[a-zA-Z]")) | 2922 ;; s: foo : bar :x is NOT label |
2923 (and (looking-at "#\\|\\([a-zA-Z0-9_$]+\\):[^:]\\|=[a-zA-Z]") | |
2924 (not (looking-at "[sym]:\\|tr:")))) | |
2922 ;; Skip over comments and labels following openbrace. | 2925 ;; Skip over comments and labels following openbrace. |
2923 (cond ((= (following-char) ?\#) | 2926 (cond ((= (following-char) ?\#) |
2924 (forward-line 1)) | 2927 (forward-line 1)) |
2925 ((= (following-char) ?\=) | 2928 ((= (following-char) ?\=) |
2926 (goto-char | 2929 (goto-char |
2987 ;; Get initial indentation of the line we are on. | 2990 ;; Get initial indentation of the line we are on. |
2988 ;; If line starts with label, calculate label indentation | 2991 ;; If line starts with label, calculate label indentation |
2989 (vector 'code-start-in-block containing-sexp char-after | 2992 (vector 'code-start-in-block containing-sexp char-after |
2990 (and delim (not is-block)) ; is a HASH | 2993 (and delim (not is-block)) ; is a HASH |
2991 old-indent ; brace first thing on a line | 2994 old-indent ; brace first thing on a line |
2992 nil (point) ; nothing interesting before | 2995 nil (point))))))))))))))) ; nothing interesting before |
2993 )))))))))))))) | |
2994 | 2996 |
2995 (defvar cperl-indent-rules-alist | 2997 (defvar cperl-indent-rules-alist |
2996 '((pod nil) ; via `syntax-type' property | 2998 '((pod nil) ; via `syntax-type' property |
2997 (here-doc nil) ; via `syntax-type' property | 2999 (here-doc nil) ; via `syntax-type' property |
2998 (here-doc-delim nil) ; via `syntax-type' property | 3000 (here-doc-delim nil) ; via `syntax-type' property |
3002 (string t) | 3004 (string t) |
3003 (comment nil)) | 3005 (comment nil)) |
3004 "Alist of indentation rules for CPerl mode. | 3006 "Alist of indentation rules for CPerl mode. |
3005 The values mean: | 3007 The values mean: |
3006 nil: do not indent; | 3008 nil: do not indent; |
3007 number: add this amount of indentation. | 3009 number: add this amount of indentation.") |
3008 | |
3009 Not finished.") | |
3010 | 3010 |
3011 (defun cperl-calculate-indent (&optional parse-data) ; was parse-start | 3011 (defun cperl-calculate-indent (&optional parse-data) ; was parse-start |
3012 "Return appropriate indentation for current line as Perl code. | 3012 "Return appropriate indentation for current line as Perl code. |
3013 In usual case returns an integer: the column to indent to. | 3013 In usual case returns an integer: the column to indent to. |
3014 Returns nil if line starts inside a string, t if in a comment. | 3014 Returns nil if line starts inside a string, t if in a comment. |
3129 ;; | 3129 ;; |
3130 ;; Indenter for lines in a block which are not leading lines | 3130 ;; Indenter for lines in a block which are not leading lines |
3131 ;; | 3131 ;; |
3132 ((eq 'have-prev-sibling (elt i 0)) | 3132 ((eq 'have-prev-sibling (elt i 0)) |
3133 ;; [have-prev-sibling sibling-beg colon-line-end block-start] | 3133 ;; [have-prev-sibling sibling-beg colon-line-end block-start] |
3134 (goto-char (elt i 1)) | 3134 (goto-char (elt i 1)) ; sibling-beg |
3135 (if (> (elt i 2) (point)) ; colon-line-end; After-label, same line | 3135 (if (> (elt i 2) (point)) ; colon-line-end; have label before point |
3136 (if (> (current-indentation) | 3136 (if (> (current-indentation) |
3137 cperl-min-label-indent) | 3137 cperl-min-label-indent) |
3138 (- (current-indentation) cperl-label-offset) | 3138 (- (current-indentation) cperl-label-offset) |
3139 ;; Do not believe: `max' was involved in calculation of indent | 3139 ;; Do not believe: `max' was involved in calculation of indent |
3140 (+ cperl-indent-level | 3140 (+ cperl-indent-level |
3181 (current-indentation)))))) | 3181 (current-indentation)))))) |
3182 (t | 3182 (t |
3183 (error "Unrecognized value of indent: %s" i)))) | 3183 (error "Unrecognized value of indent: %s" i)))) |
3184 (t | 3184 (t |
3185 (error "Got strange value of indent: %s" i)))))) | 3185 (error "Got strange value of indent: %s" i)))))) |
3186 | |
3187 (defvar cperl-indent-alist | |
3188 '((string nil) | |
3189 (comment nil) | |
3190 (toplevel 0) | |
3191 (toplevel-after-parenth 2) | |
3192 (toplevel-continued 2) | |
3193 (expression 1)) | |
3194 "Alist of indentation rules for CPerl mode. | |
3195 The values mean: | |
3196 nil: do not indent; | |
3197 number: add this amount of indentation. | |
3198 | |
3199 Not finished, not used.") | |
3200 | |
3201 (defun cperl-where-am-i (&optional parse-start start-state) | |
3202 ;; Unfinished | |
3203 "Return a list of lists ((TYPE POS)...) of good points before the point. | |
3204 POS may be nil if it is hard to find, say, when TYPE is `string' or `comment'. | |
3205 | |
3206 Not finished, not used." | |
3207 (save-excursion | |
3208 (let* ((start-point (point)) unused | |
3209 (s-s (cperl-get-state)) | |
3210 (start (nth 0 s-s)) | |
3211 (state (nth 1 s-s)) | |
3212 (prestart (nth 3 s-s)) | |
3213 (containing-sexp (car (cdr state))) | |
3214 (case-fold-search nil) | |
3215 (res (list (list 'parse-start start) (list 'parse-prestart prestart)))) | |
3216 (cond ((nth 3 state) ; In string | |
3217 (setq res (cons (list 'string nil (nth 3 state)) res))) ; What started string | |
3218 ((nth 4 state) ; In comment | |
3219 (setq res (cons '(comment) res))) | |
3220 ((null containing-sexp) | |
3221 ;; Line is at top level. | |
3222 ;; Indent like the previous top level line | |
3223 ;; unless that ends in a closeparen without semicolon, | |
3224 ;; in which case this line is the first argument decl. | |
3225 (cperl-backward-to-noncomment (or parse-start (point-min))) | |
3226 ;;(skip-chars-backward " \t\f\n") | |
3227 (cond | |
3228 ((or (bobp) | |
3229 (memq (preceding-char) (append ";}" nil))) | |
3230 (setq res (cons (list 'toplevel start) res))) | |
3231 ((eq (preceding-char) ?\) ) | |
3232 (setq res (cons (list 'toplevel-after-parenth start) res))) | |
3233 (t | |
3234 (setq res (cons (list 'toplevel-continued start) res))))) | |
3235 ((/= (char-after containing-sexp) ?{) | |
3236 ;; line is expression, not statement: | |
3237 ;; indent to just after the surrounding open. | |
3238 ;; skip blanks if we do not close the expression. | |
3239 (setq res (cons (list 'expression-blanks | |
3240 (progn | |
3241 (goto-char (1+ containing-sexp)) | |
3242 (or (looking-at "[ \t]*\\(#\\|$\\)") | |
3243 (skip-chars-forward " \t")) | |
3244 (point))) | |
3245 (cons (list 'expression containing-sexp) res)))) | |
3246 ((progn | |
3247 ;; Containing-expr starts with \{. Check whether it is a hash. | |
3248 (goto-char containing-sexp) | |
3249 (not (cperl-block-p))) | |
3250 (setq res (cons (list 'expression-blanks | |
3251 (progn | |
3252 (goto-char (1+ containing-sexp)) | |
3253 (or (looking-at "[ \t]*\\(#\\|$\\)") | |
3254 (skip-chars-forward " \t")) | |
3255 (point))) | |
3256 (cons (list 'expression containing-sexp) res)))) | |
3257 (t | |
3258 ;; Statement level. | |
3259 (setq res (cons (list 'in-block containing-sexp) res)) | |
3260 ;; Is it a continuation or a new statement? | |
3261 ;; Find previous non-comment character. | |
3262 (cperl-backward-to-noncomment containing-sexp) | |
3263 ;; Back up over label lines, since they don't | |
3264 ;; affect whether our line is a continuation. | |
3265 ;; Back up comma-delimited lines too ????? | |
3266 (while (or (eq (preceding-char) ?\,) | |
3267 (save-excursion (cperl-after-label))) | |
3268 (if (eq (preceding-char) ?\,) | |
3269 ;; Will go to beginning of line, essentially | |
3270 ;; Will ignore embedded sexpr XXXX. | |
3271 (cperl-backward-to-start-of-continued-exp containing-sexp)) | |
3272 (beginning-of-line) | |
3273 (cperl-backward-to-noncomment containing-sexp)) | |
3274 ;; Now we get the answer. | |
3275 (if (not (memq (preceding-char) (append ";}{" '(nil)))) ; Was ?\, | |
3276 ;; This line is continuation of preceding line's statement. | |
3277 (list (list 'statement-continued containing-sexp)) | |
3278 ;; This line starts a new statement. | |
3279 ;; Position following last unclosed open. | |
3280 (goto-char containing-sexp) | |
3281 ;; Is line first statement after an open-brace? | |
3282 (or | |
3283 ;; If no, find that first statement and indent like | |
3284 ;; it. If the first statement begins with label, do | |
3285 ;; not believe when the indentation of the label is too | |
3286 ;; small. | |
3287 (save-excursion | |
3288 (forward-char 1) | |
3289 (let ((colon-line-end 0)) | |
3290 (while (progn (skip-chars-forward " \t\n" start-point) | |
3291 (and (< (point) start-point) | |
3292 (looking-at | |
3293 "#\\|[a-zA-Z_][a-zA-Z0-9_]*:[^:]"))) | |
3294 ;; Skip over comments and labels following openbrace. | |
3295 (cond ((= (following-char) ?\#) | |
3296 ;;(forward-line 1) | |
3297 (end-of-line)) | |
3298 ;; label: | |
3299 (t | |
3300 (save-excursion (end-of-line) | |
3301 (setq colon-line-end (point))) | |
3302 (search-forward ":")))) | |
3303 ;; Now at the point, after label, or at start | |
3304 ;; of first statement in the block. | |
3305 (and (< (point) start-point) | |
3306 (if (> colon-line-end (point)) | |
3307 ;; Before statement after label | |
3308 (if (> (current-indentation) | |
3309 cperl-min-label-indent) | |
3310 (list (list 'label-in-block (point))) | |
3311 ;; Do not believe: `max' is involved | |
3312 (list | |
3313 (list 'label-in-block-min-indent (point)))) | |
3314 ;; Before statement | |
3315 (list 'statement-in-block (point)))))) | |
3316 ;; If no previous statement, | |
3317 ;; indent it relative to line brace is on. | |
3318 ;; For open brace in column zero, don't let statement | |
3319 ;; start there too. If cperl-indent-level is zero, | |
3320 ;; use cperl-brace-offset + cperl-continued-statement-offset instead. | |
3321 ;; For open-braces not the first thing in a line, | |
3322 ;; add in cperl-brace-imaginary-offset. | |
3323 | |
3324 ;; If first thing on a line: ????? | |
3325 (setq unused ; This is not finished... | |
3326 (+ (if (and (bolp) (zerop cperl-indent-level)) | |
3327 (+ cperl-brace-offset cperl-continued-statement-offset) | |
3328 cperl-indent-level) | |
3329 ;; Move back over whitespace before the openbrace. | |
3330 ;; If openbrace is not first nonwhite thing on the line, | |
3331 ;; add the cperl-brace-imaginary-offset. | |
3332 (progn (skip-chars-backward " \t") | |
3333 (if (bolp) 0 cperl-brace-imaginary-offset)) | |
3334 ;; If the openbrace is preceded by a parenthesized exp, | |
3335 ;; move to the beginning of that; | |
3336 ;; possibly a different line | |
3337 (progn | |
3338 (if (eq (preceding-char) ?\)) | |
3339 (forward-sexp -1)) | |
3340 ;; Get initial indentation of the line we are on. | |
3341 ;; If line starts with label, calculate label indentation | |
3342 (if (save-excursion | |
3343 (beginning-of-line) | |
3344 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]")) | |
3345 (if (> (current-indentation) cperl-min-label-indent) | |
3346 (- (current-indentation) cperl-label-offset) | |
3347 (cperl-calculate-indent)) | |
3348 (current-indentation))))))))) | |
3349 res))) | |
3350 | 3186 |
3351 (defun cperl-calculate-indent-within-comment () | 3187 (defun cperl-calculate-indent-within-comment () |
3352 "Return the indentation amount for line, assuming that | 3188 "Return the indentation amount for line, assuming that |
3353 the current line is to be regarded as part of a block comment." | 3189 the current line is to be regarded as part of a block comment." |
3354 (let (end star-start) | 3190 (let (end star-start) |
3740 (modify-syntax-entry ?\) "." st))) | 3576 (modify-syntax-entry ?\) "." st))) |
3741 (if reset-st | 3577 (if reset-st |
3742 (set-syntax-table reset-st)))) | 3578 (set-syntax-table reset-st)))) |
3743 | 3579 |
3744 (defsubst cperl-look-at-leading-count (is-x-REx e) | 3580 (defsubst cperl-look-at-leading-count (is-x-REx e) |
3745 (if (and (> (point) e) | 3581 (if (and |
3746 ;; return nil on failure, no moving | 3582 (< (point) e) |
3747 (re-search-forward (concat "\\=" | 3583 (re-search-forward (concat "\\=" (if is-x-REx "[ \t\n]*" "") "[{?+*]") |
3748 (if is-x-REx "[ \t\n]*" "") | 3584 (1- e) t)) ; return nil on failure, no moving |
3749 "[{?+*]") | |
3750 (1- e) t)) | |
3751 (if (eq ?\{ (preceding-char)) nil | 3585 (if (eq ?\{ (preceding-char)) nil |
3752 (cperl-postpone-fontification | 3586 (cperl-postpone-fontification |
3753 (1- (point)) (point) | 3587 (1- (point)) (point) |
3754 'face font-lock-warning-face)))) | 3588 'face font-lock-warning-face)))) |
3755 | 3589 |
4789 REx-subgr-start REx-subgr-end | 4623 REx-subgr-start REx-subgr-end |
4790 'face font-lock-comment-face)))))) | 4624 'face font-lock-comment-face)))))) |
4791 (if (and is-REx is-x-REx) | 4625 (if (and is-REx is-x-REx) |
4792 (put-text-property (1+ b) (1- e) | 4626 (put-text-property (1+ b) (1- e) |
4793 'syntax-subtype 'x-REx))) | 4627 'syntax-subtype 'x-REx))) |
4794 (if i2 | 4628 (if (and i2 e1 b1 (> e1 b1)) |
4795 (progn | 4629 (progn ; No errors finding the second part... |
4796 (cperl-postpone-fontification | 4630 (cperl-postpone-fontification |
4797 (1- e1) e1 'face my-cperl-delimiters-face) | 4631 (1- e1) e1 'face my-cperl-delimiters-face) |
4798 (if (and (not (eobp)) | 4632 (if (and (not (eobp)) |
4799 (assoc (char-after b) cperl-starters)) | 4633 (assoc (char-after b) cperl-starters)) |
4800 (progn | 4634 (progn |
4889 (skip-chars-backward " \t\n\f" lim) | 4723 (skip-chars-backward " \t\n\f" lim) |
4890 (setq p (point)) | 4724 (setq p (point)) |
4891 (beginning-of-line) | 4725 (beginning-of-line) |
4892 (if (memq (setq pr (get-text-property (point) 'syntax-type)) | 4726 (if (memq (setq pr (get-text-property (point) 'syntax-type)) |
4893 '(pod here-doc here-doc-delim)) | 4727 '(pod here-doc here-doc-delim)) |
4894 (cperl-unwind-to-safe nil) | 4728 (progn |
4895 (or (and (looking-at "^[ \t]*\\(#\\|$\\)") | 4729 (cperl-unwind-to-safe nil) |
4896 (not (memq pr '(string prestring)))) | 4730 (setq pr (get-text-property (point) 'syntax-type)))) |
4897 (progn (cperl-to-comment-or-eol) (bolp)) | 4731 (or (and (looking-at "^[ \t]*\\(#\\|$\\)") |
4898 (progn | 4732 (not (memq pr '(string prestring)))) |
4899 (skip-chars-backward " \t") | 4733 (progn (cperl-to-comment-or-eol) (bolp)) |
4900 (if (< p (point)) (goto-char p)) | 4734 (progn |
4901 (setq stop t))))))) | 4735 (skip-chars-backward " \t") |
4736 (if (< p (point)) (goto-char p)) | |
4737 (setq stop t)))))) | |
4902 | 4738 |
4903 ;; Used only in `cperl-calculate-indent'... | 4739 ;; Used only in `cperl-calculate-indent'... |
4904 (defun cperl-block-p () ; Do not C-M-q ! One string contains ";" ! | 4740 (defun cperl-block-p () ; Do not C-M-q ! One string contains ";" ! |
4905 ;; Positions is before ?\{. Checks whether it starts a block. | 4741 ;; Positions is before ?\{. Checks whether it starts a block. |
4906 ;; No save-excursion! This is more a distinguisher of a block/hash ref... | 4742 ;; No save-excursion! This is more a distinguisher of a block/hash ref... |
5721 | 5557 |
5722 | 5558 |
5723 (defun cperl-windowed-init () | 5559 (defun cperl-windowed-init () |
5724 "Initialization under windowed version." | 5560 "Initialization under windowed version." |
5725 (cond ((featurep 'ps-print) | 5561 (cond ((featurep 'ps-print) |
5726 (unless cperl-faces-init | 5562 (or cperl-faces-init |
5727 (if (boundp 'font-lock-multiline) | 5563 (progn |
5728 (setq cperl-font-lock-multiline t)) | 5564 (and (boundp 'font-lock-multiline) |
5729 (cperl-init-faces))) | 5565 (setq cperl-font-lock-multiline t)) |
5566 (cperl-init-faces)))) | |
5730 ((not cperl-faces-init) | 5567 ((not cperl-faces-init) |
5731 (add-hook 'font-lock-mode-hook | 5568 (add-hook 'font-lock-mode-hook |
5732 (function | 5569 (function |
5733 (lambda () | 5570 (lambda () |
5734 (if (memq major-mode '(perl-mode cperl-mode)) | 5571 (if (memq major-mode '(perl-mode cperl-mode)) |
9039 (save-excursion | 8876 (save-excursion |
9040 (goto-char from) | 8877 (goto-char from) |
9041 (cperl-fontify-syntaxically to))))) | 8878 (cperl-fontify-syntaxically to))))) |
9042 | 8879 |
9043 (defvar cperl-version | 8880 (defvar cperl-version |
9044 (let ((v "Revision: 5.22")) | 8881 (let ((v "Revision: 5.23")) |
9045 (string-match ":\\s *\\([0-9.]+\\)" v) | 8882 (string-match ":\\s *\\([0-9.]+\\)" v) |
9046 (substring v (match-beginning 1) (match-end 1))) | 8883 (substring v (match-beginning 1) (match-end 1))) |
9047 "Version of IZ-supported CPerl package this file is based on.") | 8884 "Version of IZ-supported CPerl package this file is based on.") |
9048 | 8885 |
9049 (provide 'cperl-mode) | 8886 (provide 'cperl-mode) |