1 ;;; cperl-mode.el --- Perl code editing commands for Emacs
3 ;; Copyright (C) 1985, 86, 87, 91, 92, 93, 94, 95, 96, 1997
4 ;; Free Software Foundation, Inc.
6 ;; Author: Ilya Zakharevich and Bob Olson
7 ;; Maintainer: Ilya Zakharevich <ilya@math.ohio-state.edu>
8 ;; Keywords: languages, Perl
10 ;; This file is part of GNU Emacs.
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 2, or (at your option)
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 ;; Boston, MA 02111-1307, USA.
27 ;;; Corrections made by Ilya Zakharevich ilya@math.mps.ohio-state.edu
31 ;;; You can either fine-tune the bells and whistles of this mode or
32 ;;; bulk enable them by putting
34 ;; (setq cperl-hairy t)
36 ;;; in your .emacs file. (Emacs rulers do not consider it politically
37 ;;; correct to make whistles enabled by default.)
39 ;;; DO NOT FORGET to read micro-docs (available from `Perl' menu) <<<<<<
40 ;;; or as help on variables `cperl-tips', `cperl-problems', <<<<<<
41 ;;; `cperl-non-problems', `cperl-praise', `cperl-speed'. <<<<<<
43 ;;; The mode information (on C-h m) provides some customization help.
44 ;;; If you use font-lock feature of this mode, it is advisable to use
45 ;;; either lazy-lock-mode or fast-lock-mode. I prefer lazy-lock.
47 ;;; Faces used now: three faces for first-class and second-class keywords
48 ;;; and control flow words, one for each: comments, string, labels,
49 ;;; functions definitions and packages, arrays, hashes, and variable
50 ;;; definitions. If you do not see all these faces, your font-lock does
51 ;;; not define them, so you need to define them manually.
53 ;;; into your .emacs file.
55 ;;;; This mode supports font-lock, imenu and mode-compile. In the
56 ;;;; hairy version font-lock is on, but you should activate imenu
57 ;;;; yourself (note that mode-compile is not standard yet). Well, you
58 ;;;; can use imenu from keyboard anyway (M-x imenu), but it is better
59 ;;;; to bind it like that:
61 ;; (define-key global-map [M-S-down-mouse-3] 'imenu)
65 ;; Some macros are needed for `defcustom'
66 (if (fboundp 'eval-when-compile
)
68 (defconst cperl-xemacs-p
(string-match "XEmacs\\|Lucid" emacs-version
))
69 (defmacro cperl-is-face
(arg) ; Takes quoted arg
70 (cond ((fboundp 'find-face
)
72 (;;(and (fboundp 'face-list)
75 `(member ,arg
(and (fboundp 'face-list
)
79 (defmacro cperl-make-face
(arg descr
) ; Takes unquoted arg
80 (cond ((fboundp 'make-face
)
81 `(make-face (quote ,arg
)))
83 `(defconst ,arg
(quote ,arg
) ,descr
))))
84 (defmacro cperl-force-face
(arg descr
) ; Takes unquoted arg
86 (or (cperl-is-face (quote ,arg
))
87 (cperl-make-face ,arg
,descr
))
88 (or (boundp (quote ,arg
)) ; We use unquoted variants too
89 (defconst ,arg
(quote ,arg
) ,descr
))))
91 (defmacro cperl-etags-snarf-tag
(file line
)
95 (defmacro cperl-etags-snarf-tag
(file line
)
98 (defmacro cperl-etags-goto-tag-location
(elt)
100 ;; (switch-to-buffer (get-file-buffer (elt (, elt) 0)))
101 ;; (set-buffer (get-file-buffer (elt (, elt) 0)))
102 ;; Probably will not work due to some save-excursion???
103 ;; Or save-file-position?
104 ;; (message "Did I get to line %s?" (elt (, elt) 1))
105 `(goto-line (string-to-int (elt ,elt
1))))
107 (defmacro cperl-etags-goto-tag-location
(elt)
108 `(etags-goto-tag-location ,elt
)))))
110 (defun cperl-choose-color (&rest list
)
114 (if (or (x-color-defined-p (car list
))
116 (setq answer
(car list
))))
117 (setq list
(cdr list
)))
121 "Major mode for editing Perl code."
126 (defgroup cperl-indentation-details nil
131 (defgroup cperl-affected-by-hairy nil
132 "Variables affected by `cperl-hairy'."
136 (defgroup cperl-autoinsert-details nil
137 "Auto-insert tuneup."
141 (defgroup cperl-faces nil
142 "Fontification colors."
146 (defgroup cperl-speed nil
147 "Speed vs. validity tuneup."
151 (defgroup cperl-help-system nil
152 "Help system tuneup."
157 (defcustom cperl-extra-newline-before-brace nil
158 "*Non-nil means that if, elsif, while, until, else, for, foreach
159 and do constructs look like:
171 :group
'cperl-autoinsert-details
)
173 (defcustom cperl-extra-newline-before-brace-multiline
174 cperl-extra-newline-before-brace
175 "*Non-nil means the same as `cperl-extra-newline-before-brace', but
176 for constructs with multiline if/unless/while/until/for/foreach condition."
178 :group
'cperl-autoinsert-details
)
180 (defcustom cperl-indent-level
2
181 "*Indentation of CPerl statements with respect to containing block."
183 :group
'cperl-indentation-details
)
185 (defcustom cperl-lineup-step nil
186 "*`cperl-lineup' will always lineup at multiple of this number.
187 If `nil', the value of `cperl-indent-level' will be used."
188 :type
'(choice (const nil
) integer
)
189 :group
'cperl-indentation-details
)
191 (defcustom cperl-brace-imaginary-offset
0
192 "*Imagined indentation of a Perl open brace that actually follows a statement.
193 An open brace following other text is treated as if it were this far
194 to the right of the start of its line."
196 :group
'cperl-indentation-details
)
198 (defcustom cperl-brace-offset
0
199 "*Extra indentation for braces, compared with other text in same context."
201 :group
'cperl-indentation-details
)
202 (defcustom cperl-label-offset -
2
203 "*Offset of CPerl label lines relative to usual indentation."
205 :group
'cperl-indentation-details
)
206 (defcustom cperl-min-label-indent
1
207 "*Minimal offset of CPerl label lines."
209 :group
'cperl-indentation-details
)
210 (defcustom cperl-continued-statement-offset
2
211 "*Extra indent for lines not starting new statements."
213 :group
'cperl-indentation-details
)
214 (defcustom cperl-continued-brace-offset
0
215 "*Extra indent for substatements that start with open-braces.
216 This is in addition to cperl-continued-statement-offset."
218 :group
'cperl-indentation-details
)
219 (defcustom cperl-close-paren-offset -
1
220 "*Extra indent for substatements that start with close-parenthesis."
222 :group
'cperl-indentation-details
)
224 (defcustom cperl-auto-newline nil
225 "*Non-nil means automatically newline before and after braces,
226 and after colons and semicolons, inserted in CPerl code. The following
227 \\[cperl-electric-backspace] will remove the inserted whitespace.
228 Insertion after colons requires both this variable and
229 `cperl-auto-newline-after-colon' set."
231 :group
'cperl-autoinsert-details
)
233 (defcustom cperl-auto-newline-after-colon nil
234 "*Non-nil means automatically newline even after colons.
235 Subject to `cperl-auto-newline' setting."
237 :group
'cperl-autoinsert-details
)
239 (defcustom cperl-tab-always-indent t
240 "*Non-nil means TAB in CPerl mode should always reindent the current line,
241 regardless of where in the line point is when the TAB command is used."
243 :group
'cperl-indentation-details
)
245 (defcustom cperl-font-lock nil
246 "*Non-nil (and non-null) means CPerl buffers will use font-lock-mode.
247 Can be overwritten by `cperl-hairy' if nil."
248 :type
'(choice (const null
) boolean
)
249 :group
'cperl-affected-by-hairy
)
251 (defcustom cperl-electric-lbrace-space nil
252 "*Non-nil (and non-null) means { after $ in CPerl buffers should be preceded by ` '.
253 Can be overwritten by `cperl-hairy' if nil."
254 :type
'(choice (const null
) boolean
)
255 :group
'cperl-affected-by-hairy
)
257 (defcustom cperl-electric-parens-string
"({[]})<"
258 "*String of parentheses that should be electric in CPerl.
259 Closing ones are electric only if the region is highlighted."
261 :group
'cperl-affected-by-hairy
)
263 (defcustom cperl-electric-parens nil
264 "*Non-nil (and non-null) means parentheses should be electric in CPerl.
265 Can be overwritten by `cperl-hairy' if nil."
266 :type
'(choice (const null
) boolean
)
267 :group
'cperl-affected-by-hairy
)
269 (defvar zmacs-regions
) ; Avoid warning
271 (defcustom cperl-electric-parens-mark
273 (or (and (boundp 'transient-mark-mode
) ; For Emacs
275 (and (boundp 'zmacs-regions
) ; For XEmacs
277 "*Not-nil means that electric parens look for active mark.
278 Default is yes if there is visual feedback on mark."
280 :group
'cperl-autoinsert-details
)
282 (defcustom cperl-electric-linefeed nil
283 "*If true, LFD should be hairy in CPerl, otherwise C-c LFD is hairy.
284 In any case these two mean plain and hairy linefeeds together.
285 Can be overwritten by `cperl-hairy' if nil."
286 :type
'(choice (const null
) boolean
)
287 :group
'cperl-affected-by-hairy
)
289 (defcustom cperl-electric-keywords nil
290 "*Not-nil (and non-null) means keywords are electric in CPerl.
291 Can be overwritten by `cperl-hairy' if nil."
292 :type
'(choice (const null
) boolean
)
293 :group
'cperl-affected-by-hairy
)
295 (defcustom cperl-hairy nil
296 "*Not-nil means most of the bells and whistles are enabled in CPerl.
297 Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
298 `cperl-electric-parens', `cperl-electric-linefeed', `cperl-electric-keywords',
299 `cperl-info-on-command-no-prompt', `cperl-clobber-lisp-bindings',
300 `cperl-lazy-help-time'."
302 :group
'cperl-affected-by-hairy
)
304 (defcustom cperl-comment-column
32
305 "*Column to put comments in CPerl (use \\[cperl-indent] to lineup with code)."
307 :group
'cperl-indentation-details
)
309 (defcustom cperl-vc-header-alist
'((SCCS "$sccs = '%W\%' ;")
310 (RCS "$rcs = ' $Id\$ ' ;"))
311 "*What to use as `vc-header-alist' in CPerl."
312 :type
'(repeat (list symbol string
))
315 (defcustom cperl-clobber-mode-lists
318 (boundp 'interpreter-mode-alist
)
319 (assoc "miniperl" interpreter-mode-alist
)
320 (assoc "\\.\\([pP][Llm]\\|al\\)$" auto-mode-alist
)))
321 "*Whether to install us into `interpreter-' and `extension' mode lists."
325 (defcustom cperl-info-on-command-no-prompt nil
326 "*Not-nil (and non-null) means not to prompt on C-h f.
327 The opposite behaviour is always available if prefixed with C-c.
328 Can be overwritten by `cperl-hairy' if nil."
329 :type
'(choice (const null
) boolean
)
330 :group
'cperl-affected-by-hairy
)
332 (defcustom cperl-clobber-lisp-bindings nil
333 "*Not-nil (and non-null) means not overwrite C-h f.
334 The function is available on \\[cperl-info-on-command], \\[cperl-get-help].
335 Can be overwritten by `cperl-hairy' if nil."
336 :type
'(choice (const null
) boolean
)
337 :group
'cperl-affected-by-hairy
)
339 (defcustom cperl-lazy-help-time nil
340 "*Not-nil (and non-null) means to show lazy help after given idle time.
341 Can be overwritten by `cperl-hairy' to be 5 sec if nil."
342 :type
'(choice (const null
) (const nil
) integer
)
343 :group
'cperl-affected-by-hairy
)
345 (defcustom cperl-pod-face
'font-lock-comment-face
346 "*The result of evaluation of this expression is used for pod highlighting."
350 (defcustom cperl-pod-head-face
'font-lock-variable-name-face
351 "*The result of evaluation of this expression is used for pod highlighting.
352 Font for POD headers."
356 (defcustom cperl-here-face
'font-lock-string-face
357 "*The result of evaluation of this expression is used for here-docs highlighting."
361 (defcustom cperl-invalid-face
''underline
; later evaluated by `font-lock'
362 "*The result of evaluation of this expression highlights trailing whitespace."
366 (defcustom cperl-pod-here-fontify
'(featurep 'font-lock
)
367 "*Not-nil after evaluation means to highlight pod and here-docs sections."
371 (defcustom cperl-fontify-m-as-s t
372 "*Not-nil means highlight 1arg regular expressions operators same as 2arg."
376 (defcustom cperl-pod-here-scan t
377 "*Not-nil means look for pod and here-docs sections during startup.
378 You can always make lookup from menu or using \\[cperl-find-pods-heres]."
382 (defcustom cperl-imenu-addback nil
383 "*Not-nil means add backreferences to generated `imenu's.
384 May require patched `imenu' and `imenu-go'. Obsolete."
386 :group
'cperl-help-system
)
388 (defcustom cperl-max-help-size
66
389 "*Non-nil means shrink-wrapping of info-buffer allowed up to these percents."
390 :type
'(choice integer
(const nil
))
391 :group
'cperl-help-system
)
393 (defcustom cperl-shrink-wrap-info-frame t
394 "*Non-nil means shrink-wrapping of info-buffer-frame allowed."
396 :group
'cperl-help-system
)
398 (defcustom cperl-info-page
"perl"
399 "*Name of the info page containing perl docs.
400 Older version of this page was called `perl5', newer `perl'."
402 :group
'cperl-help-system
)
404 (defcustom cperl-use-syntax-table-text-property
405 (boundp 'parse-sexp-lookup-properties
)
406 "*Non-nil means CPerl sets up and uses `syntax-table' text property."
410 (defcustom cperl-use-syntax-table-text-property-for-tags
411 cperl-use-syntax-table-text-property
412 "*Non-nil means: set up and use `syntax-table' text property generating TAGS."
416 (defcustom cperl-scan-files-regexp
"\\.\\([pP][Llm]\\|xs\\)$"
417 "*Regexp to match files to scan when generating TAGS."
421 (defcustom cperl-noscan-files-regexp
"/\\(\\.\\.?\\|SCCS\\|RCS\\|blib\\)$"
422 "*Regexp to match files/dirs to skip when generating TAGS."
426 (defcustom cperl-regexp-indent-step nil
427 "*Indentation used when beautifying regexps.
428 If `nil', the value of `cperl-indent-level' will be used."
429 :type
'(choice integer
(const nil
))
430 :group
'cperl-indentation-details
)
432 (defcustom cperl-indent-left-aligned-comments t
433 "*Non-nil means that the comment starting in leftmost column should indent."
435 :group
'cperl-indentation-details
)
437 (defcustom cperl-under-as-char nil
438 "*Non-nil means that the _ (underline) should be treated as word char."
442 (defcustom cperl-extra-perl-args
""
443 "*Extra arguments to use when starting Perl.
444 Currently used with `cperl-check-syntax' only."
448 (defcustom cperl-message-electric-keyword t
449 "*Non-nil means that the `cperl-electric-keyword' prints a help message."
451 :group
'cperl-help-system
)
453 (defcustom cperl-indent-region-fix-constructs
1
454 "*Amount of space to insert between `}' and `else' or `elsif'
455 in `cperl-indent-region'. Set to nil to leave as is. Values other
456 than 1 and nil will probably not work."
457 :type
'(choice (const nil
) (const 1))
458 :group
'cperl-indentation-details
)
460 (defcustom cperl-break-one-line-blocks-when-indent t
461 "*Non-nil means that one-line if/unless/while/until/for/foreach BLOCKs
462 need to be reformated into multiline ones when indenting a region."
464 :group
'cperl-indentation-details
)
466 (defcustom cperl-fix-hanging-brace-when-indent t
467 "*Non-nil means that BLOCK-end `}' may be put on a separate line
468 when indenting a region.
469 Braces followed by else/elsif/while/until are excepted."
471 :group
'cperl-indentation-details
)
473 (defcustom cperl-merge-trailing-else t
474 "*Non-nil means that BLOCK-end `}' followed by else/elsif/continue
475 may be merged to be on the same line when indenting a region."
477 :group
'cperl-indentation-details
)
479 (defcustom cperl-syntaxify-by-font-lock
481 (boundp 'parse-sexp-lookup-properties
))
482 "*Non-nil means that CPerl uses `font-lock's routines for syntaxification.
483 Having it TRUE may be not completely debugged yet."
484 :type
'(choice (const message
) boolean
)
487 (defcustom cperl-syntaxify-unwind
489 "*Non-nil means that CPerl unwinds to a start of along construction
490 when syntaxifying a chunk of buffer."
494 (defcustom cperl-ps-print-face-properties
495 '((font-lock-keyword-face nil nil bold shadow
)
496 (font-lock-variable-name-face nil nil bold
)
497 (font-lock-function-name-face nil nil bold italic box
)
498 (font-lock-constant-face nil
"LightGray" bold
)
499 (cperl-array-face nil
"LightGray" bold underline
)
500 (cperl-hash-face nil
"LightGray" bold italic underline
)
501 (font-lock-comment-face nil
"LightGray" italic
)
502 (font-lock-string-face nil nil italic underline
)
503 (cperl-nonoverridable-face nil nil italic underline
)
504 (font-lock-type-face nil nil underline
)
505 (underline nil
"LightGray" strikeout
))
506 "List given as an argument to `ps-extend-face-list' in `cperl-ps-print'."
507 :type
'(repeat (cons symbol
508 (cons (choice (const nil
) string
)
509 (cons (choice (const nil
) string
)
515 (defvar cperl-dark-background
516 (cperl-choose-color "navy" "os2blue" "darkgreen"))
517 (defvar cperl-dark-foreground
518 (cperl-choose-color "orchid1" "orange"))
520 (defface cperl-nonoverridable-face
521 `((((class grayscale
) (background light
))
522 (:background
"Gray90" :italic t
:underline t
))
523 (((class grayscale
) (background dark
))
524 (:foreground
"Gray80" :italic t
:underline t
:bold t
))
525 (((class color
) (background light
))
526 (:foreground
"chartreuse3"))
527 (((class color
) (background dark
))
528 (:foreground
,cperl-dark-foreground
))
529 (t (:bold t
:underline t
)))
530 "Font Lock mode face used to highlight array names."
533 (defface cperl-array-face
534 `((((class grayscale
) (background light
))
535 (:background
"Gray90" :bold t
))
536 (((class grayscale
) (background dark
))
537 (:foreground
"Gray80" :bold t
))
538 (((class color
) (background light
))
539 (:foreground
"Blue" :background
"lightyellow2" :bold t
))
540 (((class color
) (background dark
))
541 (:foreground
"yellow" :background
,cperl-dark-background
:bold t
))
543 "Font Lock mode face used to highlight array names."
546 (defface cperl-hash-face
547 `((((class grayscale
) (background light
))
548 (:background
"Gray90" :bold t
:italic t
))
549 (((class grayscale
) (background dark
))
550 (:foreground
"Gray80" :bold t
:italic t
))
551 (((class color
) (background light
))
552 (:foreground
"Red" :background
"lightyellow2" :bold t
:italic t
))
553 (((class color
) (background dark
))
554 (:foreground
"Red" :background
,cperl-dark-background
:bold t
:italic t
))
555 (t (:bold t
:italic t
)))
556 "Font Lock mode face used to highlight hash names."
557 :group
'cperl-faces
)))
561 ;;; Short extra-docs.
563 (defvar cperl-tips
'please-ignore-this-line
564 "Get newest version of this package from
565 ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs
567 ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl
568 Subdirectory `cperl-mode' may contain yet newer development releases and/or
569 patches to related files.
571 For best results apply to an older Emacs the patches from
572 ftp://ftp.math.ohio-state.edu/pub/users/ilya/cperl-mode/patches
573 \(this upgrades syntax-parsing abilities of RMS Emaxen v19.34 and
574 v20.2 up to the level of RMS Emacs v20.3 - a must for a good Perl
575 mode.) You will not get much from XEmacs, it's syntax abilities are
578 Get support packages choose-color.el (or font-lock-extra.el before
579 19.30), imenu-go.el from the same place. \(Look for other files there
580 too... ;-). Get a patch for imenu.el in 19.29. Note that for 19.30 and
581 later you should use choose-color.el *instead* of font-lock-extra.el
582 \(and you will not get smart highlighting in C :-().
584 Note that to enable Compile choices in the menu you need to install
588 $CPAN/doc/manual/info/perl-info.tar.gz
590 http://www.metronet.com:70/9/perlinfo/perl5/manual/perl5-info.tar.gz
592 If you use imenu-go, run imenu on perl5-info buffer (you can do it
593 from Perl menu). If many files are related, generate TAGS files from
594 Tools/Tags submenu in Perl menu.
596 If some class structure is too complicated, use Tools/Hierarchy-view
597 from Perl menu, or hierarchic view of imenu. The second one uses the
598 current buffer only, the first one requires generation of TAGS from
599 Perl/Tools/Tags menu beforehand.
601 Run Perl/Tools/Insert-spaces-if-needed to fix your lazy typing.
603 Switch auto-help on/off with Perl/Tools/Auto-help.
605 Though with contemporary Emaxen CPerl mode should maintain the correct
606 parsing of Perl even when editing, sometimes it may be lost. Fix this by
610 In cases of more severe confusion sometimes it is helpful to do
612 M-x load-l RET cperl-mode RET
615 Before reporting (non-)problems look in the problem section of online
616 micro-docs on what I know about CPerl problems.")
618 (defvar cperl-problems
'please-ignore-this-line
619 "Some faces will not be shown on some versions of Emacs unless you
620 install choose-color.el, available from
621 ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs/
623 Emacs had a _very_ restricted syntax parsing engine until RMS's Emacs
624 20.1. Most problems below are corrected starting from this version of
625 Emacs, and all of them should go with (future) RMS's version 20.3.
627 Note that even with newer Emacsen interaction of `font-lock' and
628 syntaxification is not cleaned up. You may get slightly different
629 colors basing on the order of fontification and syntaxification. This
630 might be corrected by setting `cperl-syntaxify-by-font-lock' to t, but
631 the corresponding code is still extremely buggy.
633 Even with older Emacsen CPerl mode tries to corrects some Emacs
634 misunderstandings, however, for efficiency reasons the degree of
635 correction is different for different operations. The partially
636 corrected problems are: POD sections, here-documents, regexps. The
637 operations are: highlighting, indentation, electric keywords, electric
640 This may be confusing, since the regexp s#//#/#\; may be highlighted
641 as a comment, but it will be recognized as a regexp by the indentation
642 code. Or the opposite case, when a pod section is highlighted, but
643 may break the indentation of the following code (though indentation
644 should work if the balance of delimiters is not broken by POD).
646 The main trick (to make $ a \"backslash\") makes constructions like
647 ${aaa} look like unbalanced braces. The only trick I can think of is
648 to insert it as $ {aaa} (legal in perl5, not in perl4).
650 Similar problems arise in regexps, when /(\\s|$)/ should be rewritten
651 as /($|\\s)/. Note that such a transposition is not always possible.
653 The solution is to upgrade your Emacs or patch an older one. Note
654 that RMS's 20.2 has some bugs related to `syntax-table' text
655 properties. Patches are available on the main CPerl download site,
658 If these bugs cannot be fixed on your machine (say, you have an inferior
659 environment and cannot recompile), you may still disable all the fancy stuff
660 via `cperl-use-syntax-table-text-property'." )
662 (defvar cperl-non-problems
'please-ignore-this-line
663 "As you know from `problems' section, Perl syntax is too hard for CPerl on
664 older Emacsen. Here is what you can do if you cannot upgrade, or if
665 you want to switch off these capabilities on RMS Emacs 20.2 (+patches) or 20.3
666 or better. Please skip this docs if you run a capable Emacs already.
668 Most of the time, if you write your own code, you may find an equivalent
669 \(and almost as readable) expression (what is discussed below is usually
670 not relevant on newer Emacsen, since they can do it automatically).
672 Try to help CPerl: add comments with embedded quotes to fix CPerl
673 misunderstandings about the end of quotation:
677 You won't need it too often. The reason: $ \"quotes\" the following
678 character (this saves a life a lot of times in CPerl), thus due to
679 Emacs parsing rules it does not consider tick (i.e., ' ) after a
680 dollar as a closing one, but as a usual character. This is usually
681 correct, but not in the above context.
683 Even with older Emacsen the indentation code is pretty wise. The only
684 drawback is that it relied on Emacs parsing to find matching
685 parentheses. And Emacs *could not* match parentheses in Perl 100%
688 would not break indentation, but
694 would confuse CPerl a lot.
696 If you still get wrong indentation in situation that you think the
697 code should be able to parse, try:
699 a) Check what Emacs thinks about balance of your parentheses.
700 b) Supply the code to me (IZ).
702 Pods were treated _very_ rudimentally. Here-documents were not
703 treated at all (except highlighting and inhibiting indentation). Upgrade.
705 To speed up coloring the following compromises exist:
706 a) sub in $mypackage::sub may be highlighted.
707 b) -z in [a-z] may be highlighted.
708 c) if your regexp contains a keyword (like \"s\"), it may be highlighted.
711 Imenu in 19.31 is broken. Set `imenu-use-keymap-menu' to t, and remove
712 `car' before `imenu-choose-buffer-index' in `imenu'.
713 `imenu-add-to-menubar' in 20.2 is broken.
715 A lot of things on XEmacs may be broken too, judging by bug reports I
716 recieve. Note that some releases of XEmacs are better than the others
717 as far as bugs reports I see are concerned.")
719 (defvar cperl-praise
'please-ignore-this-line
720 "RMS asked me to list good things about CPerl. Here they go:
722 0) It uses the newest `syntax-table' property ;-);
724 1) It does 99% of Perl syntax correct (as opposed to 80-90% in Perl
725 mode - but the latter number may have improved too in last years) even
726 with old Emaxen which do not support `syntax-table' property.
728 When using `syntax-table' property for syntax assist hints, it should
729 handle 99.995% of lines correct - or somesuch. It automatically
730 updates syntax assist hints when you edit your script.
732 2) It is generally believed to be \"the most user-friendly Emacs
733 package\" whatever it may mean (I doubt that the people who say similar
734 things tried _all_ the rest of Emacs ;-), but this was not a lonely
737 3) Everything is customizable, one-by-one or in a big sweep;
739 4) It has many easily-accessable \"tools\":
740 a) Can run program, check syntax, start debugger;
741 b) Can lineup vertically \"middles\" of rows, like `=' in
744 c) Can insert spaces where this impoves readability (in one
745 interactive sweep over the buffer);
746 d) Has support for imenu, including:
747 1) Separate unordered list of \"interesting places\";
748 2) Separate TOC of POD sections;
749 3) Separate list of packages;
750 4) Hierarchical view of methods in (sub)packages;
751 5) and functions (by the full name - with package);
752 e) Has an interface to INFO docs for Perl; The interface is
753 very flexible, including shrink-wrapping of
754 documentation buffer/frame;
755 f) Has a builtin list of one-line explanations for perl constructs.
756 g) Can show these explanations if you stay long enough at the
757 corresponding place (or on demand);
758 h) Has an enhanced fontification (using 3 or 4 additional faces
759 comparing to font-lock - basically, different
760 namespaces in Perl have different colors);
761 i) Can construct TAGS basing on its knowledge of Perl syntax,
762 the standard menu has 6 different way to generate
763 TAGS (if \"by directory\", .xs files - with C-language
764 bindings - are included in the scan);
765 j) Can build a hierarchical view of classes (via imenu) basing
766 on generated TAGS file;
767 k) Has electric parentheses, electric newlines, uses Abbrev
768 for electric logical constructs
770 with different styles of expansion (context sensitive
771 to be not so bothering). Electric parentheses behave
772 \"as they should\" in a presence of a visible region.
773 l) Changes msb.el \"on the fly\" to insert a group \"Perl files\";
779 n) Highlights (by user-choice) either 3-delimiters constructs
780 (such as tr/a/b/), or regular expressions and `y/tr'.
781 o) Highlights trailing whitespace.
783 5) The indentation engine was very smart, but most of tricks may be
784 not needed anymore with the support for `syntax-table' property. Has
785 progress indicator for indentation (with `imenu' loaded).
787 6) Indent-region improves inline-comments as well; also corrects
788 whitespace *inside* the conditional/loop constructs.
790 7) Fill-paragraph correctly handles multi-line comments;
792 8) Can switch to different indentation styles by one command, and restore
793 the settings present before the switch.
795 9) When doing indentation of control constructs, may correct
796 line-breaks/spacing between elements of the construct.
799 (defvar cperl-speed
'please-ignore-this-line
800 "This is an incomplete compendium of what is available in other parts
801 of CPerl documentation. (Please inform me if I skept anything.)
803 There is a perception that CPerl is slower than alternatives. This part
804 of documentation is designed to overcome this misconception.
806 *By default* CPerl tries to enable the most comfortable settings.
807 From most points of view, correctly working package is infinitely more
808 comfortable than a non-correctly working one, thus by default CPerl
809 prefers correctness over speed. Below is the guide how to change
810 settings if your preferences are different.
812 A) Speed of loading the file. When loading file, CPerl may perform a
813 scan which indicates places which cannot be parsed by primitive Emacs
814 syntax-parsing routines, and marks them up so that either
816 A1) CPerl may work around these deficiencies (for big chunks, mostly
817 PODs and HERE-documents), or
818 A2) On capable Emaxen CPerl will use improved syntax-handlings
819 which reads mark-up hints directly.
821 The scan in case A2 is much more comprehensive, thus may be slower.
823 User can disable syntax-engine-helping scan of A2 by setting
824 `cperl-use-syntax-table-text-property'
825 variable to nil (if it is set to t).
827 One can disable the scan altogether (both A1 and A2) by setting
828 `cperl-pod-here-scan'
831 B) Speed of editing operations.
833 One can add a (minor) speedup to editing operations by setting
834 `cperl-use-syntax-table-text-property'
835 variable to nil (if it is set to t). This will disable
836 syntax-engine-helping scan, thus will make many more Perl
837 constructs be wrongly recognized by CPerl, thus may lead to
838 wrongly matched parentheses, wrong indentation, etc.
840 One can unset `cperl-syntaxify-unwind'. This might speed up editing
841 of, say, long POD sections.
844 (defvar cperl-tips-faces
'please-ignore-this-line
845 "CPerl mode uses following faces for highlighting:
847 cperl-array-face Array names
848 cperl-hash-face Hash names
849 font-lock-comment-face Comments, PODs and whatever is considered
850 syntaxically to be not code
851 font-lock-constant-face HERE-doc delimiters, labels, delimiters of
852 2-arg operators s/y/tr/ or of RExen,
853 font-lock-function-name-face Special-cased m// and s//foo/, _ as
854 a target of a file tests, file tests,
855 subroutine names at the moment of definition
856 (except those conflicting with Perl operators),
857 package names (when recognized), format names
858 font-lock-keyword-face Control flow switch constructs, declarators
859 cperl-nonoverridable-face Non-overridable keywords, modifiers of RExen
860 font-lock-string-face Strings, qw() constructs, RExen, POD sections,
861 literal parts and the terminator of formats
862 and whatever is syntaxically considered
864 font-lock-type-face Overridable keywords
865 font-lock-variable-name-face Variable declarations, indirect array and
866 hash names, POD headers/item names
867 cperl-invalid-face Trailing whitespace
869 Note that in several situations the highlighting tries to inform about
870 possible confusion, such as different colors for function names in
871 declarations depending on what they (do not) override, or special cases
872 m// and s/// which do not do what one would expect them to do.
874 Help with best setup of these faces for printout requested (for each of
875 the faces: please specify bold, italic, underline, shadow and box.)
881 ;;; Portability stuff:
883 (defconst cperl-xemacs-p
(string-match "XEmacs\\|Lucid" emacs-version
))
885 (defmacro cperl-define-key
(emacs-key definition
&optional xemacs-key
)
886 `(define-key cperl-mode-map
888 `(if cperl-xemacs-p
,xemacs-key
,emacs-key
)
892 (defvar cperl-del-back-ch
893 (car (append (where-is-internal 'delete-backward-char
)
894 (where-is-internal 'backward-delete-char-untabify
)))
895 "Character generated by key bound to delete-backward-char.")
897 (and (vectorp cperl-del-back-ch
) (= (length cperl-del-back-ch
) 1)
898 (setq cperl-del-back-ch
(aref cperl-del-back-ch
0)))
900 (defun cperl-mark-active () (mark)) ; Avoid undefined warning
903 ;; "Active regions" are on: use region only if active
904 ;; "Active regions" are off: use region unconditionally
905 (defun cperl-use-region-p ()
906 (if zmacs-regions
(mark) t
)))
907 (defun cperl-use-region-p ()
908 (if transient-mark-mode mark-active t
))
909 (defun cperl-mark-active () mark-active
))
911 (defsubst cperl-enable-font-lock
()
912 (or cperl-xemacs-p window-system
))
914 (defun cperl-putback-char (c) ; Emacs 19
915 (set 'unread-command-events
(list c
))) ; Avoid undefined warning
917 (if (boundp 'unread-command-events
)
919 (defun cperl-putback-char (c) ; XEmacs >= 19.12
920 (setq unread-command-events
(list (eval '(character-to-event c
))))))
921 (defun cperl-putback-char (c) ; XEmacs <= 19.11
922 (set 'unread-command-event
(eval '(character-to-event c
))))) ; Avoid warnings
924 (or (fboundp 'uncomment-region
)
925 (defun uncomment-region (beg end
)
927 (comment-region beg end -
1)))
929 (defvar cperl-do-not-fontify
930 (if (string< emacs-version
"19.30")
933 "Text property which inhibits refontification.")
935 (defsubst cperl-put-do-not-fontify
(from to
&optional post
)
936 ;; If POST, do not do it with postponed fontification
937 (if (and post cperl-syntaxify-by-font-lock
)
939 (put-text-property (max (point-min) (1- from
))
940 to cperl-do-not-fontify t
)))
942 (defcustom cperl-mode-hook nil
943 "Hook run by `cperl-mode'."
947 (defvar cperl-syntax-state nil
)
948 (defvar cperl-syntax-done-to nil
)
949 (defvar cperl-emacs-can-parse
(> (length (save-excursion
950 (parse-partial-sexp 1 1))) 9))
952 ;; Make customization possible "in reverse"
953 (defsubst cperl-val
(symbol &optional default hairy
)
955 ((eq (symbol-value symbol
) 'null
) default
)
956 (cperl-hairy (or hairy t
))
957 (t (symbol-value symbol
))))
959 ;;; Probably it is too late to set these guys already, but it can help later:
961 ;;;(and cperl-clobber-mode-lists
962 ;;;(setq auto-mode-alist
963 ;;; (append '(("\\.\\([pP][Llm]\\|al\\)$" . perl-mode)) auto-mode-alist ))
964 ;;;(and (boundp 'interpreter-mode-alist)
965 ;;; (setq interpreter-mode-alist (append interpreter-mode-alist
966 ;;; '(("miniperl" . perl-mode))))))
967 (if (fboundp 'eval-when-compile
)
987 (if (fboundp 'ps-extend-face-list
)
988 (defmacro cperl-ps-extend-face-list
(arg)
989 `(ps-extend-face-list ,arg
))
990 (defmacro cperl-ps-extend-face-list
(arg)
991 `(error "This version of Emacs has no `ps-extend-face-list'.")))
992 ;; Calling `cperl-enable-font-lock' below doesn't compile on XEmacs,
993 ;; macros instead of defsubsts don't work on Emacs, so we do the
994 ;; expansion manually. Any other suggestions?
995 (if (or (string-match "XEmacs\\|Lucid" emacs-version
)
997 (require 'font-lock
))
1000 (defvar cperl-mode-abbrev-table nil
1001 "Abbrev table in use in Cperl-mode buffers.")
1003 (add-hook 'edit-var-mode-alist
'(perl-mode (regexp .
"^cperl-")))
1005 (defvar cperl-mode-map
() "Keymap used in CPerl mode.")
1007 (if cperl-mode-map nil
1008 (setq cperl-mode-map
(make-sparse-keymap))
1009 (cperl-define-key "{" 'cperl-electric-lbrace
)
1010 (cperl-define-key "[" 'cperl-electric-paren
)
1011 (cperl-define-key "(" 'cperl-electric-paren
)
1012 (cperl-define-key "<" 'cperl-electric-paren
)
1013 (cperl-define-key "}" 'cperl-electric-brace
)
1014 (cperl-define-key "]" 'cperl-electric-rparen
)
1015 (cperl-define-key ")" 'cperl-electric-rparen
)
1016 (cperl-define-key ";" 'cperl-electric-semi
)
1017 (cperl-define-key ":" 'cperl-electric-terminator
)
1018 (cperl-define-key "\C-j" 'newline-and-indent
)
1019 (cperl-define-key "\C-c\C-j" 'cperl-linefeed
)
1020 (cperl-define-key "\C-c\C-t" 'cperl-invert-if-unless
)
1021 (cperl-define-key "\C-c\C-a" 'cperl-toggle-auto-newline
)
1022 (cperl-define-key "\C-c\C-k" 'cperl-toggle-abbrev
)
1023 (cperl-define-key "\C-c\C-w" 'cperl-toggle-construct-fix
)
1024 (cperl-define-key "\C-c\C-f" 'auto-fill-mode
)
1025 (cperl-define-key "\C-c\C-e" 'cperl-toggle-electric
)
1026 (cperl-define-key "\C-c\C-ha" 'cperl-toggle-autohelp
)
1027 (cperl-define-key "\e\C-q" 'cperl-indent-exp
) ; Usually not bound
1028 (cperl-define-key [?\C-\M-\|
] 'cperl-lineup
1030 ;;(cperl-define-key "\M-q" 'cperl-fill-paragraph)
1031 ;;(cperl-define-key "\e;" 'cperl-indent-for-comment)
1032 (cperl-define-key "\177" 'cperl-electric-backspace
)
1033 (cperl-define-key "\t" 'cperl-indent-command
)
1034 ;; don't clobber the backspace binding:
1035 (cperl-define-key "\C-c\C-hF" 'cperl-info-on-command
1036 [(control c
) (control h
) F
])
1037 (if (cperl-val 'cperl-clobber-lisp-bindings
)
1039 (cperl-define-key "\C-hf"
1040 ;;(concat (char-to-string help-char) "f") ; does not work
1041 'cperl-info-on-command
1043 (cperl-define-key "\C-hv"
1044 ;;(concat (char-to-string help-char) "v") ; does not work
1047 (cperl-define-key "\C-c\C-hf"
1048 ;;(concat (char-to-string help-char) "f") ; does not work
1049 (key-binding "\C-hf")
1050 [(control c
) (control h
) f
])
1051 (cperl-define-key "\C-c\C-hv"
1052 ;;(concat (char-to-string help-char) "v") ; does not work
1053 (key-binding "\C-hv")
1054 [(control c
) (control h
) v
]))
1055 (cperl-define-key "\C-c\C-hf" 'cperl-info-on-current-command
1056 [(control c
) (control h
) f
])
1057 (cperl-define-key "\C-c\C-hv"
1058 ;;(concat (char-to-string help-char) "v") ; does not work
1060 [(control c
) (control h
) v
]))
1061 (if (and cperl-xemacs-p
1062 (<= emacs-minor-version
11) (<= emacs-major-version
19))
1064 ;; substitute-key-definition is usefulness-deenhanced...
1065 (cperl-define-key "\M-q" 'cperl-fill-paragraph
)
1066 (cperl-define-key "\e;" 'cperl-indent-for-comment
)
1067 (cperl-define-key "\e\C-\\" 'cperl-indent-region
))
1068 (substitute-key-definition
1069 'indent-sexp
'cperl-indent-exp
1070 cperl-mode-map global-map
)
1071 (substitute-key-definition
1072 'fill-paragraph
'cperl-fill-paragraph
1073 cperl-mode-map global-map
)
1074 (substitute-key-definition
1075 'indent-region
'cperl-indent-region
1076 cperl-mode-map global-map
)
1077 (substitute-key-definition
1078 'indent-for-comment
'cperl-indent-for-comment
1079 cperl-mode-map global-map
)))
1082 (defvar cperl-lazy-installed
)
1083 (defvar cperl-old-style nil
)
1087 (easy-menu-define cperl-menu cperl-mode-map
"Menu for CPerl mode"
1089 ["Beginning of function" beginning-of-defun
t]
1090 ["End of function" end-of-defun
t]
1091 ["Mark function" mark-defun
t]
1092 ["Indent expression" cperl-indent-exp t
]
1093 ["Fill paragraph/comment" cperl-fill-paragraph t
]
1095 ["Line up a construction" cperl-lineup
(cperl-use-region-p)]
1096 ["Invert if/unless/while/until" cperl-invert-if-unless t
]
1098 ["Beautify" cperl-beautify-regexp
1099 cperl-use-syntax-table-text-property
]
1100 ["Beautify a group" cperl-beautify-level
1101 cperl-use-syntax-table-text-property
]
1102 ["Contract a group" cperl-contract-level
1103 cperl-use-syntax-table-text-property
]
1104 ["Contract groups" cperl-contract-levels
1105 cperl-use-syntax-table-text-property
])
1106 ["Refresh \"hard\" constructions" cperl-find-pods-heres t
]
1108 ["Indent region" cperl-indent-region
(cperl-use-region-p)]
1109 ["Comment region" cperl-comment-region
(cperl-use-region-p)]
1110 ["Uncomment region" cperl-uncomment-region
(cperl-use-region-p)]
1112 ["Run" mode-compile
(fboundp 'mode-compile
)]
1113 ["Kill" mode-compile-kill
(and (fboundp 'mode-compile-kill
)
1114 (get-buffer "*compilation*"))]
1115 ["Next error" next-error
(get-buffer "*compilation*")]
1116 ["Check syntax" cperl-check-syntax
(fboundp 'mode-compile
)]
1118 ["Debugger" cperl-db t
]
1121 ["Imenu" imenu
(fboundp 'imenu
)]
1122 ["Insert spaces if needed" cperl-find-bad-style t
]
1123 ["Class Hierarchy from TAGS" cperl-tags-hier-init t
]
1124 ;;["Update classes" (cperl-tags-hier-init t) tags-table-list]
1125 ["CPerl pretty print (exprmntl)" cperl-ps-print
1126 (fboundp 'ps-extend-face-list
)]
1127 ["Imenu on info" cperl-imenu-on-info
(featurep 'imenu
)]
1129 ;;; ["Create tags for current file" cperl-etags t]
1130 ;;; ["Add tags for current file" (cperl-etags t) t]
1131 ;;; ["Create tags for Perl files in directory" (cperl-etags nil t) t]
1132 ;;; ["Add tags for Perl files in directory" (cperl-etags t t) t]
1133 ;;; ["Create tags for Perl files in (sub)directories"
1134 ;;; (cperl-etags nil 'recursive) t]
1135 ;;; ["Add tags for Perl files in (sub)directories"
1136 ;;; (cperl-etags t 'recursive) t])
1137 ;;;; cperl-write-tags (&optional file erase recurse dir inbuffer)
1138 ["Create tags for current file" (cperl-write-tags nil t
) t
]
1139 ["Add tags for current file" (cperl-write-tags) t
]
1140 ["Create tags for Perl files in directory"
1141 (cperl-write-tags nil t nil t
) t
]
1142 ["Add tags for Perl files in directory"
1143 (cperl-write-tags nil nil nil t
) t
]
1144 ["Create tags for Perl files in (sub)directories"
1145 (cperl-write-tags nil t t t
) t
]
1146 ["Add tags for Perl files in (sub)directories"
1147 (cperl-write-tags nil nil t t
) t
]))
1149 ["Define word at point" imenu-go-find-at-position
1150 (fboundp 'imenu-go-find-at-position
)]
1151 ["Help on function" cperl-info-on-command t
]
1152 ["Help on function at point" cperl-info-on-current-command t
]
1153 ["Help on symbol at point" cperl-get-help t
]
1154 ["Perldoc" cperl-perldoc t
]
1155 ["Perldoc on word at point" cperl-perldoc-at-point t
]
1156 ["View manpage of POD in this file" cperl-pod-to-manpage t
]
1157 ["Auto-help on" cperl-lazy-install
1158 (and (fboundp 'run-with-idle-timer
)
1159 (not cperl-lazy-installed
))]
1160 ["Auto-help off" (eval '(cperl-lazy-unstall))
1161 (and (fboundp 'run-with-idle-timer
)
1162 cperl-lazy-installed
)])
1164 ["Auto newline" cperl-toggle-auto-newline t
]
1165 ["Electric parens" cperl-toggle-electric t
]
1166 ["Electric keywords" cperl-toggle-abbrev t
]
1167 ["Fix whitespace on indent" cperl-toggle-construct-fix t
]
1168 ["Auto fill" auto-fill-mode t
])
1170 ["CPerl" (cperl-set-style "CPerl") t
]
1171 ["PerlStyle" (cperl-set-style "PerlStyle") t
]
1172 ["GNU" (cperl-set-style "GNU") t
]
1173 ["C++" (cperl-set-style "C++") t
]
1174 ["FSF" (cperl-set-style "FSF") t
]
1175 ["BSD" (cperl-set-style "BSD") t
]
1176 ["Whitesmith" (cperl-set-style "Whitesmith") t
]
1177 ["Current" (cperl-set-style "Current") t
]
1178 ["Memorized" (cperl-set-style-back) cperl-old-style
])
1180 ["Tips" (describe-variable 'cperl-tips
) t
]
1181 ["Problems" (describe-variable 'cperl-problems
) t
]
1182 ["Non-problems" (describe-variable 'cperl-non-problems
) t
]
1183 ["Speed" (describe-variable 'cperl-speed
) t
]
1184 ["Praise" (describe-variable 'cperl-praise
) t
]
1185 ["Faces" (describe-variable 'cperl-tips-faces
) t
]
1186 ["CPerl mode" (describe-function 'cperl-mode
) t
]
1188 (message "The version of master-file for this CPerl is %s"
1189 cperl-version
) t
]))))
1192 (autoload 'c-macro-expand
"cmacexp"
1193 "Display the result of expanding all C macros occurring in the region.
1194 The expansion is entirely correct because it uses the C preprocessor."
1197 (defvar cperl-mode-syntax-table nil
1198 "Syntax table in use in Cperl-mode buffers.")
1200 (defvar cperl-string-syntax-table nil
1201 "Syntax table in use in Cperl-mode string-like chunks.")
1203 (if cperl-mode-syntax-table
1205 (setq cperl-mode-syntax-table
(make-syntax-table))
1206 (modify-syntax-entry ?
\\ "\\" cperl-mode-syntax-table
)
1207 (modify-syntax-entry ?
/ "." cperl-mode-syntax-table
)
1208 (modify-syntax-entry ?
* "." cperl-mode-syntax-table
)
1209 (modify-syntax-entry ?
+ "." cperl-mode-syntax-table
)
1210 (modify-syntax-entry ?-
"." cperl-mode-syntax-table
)
1211 (modify-syntax-entry ?
= "." cperl-mode-syntax-table
)
1212 (modify-syntax-entry ?%
"." cperl-mode-syntax-table
)
1213 (modify-syntax-entry ?
< "." cperl-mode-syntax-table
)
1214 (modify-syntax-entry ?
> "." cperl-mode-syntax-table
)
1215 (modify-syntax-entry ?
& "." cperl-mode-syntax-table
)
1216 (modify-syntax-entry ?$
"\\" cperl-mode-syntax-table
)
1217 (modify-syntax-entry ?
\n ">" cperl-mode-syntax-table
)
1218 (modify-syntax-entry ?
# "<" cperl-mode-syntax-table
)
1219 (modify-syntax-entry ?
' "\"" cperl-mode-syntax-table
)
1220 (modify-syntax-entry ?
` "\"" cperl-mode-syntax-table
)
1221 (if cperl-under-as-char
1222 (modify-syntax-entry ?_
"w" cperl-mode-syntax-table
))
1223 (modify-syntax-entry ?
: "_" cperl-mode-syntax-table
)
1224 (modify-syntax-entry ?|
"." cperl-mode-syntax-table
)
1225 (setq cperl-string-syntax-table
(copy-syntax-table cperl-mode-syntax-table
))
1226 (modify-syntax-entry ?$
"." cperl-string-syntax-table
)
1227 (modify-syntax-entry ?
# "." cperl-string-syntax-table
) ; (?# comment )
1232 (defvar cperl-faces-init nil
)
1234 (defvar cperl-msb-fixed nil
)
1235 (defvar font-lock-syntactic-keywords
)
1236 (defvar perl-font-lock-keywords
)
1237 (defvar perl-font-lock-keywords-1
)
1238 (defvar perl-font-lock-keywords-2
)
1240 (defun cperl-mode ()
1241 "Major mode for editing Perl code.
1242 Expression and list commands understand all C brackets.
1243 Tab indents for Perl code.
1244 Paragraphs are separated by blank lines only.
1245 Delete converts tabs to spaces as it moves back.
1247 Various characters in Perl almost always come in pairs: {}, (), [],
1248 sometimes <>. When the user types the first, she gets the second as
1249 well, with optional special formatting done on {}. (Disabled by
1250 default.) You can always quote (with \\[quoted-insert]) the left
1251 \"paren\" to avoid the expansion. The processing of < is special,
1252 since most the time you mean \"less\". Cperl mode tries to guess
1253 whether you want to type pair <>, and inserts is if it
1254 appropriate. You can set `cperl-electric-parens-string' to the string that
1255 contains the parenths from the above list you want to be electrical.
1256 Electricity of parenths is controlled by `cperl-electric-parens'.
1257 You may also set `cperl-electric-parens-mark' to have electric parens
1258 look for active mark and \"embrace\" a region if possible.'
1260 CPerl mode provides expansion of the Perl control constructs:
1262 if, else, elsif, unless, while, until, continue, do,
1263 for, foreach, formy and foreachmy.
1265 and POD directives (Disabled by default, see `cperl-electric-keywords'.)
1267 The user types the keyword immediately followed by a space, which
1268 causes the construct to be expanded, and the point is positioned where
1269 she is most likely to want to be. eg. when the user types a space
1270 following \"if\" the following appears in the buffer: if () { or if ()
1271 } { } and the cursor is between the parentheses. The user can then
1272 type some boolean expression within the parens. Having done that,
1273 typing \\[cperl-linefeed] places you - appropriately indented - on a
1274 new line between the braces (if you typed \\[cperl-linefeed] in a POD
1275 directive line, then appropriate number of new lines is inserted).
1277 If CPerl decides that you want to insert \"English\" style construct like
1281 it will not do any expansion. See also help on variable
1282 `cperl-extra-newline-before-brace'. (Note that one can switch the
1283 help message on expansion by setting `cperl-message-electric-keyword'
1286 \\[cperl-linefeed] is a convenience replacement for typing carriage
1287 return. It places you in the next line with proper indentation, or if
1288 you type it inside the inline block of control construct, like
1290 foreach (@lines) {print; print}
1292 and you are on a boundary of a statement inside braces, it will
1293 transform the construct into a multiline and will place you into an
1294 appropriately indented blank line. If you need a usual
1295 `newline-and-indent' behaviour, it is on \\[newline-and-indent],
1296 see documentation on `cperl-electric-linefeed'.
1298 Use \\[cperl-invert-if-unless] to change a construction of the form
1308 Setting the variable `cperl-font-lock' to t switches on font-lock-mode
1309 \(even with older Emacsen), `cperl-electric-lbrace-space' to t switches
1310 on electric space between $ and {, `cperl-electric-parens-string' is
1311 the string that contains parentheses that should be electric in CPerl
1312 \(see also `cperl-electric-parens-mark' and `cperl-electric-parens'),
1313 setting `cperl-electric-keywords' enables electric expansion of
1314 control structures in CPerl. `cperl-electric-linefeed' governs which
1315 one of two linefeed behavior is preferable. You can enable all these
1316 options simultaneously (recommended mode of use) by setting
1317 `cperl-hairy' to t. In this case you can switch separate options off
1318 by setting them to `null'. Note that one may undo the extra
1319 whitespace inserted by semis and braces in `auto-newline'-mode by
1320 consequent \\[cperl-electric-backspace].
1322 If your site has perl5 documentation in info format, you can use commands
1323 \\[cperl-info-on-current-command] and \\[cperl-info-on-command] to access it.
1324 These keys run commands `cperl-info-on-current-command' and
1325 `cperl-info-on-command', which one is which is controlled by variable
1326 `cperl-info-on-command-no-prompt' and `cperl-clobber-lisp-bindings'
1327 \(in turn affected by `cperl-hairy').
1329 Even if you have no info-format documentation, short one-liner-style
1330 help is available on \\[cperl-get-help], and one can run perldoc or
1333 It is possible to show this help automatically after some idle time.
1334 This is regulated by variable `cperl-lazy-help-time'. Default with
1335 `cperl-hairy' (if the value of `cperl-lazy-help-time' is nil) is 5
1336 secs idle time . It is also possible to switch this on/off from the
1337 menu, or via \\[cperl-toggle-autohelp]. Requires `run-with-idle-timer'.
1339 Use \\[cperl-lineup] to vertically lineup some construction - put the
1340 beginning of the region at the start of construction, and make region
1341 span the needed amount of lines.
1343 Variables `cperl-pod-here-scan', `cperl-pod-here-fontify',
1344 `cperl-pod-face', `cperl-pod-head-face' control processing of pod and
1345 here-docs sections. With capable Emaxen results of scan are used
1346 for indentation too, otherwise they are used for highlighting only.
1348 Variables controlling indentation style:
1349 `cperl-tab-always-indent'
1350 Non-nil means TAB in CPerl mode should always reindent the current line,
1351 regardless of where in the line point is when the TAB command is used.
1352 `cperl-indent-left-aligned-comments'
1353 Non-nil means that the comment starting in leftmost column should indent.
1354 `cperl-auto-newline'
1355 Non-nil means automatically newline before and after braces,
1356 and after colons and semicolons, inserted in Perl code. The following
1357 \\[cperl-electric-backspace] will remove the inserted whitespace.
1358 Insertion after colons requires both this variable and
1359 `cperl-auto-newline-after-colon' set.
1360 `cperl-auto-newline-after-colon'
1361 Non-nil means automatically newline even after colons.
1362 Subject to `cperl-auto-newline' setting.
1363 `cperl-indent-level'
1364 Indentation of Perl statements within surrounding block.
1365 The surrounding block's indentation is the indentation
1366 of the line on which the open-brace appears.
1367 `cperl-continued-statement-offset'
1368 Extra indentation given to a substatement, such as the
1369 then-clause of an if, or body of a while, or just a statement continuation.
1370 `cperl-continued-brace-offset'
1371 Extra indentation given to a brace that starts a substatement.
1372 This is in addition to `cperl-continued-statement-offset'.
1373 `cperl-brace-offset'
1374 Extra indentation for line if it starts with an open brace.
1375 `cperl-brace-imaginary-offset'
1376 An open brace following other text is treated as if it the line started
1377 this far to the right of the actual line indentation.
1378 `cperl-label-offset'
1379 Extra indentation for line that is a label.
1380 `cperl-min-label-indent'
1381 Minimal indentation for line that is a label.
1383 Settings for K&R and BSD indentation styles are
1384 `cperl-indent-level' 5 8
1385 `cperl-continued-statement-offset' 5 8
1386 `cperl-brace-offset' -5 -8
1387 `cperl-label-offset' -5 -8
1389 CPerl knows several indentation styles, and may bulk set the
1390 corresponding variables. Use \\[cperl-set-style] to do this. Use
1391 \\[cperl-set-style-back] to restore the memorized preexisting values
1392 \(both available from menu).
1394 If `cperl-indent-level' is 0, the statement after opening brace in
1395 column 0 is indented on
1396 `cperl-brace-offset'+`cperl-continued-statement-offset'.
1398 Turning on CPerl mode calls the hooks in the variable `cperl-mode-hook'
1401 DO NOT FORGET to read micro-docs (available from `Perl' menu)
1402 or as help on variables `cperl-tips', `cperl-problems',
1403 `cperl-non-problems', `cperl-praise', `cperl-speed'."
1405 (kill-all-local-variables)
1406 (use-local-map cperl-mode-map
)
1407 (if (cperl-val 'cperl-electric-linefeed
)
1409 (local-set-key "\C-J" 'cperl-linefeed
)
1410 (local-set-key "\C-C\C-J" 'newline-and-indent
)))
1412 (cperl-val 'cperl-clobber-lisp-bindings
)
1413 (cperl-val 'cperl-info-on-command-no-prompt
))
1415 ;; don't clobber the backspace binding:
1416 (cperl-define-key "\C-hf" 'cperl-info-on-current-command
[(control h
) f
])
1417 (cperl-define-key "\C-c\C-hf" 'cperl-info-on-command
1418 [(control c
) (control h
) f
])))
1419 (setq major-mode
'perl-mode
)
1420 (setq mode-name
"CPerl")
1421 (if (not cperl-mode-abbrev-table
)
1422 (let ((prev-a-c abbrevs-changed
))
1423 (define-abbrev-table 'cperl-mode-abbrev-table
'(
1424 ("if" "if" cperl-electric-keyword
0)
1425 ("elsif" "elsif" cperl-electric-keyword
0)
1426 ("while" "while" cperl-electric-keyword
0)
1427 ("until" "until" cperl-electric-keyword
0)
1428 ("unless" "unless" cperl-electric-keyword
0)
1429 ("else" "else" cperl-electric-else
0)
1430 ("continue" "continue" cperl-electric-else
0)
1431 ("for" "for" cperl-electric-keyword
0)
1432 ("foreach" "foreach" cperl-electric-keyword
0)
1433 ("formy" "formy" cperl-electric-keyword
0)
1434 ("foreachmy" "foreachmy" cperl-electric-keyword
0)
1435 ("do" "do" cperl-electric-keyword
0)
1436 ("pod" "pod" cperl-electric-pod
0)
1437 ("over" "over" cperl-electric-pod
0)
1438 ("head1" "head1" cperl-electric-pod
0)
1439 ("head2" "head2" cperl-electric-pod
0)))
1440 (setq abbrevs-changed prev-a-c
)))
1441 (setq local-abbrev-table cperl-mode-abbrev-table
)
1442 (abbrev-mode (if (cperl-val 'cperl-electric-keywords
) 1 0))
1443 (set-syntax-table cperl-mode-syntax-table
)
1444 (make-local-variable 'paragraph-start
)
1445 (setq paragraph-start
(concat "^$\\|" page-delimiter
))
1446 (make-local-variable 'paragraph-separate
)
1447 (setq paragraph-separate paragraph-start
)
1448 (make-local-variable 'paragraph-ignore-fill-prefix
)
1449 (setq paragraph-ignore-fill-prefix t
)
1450 (make-local-variable 'indent-line-function
)
1451 (setq indent-line-function
'cperl-indent-line
)
1452 (make-local-variable 'require-final-newline
)
1453 (setq require-final-newline t
)
1454 (make-local-variable 'comment-start
)
1455 (setq comment-start
"# ")
1456 (make-local-variable 'comment-end
)
1457 (setq comment-end
"")
1458 (make-local-variable 'comment-column
)
1459 (setq comment-column cperl-comment-column
)
1460 (make-local-variable 'comment-start-skip
)
1461 (setq comment-start-skip
"#+ *")
1462 (make-local-variable 'defun-prompt-regexp
)
1463 (setq defun-prompt-regexp
"^[ \t]*sub[ \t]+\\([^ \t\n{(;]+\\)[ \t]*")
1464 (make-local-variable 'comment-indent-function
)
1465 (setq comment-indent-function
'cperl-comment-indent
)
1466 (make-local-variable 'parse-sexp-ignore-comments
)
1467 (setq parse-sexp-ignore-comments t
)
1468 (make-local-variable 'indent-region-function
)
1469 (setq indent-region-function
'cperl-indent-region
)
1470 ;;(setq auto-fill-function 'cperl-do-auto-fill) ; Need to switch on and off!
1471 (make-local-variable 'imenu-create-index-function
)
1472 (setq imenu-create-index-function
1473 (function imenu-example--create-perl-index
))
1474 (make-local-variable 'imenu-sort-function
)
1475 (setq imenu-sort-function nil
)
1476 (make-local-variable 'vc-header-alist
)
1477 (set 'vc-header-alist cperl-vc-header-alist
) ; Avoid warning
1478 (make-local-variable 'font-lock-defaults
)
1479 (setq font-lock-defaults
1481 ((string< emacs-version
"19.30")
1482 '(perl-font-lock-keywords-2))
1483 ((string< emacs-version
"19.33") ; Which one to use?
1484 '((perl-font-lock-keywords
1485 perl-font-lock-keywords-1
1486 perl-font-lock-keywords-2
)))
1488 '((cperl-load-font-lock-keywords
1489 cperl-load-font-lock-keywords-1
1490 cperl-load-font-lock-keywords-2
)))))
1491 (make-local-variable 'cperl-syntax-state
)
1492 (if cperl-use-syntax-table-text-property
1494 (make-variable-buffer-local 'parse-sexp-lookup-properties
)
1495 ;; Do not introduce variable if not needed, we check it!
1496 (set 'parse-sexp-lookup-properties t
)
1497 ;; Fix broken font-lock:
1498 (or (boundp 'font-lock-unfontify-region-function
)
1499 (set 'font-lock-unfontify-region-function
1500 'font-lock-default-unfontify-region
))
1501 (make-variable-buffer-local 'font-lock-unfontify-region-function
)
1502 (set 'font-lock-unfontify-region-function
1503 'cperl-font-lock-unfontify-region-function
)
1504 (make-variable-buffer-local 'cperl-syntax-done-to
)
1505 ;; Another bug: unless font-lock-syntactic-keywords, font-lock
1506 ;; ignores syntax-table text-property. (t) is a hack
1507 ;; to make font-lock think that font-lock-syntactic-keywords
1509 (make-variable-buffer-local 'font-lock-syntactic-keywords
)
1510 (setq font-lock-syntactic-keywords
1511 (if cperl-syntaxify-by-font-lock
1512 '(t (cperl-fontify-syntaxically))
1514 (make-local-variable 'cperl-old-style
)
1515 (or (fboundp 'cperl-old-auto-fill-mode
)
1517 (fset 'cperl-old-auto-fill-mode
(symbol-function 'auto-fill-mode
))
1518 (defun auto-fill-mode (&optional arg
)
1520 (eval '(cperl-old-auto-fill-mode arg
)) ; Avoid a warning
1521 (and auto-fill-function
(eq major-mode
'perl-mode
)
1522 (setq auto-fill-function
'cperl-do-auto-fill
)))))
1523 (if (cperl-enable-font-lock)
1524 (if (cperl-val 'cperl-font-lock
)
1525 (progn (or cperl-faces-init
(cperl-init-faces))
1526 (font-lock-mode 1))))
1527 (and (boundp 'msb-menu-cond
)
1528 (not cperl-msb-fixed
)
1530 (if (featurep 'easymenu
)
1531 (easy-menu-add cperl-menu
)) ; A NOP in Emacs.
1532 (run-hooks 'cperl-mode-hook
)
1533 ;; After hooks since fontification will break this
1534 (if cperl-pod-here-scan
1535 (or ;;(and (boundp 'font-lock-mode)
1536 ;; (eval 'font-lock-mode) ; Avoid warning
1537 ;; (boundp 'font-lock-hot-pass) ; Newer font-lock
1538 cperl-syntaxify-by-font-lock
;;)
1539 (progn (or cperl-faces-init
(cperl-init-faces-weak))
1540 (cperl-find-pods-heres)))))
1542 ;; Fix for perldb - make default reasonable
1543 (defvar gud-perldb-history
)
1547 (perldb (read-from-minibuffer "Run perldb (like this): "
1548 (if (consp gud-perldb-history
)
1549 (car gud-perldb-history
)
1550 (concat "perl " ;;(file-name-nondirectory
1554 (buffer-file-name)))
1556 '(gud-perldb-history .
1))))
1558 (defvar msb-menu-cond
)
1559 (defun cperl-msb-fix ()
1560 ;; Adds perl files to msb menu, supposes that msb is already loaded
1561 (setq cperl-msb-fixed t
)
1562 (let* ((l (length msb-menu-cond
))
1563 (last (nth (1- l
) msb-menu-cond
))
1564 (precdr (nthcdr (- l
2) msb-menu-cond
)) ; cdr of this is last
1565 (handle (1- (nth 1 last
))))
1566 (setcdr precdr
(list
1568 '(eq major-mode
'perl-mode
)
1573 ;; This is used by indent-for-comment
1574 ;; to decide how much to indent a comment in CPerl code
1575 ;; based on its context. Do fallback if comment is found wrong.
1577 (defvar cperl-wrong-comment
)
1578 (defvar cperl-st-cfence
'(14)) ; Comment-fence
1579 (defvar cperl-st-sfence
'(15)) ; String-fence
1580 (defvar cperl-st-punct
'(1))
1581 (defvar cperl-st-word
'(2))
1582 (defvar cperl-st-bra
'(4 . ?\
>))
1583 (defvar cperl-st-ket
'(5 . ?\
<))
1586 (defun cperl-comment-indent ()
1587 (let ((p (point)) (c (current-column)) was phony
)
1588 (if (looking-at "^#") 0 ; Existing comment at bol stays there.
1589 ;; Wrong comment found
1591 (setq was
(cperl-to-comment-or-eol)
1592 phony
(eq (get-text-property (point) 'syntax-table
)
1596 (re-search-forward "#\\|$") ; Hmm, what about embedded #?
1597 (if (eq (preceding-char) ?\
#)
1602 (skip-chars-backward " \t")
1603 (max (1+ (current-column)) ; Else indent at comment column
1606 (insert comment-start
)
1607 (backward-char (length comment-start
)))
1608 (setq cperl-wrong-comment t
)
1609 (indent-to comment-column
1) ; Indent minimum 1
1610 c
))))) ; except leave at least one space.
1612 ;;;(defun cperl-comment-indent-fallback ()
1613 ;;; "Is called if the standard comment-search procedure fails.
1614 ;;;Point is at start of real comment."
1615 ;;; (let ((c (current-column)) target cnt prevc)
1616 ;;; (if (= c comment-column) nil
1617 ;;; (setq cnt (skip-chars-backward "[ \t]"))
1618 ;;; (setq target (max (1+ (setq prevc
1619 ;;; (current-column))) ; Else indent at comment column
1620 ;;; comment-column))
1621 ;;; (if (= c comment-column) nil
1622 ;;; (delete-backward-char cnt)
1623 ;;; (while (< prevc target)
1625 ;;; (setq prevc (current-column)))
1626 ;;; (if (> prevc target) (progn (delete-char -1) (setq prevc (current-column))))
1627 ;;; (while (< prevc target)
1629 ;;; (setq prevc (current-column)))))))
1631 (defun cperl-indent-for-comment ()
1632 "Substitute for `indent-for-comment' in CPerl."
1634 (let (cperl-wrong-comment)
1635 (indent-for-comment)
1636 (if cperl-wrong-comment
1637 (progn (cperl-to-comment-or-eol)
1638 (forward-char (length comment-start
))))))
1640 (defun cperl-comment-region (b e arg
)
1641 "Comment or uncomment each line in the region in CPerl mode.
1642 See `comment-region'."
1643 (interactive "r\np")
1644 (let ((comment-start "#"))
1645 (comment-region b e arg
)))
1647 (defun cperl-uncomment-region (b e arg
)
1648 "Uncomment or comment each line in the region in CPerl mode.
1649 See `comment-region'."
1650 (interactive "r\np")
1651 (let ((comment-start "#"))
1652 (comment-region b e
(- arg
))))
1654 (defvar cperl-brace-recursing nil
)
1656 (defun cperl-electric-brace (arg &optional only-before
)
1657 "Insert character and correct line's indentation.
1658 If ONLY-BEFORE and `cperl-auto-newline', will insert newline before the
1659 place (even in empty line), but not after. If after \")\" and the inserted
1660 char is \"{\", insert extra newline before only if
1661 `cperl-extra-newline-before-brace'."
1664 (other-end (if (and cperl-electric-parens-mark
1670 (not cperl-brace-recursing
)
1671 (cperl-val 'cperl-electric-parens
)
1672 (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point)))
1673 ;; Need to insert a matching pair
1676 (setq insertpos
(point-marker))
1677 (goto-char other-end
)
1678 (setq last-command-char ?\
{)
1679 (cperl-electric-lbrace arg insertpos
))
1681 ;: Check whether we close something "usual" with `}'
1682 (if (and (eq last-command-char ?\
})
1686 (up-list (- (prefix-numeric-value arg
)))
1687 ;;(cperl-after-block-p (point-min))
1688 (cperl-after-expr-p nil
"{;)"))
1690 ;; Just insert the guy
1691 (self-insert-command (prefix-numeric-value arg
))
1692 (if (and (not arg
) ; No args, end (of empty line or auto)
1694 (or (and (null only-before
)
1696 (skip-chars-backward " \t")
1698 (and (eq last-command-char ?\
{) ; Do not insert newline
1699 ;; if after ")" and `cperl-extra-newline-before-brace'
1700 ;; is nil, do not insert extra newline.
1701 (not cperl-extra-newline-before-brace
)
1703 (skip-chars-backward " \t")
1704 (eq (preceding-char) ?\
))))
1705 (if cperl-auto-newline
1706 (progn (cperl-indent-line) (newline) t
) nil
)))
1708 (self-insert-command (prefix-numeric-value arg
))
1710 (if cperl-auto-newline
1711 (setq insertpos
(1- (point))))
1712 (if (and cperl-auto-newline
(null only-before
))
1715 (cperl-indent-line)))
1717 (if insertpos
(progn (goto-char insertpos
)
1718 (search-forward (make-string
1719 1 last-command-char
))
1720 (setq insertpos
(1- (point)))))
1724 (goto-char insertpos
)
1725 (self-insert-command (prefix-numeric-value arg
)))
1726 (self-insert-command (prefix-numeric-value arg
)))))))
1728 (defun cperl-electric-lbrace (arg &optional end
)
1729 "Insert character, correct line's indentation, correct quoting by space."
1732 (cperl-brace-recursing t
)
1733 (cperl-auto-newline cperl-auto-newline
)
1735 (if (and cperl-electric-parens-mark
1742 (and (cperl-val 'cperl-electric-lbrace-space
)
1743 (eq (preceding-char) ?$
)
1745 (skip-chars-backward "$")
1746 (looking-at "\\(\\$\\$\\)*\\$\\([^\\$]\\|$\\)"))
1748 ;; Check whether we are in comment
1752 (not (looking-at "[ \t]*#")))
1753 (cperl-after-expr-p nil
"{;)"))
1755 (setq cperl-auto-newline nil
))
1756 (cperl-electric-brace arg
)
1757 (and (cperl-val 'cperl-electric-parens
)
1758 (eq last-command-char ?
{)
1759 (memq last-command-char
1760 (append cperl-electric-parens-string nil
))
1761 (or (if other-end
(goto-char (marker-position other-end
)))
1763 (setq last-command-char ?
} pos
(point))
1764 (progn (cperl-electric-brace arg t
)
1767 (defun cperl-electric-paren (arg)
1768 "Insert a matching pair of parentheses."
1770 (let ((beg (save-excursion (beginning-of-line) (point)))
1771 (other-end (if (and cperl-electric-parens-mark
1778 (if (and (cperl-val 'cperl-electric-parens
)
1779 (memq last-command-char
1780 (append cperl-electric-parens-string nil
))
1781 (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point))
1782 ;;(not (save-excursion (search-backward "#" beg t)))
1783 (if (eq last-command-char ?
<)
1785 (and abbrev-mode
; later it is too late, may be after `for'
1787 (cperl-after-expr-p nil
"{;(,:="))
1790 (self-insert-command (prefix-numeric-value arg
))
1791 (if other-end
(goto-char (marker-position other-end
)))
1792 (insert (make-string
1793 (prefix-numeric-value arg
)
1794 (cdr (assoc last-command-char
'((?
{ .?
})
1798 (forward-char (- (prefix-numeric-value arg
))))
1799 (self-insert-command (prefix-numeric-value arg
)))))
1801 (defun cperl-electric-rparen (arg)
1802 "Insert a matching pair of parentheses if marking is active.
1803 If not, or if we are not at the end of marking range, would self-insert."
1805 (let ((beg (save-excursion (beginning-of-line) (point)))
1806 (other-end (if (and cperl-electric-parens-mark
1807 (cperl-val 'cperl-electric-parens
)
1808 (memq last-command-char
1809 (append cperl-electric-parens-string nil
))
1816 (cperl-val 'cperl-electric-parens
)
1817 (memq last-command-char
'( ?\
) ?\
] ?\
} ?\
> ))
1818 (>= (save-excursion (cperl-to-comment-or-eol) (point)) (point))
1819 ;;(not (save-excursion (search-backward "#" beg t)))
1822 (self-insert-command (prefix-numeric-value arg
))
1824 (if other-end
(goto-char other-end
))
1825 (insert (make-string
1826 (prefix-numeric-value arg
)
1827 (cdr (assoc last-command-char
'((?\
} . ?\
{)
1832 (self-insert-command (prefix-numeric-value arg
)))))
1834 (defun cperl-electric-keyword ()
1835 "Insert a construction appropriate after a keyword.
1836 Help message may be switched off by setting `cperl-message-electric-keyword'
1838 (let ((beg (save-excursion (beginning-of-line) (point)))
1839 (dollar (and (eq last-command-char ?$
)
1840 (eq this-command
'self-insert-command
)))
1841 (delete (and (memq last-command-char
'(?\ ?
\n ?
\t ?
\f))
1842 (memq this-command
'(self-insert-command newline
))))
1844 (and (save-excursion
1848 (setq do
(looking-at "do\\>")))
1850 (cperl-after-expr-p nil
"{;:"))
1854 "[#\"'`]\\|\\<q\\(\\|[wqxr]\\)\\>"
1856 (save-excursion (or (not (re-search-backward "^=" nil t
))
1859 (and cperl-use-syntax-table-text-property
1860 (not (eq (get-text-property (point)
1864 (and (eq (preceding-char) ?y
)
1865 (progn ; "foreachmy"
1871 (memq this-command
'(self-insert-command newline
)))))
1872 (and dollar
(insert " $"))
1874 ;;(insert " () {\n}")
1876 (cperl-extra-newline-before-brace
1877 (insert (if do
"\n" " ()\n"))
1883 (and do
(insert " while ();")))
1885 (insert (if do
" {\n} while ();" " () {\n}")))
1887 (or (looking-at "[ \t]\\|$") (insert " "))
1889 (if dollar
(progn (search-backward "$")
1893 (search-backward ")"))
1895 (cperl-putback-char cperl-del-back-ch
))
1896 (if cperl-message-electric-keyword
1897 (message "Precede char by C-q to avoid expansion"))))))
1899 (defun cperl-ensure-newlines (n &optional pos
)
1900 "Make sure there are N newlines after the point."
1901 (or pos
(setq pos
(point)))
1902 (if (looking-at "\n")
1906 (cperl-ensure-newlines (1- n
) pos
)
1909 (defun cperl-electric-pod ()
1910 "Insert a POD chunk appropriate after a =POD directive."
1911 (let ((delete (and (memq last-command-char
'(?\ ?
\n ?
\t ?
\f))
1912 (memq this-command
'(self-insert-command newline
))))
1913 head1 notlast name p really-delete over
)
1914 (and (save-excursion
1919 (eq (preceding-char) ?
=)
1921 (setq head1
(looking-at "head1\\>"))
1922 (setq over
(looking-at "over\\>"))
1926 (get-text-property (point) 'in-pod
)
1927 (cperl-after-expr-p nil
"{;:")
1928 (and (re-search-backward
1929 "\\(\\`\n?\\|\n\n\\)=\\sw+" (point-min) t
)
1932 (and cperl-use-syntax-table-text-property
1933 (not (eq (get-text-property (point) 'syntax-type
)
1937 (setq notlast
(search-forward "\n\n=" nil t
)))
1941 (cperl-ensure-newlines 2)
1947 (re-search-backward "\\(\\`\n?\\|\n\n\\)=head1\\>"
1948 nil t
)))) ; Only one
1951 (setq name
(file-name-sans-extension
1952 (file-name-nondirectory (buffer-file-name)))
1954 (insert " NAME\n\n" name
1955 " - \n\n=head1 SYNOPSYS\n\n\n\n"
1956 "=head1 DESCRIPTION")
1957 (cperl-ensure-newlines 4)
1961 (setq really-delete t
))
1966 (insert "\n\n=item \n\n\n\n"
1968 (cperl-ensure-newlines 2)
1972 (setq really-delete t
)))
1973 (if (and delete really-delete
)
1974 (cperl-putback-char cperl-del-back-ch
))))))
1976 (defun cperl-electric-else ()
1977 "Insert a construction appropriate after a keyword.
1978 Help message may be switched off by setting `cperl-message-electric-keyword'
1980 (let ((beg (save-excursion (beginning-of-line) (point))))
1981 (and (save-excursion
1983 (cperl-after-expr-p nil
"{;:"))
1987 "[#\"'`]\\|\\<q\\(\\|[wqxr]\\)\\>"
1989 (save-excursion (or (not (re-search-backward "^=" nil t
))
1991 (and cperl-use-syntax-table-text-property
1992 (not (eq (get-text-property (point)
1997 ;;(insert " {\n\n}")
1999 (cperl-extra-newline-before-brace
2007 (or (looking-at "[ \t]\\|$") (insert " "))
2011 (cperl-putback-char cperl-del-back-ch
)
2012 (setq this-command
'cperl-electric-else
)
2013 (if cperl-message-electric-keyword
2014 (message "Precede char by C-q to avoid expansion"))))))
2016 (defun cperl-linefeed ()
2017 "Go to end of line, open a new line and indent appropriately.
2018 If in POD, insert appropriate lines."
2020 (let ((beg (save-excursion (beginning-of-line) (point)))
2021 (end (save-excursion (end-of-line) (point)))
2022 (pos (point)) start over cut res
)
2023 (if (and ; Check if we need to split:
2024 ; i.e., on a boundary and inside "{...}"
2025 (save-excursion (cperl-to-comment-or-eol)
2026 (>= (point) pos
)) ; Not in a comment
2028 (skip-chars-backward " \t" beg
)
2030 (looking-at "[;{]")) ; After { or ; + spaces
2031 (looking-at "[ \t]*}") ; Before }
2032 (re-search-forward "\\=[ \t]*;" end t
)) ; Before spaces + ;
2035 (eq (car (parse-partial-sexp pos end -
1)) -
1)
2036 ; Leave the level of parens
2037 (looking-at "[,; \t]*\\($\\|#\\)") ; Comma to allow anon subr
2041 (setq start
(point-marker))
2042 (<= start pos
))))) ; Redundant? Are after the
2043 ; start of parens group.
2045 (skip-chars-backward " \t")
2046 (or (memq (preceding-char) (append ";{" nil
))
2052 (or (looking-at "{[ \t]*$") ; If there is a statement
2053 ; before, move it to separate line
2057 (cperl-indent-line)))
2058 (forward-line 1) ; We are on the target line
2061 (or (looking-at "[ \t]*}[,; \t]*$") ; If there is a statement
2062 ; after, move it to separate line
2065 (search-backward "}" beg
)
2066 (skip-chars-backward " \t")
2067 (or (memq (preceding-char) (append ";{" nil
))
2072 (forward-line -
1) ; We are on the line before target
2074 (newline-and-indent))
2075 (end-of-line) ; else - no splitting
2077 ((and (looking-at "\n[ \t]*{$")
2079 (skip-chars-backward " \t")
2080 (eq (preceding-char) ?\
)))) ; Probably if () {} group
2081 ; with an extra newline.
2083 (cperl-indent-line))
2084 ((save-excursion ; In POD header
2085 (forward-paragraph -
1)
2086 ;; (re-search-backward "\\(\\`\n?\\|\n\n\\)=head1\\b")
2087 ;; We are after \n now, so look for the rest
2088 (if (looking-at "\\(\\`\n?\\|\n\\)=\\sw+")
2090 (setq cut
(looking-at "\\(\\`\n?\\|\n\\)=cut\\>"))
2091 (setq over
(looking-at "\\(\\`\n?\\|\n\\)=over\\>"))
2095 (forward-paragraph -
1)
2098 (setq cut
(buffer-substring (point)
2102 (delete-char (- (save-excursion (end-of-line) (point))
2104 (setq res
(expand-abbrev))
2110 (cperl-ensure-newlines (if cut
2 4))
2112 ((get-text-property (point) 'in-pod
) ; In POD section
2113 (cperl-ensure-newlines 4)
2115 ((looking-at "\n[ \t]*$") ; Next line is empty - use it.
2117 (cperl-indent-line))
2119 (newline-and-indent))))))
2121 (defun cperl-electric-semi (arg)
2122 "Insert character and correct line's indentation."
2124 (if cperl-auto-newline
2125 (cperl-electric-terminator arg
)
2126 (self-insert-command (prefix-numeric-value arg
))))
2128 (defun cperl-electric-terminator (arg)
2129 "Insert character and correct line's indentation."
2131 (let (insertpos (end (point))
2132 (auto (and cperl-auto-newline
2133 (or (not (eq last-command-char ?
:))
2134 cperl-auto-newline-after-colon
))))
2135 (if (and ;;(not arg)
2137 (not (save-excursion
2139 (skip-chars-forward " \t")
2141 ;; Ignore in comment lines
2142 (= (following-char) ?
#)
2143 ;; Colon is special only after a label
2144 ;; So quickly rule out most other uses of colon
2145 ;; and do no indentation for them.
2146 (and (eq last-command-char ?
:)
2149 (skip-chars-forward " \t")
2150 (and (< (point) end
)
2151 (progn (goto-char (- end
1))
2152 (not (looking-at ":"))))))
2154 (beginning-of-defun)
2155 (let ((pps (parse-partial-sexp (point) end
)))
2156 (or (nth 3 pps
) (nth 4 pps
) (nth 5 pps
))))))))
2158 (self-insert-command (prefix-numeric-value arg
))
2160 (if auto
(setq insertpos
(point-marker)))
2166 (cperl-indent-line)))
2168 (if insertpos
(goto-char (1- (marker-position insertpos
)))
2173 (goto-char insertpos
)
2174 (self-insert-command (prefix-numeric-value arg
)))
2175 (self-insert-command (prefix-numeric-value arg
)))))
2177 (defun cperl-electric-backspace (arg)
2178 "Backspace-untabify, or remove the whitespace around the point inserted
2179 by an electric key."
2181 (if (and cperl-auto-newline
2182 (memq last-command
'(cperl-electric-semi
2183 cperl-electric-terminator
2184 cperl-electric-lbrace
))
2185 (memq (preceding-char) '(?\ ?
\t ?
\n)))
2187 (if (eq last-command
'cperl-electric-lbrace
)
2188 (skip-chars-forward " \t\n"))
2190 (skip-chars-backward " \t\n")
2191 (delete-region (point) p
))
2192 (and (eq last-command
'cperl-electric-else
)
2193 ;; We are removing the whitespace *inside* cperl-electric-else
2194 (setq this-command
'cperl-electric-else-really
))
2195 (if (and cperl-auto-newline
2196 (eq last-command
'cperl-electric-else-really
)
2197 (memq (preceding-char) '(?\ ?
\t ?
\n)))
2199 (skip-chars-forward " \t\n")
2201 (skip-chars-backward " \t\n")
2202 (delete-region (point) p
))
2203 (backward-delete-char-untabify arg
))))
2205 (defun cperl-inside-parens-p ()
2209 (narrow-to-region (point)
2210 (progn (beginning-of-defun) (point)))
2211 (goto-char (point-max))
2212 (= (char-after (or (scan-lists (point) -
1 1) (point-min))) ?\
()))
2215 (defun cperl-indent-command (&optional whole-exp
)
2216 "Indent current line as Perl code, or in some cases insert a tab character.
2217 If `cperl-tab-always-indent' is non-nil (the default), always indent current
2218 line. Otherwise, indent the current line only if point is at the left margin
2219 or in the line's indentation; otherwise insert a tab.
2221 A numeric argument, regardless of its value,
2222 means indent rigidly all the lines of the expression starting after point
2223 so that this line becomes properly indented.
2224 The relative indentation among the lines of the expression are preserved."
2226 (cperl-update-syntaxification (point) (point))
2228 ;; If arg, always indent this line as Perl
2229 ;; and shift remaining lines of expression the same amount.
2230 (let ((shift-amt (cperl-indent-line))
2233 (if cperl-tab-always-indent
2234 (beginning-of-line))
2241 (if (and shift-amt
(> end beg
))
2242 (indent-code-rigidly beg end shift-amt
"#")))
2243 (if (and (not cperl-tab-always-indent
)
2245 (skip-chars-backward " \t")
2248 (cperl-indent-line))))
2250 (defun cperl-indent-line (&optional parse-data
)
2251 "Indent current line as Perl code.
2252 Return the amount the indentation changed by."
2253 (let (indent i beg shift-amt
2254 (case-fold-search nil
)
2255 (pos (- (point-max) (point))))
2256 (setq indent
(cperl-calculate-indent parse-data
)
2260 (cond ((or (eq indent nil
) (eq indent t
))
2261 (setq indent
(current-indentation) i nil
))
2262 ;;((eq indent t) ; Never?
2263 ;; (setq indent (cperl-calculate-indent-within-comment)))
2264 ;;((looking-at "[ \t]*#")
2267 (skip-chars-forward " \t")
2268 (if (listp indent
) (setq indent
(car indent
)))
2269 (cond ((looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]")
2271 (setq indent
(max cperl-min-label-indent
2272 (+ indent cperl-label-offset
)))))
2273 ((= (following-char) ?
})
2274 (setq indent
(- indent cperl-indent-level
)))
2275 ((memq (following-char) '(?\
) ?\
])) ; To line up with opening paren.
2276 (setq indent
(+ indent cperl-close-paren-offset
)))
2277 ((= (following-char) ?
{)
2278 (setq indent
(+ indent cperl-brace-offset
))))))
2279 (skip-chars-forward " \t")
2280 (setq shift-amt
(and i
(- indent
(current-column))))
2281 (if (or (not shift-amt
)
2283 (if (> (- (point-max) pos
) (point))
2284 (goto-char (- (point-max) pos
)))
2285 (delete-region beg
(point))
2287 ;; If initial point was within line's indentation,
2288 ;; position after the indentation. Else stay at same point in text.
2289 (if (> (- (point-max) pos
) (point))
2290 (goto-char (- (point-max) pos
))))
2293 (defun cperl-after-label ()
2294 ;; Returns true if the point is after label. Does not do save-excursion.
2295 (and (eq (preceding-char) ?
:)
2296 (memq (char-syntax (char-after (- (point) 2)))
2300 (looking-at "[a-zA-Z_][a-zA-Z0-9_]*:[^:]"))))
2302 (defun cperl-get-state (&optional parse-start start-state
)
2303 ;; returns list (START STATE DEPTH PRESTART),
2304 ;; START is a good place to start parsing, or equal to
2305 ;; PARSE-START if preset,
2306 ;; STATE is what is returned by `parse-partial-sexp'.
2307 ;; DEPTH is true is we are immediately after end of block
2308 ;; which contains START.
2309 ;; PRESTART is the position basing on which START was found.
2311 (let ((start-point (point)) depth state start prestart
)
2312 (if (and parse-start
2313 (<= parse-start start-point
))
2314 (goto-char parse-start
)
2315 (beginning-of-defun)
2316 (setq start-state nil
))
2317 (setq prestart
(point))
2319 ;; Try to go out, if sub is not on the outermost level
2320 (while (< (point) start-point
)
2321 (setq start
(point) parse-start start depth nil
2322 state
(parse-partial-sexp start start-point -
1))
2323 (if (> (car state
) -
1) nil
2324 ;; The current line could start like }}}, so the indentation
2325 ;; corresponds to a different level than what we reached
2327 (beginning-of-line 2))) ; Go to the next line.
2328 (if start
(goto-char start
))) ; Not at the start of file
2329 (setq start
(point))
2330 (or state
(setq state
(parse-partial-sexp start start-point -
1 nil start-state
)))
2331 (list start state depth prestart
))))
2333 (defun cperl-block-p () ; Do not C-M-q ! One string contains ";" !
2334 ;; Positions is before ?\{. Checks whether it starts a block.
2335 ;; No save-excursion!
2336 (cperl-backward-to-noncomment (point-min))
2337 (or (memq (preceding-char) (append ";){}$@&%\C-@" nil
)) ; Or label! \C-@ at bobp
2338 ; Label may be mixed up with `$blah :'
2339 (save-excursion (cperl-after-label))
2340 (and (memq (char-syntax (preceding-char)) '(?w ?_
))
2343 ;; Need take into account `bless', `return', `tr',...
2344 (or (and (looking-at "[a-zA-Z0-9_:]+[ \t\n\f]*[{#]") ; Method call syntax
2345 (not (looking-at "\\(bless\\|return\\|q[wqrx]?\\|tr\\|[smy]\\)\\>")))
2347 (skip-chars-backward " \t\n\f")
2348 (and (memq (char-syntax (preceding-char)) '(?w ?_
))
2352 "sub[ \t]+[a-zA-Z0-9_:]+[ \t\n\f]*\\(([^()]*)[ \t\n\f]*\\)?[#{]")))))))))
2354 (defvar cperl-look-for-prop
'((pod in-pod
) (here-doc-delim here-doc-group
)))
2356 (defun cperl-calculate-indent (&optional parse-data
) ; was parse-start
2357 "Return appropriate indentation for current line as Perl code.
2358 In usual case returns an integer: the column to indent to.
2359 Returns nil if line starts inside a string, t if in a comment.
2361 Will not correct the indentation for labels, but will correct it for braces
2362 and closing parentheses and brackets.."
2365 (memq (get-text-property (point) 'syntax-type
)
2366 '(pod here-doc here-doc-delim format
))
2367 ;; before start of POD - whitespace found since do not have 'pod!
2368 (and (looking-at "[ \t]*\n=")
2369 (error "Spaces before pod section!"))
2370 (and (not cperl-indent-left-aligned-comments
)
2374 (let ((indent-point (point))
2375 (char-after (save-excursion
2376 (skip-chars-forward " \t")
2378 (in-pod (get-text-property (point) 'in-pod
))
2379 (pre-indent-point (point))
2383 ;; In the verbatim part, probably code example. What to do???
2388 (cperl-backward-to-noncomment nil
)
2389 (setq p
(max (point-min) (1- (point)))
2390 prop
(get-text-property p
'syntax-type
)
2391 look-prop
(or (nth 1 (assoc prop cperl-look-for-prop
))
2393 (if (memq prop
'(pod here-doc format here-doc-delim
))
2395 (goto-char (or (previous-single-property-change p look-prop
)
2398 (setq pre-indent-point
(point)))))))
2399 (goto-char pre-indent-point
)
2400 (let* ((case-fold-search nil
)
2401 (s-s (cperl-get-state (car parse-data
) (nth 1 parse-data
)))
2402 (start (or (nth 2 parse-data
)
2405 (containing-sexp (car (cdr state
)))
2408 ;;containing-sexp ;; We are buggy at toplevel :-(
2411 (setcar parse-data pre-indent-point
)
2412 (setcar (cdr parse-data
) state
)
2413 (or (nth 2 parse-data
)
2414 (setcar (cddr parse-data
) start
))
2415 ;; Before this point: end of statement
2416 (setq old-indent
(nth 3 parse-data
))))
2417 ;; (or parse-start (null symbol)
2418 ;; (setq parse-start (symbol-value symbol)
2419 ;; start-indent (nth 2 parse-start)
2420 ;; parse-start (car parse-start)))
2422 ;; (goto-char parse-start)
2423 ;; (beginning-of-defun))
2425 ;; (while (< (point) indent-point)
2426 ;; (setq start (point) parse-start start moved nil
2427 ;; state (parse-partial-sexp start indent-point -1))
2428 ;; (if (> (car state) -1) nil
2429 ;; ;; The current line could start like }}}, so the indentation
2430 ;; ;; corresponds to a different level than what we reached
2432 ;; (beginning-of-line 2))) ; Go to the next line.
2433 ;; (if start ; Not at the start of file
2435 ;; (goto-char start)
2436 ;; (setq start-indent (current-indentation))
2437 ;; (if moved ; Should correct...
2438 ;; (setq start-indent (- start-indent cperl-indent-level))))
2439 ;; (setq start-indent 0))
2440 ;; (if (< (point) indent-point) (setq parse-start (point)))
2441 ;; (or state (setq state (parse-partial-sexp
2442 ;; (point) indent-point -1 nil start-state)))
2443 ;; (setq containing-sexp
2444 ;; (or (car (cdr state))
2445 ;; (and (>= (nth 6 state) 0) old-containing-sexp))
2446 ;; old-containing-sexp nil start-state nil)
2447 ;;;; (while (< (point) indent-point)
2448 ;;;; (setq parse-start (point))
2449 ;;;; (setq state (parse-partial-sexp (point) indent-point -1 nil start-state))
2450 ;;;; (setq containing-sexp
2451 ;;;; (or (car (cdr state))
2452 ;;;; (and (>= (nth 6 state) 0) old-containing-sexp))
2453 ;;;; old-containing-sexp nil start-state nil))
2454 ;; (if symbol (set symbol (list indent-point state start-indent)))
2455 ;; (goto-char indent-point)
2456 (cond ((or (nth 3 state
) (nth 4 state
))
2457 ;; return nil or t if should not change this line
2459 ((null containing-sexp
)
2460 ;; Line is at top level. May be data or function definition,
2461 ;; or may be function argument declaration.
2462 ;; Indent like the previous top level line
2463 ;; unless that ends in a closeparen without semicolon,
2464 ;; in which case this line is the first argument decl.
2465 (skip-chars-forward " \t")
2468 (- (current-indentation)
2469 (if (nth 2 s-s
) cperl-indent-level
0)))
2470 (if (= char-after ?
{) cperl-continued-brace-offset
0)
2472 (cperl-backward-to-noncomment (or old-indent
(point-min)))
2473 ;; Look at previous line that's at column 0
2474 ;; to determine whether we are in top-level decls
2475 ;; or function's arg decls. Set basic-indent accordingly.
2476 ;; Now add a little if this is a continuation line.
2478 (eq (point) old-indent
) ; old-indent was at comment
2479 (eq (preceding-char) ?\
;)
2481 (and (eq (preceding-char) ?\
})
2482 (cperl-after-block-and-statement-beg
2483 (point-min))) ; Was start - too close
2484 (memq char-after
(append ")]}" nil
))
2485 (and (eq (preceding-char) ?\
:) ; label
2488 (skip-chars-backward " \t")
2489 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:"))))
2492 (not (eq char-after ?\C-j
)))
2493 (setcdr (cddr parse-data
)
2494 (list pre-indent-point
)))
2496 cperl-continued-statement-offset
))))
2497 ((/= (char-after containing-sexp
) ?
{)
2498 ;; line is expression, not statement:
2499 ;; indent to just after the surrounding open,
2500 ;; skip blanks if we do not close the expression.
2501 (goto-char (1+ containing-sexp
))
2502 (or (memq char-after
(append ")]}" nil
))
2503 (looking-at "[ \t]*\\(#\\|$\\)")
2504 (skip-chars-forward " \t"))
2507 ;; Containing-expr starts with \{. Check whether it is a hash.
2508 (goto-char containing-sexp
)
2509 (not (cperl-block-p)))
2510 (goto-char (1+ containing-sexp
))
2511 (or (eq char-after ?\
})
2512 (looking-at "[ \t]*\\(#\\|$\\)")
2513 (skip-chars-forward " \t"))
2514 (+ (current-column) ; Correct indentation of trailing ?\}
2515 (if (eq char-after ?\
}) (+ cperl-indent-level
2516 cperl-close-paren-offset
)
2519 ;; Statement level. Is it a continuation or a new statement?
2520 ;; Find previous non-comment character.
2521 (goto-char pre-indent-point
)
2522 (cperl-backward-to-noncomment containing-sexp
)
2523 ;; Back up over label lines, since they don't
2524 ;; affect whether our line is a continuation.
2526 (while ;;(or (eq (preceding-char) ?\,)
2527 (and (eq (preceding-char) ?
:)
2528 (or;;(eq (char-after (- (point) 2)) ?\') ; ????
2529 (memq (char-syntax (char-after (- (point) 2)))
2532 (if (eq (preceding-char) ?\
,)
2533 ;; Will go to beginning of line, essentially.
2534 ;; Will ignore embedded sexpr XXXX.
2535 (cperl-backward-to-start-of-continued-exp containing-sexp
))
2537 (cperl-backward-to-noncomment containing-sexp
))
2538 ;; Now we get the answer.
2540 (if (not (or (memq (preceding-char) (append " ;{" '(nil)))
2541 (and (eq (preceding-char) ?\
})
2542 (cperl-after-block-and-statement-beg
2543 containing-sexp
)))) ; Was ?\,
2544 ;; This line is continuation of preceding line's statement;
2545 ;; indent `cperl-continued-statement-offset' more than the
2546 ;; previous line of the statement.
2548 ;; There might be a label on this line, just
2549 ;; consider it bad style and ignore it.
2551 (cperl-backward-to-start-of-continued-exp containing-sexp
)
2552 (+ (if (memq char-after
(append "}])" nil
))
2554 cperl-continued-statement-offset
)
2555 (if (looking-at "\\w+[ \t]*:")
2556 (if (> (current-indentation) cperl-min-label-indent
)
2557 (- (current-indentation) cperl-label-offset
)
2558 ;; Do not move `parse-data', this should
2559 ;; be quick anyway (this comment comes
2560 ;;from different location):
2561 (cperl-calculate-indent))
2563 (if (eq char-after ?\
{)
2564 cperl-continued-brace-offset
0)))
2565 ;; This line starts a new statement.
2566 ;; Position following last unclosed open.
2567 (goto-char containing-sexp
)
2568 ;; Is line first statement after an open-brace?
2570 ;; If no, find that first statement and indent like
2571 ;; it. If the first statement begins with label, do
2572 ;; not believe when the indentation of the label is too
2576 (setq old-indent
(current-indentation))
2577 (let ((colon-line-end 0))
2578 (while (progn (skip-chars-forward " \t\n")
2579 (looking-at "#\\|[a-zA-Z0-9_$]*:[^:]"))
2580 ;; Skip over comments and labels following openbrace.
2581 (cond ((= (following-char) ?\
#)
2585 (save-excursion (end-of-line)
2586 (setq colon-line-end
(point)))
2587 (search-forward ":"))))
2588 ;; The first following code counts
2589 ;; if it is before the line we want to indent.
2590 (and (< (point) indent-point
)
2591 (if (> colon-line-end
(point)) ; After label
2592 (if (> (current-indentation)
2593 cperl-min-label-indent
)
2594 (- (current-indentation) cperl-label-offset
)
2595 ;; Do not believe: `max' is involved
2596 (+ old-indent cperl-indent-level
))
2597 (current-column)))))
2598 ;; If no previous statement,
2599 ;; indent it relative to line brace is on.
2600 ;; For open brace in column zero, don't let statement
2601 ;; start there too. If cperl-indent-level is zero,
2602 ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
2603 ;; For open-braces not the first thing in a line,
2604 ;; add in cperl-brace-imaginary-offset.
2606 ;; If first thing on a line: ?????
2607 (+ (if (and (bolp) (zerop cperl-indent-level
))
2608 (+ cperl-brace-offset cperl-continued-statement-offset
)
2610 ;; Move back over whitespace before the openbrace.
2611 ;; If openbrace is not first nonwhite thing on the line,
2612 ;; add the cperl-brace-imaginary-offset.
2613 (progn (skip-chars-backward " \t")
2614 (if (bolp) 0 cperl-brace-imaginary-offset
))
2615 ;; If the openbrace is preceded by a parenthesized exp,
2616 ;; move to the beginning of that;
2617 ;; possibly a different line
2619 (if (eq (preceding-char) ?\
))
2621 ;; In the case it starts a subroutine, indent with
2622 ;; respect to `sub', not with respect to the the
2623 ;; first thing on the line, say in the case of
2624 ;; anonymous sub in a hash.
2626 (skip-chars-backward " \t")
2627 (if (and (eq (preceding-char) ?b
)
2630 (looking-at "sub\\>"))
2634 (save-excursion (beginning-of-line) (point))
2636 (progn (goto-char (1+ old-indent
))
2637 (skip-chars-forward " \t")
2639 ;; Get initial indentation of the line we are on.
2640 ;; If line starts with label, calculate label indentation
2643 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
2644 (if (> (current-indentation) cperl-min-label-indent
)
2645 (- (current-indentation) cperl-label-offset
)
2646 ;; Do not move `parse-data', this should
2648 (cperl-calculate-indent))
2649 (current-indentation))))))))))))))
2651 (defvar cperl-indent-alist
2655 (toplevel-after-parenth 2)
2656 (toplevel-continued 2)
2658 "Alist of indentation rules for CPerl mode.
2661 number: add this amount of indentation.
2663 Not finished, not used.")
2665 (defun cperl-where-am-i (&optional parse-start start-state
)
2667 "Return a list of lists ((TYPE POS)...) of good points before the point.
2668 POS may be nil if it is hard to find, say, when TYPE is `string' or `comment'.
2670 Not finished, not used."
2672 (let* ((start-point (point))
2673 (s-s (cperl-get-state))
2676 (prestart (nth 3 s-s
))
2677 (containing-sexp (car (cdr state
)))
2678 (case-fold-search nil
)
2679 (res (list (list 'parse-start start
) (list 'parse-prestart prestart
))))
2680 (cond ((nth 3 state
) ; In string
2681 (setq res
(cons (list 'string nil
(nth 3 state
)) res
))) ; What started string
2682 ((nth 4 state
) ; In comment
2683 (setq res
(cons '(comment) res
)))
2684 ((null containing-sexp
)
2685 ;; Line is at top level.
2686 ;; Indent like the previous top level line
2687 ;; unless that ends in a closeparen without semicolon,
2688 ;; in which case this line is the first argument decl.
2689 (cperl-backward-to-noncomment (or parse-start
(point-min)))
2690 ;;(skip-chars-backward " \t\f\n")
2693 (memq (preceding-char) (append ";}" nil
)))
2694 (setq res
(cons (list 'toplevel start
) res
)))
2695 ((eq (preceding-char) ?\
) )
2696 (setq res
(cons (list 'toplevel-after-parenth start
) res
)))
2698 (setq res
(cons (list 'toplevel-continued start
) res
)))))
2699 ((/= (char-after containing-sexp
) ?
{)
2700 ;; line is expression, not statement:
2701 ;; indent to just after the surrounding open.
2702 ;; skip blanks if we do not close the expression.
2703 (setq res
(cons (list 'expression-blanks
2705 (goto-char (1+ containing-sexp
))
2706 (or (looking-at "[ \t]*\\(#\\|$\\)")
2707 (skip-chars-forward " \t"))
2709 (cons (list 'expression containing-sexp
) res
))))
2711 ;; Containing-expr starts with \{. Check whether it is a hash.
2712 (goto-char containing-sexp
)
2713 (not (cperl-block-p)))
2714 (setq res
(cons (list 'expression-blanks
2716 (goto-char (1+ containing-sexp
))
2717 (or (looking-at "[ \t]*\\(#\\|$\\)")
2718 (skip-chars-forward " \t"))
2720 (cons (list 'expression containing-sexp
) res
))))
2723 (setq res
(cons (list 'in-block containing-sexp
) res
))
2724 ;; Is it a continuation or a new statement?
2725 ;; Find previous non-comment character.
2726 (cperl-backward-to-noncomment containing-sexp
)
2727 ;; Back up over label lines, since they don't
2728 ;; affect whether our line is a continuation.
2729 ;; Back up comma-delimited lines too ?????
2730 (while (or (eq (preceding-char) ?\
,)
2731 (save-excursion (cperl-after-label)))
2732 (if (eq (preceding-char) ?\
,)
2733 ;; Will go to beginning of line, essentially
2734 ;; Will ignore embedded sexpr XXXX.
2735 (cperl-backward-to-start-of-continued-exp containing-sexp
))
2737 (cperl-backward-to-noncomment containing-sexp
))
2738 ;; Now we get the answer.
2739 (if (not (memq (preceding-char) (append ";}{" '(nil)))) ; Was ?\,
2740 ;; This line is continuation of preceding line's statement.
2741 (list (list 'statement-continued containing-sexp
))
2742 ;; This line starts a new statement.
2743 ;; Position following last unclosed open.
2744 (goto-char containing-sexp
)
2745 ;; Is line first statement after an open-brace?
2747 ;; If no, find that first statement and indent like
2748 ;; it. If the first statement begins with label, do
2749 ;; not believe when the indentation of the label is too
2753 (let ((colon-line-end 0))
2754 (while (progn (skip-chars-forward " \t\n" start-point
)
2755 (and (< (point) start-point
)
2757 "#\\|[a-zA-Z_][a-zA-Z0-9_]*:[^:]")))
2758 ;; Skip over comments and labels following openbrace.
2759 (cond ((= (following-char) ?\
#)
2764 (save-excursion (end-of-line)
2765 (setq colon-line-end
(point)))
2766 (search-forward ":"))))
2767 ;; Now at the point, after label, or at start
2768 ;; of first statement in the block.
2769 (and (< (point) start-point
)
2770 (if (> colon-line-end
(point))
2771 ;; Before statement after label
2772 (if (> (current-indentation)
2773 cperl-min-label-indent
)
2774 (list (list 'label-in-block
(point)))
2775 ;; Do not believe: `max' is involved
2777 (list 'label-in-block-min-indent
(point))))
2779 (list 'statement-in-block
(point))))))
2780 ;; If no previous statement,
2781 ;; indent it relative to line brace is on.
2782 ;; For open brace in column zero, don't let statement
2783 ;; start there too. If cperl-indent-level is zero,
2784 ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
2785 ;; For open-braces not the first thing in a line,
2786 ;; add in cperl-brace-imaginary-offset.
2788 ;; If first thing on a line: ?????
2789 (+ (if (and (bolp) (zerop cperl-indent-level
))
2790 (+ cperl-brace-offset cperl-continued-statement-offset
)
2792 ;; Move back over whitespace before the openbrace.
2793 ;; If openbrace is not first nonwhite thing on the line,
2794 ;; add the cperl-brace-imaginary-offset.
2795 (progn (skip-chars-backward " \t")
2796 (if (bolp) 0 cperl-brace-imaginary-offset
))
2797 ;; If the openbrace is preceded by a parenthesized exp,
2798 ;; move to the beginning of that;
2799 ;; possibly a different line
2801 (if (eq (preceding-char) ?\
))
2803 ;; Get initial indentation of the line we are on.
2804 ;; If line starts with label, calculate label indentation
2807 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
2808 (if (> (current-indentation) cperl-min-label-indent
)
2809 (- (current-indentation) cperl-label-offset
)
2810 (cperl-calculate-indent))
2811 (current-indentation))))))))
2814 (defun cperl-calculate-indent-within-comment ()
2815 "Return the indentation amount for line, assuming that
2816 the current line is to be regarded as part of a block comment."
2817 (let (end star-start
)
2820 (skip-chars-forward " \t")
2822 (and (= (following-char) ?
#)
2824 (cperl-to-comment-or-eol)
2830 (defun cperl-to-comment-or-eol ()
2831 "Goes to position before comment on the current line, or to end of line.
2832 Returns true if comment is found."
2833 (let (state stop-in cpoint
(lim (progn (end-of-line) (point))))
2836 (eq (get-text-property (point) 'syntax-type
) 'pod
)
2837 (re-search-forward "\\=[ \t]*\\(#\\|$\\)" lim t
))
2838 (if (eq (preceding-char) ?\
#) (progn (backward-char 1) t
))
2840 (while (not stop-in
)
2841 (setq state
(parse-partial-sexp (point) lim nil nil nil t
))
2843 ;; If fails (beginning-of-line inside sexp), then contains not-comment
2844 (if (nth 4 state
) ; After `#';
2845 ; (nth 2 state) can be
2846 ; beginning of m,s,qq and so
2850 (setq cpoint
(point))
2851 (goto-char (nth 2 state
))
2853 ((looking-at "\\(s\\|tr\\)\\>")
2854 (or (re-search-forward
2855 "\\=\\w+[ \t]*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*"
2858 ((looking-at "\\(m\\|q\\([qxwr]\\)?\\)\\>")
2859 (or (re-search-forward
2860 "\\=\\w+[ \t]*#\\([^\n\\\\#]\\|\\\\[\\\\#]\\)*#"
2863 (t ; It was fair comment
2864 (setq stop-in t
) ; Finish
2865 (goto-char (1- cpoint
)))))
2866 (setq stop-in t
) ; Finish
2868 (setq stop-in t
)) ; Finish
2872 (defsubst cperl-1-
(p)
2873 (max (point-min) (1- p
)))
2875 (defsubst cperl-1
+ (p)
2876 (min (point-max) (1+ p
)))
2878 (defsubst cperl-modify-syntax-type
(at how
)
2879 (if (< at
(point-max))
2881 (put-text-property at
(1+ at
) 'syntax-table how
)
2882 (put-text-property at
(1+ at
) 'rear-nonsticky t
))))
2884 (defun cperl-protect-defun-start (s e
)
2885 ;; C code looks for "^\\s(" to skip comment backward in "hard" situations
2888 (while (re-search-forward "^\\s(" e
'to-end
)
2889 (put-text-property (1- (point)) (point) 'syntax-table cperl-st-punct
))))
2891 (defun cperl-commentify (bb e string
&optional noface
)
2892 (if cperl-use-syntax-table-text-property
2893 (if (eq noface
'n
) ; Only immediate
2895 ;; We suppose that e is _after_ the end of construction, as after eol.
2896 (setq string
(if string cperl-st-sfence cperl-st-cfence
))
2897 (cperl-modify-syntax-type bb string
)
2898 (cperl-modify-syntax-type (1- e
) string
)
2899 (if (and (eq string cperl-st-sfence
) (> (- e
2) bb
))
2900 (put-text-property (1+ bb
) (1- e
)
2901 'syntax-table cperl-string-syntax-table
))
2902 (cperl-protect-defun-start bb e
))
2905 (not cperl-pod-here-fontify
)
2906 (put-text-property bb e
'face
(if string
'font-lock-string-face
2907 'font-lock-comment-face
)))))
2908 (defvar cperl-starters
'(( ?\
( . ?\
) )
2913 (defun cperl-forward-re (lim end is-2arg set-st st-l err-l argument
2914 &optional ostart oend
)
2915 ;; Works *before* syntax recognition is done
2916 ;; May modify syntax-type text property if the situation is too hard
2917 (let (b starter ender st i i2 go-forward
)
2918 (skip-chars-forward " \t")
2919 ;; ender means matching-char matcher.
2921 starter
(if (eobp) 0 (char-after b
))
2922 ender
(cdr (assoc starter cperl-starters
)))
2923 ;; What if starter == ?\\ ????
2926 (setq st
(car st-l
))
2927 (setcar st-l
(make-syntax-table))
2928 (setq i
0 st
(car st-l
))
2930 (modify-syntax-entry i
"." st
)
2932 (modify-syntax-entry ?
\\ "\\" st
)))
2934 ;; Whether we have an intermediate point
2936 ;; Prepare the syntax table:
2938 (if (not ender
) ; m/blah/, s/x//, s/x/y/
2939 (modify-syntax-entry starter
"$" st
)
2940 (modify-syntax-entry starter
(concat "(" (list ender
)) st
)
2941 (modify-syntax-entry ender
(concat ")" (list starter
)) st
)))
2944 ;; We use `$' syntax class to find matching stuff, but $$
2945 ;; is recognized the same as $, so we need to check this manually.
2946 (if (and (eq starter
(char-after (cperl-1+ b
)))
2948 ;; $ has TeXish matching rules, so $$ equiv $...
2950 (set-syntax-table st
)
2952 (set-syntax-table cperl-mode-syntax-table
)
2953 ;; Now the problem is with m;blah;;
2955 (eq (preceding-char)
2956 (char-after (- (point) 2)))
2959 (= 0 (%
(skip-chars-backward "\\\\") 2)))
2961 ;; Now we are after the first part.
2962 (and is-2arg
; Have trailing part
2964 (eq (following-char) starter
) ; Empty trailing part
2966 (or (eq (char-syntax (following-char)) ?.
)
2967 ;; Make trailing letter into punctuation
2968 (cperl-modify-syntax-type (point) cperl-st-punct
))
2969 (setq is-2arg nil go-forward t
))) ; Ignore the tail
2970 (if is-2arg
; Not number => have second part
2972 (setq i
(point) i2 i
)
2974 (if (memq (following-char) '(?\ ?
\t ?
\n ?
\f))
2976 (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
2977 (goto-char (match-end 0))
2978 (skip-chars-forward " \t\n\f"))
2981 (modify-syntax-entry starter
(if (eq starter ?
\\) "\\" ".") st
)
2982 (if ender
(modify-syntax-entry ender
"." st
))
2984 (setq ender
(cperl-forward-re lim end nil t st-l err-l
2985 argument starter ender
)
2986 ender
(nth 2 ender
)))))
2987 (error (goto-char lim
)
2991 "End of `%s%s%c ... %c' string/RE not found: %s"
2993 (if ostart
(format "%c ... %c" ostart
(or oend ostart
)) "")
2994 starter
(or ender starter
) bb
)
2995 (or (car err-l
) (setcar err-l b
)))))
2998 (modify-syntax-entry starter
(if (eq starter ?
\\) "\\" ".") st
)
2999 (if ender
(modify-syntax-entry ender
"." st
))))
3000 ;; i: have 2 args, after end of the first arg
3001 ;; i2: start of the second arg, if any (before delim iff `ender').
3002 ;; ender: the last arg bounded by parens-like chars, the second one of them
3003 ;; starter: the starting delimiter of the first arg
3004 ;; go-forward: has 2 args, and the second part is empth
3005 (list i i2 ender starter go-forward
)))
3007 (defvar font-lock-string-face
)
3008 ;;(defvar font-lock-reference-face)
3009 (defvar font-lock-constant-face
)
3010 (defsubst cperl-postpone-fontification
(b e type val
&optional now
)
3011 ;; Do after syntactic fontification?
3012 (if cperl-syntaxify-by-font-lock
3013 (or now
(put-text-property b e
'cperl-postpone
(cons type val
)))
3014 (put-text-property b e type val
)))
3016 ;;; Here is how the global structures (those which cannot be
3017 ;;; recognized locally) are marked:
3019 ;; Start-to-end is marked `in-pod' ==> t
3020 ;; Each non-literal part is marked `syntax-type' ==> `pod'
3021 ;; Each literal part is marked `syntax-type' ==> `in-pod'
3023 ;; Start-to-end is marked `here-doc-group' ==> t
3024 ;; The body is marked `syntax-type' ==> `here-doc'
3025 ;; The delimiter is marked `syntax-type' ==> `here-doc-delim'
3027 ;; After-initial-line--to-end is marked `syntax-type' ==> `format'
3028 ;; d) 'Q'uoted string:
3029 ;; part between markers inclusive is marked `syntax-type' ==> `string'
3031 (defun cperl-unwind-to-safe (before &optional end
)
3032 ;; if BEFORE, go to the previous start-of-line on each step of unwinding
3033 (let ((pos (point)) opos
)
3035 (while (and pos
(get-text-property pos
'syntax-type
))
3036 (setq pos
(previous-single-property-change pos
'syntax-type
))
3040 (goto-char (cperl-1- pos
))
3043 (goto-char (setq pos
(cperl-1- pos
))))
3045 (goto-char (point-min))))
3047 ;; Do the same for end, going small steps
3049 (while (and end
(get-text-property end
'syntax-type
))
3051 end
(next-single-property-change end
'syntax-type
)))
3054 (defun cperl-find-pods-heres (&optional min max non-inter end ignore-max
)
3055 "Scans the buffer for hard-to-parse Perl constructions.
3056 If `cperl-pod-here-fontify' is not-nil after evaluation, will fontify
3057 the sections using `cperl-pod-head-face', `cperl-pod-face',
3060 (or min
(setq min
(point-min)
3061 cperl-syntax-state nil
3062 cperl-syntax-done-to min
))
3063 (or max
(setq max
(point-max)))
3064 (let* (face head-face here-face b e bb tag qtag b1 e1 argument i c tail tb
3065 (cperl-pod-here-fontify (eval cperl-pod-here-fontify
)) go tmpend
3066 (case-fold-search nil
) (inhibit-read-only t
) (buffer-undo-list t
)
3067 (modified (buffer-modified-p))
3068 (after-change-functions nil
)
3069 (use-syntax-state (and cperl-syntax-state
3070 (>= min
(car cperl-syntax-state
))))
3071 (state-point (if use-syntax-state
3072 (car cperl-syntax-state
)
3074 (state (if use-syntax-state
3075 (cdr cperl-syntax-state
)))
3076 (st-l '(nil)) (err-l '(nil)) i2
3077 ;; Somehow font-lock may be not loaded yet...
3078 (font-lock-string-face (if (boundp 'font-lock-string-face
)
3079 font-lock-string-face
3080 'font-lock-string-face
))
3081 (font-lock-constant-face (if (boundp 'font-lock-constant-face
)
3082 font-lock-constant-face
3083 'font-lock-constant-face
))
3084 (font-lock-function-name-face
3085 (if (boundp 'font-lock-function-name-face
)
3086 font-lock-function-name-face
3087 'font-lock-function-name-face
))
3088 (cperl-nonoverridable-face
3089 (if (boundp 'cperl-nonoverridable-face
)
3090 cperl-nonoverridable-face
3091 'cperl-nonoverridable-face
))
3092 (stop-point (if ignore-max
3097 "\\(\\`\n?\\|\n\n\\)="
3099 ;; One extra () before this:
3102 ;; First variant "BLAH" or just ``.
3103 "\\([\"'`]\\)" ; 2 + 1
3104 "\\([^\"'`\n]*\\)" ; 3 + 1
3107 ;; Second variant: Identifier or \ID or empty
3108 "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 4 + 1, 5 + 1
3109 ;; Do not have <<= or << 30 or <<30 or << $blah.
3110 ;; "\\([^= \t0-9$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)" ; 6 + 1
3111 "\\(\\)" ; To preserve count of pars :-( 6 + 1
3114 ;; 1+6 extra () before this:
3115 "^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$"
3116 (if cperl-use-syntax-table-text-property
3119 ;; 1+6+2=9 extra () before this:
3120 "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>"
3122 ;; 1+6+2+1=10 extra () before this:
3123 "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob>
3125 ;; 1+6+2+1+1=11 extra () before this:
3126 "\\<sub\\>[ \t]*\\([a-zA-Z_:'0-9]+[ \t]*\\)?\\(([^()]*)\\)"
3128 ;; 1+6+2+1+1+2=13 extra () before this:
3131 ;; 1+6+2+1+1+2+1=14 extra () before this:
3132 "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'"
3133 ;; 1+6+2+1+1+2+1+1=15 extra () before this:
3135 "__\\(END\\|DATA\\)__" ; Commented - does not help with indent...
3142 (message "Scanning for \"hard\" Perl constructions..."))
3143 (and cperl-pod-here-fontify
3144 ;; We had evals here, do not know why...
3145 (setq face cperl-pod-face
3146 head-face cperl-pod-head-face
3147 here-face cperl-here-face
))
3148 (remove-text-properties min max
3149 '(syntax-type t in-pod t syntax-table t
3151 ;; Need to remove face as well...
3153 (and (eq system-type
'emx
)
3154 (looking-at "extproc[ \t]") ; Analogue of #!
3155 (cperl-commentify min
3156 (save-excursion (end-of-line) (point))
3160 (re-search-forward search max t
))
3161 (setq tmpend nil
) ; Valid for most cases
3163 ((match-beginning 1) ; POD section
3164 ;; "\\(\\`\n?\\|\n\n\\)="
3165 (if (looking-at "\n*cut\\>")
3167 nil
; Doing a chunk only
3168 (message "=cut is not preceded by a POD section")
3169 (or (car err-l
) (setcar err-l
(point))))
3174 tb
(match-beginning 0)
3175 b1 nil
) ; error condition
3176 ;; We do not search to max, since we may be called from
3177 ;; some hook of fontification, and max is random
3178 (or (re-search-forward "\n\n=cut\\>" stop-point
'toend
)
3180 (message "End of a POD section not marked by =cut")
3182 (or (car err-l
) (setcar err-l b
))))
3183 (beginning-of-line 2) ; An empty line after =cut is not POD!
3186 ;; Unrecoverable error
3190 (remove-text-properties
3191 max e
'(syntax-type t in-pod t syntax-table t
3194 (put-text-property b e
'in-pod t
)
3195 (put-text-property b e
'syntax-type
'in-pod
)
3197 (while (re-search-forward "\n\n[ \t]" e t
)
3198 ;; We start 'pod 1 char earlier to include the preceding line
3200 (put-text-property (cperl-1- b
) (point) 'syntax-type
'pod
)
3201 (cperl-put-do-not-fontify b
(point) t
)
3202 ;; mark the non-literal parts as PODs
3203 (if cperl-pod-here-fontify
3204 (cperl-postpone-fontification b
(point) 'face face t
))
3205 (re-search-forward "\n\n[^ \t\f\n]" e
'toend
)
3208 (put-text-property (cperl-1- (point)) e
'syntax-type
'pod
)
3209 (cperl-put-do-not-fontify (point) e t
)
3210 (if cperl-pod-here-fontify
3212 ;; mark the non-literal parts as PODs
3213 (cperl-postpone-fontification (point) e
'face face t
)
3216 "=[a-zA-Z0-9_]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$")
3218 (cperl-postpone-fontification
3219 (match-beginning 1) (match-end 1)
3221 (while (re-search-forward
3223 "\n\n=[a-zA-Z0-9_]+\\>[ \t]*\\(\\(\n?[^\n]\\)+\\)$"
3226 (cperl-postpone-fontification
3227 (match-beginning 1) (match-end 1)
3229 (cperl-commentify bb e nil
)
3231 (or (eq e
(point-max))
3232 (forward-char -
1))))) ; Prepare for immediate pod start.
3234 ;; We do only one here-per-line
3235 ;; ;; One extra () before this:
3238 ;; ;; First variant "BLAH" or just ``.
3239 ;; "\\([\"'`]\\)" ; 2 + 1
3240 ;; "\\([^\"'`\n]*\\)" ; 3 + 1
3243 ;; ;; Second variant: Identifier or \ID or empty
3244 ;; "\\\\?\\(\\([a-zA-Z_][a-zA-Z_0-9]*\\)?\\)" ; 4 + 1, 5 + 1
3245 ;; ;; Do not have <<= or << 30 or <<30 or << $blah.
3246 ;; ;; "\\([^= \t0-9$@%&]\\|[ \t]+[^ \t\n0-9$@%&]\\)" ; 6 + 1
3247 ;; "\\(\\)" ; To preserve count of pars :-( 6 + 1
3249 ((match-beginning 2) ; 1 + 1
3250 ;; Abort in comment:
3252 (setq state
(parse-partial-sexp state-point b nil nil state
)
3254 tb
(match-beginning 0)
3255 i
(or (nth 3 state
) (nth 4 state
)))
3260 (not (match-beginning 6)) ; Empty
3262 "[ \t]*[=0-9$@%&(]"))))
3263 (if c
; Not here-doc
3265 (if (match-beginning 5) ;4 + 1
3266 (setq b1
(match-beginning 5) ; 4 + 1
3267 e1
(match-end 5)) ; 4 + 1
3268 (setq b1
(match-beginning 4) ; 3 + 1
3269 e1
(match-end 4))) ; 3 + 1
3270 (setq tag
(buffer-substring b1 e1
)
3271 qtag
(regexp-quote tag
))
3272 (cond (cperl-pod-here-fontify
3273 ;; Highlight the starting delimiter
3274 (cperl-postpone-fontification b1 e1
'face font-lock-constant-face
)
3275 (cperl-put-do-not-fontify b1 e1 t
)))
3278 ;; We do not search to max, since we may be called from
3279 ;; some hook of fontification, and max is random
3280 (cond ((re-search-forward (concat "^" qtag
"$")
3282 (if cperl-pod-here-fontify
3284 ;; Highlight the ending delimiter
3285 (cperl-postpone-fontification (match-beginning 0) (match-end 0)
3286 'face font-lock-constant-face
)
3287 (cperl-put-do-not-fontify b
(match-end 0) t
)
3288 ;; Highlight the HERE-DOC
3289 (cperl-postpone-fontification b
(match-beginning 0)
3291 (setq e1
(cperl-1+ (match-end 0)))
3292 (put-text-property b
(match-beginning 0)
3293 'syntax-type
'here-doc
)
3294 (put-text-property (match-beginning 0) e1
3295 'syntax-type
'here-doc-delim
)
3296 (put-text-property b e1
3298 (cperl-commentify b e1 nil
)
3299 (cperl-put-do-not-fontify b
(match-end 0) t
)
3302 (t (message "End of here-document `%s' not found." tag
)
3303 (or (car err-l
) (setcar err-l b
))))))
3305 ((match-beginning 8)
3306 ;; 1+6=7 extra () before this:
3307 ;;"^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$"
3309 name
(if (match-beginning 8) ; 7 + 1
3310 (buffer-substring (match-beginning 8) ; 7 + 1
3311 (match-end 8)) ; 7 + 1
3313 tb
(match-beginning 0))
3315 (if cperl-pod-here-fontify
3316 (while (and (eq (forward-line) 0)
3317 (not (looking-at "^[.;]$")))
3319 ((looking-at "^#")) ; Skip comments
3320 ((and argument
; Skip argument multi-lines
3321 (looking-at "^[ \t]*{"))
3323 (setq argument nil
))
3324 (argument ; Skip argument lines
3325 (setq argument nil
))
3328 (setq argument
(looking-at "^[^\n]*[@^]"))
3330 ;; Highlight the format line
3331 (cperl-postpone-fontification b1
(point)
3332 'face font-lock-string-face
)
3333 (cperl-commentify b1
(point) nil
)
3334 (cperl-put-do-not-fontify b1
(point) t
))))
3335 ;; We do not search to max, since we may be called from
3336 ;; some hook of fontification, and max is random
3337 (re-search-forward "^[.;]$" stop-point
'toend
))
3339 (if (looking-at "^\\.$") ; ";" is not supported yet
3341 ;; Highlight the ending delimiter
3342 (cperl-postpone-fontification (point) (+ (point) 2)
3343 'face font-lock-string-face
)
3344 (cperl-commentify (point) (+ (point) 2) nil
)
3345 (cperl-put-do-not-fontify (point) (+ (point) 2) t
))
3346 (message "End of format `%s' not found." name
)
3347 (or (car err-l
) (setcar err-l b
)))
3351 (put-text-property b
(point) 'syntax-type
'format
))
3353 ((or (match-beginning 10) (match-beginning 11))
3354 ;; 1+6+2=9 extra () before this:
3355 ;; "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>"
3357 ;; "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob>
3358 (setq b1
(if (match-beginning 10) 10 11)
3359 argument
(buffer-substring
3360 (match-beginning b1
) (match-end b1
))
3363 c
(char-after (match-beginning b1
))
3364 bb
(char-after (1- (match-beginning b1
))) ; tmp holder
3365 ;; bb == "Not a stringy"
3366 bb
(if (eq b1
10) ; user variables/whatever
3368 (memq bb
'(?\$ ?\
@ ?\% ?\
* ?\
#)) ; $#y
3369 (and (eq bb ?-
) (eq c ?s
)) ; -s file test
3370 (and (eq bb ?\
&) ; &&m/blah/
3371 (not (eq (char-after
3372 (- (match-beginning b1
) 2))
3374 ;; <file> or <$file>
3376 ;; Do not stringify <FH> :
3379 "\\s *\\$?\\([_a-zA-Z:][_a-zA-Z0-9:]*\\s *\\)?>"))))
3380 tb
(match-beginning 0))
3381 (goto-char (match-beginning b1
))
3382 (cperl-backward-to-noncomment (point-min))
3384 (if (eq b1
11) ; bare /blah/ or ?blah? or <foo>
3389 ;; What is below: regexp-p?
3391 (or (memq (preceding-char)
3392 (append (if (memq c
'(?
\? ?\
<))
3395 "~{(=|&+-*!,;:") nil
))
3396 (and (eq (preceding-char) ?\
})
3397 (cperl-after-block-p (point-min)))
3398 (and (eq (char-syntax (preceding-char)) ?w
)
3401 ;;; After these keywords `/' starts a RE. One should add all the
3402 ;;; functions/builtins which expect an argument, but ...
3403 (if (eq (preceding-char) ?-
)
3405 (looking-at "[a-zA-Z]\\>")
3407 "\\(while\\|if\\|unless\\|until\\|and\\|or\\|not\\|xor\\|split\\|grep\\|map\\|print\\)\\>"))))
3408 (and (eq (preceding-char) ?.
)
3409 (eq (char-after (- (point) 2)) ?.
))
3411 ;; m|blah| ? foo : bar;
3414 cperl-use-syntax-table-text-property
3418 (looking-at "\\s|")))))))
3422 (if (and (eq (preceding-char) ?
>)
3423 (eq (char-after (- (point) 2)) ?-
))
3426 (or bb
(setq state
(parse-partial-sexp
3427 state-point b nil nil state
)
3430 (if (or bb
(nth 3 state
) (nth 4 state
))
3432 (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
3433 (goto-char (match-end 0))
3434 (skip-chars-forward " \t\n\f"))
3435 ;; qtag means two-arg matcher, may be reset to
3436 ;; 2 or 3 later if some special quoting is needed.
3437 ;; e1 means matching-char matcher.
3440 i2
(string-match "^\\([sy]\\|tr\\)$" argument
)
3441 ;; We do not search to max, since we may be called from
3442 ;; some hook of fontification, and max is random
3443 i
(cperl-forward-re stop-point end
3445 t st-l err-l argument
)
3446 ;; Note that if `go', then it is considered as 1-arg
3447 b1
(nth 1 i
) ; start of the second part
3448 tag
(nth 2 i
) ; ender-char, true if second part
3449 ; is with matching chars []
3450 go
(nth 4 i
) ; There is a 1-char part after the end
3451 i
(car i
) ; intermediate point
3453 ;; Before end of the second part if non-matching: ///
3454 tail
(if (and i
(not tag
))
3456 e
(if i i e1
) ; end of the first part
3457 qtag nil
) ; need to preserve backslashitis
3458 ;; Commenting \\ is dangerous, what about ( ?
3460 (eq (char-after i
) ?
\\)
3463 ;; Considered as 1arg form
3465 (cperl-commentify b
(point) t
)
3466 (put-text-property b
(point) 'syntax-type
'string
)
3468 (setq e1
(cperl-1+ e1
))
3471 (cperl-commentify b i t
)
3472 (if (looking-at "\\sw*e") ; s///e
3476 (cperl-find-pods-heres b1
(1- (point)) t end
)
3478 (goto-char (1+ max
)))
3479 (if (and tag
(eq (preceding-char) ?\
>))
3481 (cperl-modify-syntax-type (1- (point)) cperl-st-ket
)
3482 (cperl-modify-syntax-type i cperl-st-bra
)))
3483 (put-text-property b i
'syntax-type
'string
))
3484 (cperl-commentify b1
(point) t
)
3485 (put-text-property b
(point) 'syntax-type
'string
)
3487 (cperl-modify-syntax-type (1+ i
) cperl-st-punct
))
3489 ;; Now: tail: if the second part is non-matching without ///e
3490 (if (eq (char-syntax (following-char)) ?w
)
3492 (forward-word 1) ; skip modifiers s///s
3493 (if tail
(cperl-commentify tail
(point) t
))
3494 (cperl-postpone-fontification
3495 e1
(point) 'face cperl-nonoverridable-face
)))
3496 ;; Check whether it is m// which means "previous match"
3497 ;; and highlight differently
3498 (if (and (eq e
(+ 2 b
))
3499 (string-match "^\\([sm]?\\|qr\\)$" argument
)
3500 ;; <> is already filtered out
3501 ;; split // *is* using zero-pattern
3507 (not (looking-at "split\\>")))
3509 (cperl-postpone-fontification
3510 b e
'face font-lock-function-name-face
)
3511 (if (or i2
; Has 2 args
3512 (and cperl-fontify-m-as-s
3514 (string-match "^\\(m\\|qr\\)$" argument
)
3515 (and (eq 0 (length argument
))
3516 (not (eq ?\
< (char-after b
)))))))
3518 (cperl-postpone-fontification
3519 b
(cperl-1+ b
) 'face font-lock-constant-face
)
3520 (cperl-postpone-fontification
3521 (1- e
) e
'face font-lock-constant-face
))))
3524 (cperl-postpone-fontification
3525 (1- e1
) e1
'face font-lock-constant-face
)
3526 (if (assoc (char-after b
) cperl-starters
)
3527 (cperl-postpone-fontification
3528 b1
(1+ b1
) 'face font-lock-constant-face
))))
3531 ((match-beginning 13) ; sub with prototypes
3532 (setq b
(match-beginning 0))
3533 (if (memq (char-after (1- b
))
3534 '(?\$ ?\
@ ?\% ?\
& ?\
*))
3536 (setq state
(parse-partial-sexp
3537 state-point b nil nil state
)
3539 (if (or (nth 3 state
) (nth 4 state
))
3542 (cperl-commentify (match-beginning 13) (match-end 13) t
))
3543 (goto-char (match-end 0))))
3544 ;; 1+6+2+1+1+2=13 extra () before this:
3546 ((and (match-beginning 14)
3547 (eq (preceding-char) ?
\')) ; $'
3548 (setq b
(1- (point))
3549 state
(parse-partial-sexp
3550 state-point
(1- b
) nil nil state
)
3552 (if (nth 3 state
) ; in string
3553 (cperl-modify-syntax-type (1- b
) cperl-st-punct
))
3555 ;; 1+6+2+1+1+2=13 extra () before this:
3557 ((match-beginning 14) ; ${
3558 (setq bb
(match-beginning 0))
3559 (cperl-modify-syntax-type bb cperl-st-punct
))
3560 ;; 1+6+2+1+1+2+1=14 extra () before this:
3561 ;; "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'")
3562 ((match-beginning 15) ; old $abc'efg syntax
3563 (setq bb
(match-end 0)
3564 b
(match-beginning 0)
3565 state
(parse-partial-sexp
3566 state-point b nil nil state
)
3568 (if (nth 3 state
) ; in string
3570 (put-text-property (1- bb
) bb
'syntax-table cperl-st-word
))
3572 ;; 1+6+2+1+1+2+1+1=15 extra () before this:
3573 ;; "__\\(END\\|DATA\\)__"
3574 (t ; __END__, __DATA__
3575 (setq bb
(match-end 0)
3576 b
(match-beginning 0)
3577 state
(parse-partial-sexp
3578 state-point b nil nil state
)
3580 (if (or (nth 3 state
) (nth 4 state
))
3582 ;; (put-text-property b (1+ bb) 'syntax-type 'pod) ; Cheat
3583 (cperl-commentify b bb nil
)
3586 (if (> (point) stop-point
)
3589 (message "Garbage after __END__/__DATA__ ignored")
3590 (message "Unbalanced syntax found while scanning")
3591 (or (car err-l
) (setcar err-l b
)))
3592 (goto-char stop-point
))))
3593 (setq cperl-syntax-state
(cons state-point state
)
3594 cperl-syntax-done-to
(or tmpend
(max (point) max
))))
3595 (if (car err-l
) (goto-char (car err-l
))
3597 (message "Scanning for \"hard\" Perl constructions... done"))))
3598 (and (buffer-modified-p)
3600 (set-buffer-modified-p nil
))
3601 (set-syntax-table cperl-mode-syntax-table
))
3604 (defun cperl-backward-to-noncomment (lim)
3605 ;; Stops at lim or after non-whitespace that is not in comment
3607 (while (and (not stop
) (> (point) (or lim
1)))
3608 (skip-chars-backward " \t\n\f" lim
)
3611 (if (memq (setq pr
(get-text-property (point) 'syntax-type
))
3612 '(pod here-doc here-doc-delim
))
3613 (cperl-unwind-to-safe nil
)
3614 (if (or (looking-at "^[ \t]*\\(#\\|$\\)")
3615 (progn (cperl-to-comment-or-eol) (bolp)))
3616 nil
; Only comment, skip
3618 (skip-chars-backward " \t")
3619 (if (< p
(point)) (goto-char p
))
3622 (defun cperl-after-block-p (lim)
3623 ;; We suppose that the preceding char is }.
3628 (cperl-backward-to-noncomment lim
)
3629 (or (eq (point) lim
)
3630 (eq (preceding-char) ?\
) ) ; if () {} sub f () {}
3631 (if (eq (char-syntax (preceding-char)) ?w
) ; else {}
3634 (or (looking-at "\\(else\\|grep\\|map\\|BEGIN\\|END\\)\\>")
3637 (cperl-backward-to-noncomment lim
)
3638 (and (eq (char-syntax (preceding-char)) ?w
)
3641 (looking-at "sub\\>"))))))
3642 (cperl-after-expr-p lim
))))
3645 (defun cperl-after-expr-p (&optional lim chars test
)
3646 "Returns true if the position is good for start of expression.
3647 TEST is the expression to evaluate at the found position. If absent,
3648 CHARS is a string that contains good characters to have before us (however,
3649 `}' is treated \"smartly\" if it is not in the list)."
3651 (lim (or lim
(point-min))))
3653 (while (and (not stop
) (> (point) lim
))
3654 (skip-chars-backward " \t\n\f" lim
)
3657 (if (looking-at "^[ \t]*\\(#\\|$\\)") nil
; Only comment, skip
3658 ;; Else: last iteration, or a label
3659 (cperl-to-comment-or-eol)
3660 (skip-chars-backward " \t")
3661 (if (< p
(point)) (goto-char p
))
3663 (if (and (eq (preceding-char) ?
:)
3666 (skip-chars-backward " \t\n\f" lim
)
3667 (eq (char-syntax (preceding-char)) ?w
)))
3668 (forward-sexp -
1) ; Possibly label. Skip it
3671 (or (bobp) ; ???? Needed
3674 (if test
(eval test
)
3675 (or (memq (preceding-char) (append (or chars
"{;") nil
))
3676 (and (eq (preceding-char) ?\
})
3677 (cperl-after-block-p lim
)))))))))
3679 (defun cperl-backward-to-start-of-continued-exp (lim)
3680 (if (memq (preceding-char) (append ")]}\"'`" nil
))
3683 (if (<= (point) lim
)
3684 (goto-char (1+ lim
)))
3685 (skip-chars-forward " \t"))
3687 (defun cperl-after-block-and-statement-beg (lim)
3688 ;; We assume that we are after ?\}
3690 (cperl-after-block-p lim
)
3693 (cperl-backward-to-noncomment (point-min))
3696 (not (= (char-syntax (preceding-char)) ?w
))
3701 "\\(map\\|grep\\|printf?\\|system\\|exec\\|tr\\|s\\)\\>")))))))
3704 (defvar innerloop-done nil
)
3705 (defvar last-depth nil
)
3707 (defun cperl-indent-exp ()
3708 "Simple variant of indentation of continued-sexp.
3710 Will not indent comment if it starts at `comment-indent' or looks like
3711 continuation of the comment on the previous line.
3713 If `cperl-indent-region-fix-constructs', will improve spacing on
3714 conditional/loop constructs."
3717 (let ((tmp-end (progn (end-of-line) (point))) top done
)
3722 (while (= (nth 0 (parse-partial-sexp (point) tmp-end
3724 (setq top
(point))) ; Get the outermost parenths in line
3726 (while (< (point) tmp-end
)
3727 (parse-partial-sexp (point) tmp-end nil t
) ; To start-sexp or eol
3728 (or (eolp) (forward-sexp 1)))
3729 (if (> (point) tmp-end
)
3732 (setq tmp-end
(point)))
3735 (setq tmp-end
(point-marker)))
3736 (if cperl-indent-region-fix-constructs
3737 (cperl-fix-line-spacing tmp-end
))
3738 (cperl-indent-region (point) tmp-end
))))
3740 (defun cperl-fix-line-spacing (&optional end parse-data
)
3741 "Improve whitespace in a conditional/loop construct.
3742 Returns some position at the last line."
3745 (setq end
(point-max)))
3746 (let (p pp ml have-brace ret
3747 (ee (save-excursion (end-of-line) (point)))
3748 (cperl-indent-region-fix-constructs
3749 (or cperl-indent-region-fix-constructs
1)))
3756 (or (looking-at "[ \t]*\\(els\\(e\\|if\\)\\|continue\\|if\\|while\\|for\\(each\\)?\\|until\\)")
3757 (setq have-brace
(save-excursion (search-forward "}" ee t
)))))
3758 nil
; Do not need to do anything
3762 (if (and cperl-merge-trailing-else
3764 "[ \t]*}[ \t]*\n[ \t\n]*\\(els\\(e\\|if\\)\\|continue\\)\\>"))
3766 (search-forward "}")
3768 (skip-chars-forward " \t\n")
3769 (delete-region p
(point))
3770 (insert (make-string cperl-indent-region-fix-constructs ?\
))
3771 (beginning-of-line)))
3774 (if (looking-at "[ \t]*}\\(\t*\\|[ \t][ \t]+\\)\\<\\(els\\(e\\|if\\)\\|continue\\)\\>")
3776 (search-forward "}")
3777 (delete-horizontal-space)
3778 (insert (make-string cperl-indent-region-fix-constructs ?\
))
3779 (beginning-of-line)))
3783 "[ \t]*}?[ \t]*\\<\\(\\els\\(e\\|if\\)\\|continue\\|unless\\|if\\|while\\|for\\(each\\)?\\|until\\)\\>\\(\t*\\|[ \t][ \t]+\\)[^ \t\n#]")
3786 (delete-horizontal-space)
3787 (insert (make-string cperl-indent-region-fix-constructs ?\
))
3788 (beginning-of-line)))
3792 "[ \t]*\\<for\\(each\\)?[ \t]+\\(my\\|local\\)\\(\t*\\|[ \t][ \t]+\\)[^ \t\n]")
3795 (delete-horizontal-space)
3796 (insert (make-string cperl-indent-region-fix-constructs ?\
))
3797 (beginning-of-line)))
3799 ;; foreach my $var (
3801 "[ \t]*\\<for\\(each\\)?[ \t]+\\(my\\|local\\)[ \t]*\\$[_a-zA-Z0-9]+\\(\t*\\|[ \t][ \t]+\\)[^ \t\n#]")
3804 (delete-horizontal-space)
3806 (make-string cperl-indent-region-fix-constructs ?\
))
3807 (beginning-of-line)))
3809 ;; } foreach my $var () {
3811 "[ \t]*\\(}[ \t]*\\)?\\<\\(\\els\\(e\\|if\\)\\|continue\\|if\\|unless\\|while\\|for\\(each\\)?\\(\\([ t]+\\(my\\|local\\)\\)?[ \t]*\\$[_a-zA-Z0-9]+\\)?\\|until\\)\\>\\([ \t]*(\\|[ \t\n]*{\\)\\|[ \t]*{")
3813 (setq ml
(match-beginning 8))
3814 (re-search-forward "[({]")
3817 (if (eq (following-char) ?\
( )
3821 ;; after `else' or nothing
3822 (if ml
; after `else'
3823 (skip-chars-backward " \t\n")
3824 (beginning-of-line))
3826 ;; Now after the sexp before the brace
3827 ;; Multiline expr should be special
3828 (setq ml
(and pp
(save-excursion (goto-char p
)
3829 (search-forward "\n" pp t
))))
3830 (if (and (or (not pp
) (< pp end
))
3831 (looking-at "[ \t\n]*{"))
3834 ((bolp) ; Were before `{', no if/else/etc
3836 ((looking-at "\\(\t*\\| [ \t]+\\){")
3837 (delete-horizontal-space)
3839 cperl-extra-newline-before-brace-multiline
3840 cperl-extra-newline-before-brace
)
3842 (delete-horizontal-space)
3845 (if (cperl-indent-line parse-data
)
3847 (cperl-fix-line-spacing end parse-data
)
3848 (setq ret
(point)))))
3850 (make-string cperl-indent-region-fix-constructs ?\
))))
3851 ((and (looking-at "[ \t]*\n")
3853 cperl-extra-newline-before-brace-multiline
3854 cperl-extra-newline-before-brace
)))
3856 (skip-chars-forward " \t\n")
3857 (delete-region pp
(point))
3859 (make-string cperl-indent-region-fix-constructs ?\
))))
3860 ;; Now we are before `{'
3861 (if (looking-at "[ \t\n]*{[ \t]*[^ \t\n#]")
3863 (skip-chars-forward " \t\n")
3868 (setq ml
(search-forward "\n" p t
))
3869 (if (or cperl-break-one-line-blocks-when-indent ml
)
3870 ;; not good: multi-line BLOCK
3873 (delete-horizontal-space)
3876 (if (cperl-indent-line parse-data
)
3877 (setq ret
(cperl-fix-line-spacing end parse-data
)))))))))))
3879 (setq p
(point) pp
(save-excursion (end-of-line) (point))) ; May be different from ee.
3880 ;; Now check whether there is a hanging `}'
3884 cperl-fix-hanging-brace-when-indent
3886 (not (looking-at "[ \t]*}[ \t]*\\(\\<\\(els\\(if\\|e\\)\\|continue\\|while\\|until\\)\\>\\|$\\|#\\)"))
3890 (if (and (<= (point) pp
)
3891 (eq (preceding-char) ?\
} )
3892 (cperl-after-block-and-statement-beg (point-min)))
3899 (skip-chars-backward " \t")
3901 ;; `}' was the first thing on the line, insert NL *after* it.
3903 (cperl-indent-line parse-data
)
3904 (search-forward "}")
3905 (delete-horizontal-space)
3907 (delete-horizontal-space)
3908 (or (eq (preceding-char) ?\
;)
3910 (and (eq (preceding-char) ?\
} )
3911 (cperl-after-block-p (point-min)))
3915 (if (cperl-indent-line parse-data
)
3916 (setq ret
(cperl-fix-line-spacing end parse-data
)))
3917 (beginning-of-line)))))
3920 (defvar cperl-update-start
) ; Do not need to make them local
3921 (defvar cperl-update-end
)
3922 (defun cperl-delay-update-hook (beg end old-len
)
3923 (setq cperl-update-start
(min beg
(or cperl-update-start
(point-max))))
3924 (setq cperl-update-end
(max end
(or cperl-update-end
(point-min)))))
3926 (defun cperl-indent-region (start end
)
3927 "Simple variant of indentation of region in CPerl mode.
3928 Should be slow. Will not indent comment if it starts at `comment-indent'
3929 or looks like continuation of the comment on the previous line.
3930 Indents all the lines whose first character is between START and END
3933 If `cperl-indent-region-fix-constructs', will improve spacing on
3934 conditional/loop constructs."
3936 (cperl-update-syntaxification end end
)
3938 (let (cperl-update-start cperl-update-end
(h-a-c after-change-functions
))
3939 (let (st comm old-comm-indent new-comm-indent p pp i empty
3940 (indent-info (if cperl-emacs-can-parse
3941 (list nil nil nil
) ; Cannot use '(), since will modify
3943 after-change-functions
; Speed it up!
3944 (pm 0) (imenu-scanning-message "Indenting... (%3d%%)"))
3945 (if h-a-c
(add-hook 'after-change-functions
'cperl-delay-update-hook
))
3947 (setq old-comm-indent
(and (cperl-to-comment-or-eol)
3949 new-comm-indent old-comm-indent
)
3951 (setq end
(set-marker (make-marker) end
)) ; indentation changes pos
3952 (or (bolp) (beginning-of-line 2))
3953 (or (fboundp 'imenu-progress-message
)
3954 (message "Indenting... For feedback load `imenu'..."))
3955 (while (and (<= (point) end
) (not (eobp))) ; bol to check start
3956 (and (fboundp 'imenu-progress-message
)
3957 (imenu-progress-message
3958 pm
(/ (* 100 (- (point) start
)) (- end start -
1))))
3961 (setq empty
(looking-at "[ \t]*\n"))
3962 (and (setq comm
(looking-at "[ \t]*#"))
3963 (or (eq (current-indentation) (or old-comm-indent
3965 (setq old-comm-indent nil
))))
3966 (if (and old-comm-indent
3968 (= (current-indentation) old-comm-indent
)
3969 (not (eq (get-text-property (point) 'syntax-type
) 'pod
))
3970 (not (eq (get-text-property (point) 'syntax-table
)
3972 (let ((comment-column new-comm-indent
))
3973 (indent-for-comment)))
3975 (setq i
(cperl-indent-line indent-info
))
3979 (if cperl-indent-region-fix-constructs
3980 (goto-char (cperl-fix-line-spacing end indent-info
)))
3981 (if (setq old-comm-indent
3982 (and (cperl-to-comment-or-eol)
3983 (not (memq (get-text-property (point)
3986 (not (eq (get-text-property (point)
3990 (progn (indent-for-comment)
3991 (skip-chars-backward " \t")
3992 (skip-chars-backward "#")
3993 (setq new-comm-indent
(current-column))))))))
3994 (beginning-of-line 2))
3995 (if (fboundp 'imenu-progress-message
)
3996 (imenu-progress-message pm
100)
3998 ;; Now run the update hooks
3999 (if after-change-functions
4001 (if cperl-update-end
4003 (goto-char cperl-update-end
)
4006 (goto-char cperl-update-start
)
4008 (delete-char -
1))))))))
4010 ;; Stolen from lisp-mode with a lot of improvements
4012 (defun cperl-fill-paragraph (&optional justify iteration
)
4013 "Like \\[fill-paragraph], but handle CPerl comments.
4014 If any of the current line is a comment, fill the comment or the
4015 block of it that point is in, preserving the comment's initial
4016 indentation and initial hashes. Behaves usually outside of comment."
4019 ;; Non-nil if the current line contains a comment.
4022 ;; If has-comment, the appropriate fill-prefix for the comment.
4024 ;; Line that contains code and comment (or nil)
4026 c spaces len dc
(comment-column comment-column
))
4027 ;; Figure out what kind of comment we are looking at.
4032 ;; A line with nothing but a comment on it?
4033 ((looking-at "[ \t]*#[# \t]*")
4035 comment-fill-prefix
(buffer-substring (match-beginning 0)
4038 ;; A line with some code, followed by a comment? Remember that the
4039 ;; semi which starts the comment shouldn't be part of a string or
4041 ((cperl-to-comment-or-eol)
4042 (setq has-comment t
)
4043 (looking-at "#+[ \t]*")
4044 (setq start
(point) c
(current-column)
4046 (concat (make-string (current-column) ?\
)
4047 (buffer-substring (match-beginning 0) (match-end 0)))
4048 spaces
(progn (skip-chars-backward " \t")
4049 (buffer-substring (point) start
))
4050 dc
(- c
(current-column)) len
(- start
(point))
4051 start
(point-marker))
4053 (insert (make-string dc ?-
)))))
4054 (if (not has-comment
)
4055 (fill-paragraph justify
) ; Do the usual thing outside of comment
4056 ;; Narrow to include only the comment, and then fill the region.
4059 ;; Find the first line we should include in the region to fill.
4060 (if start
(progn (beginning-of-line) (point))
4062 (while (and (zerop (forward-line -
1))
4063 (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")))
4064 ;; We may have gone to far. Go forward again.
4065 (or (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")
4068 ;; Find the beginning of the first line past the region to fill.
4070 (while (progn (forward-line 1)
4071 (looking-at "^[ \t]*#+[ \t]*[^ \t\n#]")))
4073 ;; Remove existing hashes
4074 (goto-char (point-min))
4075 (while (progn (forward-line 1) (< (point) (point-max)))
4076 (skip-chars-forward " \t")
4077 (and (looking-at "#+")
4078 (delete-char (- (match-end 0) (match-beginning 0)))))
4080 ;; Lines with only hashes on them can be paragraph boundaries.
4081 (let ((paragraph-start (concat paragraph-start
"\\|^[ \t#]*$"))
4082 (paragraph-separate (concat paragraph-start
"\\|^[ \t#]*$"))
4083 (fill-prefix comment-fill-prefix
))
4084 (fill-paragraph justify
)))
4089 (progn (delete-char dc
) (insert spaces
)))
4090 (if (or (= (current-column) c
) iteration
) nil
4091 (setq comment-column c
)
4092 (indent-for-comment)
4093 ;; Repeat once more, flagging as iteration
4094 (cperl-fill-paragraph justify t
)))))))
4096 (defun cperl-do-auto-fill ()
4097 ;; Break out if the line is short enough
4098 (if (> (save-excursion
4102 (let ((c (save-excursion (beginning-of-line)
4103 (cperl-to-comment-or-eol) (point)))
4104 (s (memq (following-char) '(?\ ?
\t))) marker
)
4105 (if (>= c
(point)) nil
4106 (setq marker
(point-marker))
4107 (cperl-fill-paragraph)
4109 ;; Is not enough, sometimes marker is a start of line
4110 (if (bolp) (progn (re-search-forward "#+[ \t]*")
4111 (goto-char (match-end 0))))
4112 ;; Following space could have gone:
4113 (if (or (not s
) (memq (following-char) '(?\ ?
\t))) nil
4116 ;; Previous space could have gone:
4117 (or (memq (preceding-char) '(?\ ?
\t)) (insert " "))))))
4119 (defvar imenu-example--function-name-regexp-perl
4122 "[ \t]*\\(sub\\|package\\)[ \t\n]+\\([a-zA-Z_0-9:']+\\)[ \t]*\\(([^()]*)[ \t]*\\)?"
4124 "=head\\([12]\\)[ \t]+\\([^\n]+\\)$"
4127 (defun cperl-imenu-addback (lst &optional isback name
)
4128 ;; We suppose that the lst is a DAG, unless the first element only
4129 ;; loops back, and ISBACK is set. Thus this function cannot be
4130 ;; applied twice without ISBACK set.
4131 (cond ((not cperl-imenu-addback
) lst
)
4134 (setq name
"+++BACK+++"))
4135 (mapcar (function (lambda (elt)
4136 (if (and (listp elt
) (listp (cdr elt
)))
4138 ;; In the other order it goes up
4139 ;; one level only ;-(
4140 (setcdr elt
(cons (cons name lst
)
4142 (cperl-imenu-addback (cdr elt
) t name
)
4144 (if isback
(cdr lst
) lst
))
4147 (defun imenu-example--create-perl-index (&optional regexp
)
4149 (require 'imenu
) ; May be called from TAGS creator
4150 (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '())
4151 (index-unsorted-alist '()) (i-s-f (default-value 'imenu-sort-function
))
4152 (index-meth-alist '()) meth
4153 packages ends-ranges p
4154 (prev-pos 0) char fchar index index1 name
(end-range 0) package
)
4155 (goto-char (point-min))
4157 (message "Scanning Perl for index")
4158 (imenu-progress-message prev-pos
0))
4159 ;; Search for the function
4160 (progn ;;save-match-data
4161 (while (re-search-forward
4162 (or regexp imenu-example--function-name-regexp-perl
)
4165 (imenu-progress-message prev-pos
))
4167 ((and ; Skip some noise if building tags
4168 (match-beginning 2) ; package or sub
4169 (eq (char-after (match-beginning 2)) ?p
) ; package
4170 (not (save-match-data
4171 (looking-at "[ \t\n]*;")))) ; Plain text word 'package'
4174 (match-beginning 2) ; package or sub
4175 ;; Skip if quoted (will not skip multi-line ''-comments :-():
4176 (null (get-text-property (match-beginning 1) 'syntax-table
))
4177 (null (get-text-property (match-beginning 1) 'syntax-type
))
4178 (null (get-text-property (match-beginning 1) 'in-pod
)))
4180 (goto-char (match-beginning 2))
4181 (setq fchar
(following-char))
4183 ;; (if (looking-at "([^()]*)[ \t\n\f]*")
4184 ;; (goto-char (match-end 0))) ; Messes what follows
4185 (setq char
(following-char)
4188 (while (and ends-ranges
(>= p
(car ends-ranges
)))
4189 ;; delete obsolete entries
4190 (setq ends-ranges
(cdr ends-ranges
) packages
(cdr packages
)))
4191 (setq package
(or (car packages
) "")
4192 end-range
(or (car ends-ranges
) 0))
4194 (setq name
(buffer-substring (match-beginning 3) (match-end 3))
4196 (set-text-properties 0 (length name
) nil name
)
4198 package
(concat name
"::")
4199 name
(concat "package " name
)
4202 (parse-partial-sexp (point) (point-max) -
1) (point))
4203 ends-ranges
(cons end-range ends-ranges
)
4204 packages
(cons package packages
)))
4206 ;; Skip this function name if it is a prototype declaration.
4207 (if (and (eq fchar ?s
) (eq char ?\
;)) nil
4208 (setq index
(imenu-example--name-and-position))
4209 (if (eq fchar ?p
) nil
4210 (setq name
(buffer-substring (match-beginning 3) (match-end 3)))
4211 (set-text-properties 0 (length name
) nil name
)
4212 (cond ((string-match "[:']" name
)
4214 ((> p end-range
) nil
)
4216 (setq name
(concat package name
) meth t
))))
4219 (push index index-pack-alist
)
4220 (push index index-alist
))
4221 (if meth
(push index index-meth-alist
))
4222 (push index index-unsorted-alist
)))
4223 ((match-beginning 5) ; Pod section
4224 ;; (beginning-of-line)
4225 (setq index
(imenu-example--name-and-position)
4226 name
(buffer-substring (match-beginning 6) (match-end 6)))
4227 (set-text-properties 0 (length name
) nil name
)
4228 (if (eq (char-after (match-beginning 5)) ?
2)
4229 (setq name
(concat " " name
)))
4231 (setq index1
(cons (concat "=" name
) (cdr index
)))
4232 (push index index-pod-alist
)
4233 (push index1 index-unsorted-alist
)))))
4235 (imenu-progress-message prev-pos
100))
4237 (if (default-value 'imenu-sort-function
)
4238 (sort index-alist
(default-value 'imenu-sort-function
))
4239 (nreverse index-alist
)))
4240 (and index-pod-alist
4241 (push (cons "+POD headers+..."
4242 (nreverse index-pod-alist
))
4244 (and (or index-pack-alist index-meth-alist
)
4245 (let ((lst index-pack-alist
) hier-list pack elt group name
)
4246 ;; Remove "package ", reverse and uniquify.
4248 (setq elt
(car lst
) lst
(cdr lst
) name
(substring (car elt
) 8))
4249 (if (assoc name hier-list
) nil
4250 (setq hier-list
(cons (cons name
(cdr elt
)) hier-list
))))
4251 (setq lst index-meth-alist
)
4253 (setq elt
(car lst
) lst
(cdr lst
))
4254 (cond ((string-match "\\(::\\|'\\)[_a-zA-Z0-9]+$" (car elt
))
4255 (setq pack
(substring (car elt
) 0 (match-beginning 0)))
4256 (if (setq group
(assoc pack hier-list
))
4257 (if (listp (cdr group
))
4258 ;; Have some functions already
4260 (cons (cons (substring
4262 (+ 2 (match-beginning 0)))
4265 (setcdr group
(list (cons (substring
4267 (+ 2 (match-beginning 0)))
4271 (list (cons (substring
4273 (+ 2 (match-beginning 0)))
4276 (push (cons "+Hierarchy+..."
4279 (and index-pack-alist
4280 (push (cons "+Packages+..."
4281 (nreverse index-pack-alist
))
4283 (and (or index-pack-alist index-pod-alist
4284 (default-value 'imenu-sort-function
))
4285 index-unsorted-alist
4286 (push (cons "+Unsorted List+..."
4287 (nreverse index-unsorted-alist
))
4289 (cperl-imenu-addback index-alist
)))
4291 (defvar cperl-compilation-error-regexp-alist
4292 ;; This look like a paranoiac regexp: could anybody find a better one? (which WORK).
4293 '(("^[^\n]* \\(file\\|at\\) \\([^ \t\n]+\\) [^\n]*line \\([0-9]+\\)[\\., \n]"
4295 "Alist that specifies how to match errors in perl output.")
4297 (if (fboundp 'eval-after-load
)
4300 '(setq perl-compilation-error-regexp-alist
4301 cperl-compilation-error-regexp-alist
)))
4304 (defun cperl-windowed-init ()
4305 "Initialization under windowed version."
4306 (if (or (featurep 'ps-print
) cperl-faces-init
)
4307 ;; Need to init anyway:
4308 (or cperl-faces-init
(cperl-init-faces))
4309 (add-hook 'font-lock-mode-hook
4313 (eq major-mode
'perl-mode
)
4314 (eq major-mode
'cperl-mode
))
4316 (or cperl-faces-init
(cperl-init-faces)))))))
4317 (if (fboundp 'eval-after-load
)
4320 '(or cperl-faces-init
(cperl-init-faces))))))
4322 (defun cperl-load-font-lock-keywords ()
4323 (or cperl-faces-init
(cperl-init-faces))
4324 perl-font-lock-keywords
)
4326 (defun cperl-load-font-lock-keywords-1 ()
4327 (or cperl-faces-init
(cperl-init-faces))
4328 perl-font-lock-keywords-1
)
4330 (defun cperl-load-font-lock-keywords-2 ()
4331 (or cperl-faces-init
(cperl-init-faces))
4332 perl-font-lock-keywords-2
)
4334 (defvar perl-font-lock-keywords-1 nil
4335 "Additional expressions to highlight in Perl mode. Minimal set.")
4336 (defvar perl-font-lock-keywords nil
4337 "Additional expressions to highlight in Perl mode. Default set.")
4338 (defvar perl-font-lock-keywords-2 nil
4339 "Additional expressions to highlight in Perl mode. Maximal set")
4341 (defvar font-lock-background-mode
)
4342 (defvar font-lock-display-type
)
4343 (defun cperl-init-faces-weak ()
4344 ;; Allow `cperl-find-pods-heres' to run.
4345 (or (boundp 'font-lock-constant-face
)
4346 (cperl-force-face font-lock-constant-face
4347 "Face for constant and label names")
4348 ;;(setq font-lock-constant-face 'font-lock-constant-face)
4351 (defun cperl-init-faces ()
4352 (condition-case errs
4354 (require 'font-lock
)
4355 (and (fboundp 'font-lock-fontify-anchored-keywords
)
4356 (featurep 'font-lock-extra
)
4357 (message "You have an obsolete package `font-lock-extra'. Install `choose-color'."))
4358 (let (t-font-lock-keywords t-font-lock-keywords-1 font-lock-anchored
)
4359 (if (fboundp 'font-lock-fontify-anchored-keywords
)
4360 (setq font-lock-anchored t
))
4362 t-font-lock-keywords
4364 (list "[ \t]+$" 0 cperl-invalid-face t
)
4367 "\\(^\\|[^$@%&\\]\\)\\<\\("
4370 '("if" "until" "while" "elsif" "else" "unless" "for"
4371 "foreach" "continue" "exit" "die" "last" "goto" "next"
4372 "redo" "return" "local" "exec" "sub" "do" "dump" "use"
4373 "require" "package" "eval" "my" "BEGIN" "END")
4374 "\\|") ; Flow control
4375 "\\)\\>") 2) ; was "\\)[ \n\t;():,\|&]"
4376 ; In what follows we use `type' style
4377 ; for overwritable builtins
4380 "\\(^\\|[^$@%&\\]\\)\\<\\("
4381 ;; "CORE" "__FILE__" "__LINE__" "abs" "accept" "alarm"
4382 ;; "and" "atan2" "bind" "binmode" "bless" "caller"
4383 ;; "chdir" "chmod" "chown" "chr" "chroot" "close"
4384 ;; "closedir" "cmp" "connect" "continue" "cos" "crypt"
4385 ;; "dbmclose" "dbmopen" "die" "dump" "endgrent"
4386 ;; "endhostent" "endnetent" "endprotoent" "endpwent"
4387 ;; "endservent" "eof" "eq" "exec" "exit" "exp" "fcntl"
4388 ;; "fileno" "flock" "fork" "formline" "ge" "getc"
4389 ;; "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
4390 ;; "gethostbyname" "gethostent" "getlogin"
4391 ;; "getnetbyaddr" "getnetbyname" "getnetent"
4392 ;; "getpeername" "getpgrp" "getppid" "getpriority"
4393 ;; "getprotobyname" "getprotobynumber" "getprotoent"
4394 ;; "getpwent" "getpwnam" "getpwuid" "getservbyname"
4395 ;; "getservbyport" "getservent" "getsockname"
4396 ;; "getsockopt" "glob" "gmtime" "gt" "hex" "index" "int"
4397 ;; "ioctl" "join" "kill" "lc" "lcfirst" "le" "length"
4398 ;; "link" "listen" "localtime" "lock" "log" "lstat" "lt"
4399 ;; "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "ne"
4400 ;; "not" "oct" "open" "opendir" "or" "ord" "pack" "pipe"
4401 ;; "quotemeta" "rand" "read" "readdir" "readline"
4402 ;; "readlink" "readpipe" "recv" "ref" "rename" "require"
4403 ;; "reset" "reverse" "rewinddir" "rindex" "rmdir" "seek"
4404 ;; "seekdir" "select" "semctl" "semget" "semop" "send"
4405 ;; "setgrent" "sethostent" "setnetent" "setpgrp"
4406 ;; "setpriority" "setprotoent" "setpwent" "setservent"
4407 ;; "setsockopt" "shmctl" "shmget" "shmread" "shmwrite"
4408 ;; "shutdown" "sin" "sleep" "socket" "socketpair"
4409 ;; "sprintf" "sqrt" "srand" "stat" "substr" "symlink"
4410 ;; "syscall" "sysread" "system" "syswrite" "tell"
4411 ;; "telldir" "time" "times" "truncate" "uc" "ucfirst"
4412 ;; "umask" "unlink" "unpack" "utime" "values" "vec"
4413 ;; "wait" "waitpid" "wantarray" "warn" "write" "x" "xor"
4414 "a\\(bs\\|ccept\\|tan2\\|larm\\|nd\\)\\|"
4415 "b\\(in\\(d\\|mode\\)\\|less\\)\\|"
4416 "c\\(h\\(r\\(\\|oot\\)\\|dir\\|mod\\|own\\)\\|aller\\|rypt\\|"
4417 "lose\\(\\|dir\\)\\|mp\\|o\\(s\\|n\\(tinue\\|nect\\)\\)\\)\\|"
4418 "CORE\\|d\\(ie\\|bm\\(close\\|open\\)\\|ump\\)\\|"
4419 "e\\(x\\(p\\|it\\|ec\\)\\|q\\|nd\\(p\\(rotoent\\|went\\)\\|"
4420 "hostent\\|servent\\|netent\\|grent\\)\\|of\\)\\|"
4421 "f\\(ileno\\|cntl\\|lock\\|or\\(k\\|mline\\)\\)\\|"
4422 "g\\(t\\|lob\\|mtime\\|e\\(\\|t\\(p\\(pid\\|r\\(iority\\|"
4423 "oto\\(byn\\(ame\\|umber\\)\\|ent\\)\\)\\|eername\\|w"
4424 "\\(uid\\|ent\\|nam\\)\\|grp\\)\\|host\\(by\\(addr\\|name\\)\\|"
4425 "ent\\)\\|s\\(erv\\(by\\(port\\|name\\)\\|ent\\)\\|"
4426 "ock\\(name\\|opt\\)\\)\\|c\\|login\\|net\\(by\\(addr\\|name\\)\\|"
4427 "ent\\)\\|gr\\(ent\\|nam\\|gid\\)\\)\\)\\)\\|"
4428 "hex\\|i\\(n\\(t\\|dex\\)\\|octl\\)\\|join\\|kill\\|"
4429 "l\\(i\\(sten\\|nk\\)\\|stat\\|c\\(\\|first\\)\\|t\\|e"
4430 "\\(\\|ngth\\)\\|o\\(c\\(altime\\|k\\)\\|g\\)\\)\\|m\\(sg\\(rcv\\|snd\\|"
4431 "ctl\\|get\\)\\|kdir\\)\\|n\\(e\\|ot\\)\\|o\\(pen\\(\\|dir\\)\\|"
4432 "r\\(\\|d\\)\\|ct\\)\\|p\\(ipe\\|ack\\)\\|quotemeta\\|"
4433 "r\\(index\\|and\\|mdir\\|e\\(quire\\|ad\\(pipe\\|\\|lin"
4434 "\\(k\\|e\\)\\|dir\\)\\|set\\|cv\\|verse\\|f\\|winddir\\|name"
4435 "\\)\\)\\|s\\(printf\\|qrt\\|rand\\|tat\\|ubstr\\|e\\(t\\(p\\(r"
4436 "\\(iority\\|otoent\\)\\|went\\|grp\\)\\|hostent\\|s\\(ervent\\|"
4437 "ockopt\\)\\|netent\\|grent\\)\\|ek\\(\\|dir\\)\\|lect\\|"
4438 "m\\(ctl\\|op\\|get\\)\\|nd\\)\\|h\\(utdown\\|m\\(read\\|ctl\\|"
4439 "write\\|get\\)\\)\\|y\\(s\\(read\\|call\\|tem\\|write\\)\\|"
4440 "mlink\\)\\|in\\|leep\\|ocket\\(pair\\|\\)\\)\\|t\\(runcate\\|"
4441 "ell\\(\\|dir\\)\\|ime\\(\\|s\\)\\)\\|u\\(c\\(\\|first\\)\\|"
4442 "time\\|mask\\|n\\(pack\\|link\\)\\)\\|v\\(alues\\|ec\\)\\|"
4443 "w\\(a\\(rn\\|it\\(pid\\|\\)\\|ntarray\\)\\|rite\\)\\|"
4444 "x\\(\\|or\\)\\|__\\(FILE__\\|LINE__\\|PACKAGE__\\)"
4445 "\\)\\>") 2 'font-lock-type-face
)
4446 ;; In what follows we use `other' style
4447 ;; for nonoverwritable builtins
4448 ;; Somehow 's', 'm' are not auto-generated???
4451 "\\(^\\|[^$@%&\\]\\)\\<\\("
4452 ;; "AUTOLOAD" "BEGIN" "DESTROY" "END" "__END__" "chomp"
4453 ;; "chop" "defined" "delete" "do" "each" "else" "elsif"
4454 ;; "eval" "exists" "for" "foreach" "format" "goto"
4455 ;; "grep" "if" "keys" "last" "local" "map" "my" "next"
4456 ;; "no" "package" "pop" "pos" "print" "printf" "push"
4457 ;; "q" "qq" "qw" "qx" "redo" "return" "scalar" "shift"
4458 ;; "sort" "splice" "split" "study" "sub" "tie" "tr"
4459 ;; "undef" "unless" "unshift" "untie" "until" "use"
4461 "AUTOLOAD\\|BEGIN\\|cho\\(p\\|mp\\)\\|d\\(e\\(fined\\|lete\\)\\|"
4462 "o\\)\\|DESTROY\\|e\\(ach\\|val\\|xists\\|ls\\(e\\|if\\)\\)\\|"
4463 "END\\|for\\(\\|each\\|mat\\)\\|g\\(rep\\|oto\\)\\|if\\|keys\\|"
4464 "l\\(ast\\|ocal\\)\\|m\\(ap\\|y\\)\\|n\\(ext\\|o\\)\\|"
4465 "p\\(ackage\\|rint\\(\\|f\\)\\|ush\\|o\\(p\\|s\\)\\)\\|"
4466 "q\\(\\|q\\|w\\|x\\|r\\)\\|re\\(turn\\|do\\)\\|s\\(pli\\(ce\\|t\\)\\|"
4467 "calar\\|tudy\\|ub\\|hift\\|ort\\)\\|t\\(r\\|ie\\)\\|"
4468 "u\\(se\\|n\\(shift\\|ti\\(l\\|e\\)\\|def\\|less\\)\\)\\|"
4469 "while\\|y\\|__\\(END\\|DATA\\)__" ;__DATA__ added manually
4470 "\\|[sm]" ; Added manually
4471 "\\)\\>") 2 'cperl-nonoverridable-face
)
4472 ;; (mapconcat 'identity
4473 ;; '("#endif" "#else" "#ifdef" "#ifndef" "#if"
4474 ;; "#include" "#define" "#undef")
4476 '("-[rwxoRWXOezsfdlpSbctugkTBMAC]\\>\\([ \t]+_\\>\\)?" 0
4477 font-lock-function-name-face keep
) ; Not very good, triggers at "[a-z]"
4478 '("\\<sub[ \t]+\\([^ \t{;()]+\\)[ \t]*\\(([^()]*)[ \t]*\\)?[#{\n]" 1
4479 font-lock-function-name-face
)
4480 '("\\<\\(package\\|require\\|use\\|import\\|no\\|bootstrap\\)[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t;]" ; require A if B;
4481 2 font-lock-function-name-face
)
4482 '("^[ \t]*format[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t]*=[ \t]*$"
4483 1 font-lock-function-name-face
)
4484 (cond ((featurep 'font-lock-extra
)
4485 '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
4486 (2 font-lock-string-face t
)
4487 (0 '(restart 2 t
)))) ; To highlight $a{bc}{ef}
4489 '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
4490 (2 font-lock-string-face t
)
4491 ("\\=[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
4493 (1 font-lock-string-face t
))))
4494 (t '("\\([]}\\\\%@>*&]\\|\\$[a-zA-Z0-9_:]*\\)[ \t]*{[ \t]*\\(-?[a-zA-Z0-9_:]+\\)[ \t]*}"
4495 2 font-lock-string-face t
)))
4496 '("[\[ \t{,(]\\(-?[a-zA-Z0-9_:]+\\)[ \t]*=>" 1
4497 font-lock-string-face t
)
4498 '("^[ \t]*\\([a-zA-Z0-9_]+[ \t]*:\\)[ \t]*\\($\\|{\\|\\<\\(until\\|while\\|for\\(each\\)?\\|do\\)\\>\\)" 1
4499 font-lock-constant-face
) ; labels
4500 '("\\<\\(continue\\|next\\|last\\|redo\\|goto\\)\\>[ \t]+\\([a-zA-Z0-9_:]+\\)" ; labels as targets
4501 2 font-lock-constant-face
)
4502 (cond ((featurep 'font-lock-extra
)
4503 '("^[ \t]*\\(my\\|local\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)\\([ \t]*,\\)?"
4504 (3 font-lock-variable-name-face
)
4506 ("\\=[ \t]*,[ \t]*\\([$@%*][a-zA-Z0-9_:]+\\)\\([ \t]*,\\)?"
4507 (1 font-lock-variable-name-face
)
4508 (2 '(restart 2 nil
) nil t
)))
4509 nil t
))) ; local variables, multiple
4511 '("^[ \t{}]*\\(my\\|local\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)"
4512 (3 font-lock-variable-name-face
)
4513 ("\\=[ \t]*,[ \t]*\\([$@%*][a-zA-Z0-9_:]+\\)"
4515 (1 font-lock-variable-name-face
))))
4516 (t '("^[ \t{}]*\\(my\\|local\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)"
4517 3 font-lock-variable-name-face
)))
4518 '("\\<for\\(each\\)?[ \t]*\\(\\$[a-zA-Z_][a-zA-Z_0-9]*\\)[ \t]*("
4519 2 font-lock-variable-name-face
)))
4521 t-font-lock-keywords-1
4522 (and (fboundp 'turn-on-font-lock
) ; Check for newer font-lock
4523 (not cperl-xemacs-p
) ; not yet as of XEmacs 19.12
4525 ("\\(\\([@%]\\|\$#\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)" 1
4526 (if (eq (char-after (match-beginning 2)) ?%
)
4529 t
) ; arrays and hashes
4530 ("\\(\\([$@]+\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)[ \t]*\\([[{]\\)"
4532 (if (= (- (match-end 2) (match-beginning 2)) 1)
4533 (if (eq (char-after (match-beginning 3)) ?
{)
4535 cperl-array-face
) ; arrays and hashes
4536 font-lock-variable-name-face
) ; Just to put something
4538 ;;("\\([smy]\\|tr\\)\\([^a-z_A-Z0-9]\\)\\(\\([^\n\\]*||\\)\\)\\2")
4539 ;;; Too much noise from \s* @s[ and friends
4540 ;;("\\(\\<\\([msy]\\|tr\\)[ \t]*\\([^ \t\na-zA-Z0-9_]\\)\\|\\(/\\)\\)"
4541 ;;(3 font-lock-function-name-face t t)
4543 ;; (if (cperl-slash-is-regexp)
4544 ;; font-lock-function-name-face 'default) nil t))
4546 (setq perl-font-lock-keywords-1
4547 (if cperl-syntaxify-by-font-lock
4548 (cons 'cperl-fontify-update
4549 t-font-lock-keywords
)
4550 t-font-lock-keywords
)
4551 perl-font-lock-keywords perl-font-lock-keywords-1
4552 perl-font-lock-keywords-2
(append
4553 perl-font-lock-keywords-1
4554 t-font-lock-keywords-1
)))
4555 (if (fboundp 'ps-print-buffer
) (cperl-ps-print-init))
4556 (if (or (featurep 'choose-color
) (featurep 'font-lock-extra
))
4557 (eval ; Avoid a warning
4558 '(font-lock-require-faces
4560 ;; Color-light Color-dark Gray-light Gray-dark Mono
4561 (list 'font-lock-comment-face
4562 ["Firebrick" "OrangeRed" "DimGray" "Gray80"]
4567 (list 'font-lock-string-face
4568 ["RosyBrown" "LightSalmon" "Gray50" "LightGray"]
4573 (list 'font-lock-function-name-face
4575 "Blue" "LightSkyBlue" "Gray50" "LightGray"
4576 (cdr (assq 'background-color
; if mono
4577 (frame-parameters))))
4580 (cdr (assq 'foreground-color
; if mono
4581 (frame-parameters))))
4585 (list 'font-lock-variable-name-face
4586 ["DarkGoldenrod" "LightGoldenrod" "DimGray" "Gray90"]
4591 (list 'font-lock-type-face
4592 ["DarkOliveGreen" "PaleGreen" "DimGray" "Gray80"]
4598 (list 'font-lock-constant-face
4599 ["CadetBlue" "Aquamarine" "Gray50" "LightGray"]
4605 (list 'cperl-nonoverridable-face
4606 ["chartreuse3" ("orchid1" "orange")
4613 (list 'cperl-array-face
4614 ["blue" "yellow" nil
"Gray80"]
4615 ["lightyellow2" ("navy" "os2blue" "darkgreen")
4620 (list 'cperl-hash-face
4621 ["red" "red" nil
"Gray80"]
4622 ["lightyellow2" ("navy" "os2blue" "darkgreen")
4627 ;; Do it the dull way, without choose-color
4628 (defvar cperl-guessed-background nil
4629 "Display characteristics as guessed by cperl.")
4630 ;; (or (fboundp 'x-color-defined-p)
4631 ;; (defalias 'x-color-defined-p
4632 ;; (cond ((fboundp 'color-defined-p) 'color-defined-p)
4633 ;; ;; XEmacs >= 19.12
4634 ;; ((fboundp 'valid-color-name-p) 'valid-color-name-p)
4636 ;; (t 'x-valid-color-name-p))))
4637 (cperl-force-face font-lock-constant-face
4638 "Face for constant and label names")
4639 (cperl-force-face font-lock-variable-name-face
4640 "Face for variable names")
4641 (cperl-force-face font-lock-type-face
4642 "Face for data types")
4643 (cperl-force-face cperl-nonoverridable-face
4644 "Face for data types from another group")
4645 (cperl-force-face font-lock-comment-face
4646 "Face for comments")
4647 (cperl-force-face font-lock-function-name-face
4648 "Face for function names")
4649 (cperl-force-face cperl-hash-face
4651 (cperl-force-face cperl-array-face
4653 ;;(defvar font-lock-constant-face 'font-lock-constant-face)
4654 ;;(defvar font-lock-variable-name-face 'font-lock-variable-name-face)
4655 ;;(or (boundp 'font-lock-type-face)
4656 ;; (defconst font-lock-type-face
4657 ;; 'font-lock-type-face
4658 ;; "Face to use for data types."))
4659 ;;(or (boundp 'cperl-nonoverridable-face)
4660 ;; (defconst cperl-nonoverridable-face
4661 ;; 'cperl-nonoverridable-face
4662 ;; "Face to use for data types from another group."))
4663 ;;(if (not cperl-xemacs-p) nil
4664 ;; (or (boundp 'font-lock-comment-face)
4665 ;; (defconst font-lock-comment-face
4666 ;; 'font-lock-comment-face
4667 ;; "Face to use for comments."))
4668 ;; (or (boundp 'font-lock-keyword-face)
4669 ;; (defconst font-lock-keyword-face
4670 ;; 'font-lock-keyword-face
4671 ;; "Face to use for keywords."))
4672 ;; (or (boundp 'font-lock-function-name-face)
4673 ;; (defconst font-lock-function-name-face
4674 ;; 'font-lock-function-name-face
4675 ;; "Face to use for function names.")))
4677 (not (cperl-is-face 'cperl-array-face
))
4678 (cperl-is-face 'font-lock-emphasized-face
))
4679 (copy-face 'font-lock-emphasized-face
'cperl-array-face
))
4681 (not (cperl-is-face 'cperl-hash-face
))
4682 (cperl-is-face 'font-lock-other-emphasized-face
))
4683 (copy-face 'font-lock-other-emphasized-face
4686 (not (cperl-is-face 'cperl-nonoverridable-face
))
4687 (cperl-is-face 'font-lock-other-type-face
))
4688 (copy-face 'font-lock-other-type-face
4689 'cperl-nonoverridable-face
))
4690 ;;(or (boundp 'cperl-hash-face)
4691 ;; (defconst cperl-hash-face
4693 ;; "Face to use for hashes."))
4694 ;;(or (boundp 'cperl-array-face)
4695 ;; (defconst cperl-array-face
4696 ;; 'cperl-array-face
4697 ;; "Face to use for arrays."))
4698 ;; Here we try to guess background
4700 (if (boundp 'font-lock-background-mode
)
4701 font-lock-background-mode
4703 (face-list (and (fboundp 'face-list
) (face-list)))
4706 ;;;; (fset 'cperl-is-face
4707 ;;;; (cond ((fboundp 'find-face)
4708 ;;;; (symbol-function 'find-face))
4710 ;;;; (function (lambda (face) (member face face-list))))
4712 ;;;; (function (lambda (face) (boundp face))))))
4713 (defvar cperl-guessed-background
4714 (if (and (boundp 'font-lock-display-type
)
4715 (eq font-lock-display-type
'grayscale
))
4718 "Background as guessed by CPerl mode")
4720 (not (cperl-is-face 'font-lock-constant-face
))
4721 (cperl-is-face 'font-lock-reference-face
))
4722 (copy-face 'font-lock-reference-face
'font-lock-constant-face
))
4723 (if (cperl-is-face 'font-lock-type-face
) nil
4724 (copy-face 'default
'font-lock-type-face
)
4726 ((eq background
'light
)
4727 (set-face-foreground 'font-lock-type-face
4728 (if (x-color-defined-p "seagreen")
4731 ((eq background
'dark
)
4732 (set-face-foreground 'font-lock-type-face
4733 (if (x-color-defined-p "os2pink")
4737 (set-face-background 'font-lock-type-face
"gray90"))))
4738 (if (cperl-is-face 'cperl-nonoverridable-face
)
4740 (copy-face 'font-lock-type-face
'cperl-nonoverridable-face
)
4742 ((eq background
'light
)
4743 (set-face-foreground 'cperl-nonoverridable-face
4744 (if (x-color-defined-p "chartreuse3")
4747 ((eq background
'dark
)
4748 (set-face-foreground 'cperl-nonoverridable-face
4749 (if (x-color-defined-p "orchid1")
4752 ;;; (if (cperl-is-face 'font-lock-other-emphasized-face) nil
4753 ;;; (copy-face 'bold-italic 'font-lock-other-emphasized-face)
4755 ;;; ((eq background 'light)
4756 ;;; (set-face-background 'font-lock-other-emphasized-face
4757 ;;; (if (x-color-defined-p "lightyellow2")
4759 ;;; (if (x-color-defined-p "lightyellow")
4761 ;;; "light yellow"))))
4762 ;;; ((eq background 'dark)
4763 ;;; (set-face-background 'font-lock-other-emphasized-face
4764 ;;; (if (x-color-defined-p "navy")
4766 ;;; (if (x-color-defined-p "darkgreen")
4768 ;;; "dark green"))))
4769 ;;; (t (set-face-background 'font-lock-other-emphasized-face "gray90"))))
4770 ;;; (if (cperl-is-face 'font-lock-emphasized-face) nil
4771 ;;; (copy-face 'bold 'font-lock-emphasized-face)
4773 ;;; ((eq background 'light)
4774 ;;; (set-face-background 'font-lock-emphasized-face
4775 ;;; (if (x-color-defined-p "lightyellow2")
4777 ;;; "lightyellow")))
4778 ;;; ((eq background 'dark)
4779 ;;; (set-face-background 'font-lock-emphasized-face
4780 ;;; (if (x-color-defined-p "navy")
4782 ;;; (if (x-color-defined-p "darkgreen")
4784 ;;; "dark green"))))
4785 ;;; (t (set-face-background 'font-lock-emphasized-face "gray90"))))
4786 (if (cperl-is-face 'font-lock-variable-name-face
) nil
4787 (copy-face 'italic
'font-lock-variable-name-face
))
4788 (if (cperl-is-face 'font-lock-constant-face
) nil
4789 (copy-face 'italic
'font-lock-constant-face
))))
4790 (setq cperl-faces-init t
))
4791 (error (message "cperl-init-faces (ignored): %s" errs
))))
4794 (defun cperl-ps-print-init ()
4795 "Initialization of `ps-print' components for faces used in CPerl."
4796 (eval-after-load "ps-print"
4797 '(setq ps-bold-faces
4798 ;; font-lock-variable-name-face
4799 ;; font-lock-constant-face
4800 (append '(cperl-array-face
4804 ;; font-lock-constant-face
4805 (append '(cperl-nonoverridable-face
4809 ;; font-lock-type-face
4810 (append '(cperl-array-face
4813 cperl-nonoverridable-face
)
4814 ps-underlined-faces
))))
4816 (defvar ps-print-face-extension-alist
)
4818 (defun cperl-ps-print (&optional file
)
4819 "Pretty-print in CPerl style.
4820 If optional argument FILE is an empty string, prints to printer, otherwise
4821 to the file FILE. If FILE is nil, prompts for a file name.
4823 Style of printout regulated by the variable `cperl-ps-print-face-properties'."
4826 (setq file
(read-from-minibuffer
4827 "Print to file (if empty - to printer): "
4828 (concat (buffer-file-name) ".ps")
4829 nil nil
'file-name-history
)))
4830 (or (> (length file
) 0)
4832 (require 'ps-print
) ; To get ps-print-face-extension-alist
4833 (let ((ps-print-color-p t
)
4834 (ps-print-face-extension-alist ps-print-face-extension-alist
))
4835 (cperl-ps-extend-face-list cperl-ps-print-face-properties
)
4836 (ps-print-buffer-with-faces file
)))
4838 ;;; (defun cperl-ps-print-init ()
4839 ;;; "Initialization of `ps-print' components for faces used in CPerl."
4840 ;;; ;; Guard against old versions
4841 ;;; (defvar ps-underlined-faces nil)
4842 ;;; (defvar ps-bold-faces nil)
4843 ;;; (defvar ps-italic-faces nil)
4844 ;;; (setq ps-bold-faces
4845 ;;; (append '(font-lock-emphasized-face
4846 ;;; cperl-array-face
4847 ;;; font-lock-keyword-face
4848 ;;; font-lock-variable-name-face
4849 ;;; font-lock-constant-face
4850 ;;; font-lock-reference-face
4851 ;;; font-lock-other-emphasized-face
4852 ;;; cperl-hash-face)
4854 ;;; (setq ps-italic-faces
4855 ;;; (append '(cperl-nonoverridable-face
4856 ;;; font-lock-constant-face
4857 ;;; font-lock-reference-face
4858 ;;; font-lock-other-emphasized-face
4859 ;;; cperl-hash-face)
4860 ;;; ps-italic-faces))
4861 ;;; (setq ps-underlined-faces
4862 ;;; (append '(font-lock-emphasized-face
4863 ;;; cperl-array-face
4864 ;;; font-lock-other-emphasized-face
4866 ;;; cperl-nonoverridable-face font-lock-type-face)
4867 ;;; ps-underlined-faces))
4868 ;;; (cons 'font-lock-type-face ps-underlined-faces))
4871 (if (cperl-enable-font-lock) (cperl-windowed-init))
4873 (defconst cperl-styles-entries
4874 '(cperl-indent-level cperl-brace-offset cperl-continued-brace-offset
4875 cperl-label-offset cperl-extra-newline-before-brace
4876 cperl-merge-trailing-else
4877 cperl-continued-statement-offset
))
4879 (defconst cperl-style-alist
4880 '(("CPerl" ; =GNU without extra-newline-before-brace
4881 (cperl-indent-level .
2)
4882 (cperl-brace-offset .
0)
4883 (cperl-continued-brace-offset .
0)
4884 (cperl-label-offset . -
2)
4885 (cperl-extra-newline-before-brace . nil
)
4886 (cperl-merge-trailing-else . t
)
4887 (cperl-continued-statement-offset .
2))
4888 ("PerlStyle" ; CPerl with 4 as indent
4889 (cperl-indent-level .
4)
4890 (cperl-brace-offset .
0)
4891 (cperl-continued-brace-offset .
0)
4892 (cperl-label-offset . -
4)
4893 (cperl-extra-newline-before-brace . nil
)
4894 (cperl-merge-trailing-else . t
)
4895 (cperl-continued-statement-offset .
4))
4897 (cperl-indent-level .
2)
4898 (cperl-brace-offset .
0)
4899 (cperl-continued-brace-offset .
0)
4900 (cperl-label-offset . -
2)
4901 (cperl-extra-newline-before-brace . t
)
4902 (cperl-merge-trailing-else . nil
)
4903 (cperl-continued-statement-offset .
2))
4905 (cperl-indent-level .
5)
4906 (cperl-brace-offset .
0)
4907 (cperl-continued-brace-offset . -
5)
4908 (cperl-label-offset . -
5)
4909 ;;(cperl-extra-newline-before-brace . nil) ; ???
4910 (cperl-merge-trailing-else . nil
)
4911 (cperl-continued-statement-offset .
5))
4913 (cperl-indent-level .
4)
4914 (cperl-brace-offset .
0)
4915 (cperl-continued-brace-offset . -
4)
4916 (cperl-label-offset . -
4)
4917 ;;(cperl-extra-newline-before-brace . nil) ; ???
4918 (cperl-continued-statement-offset .
4))
4920 (cperl-indent-level .
4)
4921 (cperl-brace-offset .
0)
4922 (cperl-continued-brace-offset . -
4)
4923 (cperl-label-offset . -
4)
4924 (cperl-continued-statement-offset .
4)
4925 (cperl-merge-trailing-else . nil
)
4926 (cperl-extra-newline-before-brace . t
))
4929 (cperl-indent-level .
4)
4930 (cperl-brace-offset .
0)
4931 (cperl-continued-brace-offset .
0)
4932 (cperl-label-offset . -
4)
4933 ;;(cperl-extra-newline-before-brace . nil) ; ???
4934 (cperl-continued-statement-offset .
4)))
4935 "(Experimental) list of variables to set to get a particular indentation style.
4936 Should be used via `cperl-set-style' or via Perl menu.")
4938 (defun cperl-set-style (style)
4939 "Set CPerl-mode variables to use one of several different indentation styles.
4940 The arguments are a string representing the desired style.
4941 The list of styles is in `cperl-style-alist', available styles
4942 are GNU, K&R, BSD, C++ and Whitesmith.
4944 The current value of style is memorized (unless there is a memorized
4945 data already), may be restored by `cperl-set-style-back'.
4947 Chosing \"Current\" style will not change style, so this may be used for
4948 side-effect of memorizing only."
4950 (let ((list (mapcar (function (lambda (elt) (list (car elt
))))
4951 cperl-style-alist
)))
4952 (list (completing-read "Enter style: " list nil
'insist
))))
4954 (setq cperl-old-style
4957 (cons name
(eval name
))))
4958 cperl-styles-entries
)))
4959 (let ((style (cdr (assoc style cperl-style-alist
))) setting str sym
)
4961 (setq setting
(car style
) style
(cdr style
))
4962 (set (car setting
) (cdr setting
)))))
4964 (defun cperl-set-style-back ()
4965 "Restore a style memorised by `cperl-set-style'."
4967 (or cperl-old-style
(error "The style was not changed"))
4969 (while cperl-old-style
4970 (setq setting
(car cperl-old-style
)
4971 cperl-old-style
(cdr cperl-old-style
))
4972 (set (car setting
) (cdr setting
)))))
4974 (defun cperl-check-syntax ()
4976 (require 'mode-compile
)
4977 (let ((perl-dbg-flags (concat cperl-extra-perl-args
" -wc")))
4978 (eval '(mode-compile)))) ; Avoid a warning
4980 (defun cperl-info-buffer (type)
4981 ;; Returns buffer with documentation. Creates if missing.
4982 ;; If TYPE, this vars buffer.
4983 ;; Special care is taken to not stomp over an existing info buffer
4984 (let* ((bname (if type
"*info-perl-var*" "*info-perl*"))
4985 (info (get-buffer bname
))
4986 (oldbuf (get-buffer "*info*")))
4988 (save-window-excursion
4993 (rename-buffer "*info-perl-tmp*")))
4994 (save-window-excursion
4996 (Info-find-node cperl-info-page
(if type
"perlvar" "perlfunc"))
4997 (set-buffer "*info*")
4998 (rename-buffer bname
)
5000 (set-buffer "*info-perl-tmp*")
5001 (rename-buffer "*info*")
5002 (set-buffer bname
)))
5003 (make-variable-buffer-local 'window-min-height
)
5004 (setq window-min-height
2)
5005 (current-buffer)))))
5007 (defun cperl-word-at-point (&optional p
)
5008 ;; Returns the word at point or at P.
5010 (if p
(goto-char p
))
5011 (or (cperl-word-at-point-hard)
5014 (funcall (or (and (boundp 'find-tag-default-function
)
5015 find-tag-default-function
)
5016 (get major-mode
'find-tag-default-function
)
5017 ;; XEmacs 19.12 has `find-tag-default-hook'; it is
5018 ;; automatically used within `find-tag-default':
5019 'find-tag-default
))))))
5021 (defun cperl-info-on-command (command)
5022 "Shows documentation for Perl command in other window.
5023 If perl-info buffer is shown in some frame, uses this frame.
5024 Customized by setting variables `cperl-shrink-wrap-info-frame',
5025 `cperl-max-help-size'."
5027 (let* ((default (cperl-word-at-point))
5029 (format "Find doc for Perl function (default %s): "
5031 (list (if (equal read
"")
5035 (let ((buffer (current-buffer))
5036 (cmd-desc (concat "^" (regexp-quote command
) "[^a-zA-Z_0-9]")) ; "tr///"
5037 pos isvar height iniheight frheight buf win fr1 fr2 iniwin not-loner
5038 max-height char-height buf-list
)
5039 (if (string-match "^-[a-zA-Z]$" command
)
5040 (setq cmd-desc
"^-X[ \t\n]"))
5041 (setq isvar
(string-match "^[$@%]" command
)
5042 buf
(cperl-info-buffer isvar
)
5043 iniwin
(selected-window)
5044 fr1
(window-frame iniwin
))
5046 (beginning-of-buffer)
5048 (progn (re-search-forward "^-X[ \t\n]")
5050 (if (re-search-forward cmd-desc nil t
)
5052 ;; Go back to beginning of the group (ex, for qq)
5053 (if (re-search-backward "^[ \t\n\f]")
5058 buf-list
(list buf
"*info-perl-var*" "*info-perl*"))
5059 (while (and (not win
) buf-list
)
5060 (setq win
(get-buffer-window (car buf-list
) t
))
5061 (setq buf-list
(cdr buf-list
)))
5063 (eq (window-buffer win
) buf
)
5064 (set-window-buffer win buf
))
5065 (and win
(setq fr2
(window-frame win
)))
5066 (if (or (not fr2
) (eq fr1 fr2
))
5068 (special-display-popup-frame buf
) ; Make it visible
5069 (select-window win
))
5070 (goto-char pos
) ; Needed (?!).
5072 (setq iniheight
(window-height)
5073 frheight
(frame-height)
5074 not-loner
(< iniheight
(1- frheight
))) ; Are not alone
5075 (cond ((if not-loner cperl-max-help-size
5076 cperl-shrink-wrap-info-frame
)
5082 (if (re-search-forward
5083 "^[ \t][^\n]*\n+\\([^ \t\n\f]\\|\\'\\)" nil t
)
5084 (match-beginning 0) (point-max)))))
5087 (/ (* (- frheight
3) cperl-max-help-size
) 100)
5088 (setq char-height
(frame-char-height))
5089 ;; Non-functioning under OS/2:
5090 (if (eq char-height
1) (setq char-height
18))
5091 ;; Title, menubar, + 2 for slack
5092 (- (/ (x-display-pixel-height) char-height
) 4)
5094 (if (> height max-height
) (setq height max-height
))
5095 ;;(message "was %s doing %s" iniheight height)
5097 (enlarge-window (- height iniheight
))
5098 (set-frame-height (window-frame win
) (1+ height
)))))
5099 (set-window-start (selected-window) pos
))
5100 (message "No entry for %s found." command
))
5101 ;;(pop-to-buffer buffer)
5102 (select-window iniwin
)))
5104 (defun cperl-info-on-current-command ()
5105 "Shows documentation for Perl command at point in other window."
5107 (cperl-info-on-command (cperl-word-at-point)))
5109 (defun cperl-imenu-info-imenu-search ()
5110 (if (looking-at "^-X[ \t\n]") nil
5112 "^\n\\([-a-zA-Z_]+\\)[ \t\n]")
5115 (defun cperl-imenu-info-imenu-name ()
5117 (match-beginning 1) (match-end 1)))
5119 (defun cperl-imenu-on-info ()
5121 (let* ((buffer (current-buffer))
5122 imenu-create-index-function
5123 imenu-prev-index-position-function
5124 imenu-extract-index-name-function
5125 (index-item (save-restriction
5126 (save-window-excursion
5127 (set-buffer (cperl-info-buffer nil
))
5128 (setq imenu-create-index-function
5129 'imenu-default-create-index-function
5130 imenu-prev-index-position-function
5131 'cperl-imenu-info-imenu-search
5132 imenu-extract-index-name-function
5133 'cperl-imenu-info-imenu-name
)
5134 (imenu-choose-buffer-index)))))
5138 (pop-to-buffer "*info-perl*")
5140 ((markerp (cdr index-item
))
5141 (goto-char (marker-position (cdr index-item
))))
5143 (goto-char (cdr index-item
))))
5144 (set-window-start (selected-window) (point))
5145 (pop-to-buffer buffer
)))))
5147 (defun cperl-lineup (beg end
&optional step minshift
)
5148 "Lineup construction in a region.
5149 Beginning of region should be at the start of a construction.
5150 All first occurrences of this construction in the lines that are
5151 partially contained in the region are lined up at the same column.
5153 MINSHIFT is the minimal amount of space to insert before the construction.
5154 STEP is the tabwidth to position constructions.
5155 If STEP is `nil', `cperl-lineup-step' will be used
5156 \(or `cperl-indent-level', if `cperl-lineup-step' is `nil').
5157 Will not move the position at the start to the left."
5159 (let (search col tcol seen b e
)
5163 (setq end
(point-marker))
5165 (skip-chars-forward " \t\f")
5166 (setq beg
(point-marker))
5167 (indent-region beg end nil
)
5169 (setq col
(current-column))
5170 (if (looking-at "[a-zA-Z0-9_]")
5171 (if (looking-at "\\<[a-zA-Z0-9_]+\\>")
5175 (buffer-substring (match-beginning 0)
5176 (match-end 0))) "\\>"))
5177 (error "Cannot line up in a middle of the word"))
5178 (if (looking-at "$")
5179 (error "Cannot line up end of line"))
5180 (setq search
(regexp-quote (char-to-string (following-char)))))
5181 (setq step
(or step cperl-lineup-step cperl-indent-level
))
5182 (or minshift
(setq minshift
1))
5184 (beginning-of-line 2)
5185 (and (< (point) end
)
5186 (re-search-forward search end t
)
5187 (goto-char (match-beginning 0))))
5188 (setq tcol
(current-column) seen t
)
5189 (if (> tcol col
) (setq col tcol
)))
5191 (error "The construction to line up occurred only once"))
5193 (setq col
(+ col minshift
))
5194 (if (/= (% col step
) 0) (setq step
(* step
(1+ (/ col step
)))))
5198 (skip-chars-backward " \t")
5199 (delete-region (point) e
)
5200 (indent-to-column col
); (make-string (- col (current-column)) ?\ ))
5201 (beginning-of-line 2)
5202 (and (< (point) end
)
5203 (re-search-forward search end t
)
5204 (goto-char (match-beginning 0)))))))) ; No body
5206 (defun cperl-etags (&optional add all files
)
5207 "Run etags with appropriate options for Perl files.
5208 If optional argument ALL is `recursive', will process Perl files
5209 in subdirectories too."
5212 (args '("-l" "none" "-r" "/\\<\\(package\\|sub\\)[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)[ \\t]*\\(([^()]*)[ \t]*\\)?\\([{#]\\|$\\)\\)/\\4/"))
5214 (if add
(setq args
(cons "-a" args
)))
5215 (or files
(setq files
(list buffer-file-name
)))
5217 ((eq all
'recursive
)
5218 ;;(error "Not implemented: recursive")
5219 (setq args
(append (list "-e"
5220 "sub wanted {push @ARGV, $File::Find::name if /\\.[pP][Llm]$/}
5222 find(\\&wanted, '.');
5227 ;;(error "Not implemented: all")
5228 (setq args
(append (list "-e"
5229 "push @ARGV, <*.PL *.pl *.pm>;
5234 (setq args
(append args files
))))
5235 (setq res
(apply 'call-process cmd nil nil nil args
))
5237 (message "etags returned \"%s\"" res
))))
5239 (defun cperl-toggle-auto-newline ()
5240 "Toggle the state of `cperl-auto-newline'."
5242 (setq cperl-auto-newline
(not cperl-auto-newline
))
5243 (message "Newlines will %sbe auto-inserted now."
5244 (if cperl-auto-newline
"" "not ")))
5246 (defun cperl-toggle-abbrev ()
5247 "Toggle the state of automatic keyword expansion in CPerl mode."
5249 (abbrev-mode (if abbrev-mode
0 1))
5250 (message "Perl control structure will %sbe auto-inserted now."
5251 (if abbrev-mode
"" "not ")))
5254 (defun cperl-toggle-electric ()
5255 "Toggle the state of parentheses doubling in CPerl mode."
5257 (setq cperl-electric-parens
(if (cperl-val 'cperl-electric-parens
) 'null t
))
5258 (message "Parentheses will %sbe auto-doubled now."
5259 (if (cperl-val 'cperl-electric-parens
) "" "not ")))
5261 (defun cperl-toggle-autohelp ()
5262 "Toggle the state of automatic help message in CPerl mode.
5263 See `cperl-lazy-help-time' too."
5265 (if (fboundp 'run-with-idle-timer
)
5267 (if cperl-lazy-installed
5268 (eval '(cperl-lazy-unstall))
5269 (cperl-lazy-install))
5270 (message "Perl help messages will %sbe automatically shown now."
5271 (if cperl-lazy-installed
"" "not ")))
5272 (message "Cannot automatically show Perl help messages - run-with-idle-timer missing.")))
5274 (defun cperl-toggle-construct-fix ()
5275 "Toggle whether `indent-region'/`indent-sexp' fix whitespace too."
5277 (setq cperl-indent-region-fix-constructs
5278 (if cperl-indent-region-fix-constructs
5281 (message "indent-region/indent-sexp will %sbe automatically fix whitespace."
5282 (if cperl-indent-region-fix-constructs
"" "not ")))
5284 ;;;; Tags file creation.
5286 (defvar cperl-tmp-buffer
" *cperl-tmp*")
5288 (defun cperl-setup-tmp-buf ()
5289 (set-buffer (get-buffer-create cperl-tmp-buffer
))
5290 (set-syntax-table cperl-mode-syntax-table
)
5291 (buffer-disable-undo)
5293 (if cperl-use-syntax-table-text-property-for-tags
5295 (make-variable-buffer-local 'parse-sexp-lookup-properties
)
5296 ;; Do not introduce variable if not needed, we check it!
5297 (set 'parse-sexp-lookup-properties t
))))
5299 (defun cperl-xsub-scan ()
5302 (let ((index-alist '())
5303 (prev-pos 0) index index1 name package prefix
)
5304 (goto-char (point-min))
5306 (message "Scanning XSUB for index")
5307 (imenu-progress-message prev-pos
0))
5308 ;; Search for the function
5309 (progn ;;save-match-data
5310 (while (re-search-forward
5311 "^\\([ \t]*MODULE\\>[^\n]*\\<PACKAGE[ \t]*=[ \t]*\\([a-zA-Z_][a-zA-Z_0-9:]*\\)\\>\\|\\([a-zA-Z_][a-zA-Z_0-9]*\\)(\\|[ \t]*BOOT:\\)"
5314 (imenu-progress-message prev-pos
))
5316 ((match-beginning 2) ; SECTION
5317 (setq package
(buffer-substring (match-beginning 2) (match-end 2)))
5318 (goto-char (match-beginning 0))
5319 (skip-chars-forward " \t")
5321 (if (looking-at "[^\n]*\\<PREFIX[ \t]*=[ \t]*\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>")
5322 (setq prefix
(buffer-substring (match-beginning 1) (match-end 1)))
5324 ((not package
) nil
) ; C language section
5325 ((match-beginning 3) ; XSUB
5326 (goto-char (1+ (match-beginning 3)))
5327 (setq index
(imenu-example--name-and-position))
5328 (setq name
(buffer-substring (match-beginning 3) (match-end 3)))
5329 (if (and prefix
(string-match (concat "^" prefix
) name
))
5330 (setq name
(substring name
(length prefix
))))
5331 (cond ((string-match "::" name
) nil
)
5333 (setq index1
(cons (concat package
"::" name
) (cdr index
)))
5334 (push index1 index-alist
)))
5336 (push index index-alist
))
5338 ;; (beginning-of-line)
5339 (setq index
(imenu-example--name-and-position))
5340 (setcar index
(concat package
"::BOOT:"))
5341 (push index index-alist
)))))
5343 (imenu-progress-message prev-pos
100))
5346 (defun cperl-find-tags (file xs topdir
)
5347 (let (ind (b (get-buffer cperl-tmp-buffer
)) lst elt pos ret rel
5348 (cperl-pod-here-fontify nil
))
5350 (if b
(set-buffer b
)
5351 (cperl-setup-tmp-buf))
5353 (setq file
(car (insert-file-contents file
)))
5354 (message "Scanning file %s ..." file
)
5355 (if (and cperl-use-syntax-table-text-property-for-tags
5357 (condition-case err
; after __END__ may have garbage
5358 (cperl-find-pods-heres)
5359 (error (message "While scanning for syntax: %s" err
))))
5361 (setq lst
(cperl-xsub-scan))
5362 (setq ind
(imenu-example--create-perl-index))
5363 (setq lst
(cdr (assoc "+Unsorted List+..." ind
))))
5368 (cond ((string-match "^[_a-zA-Z]" (car elt
))
5369 (goto-char (cdr elt
))
5370 (beginning-of-line) ; pos should be of the start of the line
5373 (1+ (count-lines 1 (point))) ; 1+ since at beg-o-l
5374 (buffer-substring (progn
5377 (or (eolp) (forward-char 1))
5385 (setq elt
(car lst
) lst
(cdr lst
))
5390 (if (string-match "^package " (car elt
))
5391 (substring (car elt
) 8)
5394 (number-to-string (elt elt
2)) ; Line
5396 (number-to-string (1- (elt elt
1))) ; Char pos 0-based
5398 (if (and (string-match "^[_a-zA-Z]+::" (car elt
))
5399 (string-match "^sub[ \t]+\\([_a-zA-Z]+\\)[^:_a-zA-Z]"
5401 ;; Need to insert the name without package as well
5402 (setq lst
(cons (cons (substring (elt elt
3)
5410 ;; On case-preserving filesystems (EMX on OS/2) case might be encoded in properties
5411 (set-text-properties 0 (length rel
) nil rel
)
5412 (and (equal topdir
(substring rel
0 (length topdir
)))
5413 (setq rel
(substring file
(length topdir
))))
5414 (insert "\f\n" rel
"," (number-to-string (1- pos
)) "\n")
5415 (setq ret
(buffer-substring 1 (point-max)))
5418 (message "Scanning file %s finished" file
))
5421 (defun cperl-add-tags-recurse-noxs ()
5422 "Add to TAGS data for Perl and XSUB files in the current directory and kids.
5424 emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
5425 -f cperl-add-tags-recurse
5427 (cperl-write-tags nil nil t t nil t
))
5429 (defun cperl-add-tags-recurse ()
5430 "Add to TAGS file data for Perl files in the current directory and kids.
5432 emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
5433 -f cperl-add-tags-recurse
5435 (cperl-write-tags nil nil t t
))
5437 (defun cperl-write-tags (&optional file erase recurse dir inbuffer noxs topdir
)
5438 ;; If INBUFFER, do not select buffer, and do not save
5439 ;; If ERASE is `ignore', do not erase, and do not try to delete old info.
5442 (setq file
(if dir default-directory
(buffer-file-name)))
5443 (if (and (not dir
) (buffer-modified-p)) (error "Save buffer first!")))
5445 (setq topdir default-directory
))
5446 (let ((tags-file-name "TAGS")
5447 (case-fold-search (eq system-type
'emx
))
5450 (cond (inbuffer nil
) ; Already there
5451 ((file-exists-p tags-file-name
)
5453 (visit-tags-table-buffer)
5454 (visit-tags-table-buffer tags-file-name
)))
5455 (t (set-buffer (find-file-noselect tags-file-name
))))
5458 (cond ((eq erase
'ignore
))
5461 (setq erase
'ignore
)))
5463 (directory-files file t
5464 (if recurse nil cperl-scan-files-regexp
)
5466 (mapcar (function (lambda (file)
5468 ((string-match cperl-noscan-files-regexp file
)
5470 ((not (file-directory-p file
))
5471 (if (string-match cperl-scan-files-regexp file
)
5472 (cperl-write-tags file erase recurse nil t noxs topdir
)))
5474 (t (cperl-write-tags file erase recurse t t noxs topdir
)))))
5478 (setq xs
(string-match "\\.xs$" file
))
5479 (if (not (and xs noxs
))
5481 (cond ((eq erase
'ignore
) (goto-char (point-max)))
5482 (erase (erase-buffer))
5486 ;; On case-preserving filesystems (EMX on OS/2) case might be encoded in properties
5487 (set-text-properties 0 (length rel
) nil rel
)
5488 (and (equal topdir
(substring rel
0 (length topdir
)))
5489 (setq rel
(substring file
(length topdir
))))
5490 (if (search-forward (concat "\f\n" rel
",") nil t
)
5492 (search-backward "\f\n")
5493 (delete-region (point)
5496 (if (search-forward "\f\n"
5500 (goto-char (point-max)))))
5501 (insert (cperl-find-tags file xs topdir
))))))
5502 (if inbuffer nil
; Delegate to the caller
5503 (save-buffer 0) ; No backup
5504 (if (fboundp 'initialize-new-tags-table
) ; Do we need something special in XEmacs?
5505 (initialize-new-tags-table))))))
5507 (defvar cperl-tags-hier-regexp-list
5514 "[a-zA-Z_][a-zA-Z_0-9:]*(\C-?[^\n]+::" ; XSUB?
5516 "[ \t]*BOOT:\C-?[^\n]+::" ; BOOT section
5519 (defvar cperl-hierarchy
'(() ())
5520 "Global hierarchy of classes")
5522 (defun cperl-tags-hier-fill ()
5523 ;; Suppose we are in a tag table cooked by cperl.
5525 (let (type pack name pos line chunk ord cons1 file str info fileind
)
5526 (while (re-search-forward cperl-tags-hier-regexp-list nil t
)
5527 (setq pos
(match-beginning 0)
5528 pack
(match-beginning 2))
5530 (if (looking-at (concat
5539 (setq ;;str (buffer-substring (match-beginning 1) (match-end 1))
5540 name
(buffer-substring (match-beginning 2) (match-end 2))
5541 ;;pos (buffer-substring (match-beginning 3) (match-end 3))
5542 line
(buffer-substring (match-beginning 3) (match-end 3))
5545 fileind
(format "%s:%s" file line
)
5546 ;; Moves to beginning of the next line:
5547 info
(cperl-etags-snarf-tag file line
))
5550 ;; Make new member of hierarchy name ==> file ==> pos if needed
5551 (if (setq cons1
(assoc name
(nth ord cperl-hierarchy
)))
5553 (setcdr cons1
(cons (cons fileind
(vector file info
))
5555 ;; First occurrence of the name, start alist
5556 (setq cons1
(cons name
(list (cons fileind
(vector file info
)))))
5558 (setcar (cdr cperl-hierarchy
)
5559 (cons cons1
(nth 1 cperl-hierarchy
)))
5560 (setcar cperl-hierarchy
5561 (cons cons1
(car cperl-hierarchy
)))))))
5564 (defun cperl-tags-hier-init (&optional update
)
5565 "Show hierarchical menu of classes and methods.
5566 Finds info about classes by a scan of loaded TAGS files.
5567 Supposes that the TAGS files contain fully qualified function names.
5568 One may build such TAGS files from CPerl mode menu."
5572 (if (or update
(null (nth 2 cperl-hierarchy
)))
5573 (let (pack name cons1 to l1 l2 l3 l4 b
5574 (remover (function (lambda (elt) ; (name (file1...) (file2..))
5577 (setcdr elt
(cdr (nth 1 elt
))))))))
5578 ;; (setq cperl-hierarchy '(() () ())) ; Would write into '() later!
5579 (setq cperl-hierarchy
(list l1 l2 l3
))
5580 (if cperl-xemacs-p
; Not checked
5583 ;; Does this work in XEmacs?
5584 (call-interactively 'visit-tags-table
))
5585 (message "Updating list of classes...")
5586 (set-buffer (get-file-buffer tags-file-name
))
5587 (cperl-tags-hier-fill))
5589 (call-interactively 'visit-tags-table
))
5593 (message "Updating list of classes... %s" tagsfile
)
5594 (set-buffer (get-file-buffer tagsfile
))
5595 (cperl-tags-hier-fill)))
5597 (message "Updating list of classes... postprocessing..."))
5598 (mapcar remover
(car cperl-hierarchy
))
5599 (mapcar remover
(nth 1 cperl-hierarchy
))
5600 (setq to
(list nil
(cons "Packages: " (nth 1 cperl-hierarchy
))
5601 (cons "Methods: " (car cperl-hierarchy
))))
5602 (cperl-tags-treeify to
1)
5603 (setcar (nthcdr 2 cperl-hierarchy
)
5604 (cperl-menu-to-keymap (cons '("+++UPDATE+++" . -
999) (cdr to
))))
5605 (message "Updating list of classes: done, requesting display...")
5606 ;;(cperl-imenu-addback (nth 2 cperl-hierarchy))
5608 (or (nth 2 cperl-hierarchy
)
5609 (error "No items found"))
5611 ;;; (imenu-choose-buffer-index "Packages: " (nth 2 cperl-hierarchy))
5613 (x-popup-menu t
(nth 2 cperl-hierarchy
))
5615 (tmm-prompt (nth 2 cperl-hierarchy
))))
5616 (if (and update
(listp update
))
5617 (progn (while (cdr update
) (setq update
(cdr update
)))
5618 (setq update
(car update
)))) ; Get the last from the list
5619 (if (vectorp update
)
5621 (find-file (elt update
0))
5622 (cperl-etags-goto-tag-location (elt update
1))))
5623 (if (eq update -
999) (cperl-tags-hier-init t
)))
5625 (defun cperl-tags-treeify (to level
)
5626 ;; cadr of `to' is read-write. On start it is a cons
5627 (let* ((regexp (concat "^\\(" (mapconcat
5629 (make-list level
"[_a-zA-Z0-9]+")
5632 (packages (cdr (nth 1 to
)))
5633 (methods (cdr (nth 2 to
)))
5634 l1 head tail cons1 cons2 ord writeto packs recurse
5635 root-packages root-functions ms many_ms same_name ps
5639 (cond ((and (string-match regexp
(car elt
))
5640 (or (eq ord
1) (match-end 2)))
5641 (setq head
(substring (car elt
) 0 (match-end 1))
5642 tail
(if (match-end 2) (substring (car elt
)
5645 (if (setq cons1
(assoc head writeto
)) nil
5646 ;; Need to init new head
5647 (setcdr writeto
(cons (list head
(list "Packages: ")
5650 (setq cons1
(nth 1 writeto
)))
5651 (setq cons2
(nth ord cons1
)) ; Either packs or meths
5652 (setcdr cons2
(cons elt
(cdr cons2
))))
5654 (setq root-functions
(cons elt root-functions
)))
5656 (setq root-packages
(cons elt root-packages
))))))))
5657 (setcdr to l1
) ; Init to dynamic space
5660 (mapcar move-deeper packages
)
5662 (mapcar move-deeper methods
)
5664 (mapcar (function (lambda (elt)
5665 (cperl-tags-treeify elt
(1+ level
))))
5667 ;;Now clean up leaders with one child only
5668 (mapcar (function (lambda (elt)
5669 (if (not (and (listp (cdr elt
))
5670 (eq (length elt
) 2))) nil
5671 (setcar elt
(car (nth 1 elt
)))
5672 (setcdr elt
(cdr (nth 1 elt
))))))
5674 ;; Sort the roots of subtrees
5675 (if (default-value 'imenu-sort-function
)
5677 (sort (cdr to
) (default-value 'imenu-sort-function
))))
5678 ;; Now add back functions removed from display
5679 (mapcar (function (lambda (elt)
5680 (setcdr to
(cons elt
(cdr to
)))))
5681 (if (default-value 'imenu-sort-function
)
5683 (sort root-functions
(default-value 'imenu-sort-function
)))
5685 ;; Now add back packages removed from display
5686 (mapcar (function (lambda (elt)
5687 (setcdr to
(cons (cons (concat "package " (car elt
))
5690 (if (default-value 'imenu-sort-function
)
5692 (sort root-packages
(default-value 'imenu-sort-function
)))
5697 ;;; '(keymap "Name1"
5701 ;;; ("Tail1" "x") ("Tail2" "y"))))
5703 (defun cperl-list-fold (list name limit
)
5704 (let (list1 list2 elt1
(num 0))
5705 (if (<= (length list
) limit
) list
5706 (setq list1 nil list2 nil
)
5711 (if (<= num imenu-max-items
)
5712 (setq list2
(cons elt1 list2
))
5713 (setq list1
(cons (cons name
5718 (nreverse (cons (cons name
5722 (defun cperl-menu-to-keymap (menu &optional name
)
5728 (cond ((listp (cdr elt
))
5729 (setq list
(cperl-list-fold
5730 (cdr elt
) (car elt
) imenu-max-items
))
5733 (cperl-menu-to-keymap list
))))
5735 (list (cdr elt
) (car elt
) t
))))) ; t is needed in 19.34
5736 (cperl-list-fold menu
"Root" imenu-max-items
)))))
5739 (defvar cperl-bad-style-regexp
5740 (mapconcat 'identity
5741 '("[^-\n\t <>=+!.&|(*/'`\"#^][-=+<>!|&^]" ; char sign
5742 "[-<>=+^&|]+[^- \t\n=+<>~]" ; sign+ char
5745 "Finds places such that insertion of a whitespace may help a lot.")
5747 (defvar cperl-not-bad-style-regexp
5748 (mapconcat 'identity
5749 '("[^-\t <>=+]\\(--\\|\\+\\+\\)" ; var-- var++
5750 "[a-zA-Z0-9_][|&][a-zA-Z0-9_$]" ; abc|def abc&def are often used.
5751 "&[(a-zA-Z0-9_$]" ; &subroutine &(var->field)
5752 "<\\$?\\sw+\\(\\.\\sw+\\)?>" ; <IN> <stdin.h>
5753 "-[a-zA-Z][ \t]+[_$\"'`a-zA-Z]" ; -f file, -t STDIN
5760 "\\\\[&$@*\\\\]" ; \&func
5763 "<<[a-zA-Z_'\"`]" ; <<FOO, <<'FOO'
5766 "[CBIXSLFZ]<\\(\\sw\\|\\s \\|\\s_\\|[\n]\\)*>" ; C<code like text>
5767 "-[a-zA-Z_0-9]+[ \t]*=>" ; -option => value
5768 ;; Unaddressed trouble spots: = -abc, f(56, -abc) --- specialcased below
5772 "If matches at the start of match found by `my-bad-c-style-regexp',
5773 insertion of a whitespace will not help.")
5777 (defun cperl-find-bad-style ()
5778 "Find places in the buffer where insertion of a whitespace may help.
5779 Prompts user for insertion of spaces.
5780 Currently it is tuned to C and Perl syntax."
5782 (let (found-bad (p (point)))
5783 (setq last-nonmenu-event
13) ; To disable popup
5784 (beginning-of-buffer)
5785 (map-y-or-n-p "Insert space here? "
5786 (function (lambda (arg) (insert " ")))
5787 'cperl-next-bad-style
5788 '("location" "locations" "insert a space into")
5789 '((?\C-r
(lambda (arg)
5790 (let ((buffer-quit-function
5791 'exit-recursive-edit
))
5792 (message "Exit with Esc Esc")
5794 t
)) ; Consider acted upon
5795 "edit, exit with Esc Esc")
5797 (let ((buffer-quit-function
5798 'exit-recursive-edit
))
5799 (message "Exit with Esc Esc")
5801 t
)) ; Consider acted upon
5802 "edit, exit with Esc Esc"))
5804 (if found-bad
(goto-char found-bad
)
5806 (message "No appropriate place found"))))
5808 (defun cperl-next-bad-style ()
5809 (let (p (not-found t
) (point (point)) found
)
5810 (while (and not-found
5811 (re-search-forward cperl-bad-style-regexp nil
'to-end
))
5813 (goto-char (match-beginning 0))
5815 (looking-at cperl-not-bad-style-regexp
)
5816 ;; Check for a < -b and friends
5817 (and (eq (following-char) ?\-
)
5819 (skip-chars-backward " \t\n")
5820 (memq (preceding-char) '(?\
= ?\
> ?\
< ?\
, ?\
(, ?\
[, ?\
{))))
5821 ;; Now check for syntax type
5823 (setq found
(point))
5824 (beginning-of-defun)
5825 (let ((pps (parse-partial-sexp (point) found
)))
5826 (or (nth 3 pps
) (nth 4 pps
) (nth 5 pps
)))))
5827 (goto-char (match-end 0))
5835 (defvar cperl-have-help-regexp
5839 '("[$@%*&][0-9a-zA-Z_:]+\\([ \t]*[[{]\\)?" ; Usual variable
5840 "[$@]\\^[a-zA-Z]" ; Special variable
5841 "[$@][^ \n\t]" ; Special variable
5842 "-[a-zA-Z]" ; File test
5843 "\\\\[a-zA-Z0]" ; Special chars
5844 "^=[a-z][a-zA-Z0-9_]*" ; Pod sections
5845 "[-!&*+,-./<=>?\\\\^|~]+" ; Operator
5846 "[a-zA-Z_0-9:]+" ; symbol or number
5855 "Matches places in the buffer we can find help for.")
5857 (defvar cperl-message-on-help-error t
)
5858 (defvar cperl-help-from-timer nil
)
5860 (defun cperl-word-at-point-hard ()
5861 ;; Does not save-excursion
5862 ;; Get to the something meaningful
5863 (or (eobp) (eolp) (forward-char 1))
5864 (re-search-backward "[-a-zA-Z0-9_:!&*+,-./<=>?\\\\^|~$%@]"
5865 (save-excursion (beginning-of-line) (point))
5868 ;; ((or (eobp) (looking-at "[][ \t\n{}();,]")) ; Not at a symbol
5869 ;; (skip-chars-backward " \n\t\r({[]});,")
5870 ;; (or (bobp) (backward-char 1))))
5873 ((looking-at "[a-zA-Z0-9_:]") ; symbol
5874 (skip-chars-backward "a-zA-Z0-9_:")
5876 ((and (eq (preceding-char) ?^
) ; $^I
5877 (eq (char-after (- (point) 2)) ?\$
))
5879 ((memq (preceding-char) (append "*$@%&\\" nil
)) ; *glob
5881 ((and (eq (preceding-char) ?\
=)
5882 (eq (current-column) 1))
5883 (forward-char -
1))) ; =head1
5884 (if (and (eq (preceding-char) ?\
<)
5885 (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <FH>
5887 ((and (looking-at "=") (eq (preceding-char) ?x
)) ; x=
5889 ((and (looking-at "\\^") (eq (preceding-char) ?\$
)) ; $^I
5891 ((looking-at "[-!&*+,-./<=>?\\\\^|~]")
5892 (skip-chars-backward "-!&*+,-./<=>?\\\\^|~")
5894 ((and (eq (preceding-char) ?\$
)
5895 (not (eq (char-after (- (point) 2)) ?\$
))) ; $-
5897 ((and (eq (following-char) ?\
>)
5898 (string-match "[a-zA-Z0-9_]" (char-to-string (preceding-char)))
5901 (and (eq (preceding-char) ?\
<)
5902 (looking-at "\\$?[a-zA-Z0-9_:]+>")))) ; <FH>
5903 (search-backward "<"))))
5904 ((and (eq (following-char) ?\$
)
5905 (eq (preceding-char) ?\
<)
5906 (looking-at "\\$?[a-zA-Z0-9_:]+>")) ; <$fh>
5908 (if (looking-at cperl-have-help-regexp
)
5909 (buffer-substring (match-beginning 0) (match-end 0))))
5911 (defun cperl-get-help ()
5912 "Get one-line docs on the symbol at the point.
5913 The data for these docs is a little bit obsolete and may be in fact longer
5914 than a line. Your contribution to update/shorten it is appreciated."
5916 (save-match-data ; May be called "inside" query-replace
5918 (let ((word (cperl-word-at-point-hard)))
5920 (if (and cperl-help-from-timer
; Bail out if not in mainland
5921 (not (string-match "^#!\\|\\\\\\|^=" word
)) ; Show help even in comments/strings.
5922 (or (memq (get-text-property (point) 'face
)
5923 '(font-lock-comment-face font-lock-string-face
))
5924 (memq (get-text-property (point) 'syntax-type
)
5925 '(pod here-doc format
))))
5927 (cperl-describe-perl-symbol word
))
5928 (if cperl-message-on-help-error
5929 (message "Nothing found for %s..."
5930 (buffer-substring (point) (min (+ 5 (point)) (point-max))))))))))
5932 ;;; Stolen from perl-descr.el by Johan Vromans:
5934 (defvar cperl-doc-buffer
" *perl-doc*"
5935 "Where the documentation can be found.")
5937 (defun cperl-describe-perl-symbol (val)
5938 "Display the documentation of symbol at point, a Perl operator."
5939 (let ((enable-recursive-minibuffers t
)
5942 ((string-match "^[&*][a-zA-Z_]" val
)
5943 (setq val
(concat (substring val
0 1) "NAME")))
5944 ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*\\[" val
)
5945 (setq val
(concat "@" (substring val
1 (match-end 1)))))
5946 ((string-match "^[$@]\\([a-zA-Z_:0-9]+\\)[ \t]*{" val
)
5947 (setq val
(concat "%" (substring val
1 (match-end 1)))))
5948 ((and (string= val
"x") (string-match "^x=" val
))
5950 ((string-match "^\\$[\C-a-\C-z]" val
)
5951 (setq val
(concat "$^" (char-to-string (+ ?A -
1 (aref val
1))))))
5952 ((string-match "^CORE::" val
)
5953 (setq val
"CORE::"))
5954 ((string-match "^SUPER::" val
)
5955 (setq val
"SUPER::"))
5956 ((and (string= "<" val
) (string-match "^<\\$?[a-zA-Z0-9_:]+>" val
))
5957 (setq val
"<NAME>")))
5958 (setq regexp
(concat "^"
5959 "\\([^a-zA-Z0-9_:]+[ \t]+\\)?"
5961 "\\([ \t([/]\\|$\\)"))
5963 ;; get the buffer with the documentation text
5964 (cperl-switch-to-doc-buffer)
5966 ;; lookup in the doc
5967 (goto-char (point-min))
5968 (let ((case-fold-search nil
))
5970 (if (re-search-forward regexp
(point-max) t
)
5972 (beginning-of-line 1)
5973 (let ((lnstart (point)))
5975 (message "%s" (buffer-substring lnstart
(point)))))
5976 (if cperl-message-on-help-error
5977 (message "No definition for %s" val
)))))))
5979 (defvar cperl-short-docs
"Ignore my value"
5980 ;; Perl4 version was written by Johan Vromans (jvromans@squirrel.nl)
5981 "# based on '@(#)@ perl-descr.el 1.9 - describe-perl-symbol' [Perl 5]
5982 ! ... Logical negation.
5983 ... != ... Numeric inequality.
5984 ... !~ ... Search pattern, substitution, or translation (negated).
5985 $! In numeric context: errno. In a string context: error string.
5986 $\" The separator which joins elements of arrays interpolated in strings.
5987 $# The output format for printed numbers. Initial value is %.15g or close.
5988 $$ Process number of this script. Changes in the fork()ed child process.
5989 $% The current page number of the currently selected output channel.
5991 The following variables are always local to the current block:
5993 $1 Match of the 1st set of parentheses in the last match (auto-local).
5994 $2 Match of the 2nd set of parentheses in the last match (auto-local).
5995 $3 Match of the 3rd set of parentheses in the last match (auto-local).
5996 $4 Match of the 4th set of parentheses in the last match (auto-local).
5997 $5 Match of the 5th set of parentheses in the last match (auto-local).
5998 $6 Match of the 6th set of parentheses in the last match (auto-local).
5999 $7 Match of the 7th set of parentheses in the last match (auto-local).
6000 $8 Match of the 8th set of parentheses in the last match (auto-local).
6001 $9 Match of the 9th set of parentheses in the last match (auto-local).
6002 $& The string matched by the last pattern match (auto-local).
6003 $' The string after what was matched by the last match (auto-local).
6004 $` The string before what was matched by the last match (auto-local).
6006 $( The real gid of this process.
6007 $) The effective gid of this process.
6008 $* Deprecated: Set to 1 to do multiline matching within a string.
6009 $+ The last bracket matched by the last search pattern.
6010 $, The output field separator for the print operator.
6011 $- The number of lines left on the page.
6012 $. The current input line number of the last filehandle that was read.
6013 $/ The input record separator, newline by default.
6014 $0 Name of the file containing the perl script being executed. May be set.
6015 $: String may be broken after these characters to fill ^-lines in a format.
6016 $; Subscript separator for multi-dim array emulation. Default \"\\034\".
6017 $< The real uid of this process.
6018 $= The page length of the current output channel. Default is 60 lines.
6019 $> The effective uid of this process.
6020 $? The status returned by the last ``, pipe close or `system'.
6021 $@ The perl error message from the last eval or do @var{EXPR} command.
6022 $ARGV The name of the current file used with <> .
6023 $[ Deprecated: The index of the first element/char in an array/string.
6024 $\\ The output record separator for the print operator.
6025 $] The perl version string as displayed with perl -v.
6026 $^ The name of the current top-of-page format.
6027 $^A The current value of the write() accumulator for format() lines.
6028 $^D The value of the perl debug (-D) flags.
6029 $^E Information about the last system error other than that provided by $!.
6030 $^F The highest system file descriptor, ordinarily 2.
6031 $^H The current set of syntax checks enabled by `use strict'.
6032 $^I The value of the in-place edit extension (perl -i option).
6033 $^L What formats output to perform a formfeed. Default is \f.
6034 $^M A buffer for emergency memory allocation when running out of memory.
6035 $^O The operating system name under which this copy of Perl was built.
6036 $^P Internal debugging flag.
6037 $^T The time the script was started. Used by -A/-M/-C file tests.
6038 $^W True if warnings are requested (perl -w flag).
6039 $^X The name under which perl was invoked (argv[0] in C-speech).
6040 $_ The default input and pattern-searching space.
6041 $| Auto-flush after write/print on current output channel? Default 0.
6042 $~ The name of the current report format.
6043 ... % ... Modulo division.
6044 ... %= ... Modulo division assignment.
6045 %ENV Contains the current environment.
6046 %INC List of files that have been require-d or do-ne.
6047 %SIG Used to set signal handlers for various signals.
6048 ... & ... Bitwise and.
6049 ... && ... Logical and.
6050 ... &&= ... Logical and assignment.
6051 ... &= ... Bitwise and assignment.
6052 ... * ... Multiplication.
6053 ... ** ... Exponentiation.
6054 *NAME Glob: all objects refered by NAME. *NAM1 = *NAM2 aliases NAM1 to NAM2.
6055 &NAME(arg0, ...) Subroutine call. Arguments go to @_.
6056 ... + ... Addition. +EXPR Makes EXPR into scalar context.
6057 ++ Auto-increment (magical on strings). ++EXPR EXPR++
6058 ... += ... Addition assignment.
6060 ... - ... Subtraction.
6061 -- Auto-decrement (NOT magical on strings). --EXPR EXPR--
6062 ... -= ... Subtraction assignment.
6063 -A Access time in days since script started.
6064 -B File is a non-text (binary) file.
6065 -C Inode change time in days since script started.
6066 -M Age in days since script started.
6067 -O File is owned by real uid.
6068 -R File is readable by real uid.
6069 -S File is a socket .
6070 -T File is a text file.
6071 -W File is writable by real uid.
6072 -X File is executable by real uid.
6073 -b File is a block special file.
6074 -c File is a character special file.
6075 -d File is a directory.
6077 -f File is a plain file.
6078 -g File has setgid bit set.
6079 -k File has sticky bit set.
6080 -l File is a symbolic link.
6081 -o File is owned by effective uid.
6082 -p File is a named pipe (FIFO).
6083 -r File is readable by effective uid.
6084 -s File has non-zero size.
6085 -t Tests if filehandle (STDIN by default) is opened to a tty.
6086 -u File has setuid bit set.
6087 -w File is writable by effective uid.
6088 -x File is executable by effective uid.
6089 -z File has zero size.
6090 . Concatenate strings.
6091 .. Alternation, also range operator.
6092 .= Concatenate assignment strings
6093 ... / ... Division. /PATTERN/ioxsmg Pattern match
6094 ... /= ... Division assignment.
6095 /PATTERN/ioxsmg Pattern match.
6096 ... < ... Numeric less than. <pattern> Glob. See <NAME>, <> as well.
6097 <NAME> Reads line from filehandle NAME (a bareword or dollar-bareword).
6098 <pattern> Glob (Unless pattern is bareword/dollar-bareword - see <NAME>).
6099 <> Reads line from union of files in @ARGV (= command line) and STDIN.
6100 ... << ... Bitwise shift left. << start of HERE-DOCUMENT.
6101 ... <= ... Numeric less than or equal to.
6102 ... <=> ... Numeric compare.
6103 ... = ... Assignment.
6104 ... == ... Numeric equality.
6105 ... =~ ... Search pattern, substitution, or translation
6106 ... > ... Numeric greater than.
6107 ... >= ... Numeric greater than or equal to.
6108 ... >> ... Bitwise shift right.
6109 ... >>= ... Bitwise shift right assignment.
6110 ... ? ... : ... Condition=if-then-else operator. ?PAT? One-time pattern match.
6111 ?PATTERN? One-time pattern match.
6112 @ARGV Command line arguments (not including the command name - see $0).
6113 @INC List of places to look for perl scripts during do/include/use.
6114 @_ Parameter array for subroutines. Also used by split unless in array context.
6115 \\ Creates reference to what follows, like \$var, or quotes non-\w in strings.
6116 \\0 Octal char, e.g. \\033.
6117 \\E Case modification terminator. See \\Q, \\L, and \\U.
6118 \\L Lowercase until \\E . See also \l, lc.
6119 \\U Upcase until \\E . See also \u, uc.
6120 \\Q Quote metacharacters until \\E . See also quotemeta.
6121 \\a Alarm character (octal 007).
6122 \\b Backspace character (octal 010).
6123 \\c Control character, e.g. \\c[ .
6124 \\e Escape character (octal 033).
6125 \\f Formfeed character (octal 014).
6126 \\l Lowercase the next character. See also \\L and \\u, lcfirst.
6127 \\n Newline character (octal 012 on most systems).
6128 \\r Return character (octal 015 on most systems).
6129 \\t Tab character (octal 011).
6130 \\u Upcase the next character. See also \\U and \\l, ucfirst.
6131 \\x Hex character, e.g. \\x1b.
6132 ... ^ ... Bitwise exclusive or.
6133 __END__ Ends program source.
6134 __DATA__ Ends program source.
6135 __FILE__ Current (source) filename.
6136 __LINE__ Current line in current source.
6137 __PACKAGE__ Current package.
6138 ARGV Default multi-file input filehandle. <ARGV> is a synonym for <>.
6139 ARGVOUT Output filehandle with -i flag.
6140 BEGIN { ... } Immediately executed (during compilation) piece of code.
6141 END { ... } Pseudo-subroutine executed after the script finishes.
6142 DATA Input filehandle for what follows after __END__ or __DATA__.
6143 accept(NEWSOCKET,GENERICSOCKET)
6156 ... cmp ... String compare.
6157 connect(SOCKET,NAME)
6158 continue of { block } continue { block }. Is executed after `next' or at end.
6160 crypt(PLAINTEXT,SALT)
6162 dbmopen(%HASH,DBNAME,MODE)
6166 do { ... }|SUBR while|until EXPR executes at least once
6167 do(EXPR|SUBR([LIST])) (with while|until executes at least once)
6177 ... eq ... String equality.
6178 eval(EXPR) or eval { BLOCK }
6182 fcntl(FILEHANDLE,FUNCTION,SCALAR)
6184 flock(FILEHANDLE,OPERATION)
6185 for (EXPR;EXPR;EXPR) { ... }
6186 foreach [VAR] (@ARRAY) { ... }
6188 ... ge ... String greater than or equal.
6193 gethostbyaddr(ADDR,ADDRTYPE)
6197 getnetbyaddr(ADDR,ADDRTYPE)
6203 getpriority(WHICH,WHO)
6204 getprotobyname(NAME)
6205 getprotobynumber(NUMBER)
6210 getservbyname(NAME,PROTO)
6211 getservbyport(PORT,PROTO)
6214 getsockopt(SOCKET,LEVEL,OPTNAME)
6217 ... gt ... String greater than.
6219 if (EXPR) { ... } [ elsif (EXPR) { ... } ... ] [ else { ... } ] or EXPR if EXPR
6220 index(STR,SUBSTR[,OFFSET])
6222 ioctl(FILEHANDLE,FUNCTION,SCALAR)
6227 ... le ... String less than or equal.
6229 link(OLDFILE,NEWFILE)
6230 listen(SOCKET,QUEUESIZE)
6234 lstat(EXPR|FILEHANDLE|VAR)
6235 ... lt ... String less than.
6237 mkdir(FILENAME,MODE)
6240 msgrcv(ID,VAR,SIZE,TYPE.FLAGS)
6241 msgsnd(ID,MSG,FLAGS)
6242 my VAR or my (VAR1,...) Introduces a lexical variable ($VAR, @ARR, or %HASH).
6243 ... ne ... String inequality.
6246 open(FILEHANDLE[,EXPR])
6247 opendir(DIRHANDLE,EXPR)
6248 ord(EXPR) ASCII value of the first char of the string.
6250 package NAME Introduces package context.
6251 pipe(READHANDLE,WRITEHANDLE) Create a pair of filehandles on ends of a pipe.
6253 print [FILEHANDLE] [(LIST)]
6254 printf [FILEHANDLE] (FORMAT,LIST)
6256 q/STRING/ Synonym for 'STRING'
6257 qq/STRING/ Synonym for \"STRING\"
6258 qx/STRING/ Synonym for `STRING`
6260 read(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
6263 recv(SOCKET,SCALAR,LEN,FLAGS)
6265 rename(OLDNAME,NEWNAME)
6266 require [FILENAME | PERL_VERSION]
6270 rewinddir(DIRHANDLE)
6271 rindex(STR,SUBSTR[,OFFSET])
6273 s/PATTERN/REPLACEMENT/gieoxsm
6275 seek(FILEHANDLE,POSITION,WHENCE)
6276 seekdir(DIRHANDLE,POS)
6277 select(FILEHANDLE | RBITS,WBITS,EBITS,TIMEOUT)
6278 semctl(ID,SEMNUM,CMD,ARG)
6279 semget(KEY,NSEMS,SIZE,FLAGS)
6281 send(SOCKET,MSG,FLAGS[,TO])
6283 sethostent(STAYOPEN)
6286 setpriority(WHICH,WHO,PRIORITY)
6287 setprotoent(STAYOPEN)
6289 setservent(STAYOPEN)
6290 setsockopt(SOCKET,LEVEL,OPTNAME,OPTVAL)
6293 shmget(KEY,SIZE,FLAGS)
6294 shmread(ID,VAR,POS,SIZE)
6295 shmwrite(ID,STRING,POS,SIZE)
6296 shutdown(SOCKET,HOW)
6299 socket(SOCKET,DOMAIN,TYPE,PROTOCOL)
6300 socketpair(SOCKET1,SOCKET2,DOMAIN,TYPE,PROTOCOL)
6301 sort [SUBROUTINE] (LIST)
6302 splice(ARRAY,OFFSET[,LENGTH[,LIST]])
6303 split[(/PATTERN/[,EXPR[,LIMIT]])]
6304 sprintf(FORMAT,LIST)
6307 stat(EXPR|FILEHANDLE|VAR)
6309 sub [NAME [(format)]] { BODY } sub NAME [(format)]; sub [(format)] {...}
6310 substr(EXPR,OFFSET[,LEN])
6311 symlink(OLDFILE,NEWFILE)
6313 sysread(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
6315 syswrite(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
6320 tr/SEARCHLIST/REPLACEMENTLIST/cds
6321 truncate(FILE|EXPR,LENGTH)
6324 unless (EXPR) { ... } [ else { ... } ] or EXPR unless EXPR
6326 unpack(TEMPLATE,EXPR)
6328 until (EXPR) { ... } EXPR until EXPR
6331 vec(EXPR,OFFSET,BITS)
6334 wantarray Returns true if the sub/eval is called in list context.
6336 while (EXPR) { ... } EXPR while EXPR
6337 write[(EXPR|FILEHANDLE)]
6338 ... x ... Repeat string or array.
6339 x= ... Repetition assignment.
6340 y/SEARCHLIST/REPLACEMENTLIST/
6341 ... | ... Bitwise or.
6342 ... || ... Logical or.
6343 ~ ... Unary bitwise complement.
6344 #! OS interpreter indicator. If contains `perl', used for options, and -x.
6345 AUTOLOAD {...} Shorthand for `sub AUTOLOAD {...}'.
6346 CORE:: Prefix to access builtin function if imported sub obscures it.
6347 SUPER:: Prefix to lookup for a method in @ISA classes.
6348 DESTROY Shorthand for `sub DESTROY {...}'.
6349 ... EQ ... Obsolete synonym of `eq'.
6350 ... GE ... Obsolete synonym of `ge'.
6351 ... GT ... Obsolete synonym of `gt'.
6352 ... LE ... Obsolete synonym of `le'.
6353 ... LT ... Obsolete synonym of `lt'.
6354 ... NE ... Obsolete synonym of `ne'.
6355 abs [ EXPR ] absolute value
6356 ... and ... Low-precedence synonym for &&.
6357 bless REFERENCE [, PACKAGE] Makes reference into an object of a package.
6358 chomp [LIST] Strips $/ off LIST/$_. Returns count. Special if $/ eq ''!
6359 chr Converts a number to char with the same ordinal.
6360 else Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
6361 elsif Part of if/unless {BLOCK} elsif {BLOCK} else {BLOCK}.
6362 exists $HASH{KEY} True if the key exists.
6363 format [NAME] = Start of output format. Ended by a single dot (.) on a line.
6364 formline PICTURE, LIST Backdoor into \"format\" processing.
6365 glob EXPR Synonym of <EXPR>.
6366 lc [ EXPR ] Returns lowercased EXPR.
6367 lcfirst [ EXPR ] Returns EXPR with lower-cased first letter.
6368 grep EXPR,LIST or grep {BLOCK} LIST Filters LIST via EXPR/BLOCK.
6369 map EXPR, LIST or map {BLOCK} LIST Applies EXPR/BLOCK to elts of LIST.
6370 no PACKAGE [SYMBOL1, ...] Partial reverse for `use'. Runs `unimport' method.
6371 not ... Low-precedence synonym for ! - negation.
6372 ... or ... Low-precedence synonym for ||.
6373 pos STRING Set/Get end-position of the last match over this string, see \\G.
6374 quotemeta [ EXPR ] Quote regexp metacharacters.
6375 qw/WORD1 .../ Synonym of split('', 'WORD1 ...')
6376 readline FH Synonym of <FH>.
6377 readpipe CMD Synonym of `CMD`.
6378 ref [ EXPR ] Type of EXPR when dereferenced.
6379 sysopen FH, FILENAME, MODE [, PERM] (MODE is numeric, see Fcntl.)
6380 tie VAR, PACKAGE, LIST Hide an object behind a simple Perl variable.
6381 tied Returns internal object for a tied data.
6382 uc [ EXPR ] Returns upcased EXPR.
6383 ucfirst [ EXPR ] Returns EXPR with upcased first letter.
6384 untie VAR Unlink an object from a simple Perl variable.
6385 use PACKAGE [SYMBOL1, ...] Compile-time `require' with consequent `import'.
6386 ... xor ... Low-precedence synonym for exclusive or.
6387 prototype \&SUB Returns prototype of the function given a reference.
6388 =head1 Top-level heading.
6389 =head2 Second-level heading.
6390 =head3 Third-level heading (is there such?).
6391 =over [ NUMBER ] Start list.
6392 =item [ TITLE ] Start new item in the list.
6394 =cut Switch from POD to Perl.
6395 =pod Switch from Perl to POD.
6398 (defun cperl-switch-to-doc-buffer ()
6399 "Go to the perl documentation buffer and insert the documentation."
6401 (let ((buf (get-buffer-create cperl-doc-buffer
)))
6403 (switch-to-buffer-other-window buf
)
6405 (if (= (buffer-size) 0)
6407 (insert (documentation-property 'cperl-short-docs
6408 'variable-documentation
))
6409 (setq buffer-read-only t
)))))
6411 (defun cperl-beautify-regexp-piece (b e embed
)
6412 ;; b is before the starting delimiter, e before the ending
6413 ;; e should be a marker, may be changed, but remains "correct".
6414 (let (s c tmp
(m (make-marker)) (m1 (make-marker)) c1 spaces inline code
)
6418 (cond ((looking-at "(\\?\\\\#") ; badly commented (?#)
6422 ((looking-at "(\\?[^a-zA-Z]")
6424 ((looking-at "(\\?") ; (?i)
6428 (setq c
(if embed
(current-indentation) (1- (current-column)))
6429 c1
(+ c
(or cperl-regexp-indent-step cperl-indent-level
)))
6430 (or (looking-at "[ \t]*[\n#]")
6435 (if (re-search-forward "[^ \t]" e t
)
6439 (indent-to-column c
)
6440 (set-marker e
(point))))
6443 (while (< (point) (marker-position e
))
6447 (skip-chars-forward " \t")
6448 (delete-region s
(point))
6449 (indent-to-column c1
)
6453 (concat "\\([a-zA-Z0-9]+[^*+{?]\\)" ; 1 word
6454 "\\|" ; Embedded variable
6455 "\\$\\([a-zA-Z0-9_]+\\([[{]\\)?\\|[^\n \t)|]\\)" ; 2 3
6458 "\\|" ; simple-code simple-code*?
6459 "\\(\\\\.\\|[^][()#|*+?\n]\\)\\([*+{?]\\??\\)?" ; 4 5
6463 "\\((\\(\\?\\)?\\)" ; 7 8
6467 (goto-char (match-end 0))
6469 (cond ((match-beginning 1) ; Alphanum word + junk
6471 ((or (match-beginning 3) ; $ab[12]
6472 (and (match-beginning 5) ; X* X+ X{2,3}
6473 (eq (preceding-char) ?\
{)))
6476 ((match-beginning 6) ; []
6478 (if (looking-at "\\^?\\]")
6479 (goto-char (match-end 0)))
6480 (or (re-search-forward "\\]\\([*+{?]\\)?" e t
)
6482 (goto-char (1- tmp
))
6483 (error "[]-group not terminated")))
6484 (if (not (eq (preceding-char) ?\
{)) nil
6487 ((match-beginning 7) ; ()
6488 (goto-char (match-beginning 0))
6489 (or (eq (current-column) c1
)
6492 (indent-to-column c1
)))
6495 ;; (or (forward-sexp 1)
6498 ;; (error "()-group not terminated")))
6499 (set-marker m
(1- (point)))
6500 (set-marker m1
(point))
6502 ((not (match-beginning 8))
6503 (cperl-beautify-regexp-piece tmp m t
))
6504 ((eq (char-after (+ 2 tmp
)) ?\
{) ; Code
6506 ((eq (char-after (+ 2 tmp
)) ?\
() ; Conditional
6507 (goto-char (+ 2 tmp
))
6509 (cperl-beautify-regexp-piece (point) m t
))
6510 ((eq (char-after (+ 2 tmp
)) ?
<) ; Lookbehind
6511 (goto-char (+ 3 tmp
))
6512 (cperl-beautify-regexp-piece (point) m t
))
6514 (cperl-beautify-regexp-piece tmp m t
)))
6516 (cond ((looking-at "[*+?]\\??")
6517 (goto-char (match-end 0)))
6518 ((eq (following-char) ?\
{)
6520 (if (eq (following-char) ?
\?)
6522 (skip-chars-forward " \t")
6524 (if (looking-at "[#\n]")
6526 (or (eolp) (indent-for-comment))
6527 (beginning-of-line 2))
6531 ((match-beginning 9) ; |
6535 (if (re-search-forward "[^ \t]" tmp t
)
6540 (delete-region (point) tmp
))
6541 (indent-to-column c
)
6543 (skip-chars-forward " \t")
6545 (if (looking-at "[#\n]")
6546 (beginning-of-line 2)
6550 (or (looking-at "[ \t\n]")
6553 (skip-chars-forward " \t"))
6554 (or (looking-at "[#\n]")
6555 (error "unknown code \"%s\" in a regexp" (buffer-substring (point)
6557 (and inline
(end-of-line 2)))
6558 ;; Special-case the last line of group
6559 (if (and (>= (point) (marker-position e
))
6560 (/= (current-indentation) c
))
6564 (skip-chars-forward " \t")
6565 (delete-region s
(point))
6566 (indent-to-column c
)))
6569 (defun cperl-make-regexp-x ()
6570 ;; Returns position of the start
6572 (or cperl-use-syntax-table-text-property
6573 (error "I need to have a regexp marked!"))
6575 (if (looking-at "\\s|")
6577 (if (looking-at "\\([smy]\\|qr\\)\\s|")
6579 (re-search-backward "\\s|"))) ; Assume it is scanned already.
6581 (let ((b (point)) (e (make-marker)) have-x delim
(c (current-column))
6582 (sub-p (eq (preceding-char) ?s
)) s
)
6584 (set-marker e
(1- (point)))
6585 (setq delim
(preceding-char))
6586 (if (and sub-p
(eq delim
(char-after (- (point) 2))))
6587 (error "Possible s/blah// - do not know how to deal with"))
6588 (if sub-p
(forward-sexp 1))
6589 (if (looking-at "\\sw*x")
6592 ;; Protect fragile " ", "#"
6595 (while (re-search-forward "\\(\\=\\|[^\\\\]\\)\\(\\\\\\\\\\)*[ \t\n#]" e t
) ; Need to include (?#) too?
6601 (defun cperl-beautify-regexp ()
6602 "do it. (Experimental, may change semantics, recheck the result.)
6603 We suppose that the regexp is scanned already."
6605 (goto-char (cperl-make-regexp-x))
6606 (let ((b (point)) (e (make-marker)))
6608 (set-marker e
(1- (point)))
6609 (cperl-beautify-regexp-piece b e nil
)))
6611 (defun cperl-regext-to-level-start ()
6612 "Goto start of an enclosing group in regexp.
6613 We suppose that the regexp is scanned already."
6615 (let ((limit (cperl-make-regexp-x)) done
)
6617 (or (eq (following-char) ?\
()
6618 (search-backward "(" (1+ limit
) t
)
6619 (error "Cannot find `(' which starts a group"))
6622 (skip-chars-backward "\\")
6623 (looking-at "\\(\\\\\\\\\\)*(")))
6624 (or done
(forward-char -
1)))))
6626 (defun cperl-contract-level ()
6627 "Find an enclosing group in regexp and contract it.
6628 \(Experimental, may change semantics, recheck the result.)
6629 We suppose that the regexp is scanned already."
6631 (cperl-regext-to-level-start)
6632 (let ((b (point)) (e (make-marker)) s c
)
6634 (set-marker e
(1- (point)))
6636 (while (re-search-forward "\\(#\\)\\|\n" e t
)
6638 ((match-beginning 1) ; #-comment
6639 (or c
(setq c
(current-indentation)))
6640 (beginning-of-line 2) ; Skip
6642 (skip-chars-forward " \t")
6643 (delete-region s
(point))
6644 (indent-to-column c
))
6647 (just-one-space))))))
6649 (defun cperl-contract-levels ()
6650 "Find an enclosing group in regexp and contract all the kids.
6651 \(Experimental, may change semantics, recheck the result.)
6652 We suppose that the regexp is scanned already."
6655 (cperl-regext-to-level-start)
6656 (error ; We are outside outermost group
6657 (goto-char (cperl-make-regexp-x))))
6658 (let ((b (point)) (e (make-marker)) s c
)
6660 (set-marker e
(1- (point)))
6662 (while (re-search-forward "\\(\\\\\\\\\\)\\|(" e t
)
6664 ((match-beginning 1) ; Skip
6667 (cperl-contract-level))))))
6669 (defun cperl-beautify-level ()
6670 "Find an enclosing group in regexp and beautify it.
6671 \(Experimental, may change semantics, recheck the result.)
6672 We suppose that the regexp is scanned already."
6674 (cperl-regext-to-level-start)
6675 (let ((b (point)) (e (make-marker)))
6677 (set-marker e
(1- (point)))
6678 (cperl-beautify-regexp-piece b e nil
)))
6680 (defun cperl-invert-if-unless ()
6681 "Change `if (A) {B}' into `B if A;' if possible."
6683 (or (looking-at "\\<")
6685 (if (looking-at "\\<\\(if\\|unless\\|while\\|until\\)\\>")
6686 (let ((pos1 (point))
6687 pos2 pos3 pos4 pos5 s1 s2 state p pos45
6688 (s0 (buffer-substring (match-beginning 0) (match-end 0))))
6693 (if (eq (following-char) ?\
( )
6700 ;; XXXX In fact may be `A if (B); {C}' ...
6701 (if (and (eq (following-char) ?\
{ )
6703 (cperl-backward-to-noncomment pos3
)
6704 (eq (preceding-char) ?\
) )))
6705 (if (condition-case nil
6710 (looking-at "\\<els\\(e\\|if\\)\\>"))
6713 "`%s' (EXPR) {BLOCK} with `else'/`elsif'" s0
)
6714 (goto-char (1- pos5
))
6715 (cperl-backward-to-noncomment pos4
)
6716 (if (eq (preceding-char) ?\
;)
6718 (setq pos45
(point))
6720 (while (re-search-forward "\\<\\(for\\|foreach\\|if\\|unless\\|while\\|until\\)\\>\\|;" pos45 t
)
6721 (setq p
(match-beginning 0)
6722 s1
(buffer-substring p
(match-end 0))
6723 state
(parse-partial-sexp pos4 p
))
6727 (error "`%s' inside `%s' BLOCK" s1 s0
))
6728 (goto-char (match-end 0)))
6730 (goto-char (1+ pos4
))
6731 (skip-chars-forward " \t\n")
6732 (setq s2
(buffer-substring (point) pos45
))
6734 (or (looking-at ";?[ \t\n]*}")
6736 (skip-chars-forward "; \t\n")
6737 (setq s2
(concat s2
"\n" (buffer-substring (point) (1- pos5
))))))
6740 (goto-char (1- pos3
))
6741 (cperl-backward-to-noncomment pos2
)
6742 (or (looking-at "[ \t\n]*)")
6743 (goto-char (1- pos3
)))
6745 (goto-char (1+ pos2
))
6746 (skip-chars-forward " \t\n")
6747 (setq s1
(buffer-substring (point) p
))
6748 (delete-region pos4 pos5
)
6749 (delete-region pos2 pos3
)
6757 (delete-horizontal-space)
6760 (cperl-indent-line))
6761 (error "`%s' (EXPR) not with an {BLOCK}" s0
)))
6762 (error "`%s' not with an (EXPR)" s0
)))
6763 (error "Not at `if', `unless', `while', or `unless'")))
6765 ;;; By Anthony Foiani <afoiani@uswest.com>
6766 ;;; Getting help on modules in C-h f ?
6767 ;;; This is a modified version of `man'.
6768 ;;; Need to teach it how to lookup functions
6769 (defun cperl-perldoc (word)
6770 "Run `perldoc' on WORD."
6772 (list (let* ((default-entry (cperl-word-at-point))
6774 (format "perldoc entry%s: "
6775 (if (string= default-entry
"")
6777 (format " (default %s)" default-entry
))))))
6778 (if (string= input
"")
6779 (if (string= default-entry
"")
6780 (error "No perldoc args given")
6783 (let* ((is-func (and
6784 (string-match "^[a-z]+$" word
)
6785 (string-match (concat "^" word
"\\>")
6786 (documentation-property
6788 'variable-documentation
))))
6789 (manual-program (if is-func
"perldoc -f" "perldoc")))
6791 (Man-getpage-in-background word
)))
6793 (defun cperl-perldoc-at-point ()
6794 "Run a `perldoc' on the word around point."
6796 (cperl-perldoc (cperl-word-at-point)))
6798 (defcustom pod2man-program
"pod2man"
6799 "*File name for `pod2man'."
6803 ;;; By Nick Roberts <Nick.Roberts@src.bae.co.uk> (with changes)
6804 (defun cperl-pod-to-manpage ()
6805 "Create a virtual manpage in Emacs from the Perl Online Documentation."
6808 (let* ((pod2man-args (concat buffer-file-name
" | nroff -man "))
6809 (bufname (concat "Man " buffer-file-name
))
6810 (buffer (generate-new-buffer bufname
)))
6813 (let ((process-environment (copy-sequence process-environment
)))
6814 ;; Prevent any attempt to use display terminal fanciness.
6815 (setenv "TERM" "dumb")
6816 (set-process-sentinel
6817 (start-process pod2man-program buffer
"sh" "-c"
6818 (format (cperl-pod2man-build-command) pod2man-args
))
6819 'Man-bgproc-sentinel
)))))
6821 (defun cperl-pod2man-build-command ()
6822 "Builds the entire background manpage and cleaning command."
6823 (let ((command (concat pod2man-program
" %s 2>/dev/null"))
6824 (flist Man-filter-list
))
6825 (while (and flist
(car flist
))
6826 (let ((pcom (car (car flist
)))
6827 (pargs (cdr (car flist
))))
6829 (concat command
" | " pcom
" "
6830 (mapconcat '(lambda (phrase)
6831 (if (not (stringp phrase
))
6832 (error "Malformed Man-filter-list"))
6835 (setq flist
(cdr flist
))))
6838 (defun cperl-lazy-install ()) ; Avoid a warning
6840 (if (fboundp 'run-with-idle-timer
)
6842 (defvar cperl-help-shown nil
6843 "Non-nil means that the help was already shown now.")
6845 (defvar cperl-lazy-installed nil
6846 "Non-nil means that the lazy-help handlers are installed now.")
6848 (defun cperl-lazy-install ()
6850 (make-variable-buffer-local 'cperl-help-shown
)
6851 (if (and (cperl-val 'cperl-lazy-help-time
)
6852 (not cperl-lazy-installed
))
6854 (add-hook 'post-command-hook
'cperl-lazy-hook
)
6855 (run-with-idle-timer
6856 (cperl-val 'cperl-lazy-help-time
1000000 5)
6858 'cperl-get-help-defer
)
6859 (setq cperl-lazy-installed t
))))
6861 (defun cperl-lazy-unstall ()
6863 (remove-hook 'post-command-hook
'cperl-lazy-hook
)
6864 (cancel-function-timers 'cperl-get-help-defer
)
6865 (setq cperl-lazy-installed nil
))
6867 (defun cperl-lazy-hook ()
6868 (setq cperl-help-shown nil
))
6870 (defun cperl-get-help-defer ()
6871 (if (not (eq major-mode
'perl-mode
)) nil
6872 (let ((cperl-message-on-help-error nil
) (cperl-help-from-timer t
))
6874 (setq cperl-help-shown t
))))
6875 (cperl-lazy-install)))
6878 ;;; Plug for wrong font-lock:
6880 (defun cperl-font-lock-unfontify-region-function (beg end
)
6881 (let* ((modified (buffer-modified-p)) (buffer-undo-list t
)
6882 (inhibit-read-only t
) (inhibit-point-motion-hooks t
)
6883 before-change-functions after-change-functions
6884 deactivate-mark buffer-file-name buffer-file-truename
)
6885 (remove-text-properties beg end
'(face nil
))
6886 (when (and (not modified
) (buffer-modified-p))
6887 (set-buffer-modified-p nil
))))
6889 (defvar cperl-d-l nil
)
6890 (defun cperl-fontify-syntaxically (end)
6891 ;; Some vars for debugging only
6892 (let (start (dbg (point)) (iend end
)
6893 (istate (car cperl-syntax-state
)))
6894 (and cperl-syntaxify-unwind
6895 (setq end
(cperl-unwind-to-safe t end
)))
6896 (setq start
(point))
6897 (or cperl-syntax-done-to
6898 (setq cperl-syntax-done-to
(point-min)))
6899 (if (or (not (boundp 'font-lock-hot-pass
))
6900 (eval 'font-lock-hot-pass
)
6901 t
) ; Not debugged otherwise
6902 ;; Need to forget what is after `start'
6903 (setq start
(min cperl-syntax-done-to start
))
6904 ;; Fontification without a change
6905 (setq start
(max cperl-syntax-done-to start
)))
6907 (setq cperl-syntax-done-to start
) ; In case what follows fails
6908 (cperl-find-pods-heres start end t nil t
))
6909 ;;(setq cperl-d-l (cons (format "Syntaxifying %s..%s from %s to %s\n"
6910 ;; dbg end start cperl-syntax-done-to)
6912 ;;(let ((standard-output (get-buffer "*Messages*")))
6913 ;;(princ (format "Syntaxifying %s..%s from %s to %s\n"
6914 ;; dbg end start cperl-syntax-done-to)))
6915 (if (eq cperl-syntaxify-by-font-lock
'message
)
6916 (message "Syntaxified %s..%s from %s to %s(%s), state %s-->%s"
6918 start end cperl-syntax-done-to
6919 istate
(car cperl-syntax-state
))) ; For debugging
6920 nil
)) ; Do not iterate
6922 (defun cperl-fontify-update (end)
6923 (let ((pos (point)) prop posend
)
6925 (setq prop
(get-text-property pos
'cperl-postpone
))
6926 (setq posend
(next-single-property-change pos
'cperl-postpone nil end
))
6927 (and prop
(put-text-property pos posend
(car prop
) (cdr prop
)))
6929 nil
) ; Do not iterate
6931 (defun cperl-update-syntaxification (from to
)
6932 (if (and cperl-use-syntax-table-text-property
6933 cperl-syntaxify-by-font-lock
6934 (or (null cperl-syntax-done-to
)
6935 (< cperl-syntax-done-to to
)))
6939 (cperl-fontify-syntaxically to
)))))
6941 (defvar cperl-version
6942 (let ((v "Revision: 4.21"))
6943 (string-match ":\\s *\\([0-9.]+\\)" v
)
6944 (substring v
(match-beginning 1) (match-end 1)))
6945 "Version of IZ-supported CPerl package this file is based on.")
6947 (provide 'cperl-mode
)
6949 ;;; cperl-mode.el ends here