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)