aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2006-10-11 06:47:35 +0000
committerStefan Monnier2006-10-11 06:47:35 +0000
commit4ab89e7b3b31b6056ca9a987b2454851f37c421b (patch)
tree160da737b735776d927f99d7b6b326ff3f38cb32
parenta3545af4a82be7b032738a2d0cc7e5e7f3ac78f0 (diff)
downloademacs-4ab89e7b3b31b6056ca9a987b2454851f37c421b.tar.gz
emacs-4ab89e7b3b31b6056ca9a987b2454851f37c421b.zip
Merge from upstream, upto version 5.22.
After 5.0: `cperl-add-tags-recurse-noxs-fullpath': new function (for -batch mode) After 5.1: ;; Major edit. Summary of most visible changes: ;; a) Multiple <<HERE per line allowed. ;; b) Handles multiline subroutine declaration headers (with comments). ;; (The exception is `cperl-etags' - but it is not used in the rest ;; of the mode.) ;; c) Fontifies multiline my/our declarations (even with comments, ;; and with legacy `font-lock'). ;; d) Major speedup of syntaxification, both immediate and postponed ;; (3.5x to 15x [for different CPUs and versions of Emacs] on the ;; huge real-life document I tested). ;; e) New bindings, edits to imenu. ;; f) "_" is made into word-char during fontification/syntaxification; ;; some attempts to recognize non-word "_" during other operations too. ;; g) Detect bug in Emacs with `looking-at' inside `narrow' and bulk out. ;; h) autoload some more perldoc-related stuff ;; i) Some new convenience features: ISpell POD/HEREDOCs, narrow-to-HEREDOC ;; j) Attempt to incorporate XEmacs edits which reached me Fine-grained changelog: `cperl-hook-after-change': New configuration variable `cperl-vc-sccs-header': Likewise. `cperl-vc-sccs-header': Likewise. `cperl-vc-header-alist': Default via two preceding variables `cperl-invalid-face': Remove double quoting under XEmacs (still needed under 21.2) `cperl-tips': Update URLs for resources `cperl-problems': Likewise. `cperl-praise': Mention new features New C-c key bindings: for `cperl-find-bad-style', `cperl-pod-spell', `cperl-here-doc-spell', `cperl-narrow-to-here-doc', `cperl-perdoc', `cperl-perldoc-at-point' CPerl Mode menu changes: "Fix style by spaces", "Imenu on Perl Info" moved, new submenu of Tools with Ispell entries and narrowing. `cperl-after-sub-regexp': New defsubst `cperl-imenu--function-name-regexp-perl': Use `cperl-after-sub-regexp', Allows heads up to head4 Allow "package;" `defun-prompt-regexp': Use `cperl-after-sub-regexp', `paren-backwards-message': ??? Something for XEmacs??? `cperl-mode': Never auto-switch abbrev-mode off Try to allow '_' be non-word char Do not use `font-lock-unfontify-region-function' on XEmacs Reset syntax cache on mode start Support multiline facification (even on legacy `font-lock') `cperl-facemenu-add-face-function': ??? Some contributed code ??? `cperl-after-change-function': Since `font-lock' and `lazy-lock' refuse to inform us whether the fontification is due to lazy calling or due to edit to a buffer, install our own hook (controlled by `cperl-hook-after-change') `cperl-electric-pod': =cut may have been recognized as start `cperl-block-p': Moved, updated for attributes `cperl-calculate-indent': Try to allow '_' be non-word char Support subs with attributes `cperl-where-am-i': Queit (?) a warning `cperl-cached-syntax-table' New function `cperl-forward-re': Use `cperl-cached-syntax-table' `cperl-unwind-to-safe': Recognize `syntax-type' property changing in a middle of line `cperl-find-sub-attrs': New function `cperl-find-pods-heres': Allow many <<EOP per line Allow subs with attributes Major speedups (3.5x..15x on a real-life test file nph-proxy.pl) Recognize "extproc " (OS/2) case-folded and only at start /x on s///x with empty replacement was not recognized Better comments `cperl-after-block-p': Remarks on diff with `cperl-block-p' Allow subs with attributes, labels Do not confuse "else::foo" with "else" Minor optimizations... `cperl-after-expr-p': Try to allow '_' be non-word char `cperl-fill-paragraph': Try to detect a major bug in Emacs with `looking-at' inside `narrow' and bulk out if found `cperl-imenu--create-perl-index': Updates for new `cperl-imenu--function-name-regexp-perl' `cperl-outline-level': Likewise. `cperl-init-faces': Allow multiline subroutine headers and my/our declarations, and ones with comments Allow subroutine attributes `cperl-imenu-on-info': Better docstring. `cperl-etags' Rudimentary support for attributes Support for packages and "package;" `cperl-add-tags-recurse-noxs': Better (?) docstring `cperl-add-tags-recurse-noxs-fullpath': Likewise. `cperl-tags-hier-init': Misprint for `fboundp' fixed `cperl-not-bad-style-regexp': Try to allow '_' be non-word char `cperl-perldoc': Add autoload `cperl-perldoc-at-point': Likewise. `cperl-here-doc-spell': New function `cperl-pod-spell': Likewise. `cperl-map-pods-heres': Likewise. `cperl-get-here-doc-region': Likewise. `cperl-font-lock-fontify-region-function': Likewise (backward compatibility for legacy `font-lock') `cperl-font-lock-unfontify-region-function': Fix style `cperl-fontify-syntaxically': Recognize and optimize away deferred calls with no-change. Governed by `cperl-hook-after-change' `cperl-fontify-update': Recognize that syntaxification region can be larger than fontification one. XXXX we leave `cperl-postpone' property, so this is quadratic... `cperl-fontify-update-bad': Temporary placeholder until it is clear how to implement `cperl-fontify-update'. `cperl-time-fontification': New function `attrib-group': New text attribute `multiline': New value: `syntax-type' text attribute After 5.2: `cperl-emulate-lazy-lock': New function `cperl-fontify-syntaxically': Would skip large regions Add `cperl-time-fontification', `cperl-emulate-lazy-lock' to menu Some globals were declared, but uninitialized After 5.3, 5.4: `cperl-facemenu-add-face-function': Add docs, fix U<> Copyright message updated. `cperl-init-faces': Work around a bug in `font-lock'. May slow facification down a bit. Misprint for my|our|local for old `font-lock' "our" was not fontified same as "my|local" Highlight variables after "my" etc even in a middle of an expression Do not facify multiple variables after my etc unless parentheses are present After 5.5, 5.6 `cperl-fontify-syntaxically': after-change hook could reset `cperl-syntax-done-to' to a middle of line; unwind to BOL. After 5.7: `cperl-init-faces': Allow highlighting of local ($/) `cperl-problems-old-emaxen': New variable (for the purpose of DOCSTRING). `cperl-problems': Remove fixed problems. `cperl-find-pods-heres': Recognize #-comments in m##x too Recognize charclasses (unless delimiter is \). `cperl-fontify-syntaxically': Unwinding to safe was done in wrong order `cperl-regexp-scan': Update docs `cperl-beautify-regexp-piece': use information got from regexp scan After 5.8: Major user visible changes: Recognition and fontification of character classes in RExen. Variable indentation of RExen according to groups `cperl-find-pods-heres': Recognize POSIX classes in REx charclasses Fontify REx charclasses in variable-name face Fontify POSIX charclasses in "type" face Fontify unmatched "]" in function-name face Mark first-char of HERE-doc as `front-sticky' Reset `front-sticky' property when needed `cperl-calculate-indent': Indents //x -RExen accordning to parens level `cperl-to-comment-or-eol': Recognize ends of `syntax-type' constructs `cperl-backward-to-noncomment': Recognize stringy `syntax-type' constructs Support `narrow'ed buffers. `cperl-praise': Remove a reservation `cperl-make-indent': New function `cperl-indent-for-comment': Use `cperl-make-indent' `cperl-indent-line': Likewise. `cperl-lineup': Likewise. `cperl-beautify-regexp-piece': Likewise. `cperl-contract-level': Likewise. `cperl-toggle-set-debug-unwind': New function New menu entry for this `fill-paragraph-function': Use when `boundp' `cperl-calculate-indent': Take into account groups when indenting RExen `cperl-to-comment-or-eol': Recognize # which end a string `cperl-modify-syntax-type': Make only syntax-table property non-sticky `cperl-fill-paragraph': Return t: needed for `fill-paragraph-function' `cperl-fontify-syntaxically': More clear debugging message `cperl-pod2man-build-command': XEmacs portability: check `Man-filter-list' `cperl-init-faces': More complicated highlight even on XEmacs (new) Merge cosmetic changes from XEmacs After 5.9: `cperl-1+': Moved to before the first use `cperl-1-': Likewise. After 5.10: This code may lock Emacs hard!!! Use on your own risk! `cperl-font-locking': New internal variable `cperl-beginning-of-property': New function `cperl-calculate-indent': Use `cperl-beginning-of-property' instead of `previous-single-property-change' `cperl-unwind-to-safe': Likewise. `cperl-after-expr-p': Likewise. `cperl-get-here-doc-region': Likewise. `cperl-font-lock-fontify-region-function': Likewise. `cperl-to-comment-or-eol': Do not call `cperl-update-syntaxification' recursively Bound `next-single-property-change' via `point-max' `cperl-unwind-to-safe': Bound likewise `cperl-font-lock-fontify-region-function': Likewise. `cperl-find-pods-heres': Mark as recursive for `cperl-to-comment-or-eol' Initialization of `cperl-font-lock-multiline-start' could be missed if the "main" fontification did not run due to the keyword being already fontified. `cperl-pod-spell': Return t from do-one-chunk function `cperl-map-pods-heres': Stop when the worker returns nil Call `cperl-update-syntaxification' `cperl-get-here-doc-region': Call `cperl-update-syntaxification' `cperl-get-here-doc-delim': Remove unused function After 5.11: The possible lockup of Emacs (introduced in 5.10) fixed `cperl-unwind-to-safe': `cperl-beginning-of-property' won't return nil `cperl-syntaxify-for-menu': New customization variable `cperl-select-this-pod-or-here-doc': New function `cperl-get-here-doc-region': Extra argument Do not adjust pos by 1 New menu entries (Perl/Tools): Selection of current POD or HERE-DOC section (Debugging CPerl:) backtrace on fontification After 5.12: `cperl-cached-syntax-table': use `car-safe' `cperl-forward-re': Remove spurious argument SET-ST Add documentation `cperl-forward-group-in-re': New function `cperl-find-pods-heres': Find and highlight (?{}) blocks in RExen (XXXX Temporary (?) hack is to syntax-mark them as comment) After 5.13: `cperl-string-syntax-table': Make { and } not-grouping (Sometimes they ARE grouping in RExen, but matching them would only confuse in many situations when they are not) `beginning-of-buffer': Replaced two occurences with goto-char... `cperl-calculate-indent': `char-after' could be nil... `cperl-find-pods-heres': REx can start after "[" too Hightlight (??{}) in RExen too `cperl-maybe-white-and-comment-rex': New constant `cperl-white-and-comment-rex': Likewise. XXXX Not very efficient, but hard to make better while keeping 1 group After 5.13: `cperl-find-pods-heres': $foo << identifier() is not a HERE-DOC Likewise for 1 << identifier After 5.14: `cperl-find-pods-heres': Different logic for $foo .= <<EOF etc Error-less condition-case could fail `cperl-font-lock-fontify-region-function': Likewise. `cperl-init-faces': Likewise. After 5.15: `cperl-find-pods-heres': Support property REx-part2 `cperl-calculate-indent': Likewise. Don't special-case REx with non-empty 1st line `cperl-find-pods-heres': In RExen, highlight non-literal backslashes Invert highlighting of charclasses: now the envelop is highlighted Highlight many others 0-length builtins `cperl-praise': Mention indenting and highlight in RExen After 5.15: `cperl-find-pods-heres': Highlight capturing parens in REx After 5.16: `cperl-find-pods-heres': Highlight '|' for alternation Initialize `font-lock-warning-face' if not present `cperl-find-pods-heres': Use `font-lock-warning-face' instead of `font-lock-function-name-face' `cperl-look-at-leading-count': Likewise. `cperl-find-pods-heres': localize `font-lock-variable-name-face' `font-lock-keyword-face' (needed for batch processing) etc Use `font-lock-builtin-face' for builtin in REx Now `font-lock-variable-name-face' is used for interpolated variables Use "talking aliases" for faces inside REx Highlight parts of REx (except in charclasses) according to the syntax and/or semantic Syntax-mark a {}-part of (?{}) as "comment" (it was the ()-part) Better logic to distinguish what is what in REx `cperl-tips-faces': Document REx highlighting `cperl-praise': Mention REx syntax highlight etc. After 5.17: `cperl-find-sub-attrs': Would not always manage to print error message `cperl-find-pods-heres': localize `font-lock-constant-face' After 5.18: `cperl-find-pods-heres': Misprint in REx for parsing REx Very minor optimization `my-cperl-REx-modifiers-face' got quoted Recognize "print $foo <<END" as HERE-doc Put `REx-interpolated' text attribute if needed `cperl-invert-if-unless-modifiers': New function `cperl-backward-to-start-of-expr': Likewise. `cperl-forward-to-end-of-expr': Likewise. `cperl-invert-if-unless': Works in "the opposite way" too Cursor position on return is on the switch-word Indents comments better `REx-interpolated': New text attribute `cperl-next-interpolated-REx': New function `cperl-next-interpolated-REx-0': Likewise. `cperl-next-interpolated-REx-1': Likewise. "\C-c\C-x", "\C-c\C-y", "\C-c\C-v": New keybinding for these functions Perl/Regexp menu: 3 new entries for `cperl-next-interpolated-REx' `cperl-praise': Mention finded interpolated RExen After 5.19: `cperl-init-faces': Highlight %$foo, @$foo too `cperl-short-docs': Better docs for system, exec `cperl-find-pods-heres': Better detect << after print {FH} <<EOF etc. Would not find HERE-doc ended by EOF without NL `cperl-short-docs': Correct not-doubled \-escapes start block: Put some `defvar' for stuff gone from XEmacs After 5.20: initial comment: Extend copyright, fix email address `cperl-indent-comment-at-column-0': New customization variable `cperl-comment-indent': Indentation after $#a would increasy by 1 `cperl-mode': Make `defun-prompt-regexp' grok BEGIN/END etc `cperl-find-pods-heres': Mark CODE of s///e as `syntax-type' `multiline' `cperl-at-end-of-expr': Would fail if @BAR=12 follows after ";" `cperl-init-faces': If `cperl-highlight-variables-indiscriminately' highlight $ in $foo too (UNTESTED) `cperl-set-style': Docstring missed some available styles toplevel: Menubar/Perl/Indent-Styles had FSF, now K&R Change "Current" to "Memorize Current" `cperl-indent-wrt-brace': New customization variable; the default is as for pre-5.2 version `cperl-styles-entries': Keep `cperl-extra-newline-before-brace-multiline' `cperl-style-alist': Likewise. `cperl-fix-line-spacing': Support `cperl-merge-trailing-else' being nil, and `cperl-extra-newline-before-brace' etc being t `cperl-indent-exp': Plans B and C to find continuation blocks even if `cperl-extra-newline-before-brace' is t After 5.21: Improve some docstrings concerning indentation. `cperl-indent-rules-alist': New variable `cperl-sniff-for-indent': New function name (separated from `cperl-calculate-indent') `cperl-calculate-indent': Separated the sniffer and the indenter; uses `cperl-sniff-for-indent' now `cperl-comment-indent': Test for `cperl-indent-comment-at-column-0' was inverted; Support `comment-column' = 0
-rw-r--r--lisp/progmodes/cperl-mode.el4132
1 files changed, 2947 insertions, 1185 deletions
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 69f4549a0bf..3264e0e72f6 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -5,7 +5,7 @@
5;; Free Software Foundation, Inc. 5;; Free Software Foundation, Inc.
6 6
7;; Author: Ilya Zakharevich and Bob Olson 7;; Author: Ilya Zakharevich and Bob Olson
8;; Maintainer: Ilya Zakharevich <cperl@ilyaz.org> 8;; Maintainer: Ilya Zakharevich <ilyaz@cpan.org>
9;; Keywords: languages, Perl 9;; Keywords: languages, Perl
10 10
11;; This file is part of GNU Emacs. 11;; This file is part of GNU Emacs.
@@ -25,7 +25,7 @@
25;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 25;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26;; Boston, MA 02110-1301, USA. 26;; Boston, MA 02110-1301, USA.
27 27
28;;; Corrections made by Ilya Zakharevich cperl@ilyaz.org 28;;; Corrections made by Ilya Zakharevich ilyaz@cpan.org
29 29
30;;; Commentary: 30;;; Commentary:
31 31
@@ -67,67 +67,89 @@
67;; likewise with m, tr, y, q, qX instead of s 67;; likewise with m, tr, y, q, qX instead of s
68 68
69;;; Code: 69;;; Code:
70 70
71(defvar vc-rcs-header) 71(defvar vc-rcs-header)
72(defvar vc-sccs-header) 72(defvar vc-sccs-header)
73 73
74;; Some macros are needed for `defcustom'
75(eval-when-compile 74(eval-when-compile
76 (condition-case nil 75 (condition-case nil
77 (require 'man) 76 (require 'custom)
78 (error nil)) 77 (error nil))
79 (defconst cperl-xemacs-p (string-match "XEmacs\\|Lucid" emacs-version)) 78 (condition-case nil
80 (defvar cperl-can-font-lock 79 (require 'man)
81 (or cperl-xemacs-p 80 (error nil))
82 (and (boundp 'emacs-major-version) 81 (defconst cperl-xemacs-p (string-match "XEmacs\\|Lucid" emacs-version))
83 (or window-system 82 (defvar cperl-can-font-lock
84 (> emacs-major-version 20))))) 83 (or cperl-xemacs-p
85 (if cperl-can-font-lock 84 (and (boundp 'emacs-major-version)
86 (require 'font-lock)) 85 (or window-system
87 (defvar msb-menu-cond) 86 (> emacs-major-version 20)))))
88 (defvar gud-perldb-history) 87 (if cperl-can-font-lock
89 (defvar font-lock-background-mode) ; not in Emacs 88 (require 'font-lock))
90 (defvar font-lock-display-type) ; ditto 89 (defvar msb-menu-cond)
91 (defmacro cperl-is-face (arg) ; Takes quoted arg 90 (defvar gud-perldb-history)
92 (cond ((fboundp 'find-face) 91 (defvar font-lock-background-mode) ; not in Emacs
93 `(find-face ,arg)) 92 (defvar font-lock-display-type) ; ditto
94 (;;(and (fboundp 'face-list) 93 (defvar paren-backwards-message) ; Not in newer XEmacs?
95 ;; (face-list)) 94 (or (fboundp 'defgroup)
96 (fboundp 'face-list) 95 (defmacro defgroup (name val doc &rest arr)
97 `(member ,arg (and (fboundp 'face-list) 96 nil))
98 (face-list)))) 97 (or (fboundp 'custom-declare-variable)
99 (t 98 (defmacro defcustom (name val doc &rest arr)
100 `(boundp ,arg)))) 99 (` (defvar (, name) (, val) (, doc)))))
101 (defmacro cperl-make-face (arg descr) ; Takes unquoted arg 100 (or (and (fboundp 'custom-declare-variable)
102 (cond ((fboundp 'make-face) 101 (string< "19.31" emacs-version)) ; Checked with 19.30: defface does not work
103 `(make-face (quote ,arg))) 102 (defmacro defface (&rest arr)
104 (t 103 nil))
105 `(defvar ,arg (quote ,arg) ,descr)))) 104 ;; Avoid warning (tmp definitions)
106 (defmacro cperl-force-face (arg descr) ; Takes unquoted arg 105 (or (fboundp 'x-color-defined-p)
107 `(progn 106 (defmacro x-color-defined-p (col)
108 (or (cperl-is-face (quote ,arg)) 107 (cond ((fboundp 'color-defined-p) (` (color-defined-p (, col))))
109 (cperl-make-face ,arg ,descr)) 108 ;; XEmacs >= 19.12
110 (or (boundp (quote ,arg)) ; We use unquoted variants too 109 ((fboundp 'valid-color-name-p) (` (valid-color-name-p (, col))))
111 (defvar ,arg (quote ,arg) ,descr)))) 110 ;; XEmacs 19.11
112 (if cperl-xemacs-p 111 ((fboundp 'x-valid-color-name-p) (` (x-valid-color-name-p (, col))))
113 (defmacro cperl-etags-snarf-tag (file line) 112 (t '(error "Cannot implement color-defined-p")))))
114 `(progn 113 (defmacro cperl-is-face (arg) ; Takes quoted arg
115 (beginning-of-line 2) 114 (cond ((fboundp 'find-face)
116 (list ,file ,line))) 115 (` (find-face (, arg))))
117 (defmacro cperl-etags-snarf-tag (file line) 116 (;;(and (fboundp 'face-list)
118 `(etags-snarf-tag))) 117 ;; (face-list))
119 (if cperl-xemacs-p 118 (fboundp 'face-list)
120 (defmacro cperl-etags-goto-tag-location (elt) 119 (` (member (, arg) (and (fboundp 'face-list)
121 ;;(progn 120 (face-list)))))
122 ;; (switch-to-buffer (get-file-buffer (elt (, elt) 0))) 121 (t
123 ;; (set-buffer (get-file-buffer (elt (, elt) 0))) 122 (` (boundp (, arg))))))
124 ;; Probably will not work due to some save-excursion??? 123 (defmacro cperl-make-face (arg descr) ; Takes unquoted arg
125 ;; Or save-file-position? 124 (cond ((fboundp 'make-face)
126 ;; (message "Did I get to line %s?" (elt (, elt) 1)) 125 (` (make-face (quote (, arg)))))
127 `(goto-line (string-to-number (elt ,elt 1)))) 126 (t
128 ;;) 127 (` (defvar (, arg) (quote (, arg)) (, descr))))))
129 (defmacro cperl-etags-goto-tag-location (elt) 128 (defmacro cperl-force-face (arg descr) ; Takes unquoted arg
130 `(etags-goto-tag-location ,elt)))) 129 (` (progn
130 (or (cperl-is-face (quote (, arg)))
131 (cperl-make-face (, arg) (, descr)))
132 (or (boundp (quote (, arg))) ; We use unquoted variants too
133 (defvar (, arg) (quote (, arg)) (, descr))))))
134 (if cperl-xemacs-p
135 (defmacro cperl-etags-snarf-tag (file line)
136 (` (progn
137 (beginning-of-line 2)
138 (list (, file) (, line)))))
139 (defmacro cperl-etags-snarf-tag (file line)
140 (` (etags-snarf-tag))))
141 (if cperl-xemacs-p
142 (defmacro cperl-etags-goto-tag-location (elt)
143 (`;;(progn
144 ;; (switch-to-buffer (get-file-buffer (elt (, elt) 0)))
145 ;; (set-buffer (get-file-buffer (elt (, elt) 0)))
146 ;; Probably will not work due to some save-excursion???
147 ;; Or save-file-position?
148 ;; (message "Did I get to line %s?" (elt (, elt) 1))
149 (goto-line (string-to-int (elt (, elt) 1)))))
150 ;;)
151 (defmacro cperl-etags-goto-tag-location (elt)
152 (` (etags-goto-tag-location (, elt))))))
131 153
132(defconst cperl-xemacs-p (string-match "XEmacs\\|Lucid" emacs-version)) 154(defconst cperl-xemacs-p (string-match "XEmacs\\|Lucid" emacs-version))
133 155
@@ -251,6 +273,12 @@ This is in addition to cperl-continued-statement-offset."
251 :type 'integer 273 :type 'integer
252 :group 'cperl-indentation-details) 274 :group 'cperl-indentation-details)
253 275
276(defcustom cperl-indent-wrt-brace t
277 "*Non-nil means indent statements in if/etc block relative brace, not if/etc.
278Versions 5.2 ... 5.20 behaved as if this were `nil'."
279 :type 'boolean
280 :group 'cperl-indentation-details)
281
254(defcustom cperl-auto-newline nil 282(defcustom cperl-auto-newline nil
255 "*Non-nil means automatically newline before and after braces, 283 "*Non-nil means automatically newline before and after braces,
256and after colons and semicolons, inserted in CPerl code. The following 284and after colons and semicolons, inserted in CPerl code. The following
@@ -347,20 +375,26 @@ Affects: `cperl-font-lock', `cperl-electric-lbrace-space',
347 :type 'integer 375 :type 'integer
348 :group 'cperl-indentation-details) 376 :group 'cperl-indentation-details)
349 377
350(defvar cperl-vc-header-alist nil) 378(defcustom cperl-indent-comment-at-column-0 nil
351(make-obsolete-variable 379 "*Non-nil means that comment started at column 0 should be indentable."
352 'cperl-vc-header-alist 380 :type 'boolean
353 "use cperl-vc-rcs-header or cperl-vc-sccs-header instead.") 381 :group 'cperl-indentation-details)
354 382
355(defcustom cperl-vc-sccs-header '("($sccs) = ('%W\%' =~ /(\\d+(\\.\\d+)+)/) ;") 383(defcustom cperl-vc-sccs-header '("($sccs) = ('%W\%' =~ /(\\d+(\\.\\d+)+)/) ;")
356 "*Special version of `vc-sccs-header' that is used in CPerl mode buffers." 384 "*Special version of `vc-sccs-header' that is used in CPerl mode buffers."
357 :type '(repeat string) 385 :type '(repeat string)
358 :group 'cperl) 386 :group 'cperl)
359 387
360(defcustom cperl-vc-rcs-header '("($rcs) = (' $Id\$ ' =~ /(\\d+(\\.\\d+)+)/) ;") 388(defcustom cperl-vc-rcs-header '("($rcs) = (' $Id\$ ' =~ /(\\d+(\\.\\d+)+)/);")
361 "*Special version of `vc-rcs-header' that is used in CPerl mode buffers." 389 "*Special version of `vc-rcs-header' that is used in CPerl mode buffers."
362 :type '(repeat string) 390 :type '(repeat string)
363 :group 'cperl) 391 :group 'cperl)
392
393;; This became obsolete...
394(defvar cperl-vc-header-alist nil)
395(make-obsolete-variable
396 'cperl-vc-header-alist
397 "use cperl-vc-rcs-header or cperl-vc-sccs-header instead.")
364 398
365(defcustom cperl-clobber-mode-lists 399(defcustom cperl-clobber-mode-lists
366 (not 400 (not
@@ -408,8 +442,15 @@ Font for POD headers."
408 :type 'face 442 :type 'face
409 :group 'cperl-faces) 443 :group 'cperl-faces)
410 444
411(defcustom cperl-invalid-face 'underline 445;;; Some double-evaluation happened with font-locks... Needed with 21.2...
412 "*Face for highlighting trailing whitespace." 446(defvar cperl-singly-quote-face cperl-xemacs-p)
447
448(defcustom cperl-invalid-face ; Does not customize with '' on XEmacs
449 (if cperl-singly-quote-face
450 'underline ''underline) ; On older Emacsen was evaluated by `font-lock'
451 (if cperl-singly-quote-face
452 "*This face is used for highlighting trailing whitespace."
453 "*Face for highlighting trailing whitespace.")
413 :type 'face 454 :type 'face
414 :version "21.1" 455 :version "21.1"
415 :group 'cperl-faces) 456 :group 'cperl-faces)
@@ -441,7 +482,14 @@ You can always make lookup from menu or using \\[cperl-find-pods-heres]."
441 482
442(defcustom cperl-regexp-scan t 483(defcustom cperl-regexp-scan t
443 "*Not-nil means make marking of regular expression more thorough. 484 "*Not-nil means make marking of regular expression more thorough.
444Effective only with `cperl-pod-here-scan'. Not implemented yet." 485Effective only with `cperl-pod-here-scan'."
486 :type 'boolean
487 :group 'cperl-speed)
488
489(defcustom cperl-hook-after-change t
490 "*Not-nil means install hook to know which regions of buffer are changed.
491May significantly speed up delayed fontification. Changes take effect
492after reload."
445 :type 'boolean 493 :type 'boolean
446 :group 'cperl-speed) 494 :group 'cperl-speed)
447 495
@@ -564,17 +612,25 @@ when syntaxifying a chunk of buffer."
564 :type 'boolean 612 :type 'boolean
565 :group 'cperl-speed) 613 :group 'cperl-speed)
566 614
615(defcustom cperl-syntaxify-for-menu
616 t
617 "*Non-nil means that CPerl syntaxifies up to the point before showing menu.
618This way enabling/disabling of menu items is more correct."
619 :type 'boolean
620 :group 'cperl-speed)
621
567(defcustom cperl-ps-print-face-properties 622(defcustom cperl-ps-print-face-properties
568 '((font-lock-keyword-face nil nil bold shadow) 623 '((font-lock-keyword-face nil nil bold shadow)
569 (font-lock-variable-name-face nil nil bold) 624 (font-lock-variable-name-face nil nil bold)
570 (font-lock-function-name-face nil nil bold italic box) 625 (font-lock-function-name-face nil nil bold italic box)
571 (font-lock-constant-face nil "LightGray" bold) 626 (font-lock-constant-face nil "LightGray" bold)
572 (cperl-array nil "LightGray" bold underline) 627 (cperl-array-face nil "LightGray" bold underline)
573 (cperl-hash nil "LightGray" bold italic underline) 628 (cperl-hash-face nil "LightGray" bold italic underline)
574 (font-lock-comment-face nil "LightGray" italic) 629 (font-lock-comment-face nil "LightGray" italic)
575 (font-lock-string-face nil nil italic underline) 630 (font-lock-string-face nil nil italic underline)
576 (cperl-nonoverridable nil nil italic underline) 631 (cperl-nonoverridable-face nil nil italic underline)
577 (font-lock-type-face nil nil underline) 632 (font-lock-type-face nil nil underline)
633 (font-lock-warning-face nil "LightGray" bold italic box)
578 (underline nil "LightGray" strikeout)) 634 (underline nil "LightGray" strikeout))
579 "List given as an argument to `ps-extend-face-list' in `cperl-ps-print'." 635 "List given as an argument to `ps-extend-face-list' in `cperl-ps-print'."
580 :type '(repeat (cons symbol 636 :type '(repeat (cons symbol
@@ -588,7 +644,7 @@ when syntaxifying a chunk of buffer."
588(defvar cperl-dark-foreground 644(defvar cperl-dark-foreground
589 (cperl-choose-color "orchid1" "orange")) 645 (cperl-choose-color "orchid1" "orange"))
590 646
591(defface cperl-nonoverridable 647(defface cperl-nonoverridable-face
592 `((((class grayscale) (background light)) 648 `((((class grayscale) (background light))
593 (:background "Gray90" :slant italic :underline t)) 649 (:background "Gray90" :slant italic :underline t))
594 (((class grayscale) (background dark)) 650 (((class grayscale) (background dark))
@@ -600,10 +656,8 @@ when syntaxifying a chunk of buffer."
600 (t (:weight bold :underline t))) 656 (t (:weight bold :underline t)))
601 "Font Lock mode face used non-overridable keywords and modifiers of regexps." 657 "Font Lock mode face used non-overridable keywords and modifiers of regexps."
602 :group 'cperl-faces) 658 :group 'cperl-faces)
603;; backward-compatibility alias
604(put 'cperl-nonoverridable-face 'face-alias 'cperl-nonoverridable)
605 659
606(defface cperl-array 660(defface cperl-array-face
607 `((((class grayscale) (background light)) 661 `((((class grayscale) (background light))
608 (:background "Gray90" :weight bold)) 662 (:background "Gray90" :weight bold))
609 (((class grayscale) (background dark)) 663 (((class grayscale) (background dark))
@@ -615,10 +669,8 @@ when syntaxifying a chunk of buffer."
615 (t (:weight bold))) 669 (t (:weight bold)))
616 "Font Lock mode face used to highlight array names." 670 "Font Lock mode face used to highlight array names."
617 :group 'cperl-faces) 671 :group 'cperl-faces)
618;; backward-compatibility alias
619(put 'cperl-array-face 'face-alias 'cperl-array)
620 672
621(defface cperl-hash 673(defface cperl-hash-face
622 `((((class grayscale) (background light)) 674 `((((class grayscale) (background light))
623 (:background "Gray90" :weight bold :slant italic)) 675 (:background "Gray90" :weight bold :slant italic))
624 (((class grayscale) (background dark)) 676 (((class grayscale) (background dark))
@@ -630,8 +682,6 @@ when syntaxifying a chunk of buffer."
630 (t (:weight bold :slant italic))) 682 (t (:weight bold :slant italic)))
631 "Font Lock mode face used to highlight hash names." 683 "Font Lock mode face used to highlight hash names."
632 :group 'cperl-faces) 684 :group 'cperl-faces)
633;; backward-compatibility alias
634(put 'cperl-hash-face 'face-alias 'cperl-hash)
635 685
636 686
637 687
@@ -639,9 +689,7 @@ when syntaxifying a chunk of buffer."
639 689
640(defvar cperl-tips 'please-ignore-this-line 690(defvar cperl-tips 'please-ignore-this-line
641 "Get maybe newer version of this package from 691 "Get maybe newer version of this package from
642 ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs 692 http://ilyaz.org/software/emacs
643and/or
644 ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl
645Subdirectory `cperl-mode' may contain yet newer development releases and/or 693Subdirectory `cperl-mode' may contain yet newer development releases and/or
646patches to related files. 694patches to related files.
647 695
@@ -666,9 +714,9 @@ want it to: put the following into your .emacs file:
666 (defalias 'perl-mode 'cperl-mode) 714 (defalias 'perl-mode 'cperl-mode)
667 715
668Get perl5-info from 716Get perl5-info from
669 $CPAN/doc/manual/info/perl-info.tar.gz 717 $CPAN/doc/manual/info/perl5-old/perl5-info.tar.gz
670older version was on 718Also, one can generate a newer documentation running `pod2texi' converter
671 http://www.metronet.com:70/9/perlinfo/perl5/manual/perl5-info.tar.gz 719 $CPAN/doc/manual/info/perl5/pod2texi-0.1.tar.gz
672 720
673If you use imenu-go, run imenu on perl5-info buffer (you can do it 721If you use imenu-go, run imenu on perl5-info buffer (you can do it
674from Perl menu). If many files are related, generate TAGS files from 722from Perl menu). If many files are related, generate TAGS files from
@@ -700,11 +748,18 @@ micro-docs on what I know about CPerl problems.")
700 "Description of problems in CPerl mode. 748 "Description of problems in CPerl mode.
701Some faces will not be shown on some versions of Emacs unless you 749Some faces will not be shown on some versions of Emacs unless you
702install choose-color.el, available from 750install choose-color.el, available from
703 ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs/ 751 http://ilyaz.org/software/emacs
704 752
705`fill-paragraph' on a comment may leave the point behind the 753`fill-paragraph' on a comment may leave the point behind the
706paragraph. Parsing of lines with several <<EOF is not implemented 754paragraph. It also triggers a bug in some versions of Emacs (CPerl tries
707yet. 755to detect it and bulk out).
756
757See documentation of a variable `cperl-problems-old-emaxen' for the
758problems which disappear if you upgrade Emacs to a reasonably new
759version (20.3 for Emacs, and those of 2004 for XEmacs).")
760
761(defvar cperl-problems-old-emaxen 'please-ignore-this-line
762 "Description of problems in CPerl mode specific for older Emacs versions.
708 763
709Emacs had a _very_ restricted syntax parsing engine until version 764Emacs had a _very_ restricted syntax parsing engine until version
71020.1. Most problems below are corrected starting from this version of 76520.1. Most problems below are corrected starting from this version of
@@ -812,6 +867,13 @@ voice);
812 o) Highlights trailing whitespace; 867 o) Highlights trailing whitespace;
813 p) Is able to manipulate Perl Regular Expressions to ease 868 p) Is able to manipulate Perl Regular Expressions to ease
814 conversion to a more readable form. 869 conversion to a more readable form.
870 q) Can ispell POD sections and HERE-DOCs.
871 r) Understands comments and character classes inside regular
872 expressions; can find matching () and [] in a regular expression.
873 s) Allows indentation of //x-style regular expressions;
874 t) Highlights different symbols in regular expressions according
875 to their function; much less problems with backslashitis;
876 u) Allows to find regular expressions which contain interpolated parts.
815 877
8165) The indentation engine was very smart, but most of tricks may be 8785) The indentation engine was very smart, but most of tricks may be
817not needed anymore with the support for `syntax-table' property. Has 879not needed anymore with the support for `syntax-table' property. Has
@@ -829,7 +891,10 @@ the settings present before the switch.
829line-breaks/spacing between elements of the construct. 891line-breaks/spacing between elements of the construct.
830 892
83110) Uses a linear-time algorith for indentation of regions (on Emaxen with 89310) Uses a linear-time algorith for indentation of regions (on Emaxen with
832capable syntax engines).") 894capable syntax engines).
895
89611) Syntax-highlight, indentation, sexp-recognition inside regular expressions.
897")
833 898
834(defvar cperl-speed 'please-ignore-this-line 899(defvar cperl-speed 'please-ignore-this-line
835 "This is an incomplete compendium of what is available in other parts 900 "This is an incomplete compendium of what is available in other parts
@@ -878,19 +943,19 @@ B) Speed of editing operations.
878(defvar cperl-tips-faces 'please-ignore-this-line 943(defvar cperl-tips-faces 'please-ignore-this-line
879 "CPerl mode uses following faces for highlighting: 944 "CPerl mode uses following faces for highlighting:
880 945
881 `cperl-array' Array names 946 `cperl-array-face' Array names
882 `cperl-hash' Hash names 947 `cperl-hash-face' Hash names
883 `font-lock-comment-face' Comments, PODs and whatever is considered 948 `font-lock-comment-face' Comments, PODs and whatever is considered
884 syntaxically to be not code 949 syntaxically to be not code
885 `font-lock-constant-face' HERE-doc delimiters, labels, delimiters of 950 `font-lock-constant-face' HERE-doc delimiters, labels, delimiters of
886 2-arg operators s/y/tr/ or of RExen, 951 2-arg operators s/y/tr/ or of RExen,
887 `font-lock-function-name-face' Special-cased m// and s//foo/, _ as 952 `font-lock-warning-face' Special-cased m// and s//foo/,
888 a target of a file tests, file tests, 953 `font-lock-function-name-face' _ as a target of a file tests, file tests,
889 subroutine names at the moment of definition 954 subroutine names at the moment of definition
890 (except those conflicting with Perl operators), 955 (except those conflicting with Perl operators),
891 package names (when recognized), format names 956 package names (when recognized), format names
892 `font-lock-keyword-face' Control flow switch constructs, declarators 957 `font-lock-keyword-face' Control flow switch constructs, declarators
893 `cperl-nonoverridable' Non-overridable keywords, modifiers of RExen 958 `cperl-nonoverridable-face' Non-overridable keywords, modifiers of RExen
894 `font-lock-string-face' Strings, qw() constructs, RExen, POD sections, 959 `font-lock-string-face' Strings, qw() constructs, RExen, POD sections,
895 literal parts and the terminator of formats 960 literal parts and the terminator of formats
896 and whatever is syntaxically considered 961 and whatever is syntaxically considered
@@ -908,7 +973,25 @@ m// and s/// which do not do what one would expect them to do.
908Help with best setup of these faces for printout requested (for each of 973Help with best setup of these faces for printout requested (for each of
909the faces: please specify bold, italic, underline, shadow and box.) 974the faces: please specify bold, italic, underline, shadow and box.)
910 975
911\(Not finished.)") 976In regular expressions (except character classes):
977 `font-lock-string-face' \"Normal\" stuff and non-0-length constructs
978 `font-lock-constant-face': Delimiters
979 `font-lock-warning-face' Special-cased m// and s//foo/,
980 Mismatched closing delimiters, parens
981 we couldn't match, misplaced quantifiers,
982 unrecognized escape sequences
983 `cperl-nonoverridable-face' Modifiers, as gism in m/REx/gism
984 `font-lock-type-face' POSIX classes inside charclasses,
985 escape sequences with arguments (\x \23 \p \N)
986 and others match-a-char escape sequences
987 `font-lock-keyword-face' Capturing parens, and |
988 `font-lock-function-name-face' Special symbols: $ ^ . [ ] [^ ] (?{ }) (??{ })
989 `font-lock-builtin-face' \"Remaining\" 0-length constructs, executable
990 parts of a REx, not-capturing parens
991 `font-lock-variable-name-face' Interpolated constructs, embedded code
992 `font-lock-comment-face' Embedded comments
993
994")
912 995
913 996
914 997
@@ -985,6 +1068,25 @@ the faces: please specify bold, italic, underline, shadow and box.)
985 (cperl-hairy (or hairy t)) 1068 (cperl-hairy (or hairy t))
986 (t (symbol-value symbol)))) 1069 (t (symbol-value symbol))))
987 1070
1071
1072(defun cperl-make-indent (column &optional minimum keep)
1073 "Makes indent of the current line the requested amount.
1074Unless KEEP, removes the old indentation. Works around a bug in ancient
1075versions of Emacs."
1076 (let ((prop (get-text-property (point) 'syntax-type)))
1077 (or keep
1078 (delete-horizontal-space))
1079 (indent-to column minimum)
1080 ;; In old versions (e.g., 19.33) `indent-to' would not inherit properties
1081 (and prop
1082 (> (current-column) 0)
1083 (save-excursion
1084 (beginning-of-line)
1085 (or (get-text-property (point) 'syntax-type)
1086 (and (looking-at "\\=[ \t]")
1087 (put-text-property (point) (match-end 0)
1088 'syntax-type prop)))))))
1089
988;;; Probably it is too late to set these guys already, but it can help later: 1090;;; Probably it is too late to set these guys already, but it can help later:
989 1091
990;;;(and cperl-clobber-mode-lists 1092;;;(and cperl-clobber-mode-lists
@@ -1035,7 +1137,16 @@ the faces: please specify bold, italic, underline, shadow and box.)
1035 (cperl-define-key "\C-c\C-w" 'cperl-toggle-construct-fix) 1137 (cperl-define-key "\C-c\C-w" 'cperl-toggle-construct-fix)
1036 (cperl-define-key "\C-c\C-f" 'auto-fill-mode) 1138 (cperl-define-key "\C-c\C-f" 'auto-fill-mode)
1037 (cperl-define-key "\C-c\C-e" 'cperl-toggle-electric) 1139 (cperl-define-key "\C-c\C-e" 'cperl-toggle-electric)
1140 (cperl-define-key "\C-c\C-b" 'cperl-find-bad-style)
1141 (cperl-define-key "\C-c\C-p" 'cperl-pod-spell)
1142 (cperl-define-key "\C-c\C-d" 'cperl-here-doc-spell)
1143 (cperl-define-key "\C-c\C-n" 'cperl-narrow-to-here-doc)
1144 (cperl-define-key "\C-c\C-v" 'cperl-next-interpolated-REx)
1145 (cperl-define-key "\C-c\C-x" 'cperl-next-interpolated-REx-0)
1146 (cperl-define-key "\C-c\C-y" 'cperl-next-interpolated-REx-1)
1038 (cperl-define-key "\C-c\C-ha" 'cperl-toggle-autohelp) 1147 (cperl-define-key "\C-c\C-ha" 'cperl-toggle-autohelp)
1148 (cperl-define-key "\C-c\C-hp" 'cperl-perldoc)
1149 (cperl-define-key "\C-c\C-hP" 'cperl-perldoc-at-point)
1039 (cperl-define-key "\e\C-q" 'cperl-indent-exp) ; Usually not bound 1150 (cperl-define-key "\e\C-q" 'cperl-indent-exp) ; Usually not bound
1040 (cperl-define-key [?\C-\M-\|] 'cperl-lineup 1151 (cperl-define-key [?\C-\M-\|] 'cperl-lineup
1041 [(control meta |)]) 1152 [(control meta |)])
@@ -1074,9 +1185,13 @@ the faces: please specify bold, italic, underline, shadow and box.)
1074 (<= emacs-minor-version 11) (<= emacs-major-version 19)) 1185 (<= emacs-minor-version 11) (<= emacs-major-version 19))
1075 (progn 1186 (progn
1076 ;; substitute-key-definition is usefulness-deenhanced... 1187 ;; substitute-key-definition is usefulness-deenhanced...
1077 (cperl-define-key "\M-q" 'cperl-fill-paragraph) 1188 ;;;;;(cperl-define-key "\M-q" 'cperl-fill-paragraph)
1078 (cperl-define-key "\e;" 'cperl-indent-for-comment) 1189 (cperl-define-key "\e;" 'cperl-indent-for-comment)
1079 (cperl-define-key "\e\C-\\" 'cperl-indent-region)) 1190 (cperl-define-key "\e\C-\\" 'cperl-indent-region))
1191 (or (boundp 'fill-paragraph-function)
1192 (substitute-key-definition
1193 'fill-paragraph 'cperl-fill-paragraph
1194 cperl-mode-map global-map))
1080 (substitute-key-definition 1195 (substitute-key-definition
1081 'indent-sexp 'cperl-indent-exp 1196 'indent-sexp 'cperl-indent-exp
1082 cperl-mode-map global-map) 1197 cperl-mode-map global-map)
@@ -1094,52 +1209,101 @@ the faces: please specify bold, italic, underline, shadow and box.)
1094 (progn 1209 (progn
1095 (require 'easymenu) 1210 (require 'easymenu)
1096 (easy-menu-define 1211 (easy-menu-define
1097 cperl-menu cperl-mode-map "Menu for CPerl mode" 1212 cperl-menu cperl-mode-map "Menu for CPerl mode"
1098 '("Perl" 1213 '("Perl"
1099 ["Beginning of function" beginning-of-defun t] 1214 ["Beginning of function" beginning-of-defun t]
1100 ["End of function" end-of-defun t] 1215 ["End of function" end-of-defun t]
1101 ["Mark function" mark-defun t] 1216 ["Mark function" mark-defun t]
1102 ["Indent expression" cperl-indent-exp t] 1217 ["Indent expression" cperl-indent-exp t]
1103 ["Fill paragraph/comment" fill-paragraph t] 1218 ["Fill paragraph/comment" fill-paragraph t]
1219 "----"
1220 ["Line up a construction" cperl-lineup (cperl-use-region-p)]
1221 ["Invert if/unless/while etc" cperl-invert-if-unless t]
1222 ("Regexp"
1223 ["Beautify" cperl-beautify-regexp
1224 cperl-use-syntax-table-text-property]
1225 ["Beautify one level deep" (cperl-beautify-regexp 1)
1226 cperl-use-syntax-table-text-property]
1227 ["Beautify a group" cperl-beautify-level
1228 cperl-use-syntax-table-text-property]
1229 ["Beautify a group one level deep" (cperl-beautify-level 1)
1230 cperl-use-syntax-table-text-property]
1231 ["Contract a group" cperl-contract-level
1232 cperl-use-syntax-table-text-property]
1233 ["Contract groups" cperl-contract-levels
1234 cperl-use-syntax-table-text-property]
1104 "----" 1235 "----"
1105 ["Line up a construction" cperl-lineup (cperl-use-region-p)] 1236 ["Find next interpolated" cperl-next-interpolated-REx
1106 ["Invert if/unless/while etc" cperl-invert-if-unless t] 1237 (next-single-property-change (point-min) 'REx-interpolated)]
1107 ("Regexp" 1238 ["Find next interpolated (no //o)"
1108 ["Beautify" cperl-beautify-regexp 1239 cperl-next-interpolated-REx-0
1109 cperl-use-syntax-table-text-property] 1240 (or (text-property-any (point-min) (point-max) 'REx-interpolated t)
1110 ["Beautify one level deep" (cperl-beautify-regexp 1) 1241 (text-property-any (point-min) (point-max) 'REx-interpolated 1))]
1111 cperl-use-syntax-table-text-property] 1242 ["Find next interpolated (neither //o nor whole-REx)"
1112 ["Beautify a group" cperl-beautify-level 1243 cperl-next-interpolated-REx-1
1113 cperl-use-syntax-table-text-property] 1244 (text-property-any (point-min) (point-max) 'REx-interpolated t)])
1114 ["Beautify a group one level deep" (cperl-beautify-level 1) 1245 ["Insert spaces if needed to fix style" cperl-find-bad-style t]
1115 cperl-use-syntax-table-text-property] 1246 ["Refresh \"hard\" constructions" cperl-find-pods-heres t]
1116 ["Contract a group" cperl-contract-level 1247 "----"
1117 cperl-use-syntax-table-text-property] 1248 ["Indent region" cperl-indent-region (cperl-use-region-p)]
1118 ["Contract groups" cperl-contract-levels 1249 ["Comment region" cperl-comment-region (cperl-use-region-p)]
1119 cperl-use-syntax-table-text-property]) 1250 ["Uncomment region" cperl-uncomment-region (cperl-use-region-p)]
1120 ["Refresh \"hard\" constructions" cperl-find-pods-heres t] 1251 "----"
1252 ["Run" mode-compile (fboundp 'mode-compile)]
1253 ["Kill" mode-compile-kill (and (fboundp 'mode-compile-kill)
1254 (get-buffer "*compilation*"))]
1255 ["Next error" next-error (get-buffer "*compilation*")]
1256 ["Check syntax" cperl-check-syntax (fboundp 'mode-compile)]
1257 "----"
1258 ["Debugger" cperl-db t]
1259 "----"
1260 ("Tools"
1261 ["Imenu" imenu (fboundp 'imenu)]
1262 ["Imenu on Perl Info" cperl-imenu-on-info (featurep 'imenu)]
1121 "----" 1263 "----"
1122 ["Indent region" cperl-indent-region (cperl-use-region-p)] 1264 ["Ispell PODs" cperl-pod-spell
1123 ["Comment region" cperl-comment-region (cperl-use-region-p)] 1265 ;; Better not to update syntaxification here:
1124 ["Uncomment region" cperl-uncomment-region (cperl-use-region-p)] 1266 ;; debugging syntaxificatio can be broken by this???
1267 (or
1268 (get-text-property (point-min) 'in-pod)
1269 (< (progn
1270 (and cperl-syntaxify-for-menu
1271 (cperl-update-syntaxification (point-max) (point-max)))
1272 (next-single-property-change (point-min) 'in-pod nil (point-max)))
1273 (point-max)))]
1274 ["Ispell HERE-DOCs" cperl-here-doc-spell
1275 (< (progn
1276 (and cperl-syntaxify-for-menu
1277 (cperl-update-syntaxification (point-max) (point-max)))
1278 (next-single-property-change (point-min) 'here-doc-group nil (point-max)))
1279 (point-max))]
1280 ["Narrow to this HERE-DOC" cperl-narrow-to-here-doc
1281 (eq 'here-doc (progn
1282 (and cperl-syntaxify-for-menu
1283 (cperl-update-syntaxification (point) (point)))
1284 (get-text-property (point) 'syntax-type)))]
1285 ["Select this HERE-DOC or POD section"
1286 cperl-select-this-pod-or-here-doc
1287 (memq (progn
1288 (and cperl-syntaxify-for-menu
1289 (cperl-update-syntaxification (point) (point)))
1290 (get-text-property (point) 'syntax-type))
1291 '(here-doc pod))]
1125 "----" 1292 "----"
1126 ["Run" mode-compile (fboundp 'mode-compile)] 1293 ["CPerl pretty print (exprmntl)" cperl-ps-print
1127 ["Kill" mode-compile-kill (and (fboundp 'mode-compile-kill) 1294 (fboundp 'ps-extend-face-list)]
1128 (get-buffer "*compilation*"))]
1129 ["Next error" next-error (get-buffer "*compilation*")]
1130 ["Check syntax" cperl-check-syntax (fboundp 'mode-compile)]
1131 "----" 1295 "----"
1132 ["Debugger" cperl-db t] 1296 ["Syntaxify region" cperl-find-pods-heres-region
1297 (cperl-use-region-p)]
1298 ["Profile syntaxification" cperl-time-fontification t]
1299 ["Debug errors in delayed fontification" cperl-emulate-lazy-lock t]
1300 ["Debug unwind for syntactic scan" cperl-toggle-set-debug-unwind t]
1301 ["Debug backtrace on syntactic scan (BEWARE!!!)"
1302 (cperl-toggle-set-debug-unwind nil t) t]
1133 "----" 1303 "----"
1134 ("Tools" 1304 ["Class Hierarchy from TAGS" cperl-tags-hier-init t]
1135 ["Imenu" imenu (fboundp 'imenu)] 1305 ;;["Update classes" (cperl-tags-hier-init t) tags-table-list]
1136 ["Insert spaces if needed" cperl-find-bad-style t] 1306 ("Tags"
1137 ["Class Hierarchy from TAGS" cperl-tags-hier-init t]
1138 ;;["Update classes" (cperl-tags-hier-init t) tags-table-list]
1139 ["CPerl pretty print (exprmntl)" cperl-ps-print
1140 (fboundp 'ps-extend-face-list)]
1141 ["Imenu on info" cperl-imenu-on-info (featurep 'imenu)]
1142 ("Tags"
1143;;; ["Create tags for current file" cperl-etags t] 1307;;; ["Create tags for current file" cperl-etags t]
1144;;; ["Add tags for current file" (cperl-etags t) t] 1308;;; ["Add tags for current file" (cperl-etags t) t]
1145;;; ["Create tags for Perl files in directory" (cperl-etags nil t) t] 1309;;; ["Create tags for Perl files in directory" (cperl-etags nil t) t]
@@ -1186,10 +1350,10 @@ the faces: please specify bold, italic, underline, shadow and box.)
1186 ["PerlStyle" (cperl-set-style "PerlStyle") t] 1350 ["PerlStyle" (cperl-set-style "PerlStyle") t]
1187 ["GNU" (cperl-set-style "GNU") t] 1351 ["GNU" (cperl-set-style "GNU") t]
1188 ["C++" (cperl-set-style "C++") t] 1352 ["C++" (cperl-set-style "C++") t]
1189 ["FSF" (cperl-set-style "FSF") t] 1353 ["K&R" (cperl-set-style "K&R") t]
1190 ["BSD" (cperl-set-style "BSD") t] 1354 ["BSD" (cperl-set-style "BSD") t]
1191 ["Whitesmith" (cperl-set-style "Whitesmith") t] 1355 ["Whitesmith" (cperl-set-style "Whitesmith") t]
1192 ["Current" (cperl-set-style "Current") t] 1356 ["Memorize Current" (cperl-set-style "Current") t]
1193 ["Memorized" (cperl-set-style-back) cperl-old-style]) 1357 ["Memorized" (cperl-set-style-back) cperl-old-style])
1194 ("Micro-docs" 1358 ("Micro-docs"
1195 ["Tips" (describe-variable 'cperl-tips) t] 1359 ["Tips" (describe-variable 'cperl-tips) t]
@@ -1208,12 +1372,73 @@ the faces: please specify bold, italic, underline, shadow and box.)
1208The expansion is entirely correct because it uses the C preprocessor." 1372The expansion is entirely correct because it uses the C preprocessor."
1209 t) 1373 t)
1210 1374
1375;;; These two must be unwound, otherwise take exponential time
1376(defconst cperl-maybe-white-and-comment-rex "[ \t\n]*\\(#[^\n]*\n[ \t\n]*\\)*"
1377"Regular expression to match optional whitespace with interpspersed comments.
1378Should contain exactly one group.")
1379
1380;;; This one is tricky to unwind; still very inefficient...
1381(defconst cperl-white-and-comment-rex "\\([ \t\n]\\|#[^\n]*\n\\)+"
1382"Regular expression to match whitespace with interpspersed comments.
1383Should contain exactly one group.")
1384
1385
1386;;; Is incorporated in `cperl-imenu--function-name-regexp-perl'
1387;;; `cperl-outline-regexp', `defun-prompt-regexp'.
1388;;; Details of groups in this may be used in several functions; see comments
1389;;; near mentioned above variable(s)...
1390;;; sub($$):lvalue{} sub:lvalue{} Both allowed...
1391(defsubst cperl-after-sub-regexp (named attr) ; 9 groups without attr...
1392 "Match the text after `sub' in a subroutine declaration.
1393If NAMED is nil, allows anonymous subroutines. Matches up to the first \":\"
1394of attributes (if present), or end of the name or prototype (whatever is
1395the last)."
1396 (concat ; Assume n groups before this...
1397 "\\(" ; n+1=name-group
1398 cperl-white-and-comment-rex ; n+2=pre-name
1399 "\\(::[a-zA-Z_0-9:']+\\|[a-zA-Z_'][a-zA-Z_0-9:']*\\)" ; n+3=name
1400 "\\)" ; END n+1=name-group
1401 (if named "" "?")
1402 "\\(" ; n+4=proto-group
1403 cperl-maybe-white-and-comment-rex ; n+5=pre-proto
1404 "\\(([^()]*)\\)" ; n+6=prototype
1405 "\\)?" ; END n+4=proto-group
1406 "\\(" ; n+7=attr-group
1407 cperl-maybe-white-and-comment-rex ; n+8=pre-attr
1408 "\\(" ; n+9=start-attr
1409 ":"
1410 (if attr (concat
1411 "\\("
1412 cperl-maybe-white-and-comment-rex ; whitespace-comments
1413 "\\(\\sw\\|_\\)+" ; attr-name
1414 ;; attr-arg (1 level of internal parens allowed!)
1415 "\\((\\(\\\\.\\|[^\\\\()]\\|([^\\\\()]*)\\)*)\\)?"
1416 "\\(" ; optional : (XXX allows trailing???)
1417 cperl-maybe-white-and-comment-rex ; whitespace-comments
1418 ":\\)?"
1419 "\\)+")
1420 "[^:]")
1421 "\\)"
1422 "\\)?" ; END n+6=proto-group
1423 ))
1424
1425;;; Details of groups in this are used in `cperl-imenu--create-perl-index'
1426;;; and `cperl-outline-level'.
1427;;;; Was: 2=sub|package; now 2=package-group, 5=package-name 8=sub-name (+3)
1211(defvar cperl-imenu--function-name-regexp-perl 1428(defvar cperl-imenu--function-name-regexp-perl
1212 (concat 1429 (concat
1213 "^\\(" 1430 "^\\(" ; 1 = all
1214 "[ \t]*\\(sub\\|package\\)[ \t\n]+\\([a-zA-Z_0-9:']+\\)[ \t]*\\(([^()]*)[ \t]*\\)?" 1431 "\\([ \t]*package" ; 2 = package-group
1215 "\\|" 1432 "\\(" ; 3 = package-name-group
1216 "=head\\([12]\\)[ \t]+\\([^\n]+\\)$" 1433 cperl-white-and-comment-rex ; 4 = pre-package-name
1434 "\\([a-zA-Z_0-9:']+\\)\\)?\\)" ; 5 = package-name
1435 "\\|"
1436 "[ \t]*sub"
1437 (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
1438 cperl-maybe-white-and-comment-rex ; 15=pre-block
1439 "\\|"
1440 "=head\\([1-4]\\)[ \t]+" ; 16=level
1441 "\\([^\n]+\\)$" ; 17=text
1217 "\\)")) 1442 "\\)"))
1218 1443
1219(defvar cperl-outline-regexp 1444(defvar cperl-outline-regexp
@@ -1225,6 +1450,12 @@ The expansion is entirely correct because it uses the C preprocessor."
1225(defvar cperl-string-syntax-table nil 1450(defvar cperl-string-syntax-table nil
1226 "Syntax table in use in CPerl mode string-like chunks.") 1451 "Syntax table in use in CPerl mode string-like chunks.")
1227 1452
1453(defsubst cperl-1- (p)
1454 (max (point-min) (1- p)))
1455
1456(defsubst cperl-1+ (p)
1457 (min (point-max) (1+ p)))
1458
1228(if cperl-mode-syntax-table 1459(if cperl-mode-syntax-table
1229 () 1460 ()
1230 (setq cperl-mode-syntax-table (make-syntax-table)) 1461 (setq cperl-mode-syntax-table (make-syntax-table))
@@ -1249,6 +1480,8 @@ The expansion is entirely correct because it uses the C preprocessor."
1249 (modify-syntax-entry ?| "." cperl-mode-syntax-table) 1480 (modify-syntax-entry ?| "." cperl-mode-syntax-table)
1250 (setq cperl-string-syntax-table (copy-syntax-table cperl-mode-syntax-table)) 1481 (setq cperl-string-syntax-table (copy-syntax-table cperl-mode-syntax-table))
1251 (modify-syntax-entry ?$ "." cperl-string-syntax-table) 1482 (modify-syntax-entry ?$ "." cperl-string-syntax-table)
1483 (modify-syntax-entry ?\{ "." cperl-string-syntax-table)
1484 (modify-syntax-entry ?\} "." cperl-string-syntax-table)
1252 (modify-syntax-entry ?# "." cperl-string-syntax-table)) ; (?# comment ) 1485 (modify-syntax-entry ?# "." cperl-string-syntax-table)) ; (?# comment )
1253 1486
1254 1487
@@ -1257,6 +1490,10 @@ The expansion is entirely correct because it uses the C preprocessor."
1257;; Fix for msb.el 1490;; Fix for msb.el
1258(defvar cperl-msb-fixed nil) 1491(defvar cperl-msb-fixed nil)
1259(defvar cperl-use-major-mode 'cperl-mode) 1492(defvar cperl-use-major-mode 'cperl-mode)
1493(defvar cperl-font-lock-multiline-start nil)
1494(defvar cperl-font-lock-multiline nil)
1495(defvar cperl-compilation-error-regexp-alist nil)
1496(defvar cperl-font-locking nil)
1260 1497
1261;;;###autoload 1498;;;###autoload
1262(defun cperl-mode () 1499(defun cperl-mode ()
@@ -1402,16 +1639,24 @@ Variables controlling indentation style:
1402 `cperl-min-label-indent' 1639 `cperl-min-label-indent'
1403 Minimal indentation for line that is a label. 1640 Minimal indentation for line that is a label.
1404 1641
1405Settings for K&R and BSD indentation styles are 1642Settings for classic indent-styles: K&R BSD=C++ GNU PerlStyle=Whitesmith
1406 `cperl-indent-level' 5 8 1643 `cperl-indent-level' 5 4 2 4
1407 `cperl-continued-statement-offset' 5 8 1644 `cperl-brace-offset' 0 0 0 0
1408 `cperl-brace-offset' -5 -8 1645 `cperl-continued-brace-offset' -5 -4 0 0
1409 `cperl-label-offset' -5 -8 1646 `cperl-label-offset' -5 -4 -2 -4
1647 `cperl-continued-statement-offset' 5 4 2 4
1410 1648
1411CPerl knows several indentation styles, and may bulk set the 1649CPerl knows several indentation styles, and may bulk set the
1412corresponding variables. Use \\[cperl-set-style] to do this. Use 1650corresponding variables. Use \\[cperl-set-style] to do this. Use
1413\\[cperl-set-style-back] to restore the memorized preexisting values 1651\\[cperl-set-style-back] to restore the memorized preexisting values
1414\(both available from menu). 1652\(both available from menu). See examples in `cperl-style-examples'.
1653
1654Part of the indentation style is how different parts of if/elsif/else
1655statements are broken into lines; in CPerl, this is reflected on how
1656templates for these constructs are created (controlled by
1657`cperl-extra-newline-before-brace'), and how reflow-logic should treat \"continuation\" blocks of else/elsif/continue, controlled by the same variable,
1658and by `cperl-extra-newline-before-brace-multiline',
1659`cperl-merge-trailing-else', `cperl-indent-region-fix-constructs'.
1415 1660
1416If `cperl-indent-level' is 0, the statement after opening brace in 1661If `cperl-indent-level' is 0, the statement after opening brace in
1417column 0 is indented on 1662column 0 is indented on
@@ -1465,8 +1710,12 @@ or as help on variables `cperl-tips', `cperl-problems',
1465 ("head2" "head2" cperl-electric-pod 0))) 1710 ("head2" "head2" cperl-electric-pod 0)))
1466 (setq abbrevs-changed prev-a-c))) 1711 (setq abbrevs-changed prev-a-c)))
1467 (setq local-abbrev-table cperl-mode-abbrev-table) 1712 (setq local-abbrev-table cperl-mode-abbrev-table)
1468 (abbrev-mode (if (cperl-val 'cperl-electric-keywords) 1 0)) 1713 (if (cperl-val 'cperl-electric-keywords)
1714 (abbrev-mode 1))
1469 (set-syntax-table cperl-mode-syntax-table) 1715 (set-syntax-table cperl-mode-syntax-table)
1716 ;; Until Emacs is multi-threaded, we do not actually need it local:
1717 (make-local-variable 'cperl-font-lock-multiline-start)
1718 (make-local-variable 'cperl-font-locking)
1470 (make-local-variable 'outline-regexp) 1719 (make-local-variable 'outline-regexp)
1471 ;; (setq outline-regexp imenu-example--function-name-regexp-perl) 1720 ;; (setq outline-regexp imenu-example--function-name-regexp-perl)
1472 (setq outline-regexp cperl-outline-regexp) 1721 (setq outline-regexp cperl-outline-regexp)
@@ -1478,7 +1727,10 @@ or as help on variables `cperl-tips', `cperl-problems',
1478 (setq paragraph-separate paragraph-start) 1727 (setq paragraph-separate paragraph-start)
1479 (make-local-variable 'paragraph-ignore-fill-prefix) 1728 (make-local-variable 'paragraph-ignore-fill-prefix)
1480 (setq paragraph-ignore-fill-prefix t) 1729 (setq paragraph-ignore-fill-prefix t)
1481 (set (make-local-variable 'fill-paragraph-function) 'cperl-fill-paragraph) 1730 (if cperl-xemacs-p
1731 (progn
1732 (make-local-variable 'paren-backwards-message)
1733 (set 'paren-backwards-message t)))
1482 (make-local-variable 'indent-line-function) 1734 (make-local-variable 'indent-line-function)
1483 (setq indent-line-function 'cperl-indent-line) 1735 (setq indent-line-function 'cperl-indent-line)
1484 (make-local-variable 'require-final-newline) 1736 (make-local-variable 'require-final-newline)
@@ -1492,9 +1744,22 @@ or as help on variables `cperl-tips', `cperl-problems',
1492 (make-local-variable 'comment-start-skip) 1744 (make-local-variable 'comment-start-skip)
1493 (setq comment-start-skip "#+ *") 1745 (setq comment-start-skip "#+ *")
1494 (make-local-variable 'defun-prompt-regexp) 1746 (make-local-variable 'defun-prompt-regexp)
1495 (setq defun-prompt-regexp "^[ \t]*sub[ \t\n]+\\([^ \t\n{(;]+\\)\\([ \t\n]*([^()]*)[ \t\n]*\\)?[ \t\n]*") 1747;;; "[ \t]*sub"
1748;;; (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
1749;;; cperl-maybe-white-and-comment-rex ; 15=pre-block
1750 (setq defun-prompt-regexp
1751 (concat "^[ \t]*\\(sub"
1752 (cperl-after-sub-regexp 'named 'attr-groups)
1753 "\\|" ; per toke.c
1754 "\\(BEGIN\\|CHECK\\|INIT\\|END\\|AUTOLOAD\\|DESTROY\\)"
1755 "\\)"
1756 cperl-maybe-white-and-comment-rex))
1496 (make-local-variable 'comment-indent-function) 1757 (make-local-variable 'comment-indent-function)
1497 (setq comment-indent-function 'cperl-comment-indent) 1758 (setq comment-indent-function 'cperl-comment-indent)
1759 (and (boundp 'fill-paragraph-function)
1760 (progn
1761 (make-local-variable 'fill-paragraph-function)
1762 (set 'fill-paragraph-function 'cperl-fill-paragraph)))
1498 (make-local-variable 'parse-sexp-ignore-comments) 1763 (make-local-variable 'parse-sexp-ignore-comments)
1499 (setq parse-sexp-ignore-comments t) 1764 (setq parse-sexp-ignore-comments t)
1500 (make-local-variable 'indent-region-function) 1765 (make-local-variable 'indent-region-function)
@@ -1509,21 +1774,40 @@ or as help on variables `cperl-tips', `cperl-problems',
1509 (set 'vc-rcs-header cperl-vc-rcs-header) 1774 (set 'vc-rcs-header cperl-vc-rcs-header)
1510 (make-local-variable 'vc-sccs-header) 1775 (make-local-variable 'vc-sccs-header)
1511 (set 'vc-sccs-header cperl-vc-sccs-header) 1776 (set 'vc-sccs-header cperl-vc-sccs-header)
1777 ;; This one is obsolete...
1778 (make-local-variable 'vc-header-alist)
1779 (set 'vc-header-alist (or cperl-vc-header-alist ; Avoid warning
1780 (` ((SCCS (, (car cperl-vc-sccs-header)))
1781 (RCS (, (car cperl-vc-rcs-header)))))))
1782 (cond ((boundp 'compilation-error-regexp-alist-alist);; xemacs 20.x
1783 (make-local-variable 'compilation-error-regexp-alist-alist)
1784 (set 'compilation-error-regexp-alist-alist
1785 (cons (cons 'cperl cperl-compilation-error-regexp-alist)
1786 (symbol-value 'compilation-error-regexp-alist-alist)))
1787 (if (fboundp 'compilation-build-compilation-error-regexp-alist)
1788 (let ((f 'compilation-build-compilation-error-regexp-alist))
1789 (funcall f))
1790 (push 'cperl compilation-error-regexp-alist)))
1791 ((boundp 'compilation-error-regexp-alist);; xmeacs 19.x
1792 (make-local-variable 'compilation-error-regexp-alist)
1793 (set 'compilation-error-regexp-alist
1794 (cons cperl-compilation-error-regexp-alist
1795 (symbol-value 'compilation-error-regexp-alist)))))
1512 (make-local-variable 'font-lock-defaults) 1796 (make-local-variable 'font-lock-defaults)
1513 (setq font-lock-defaults 1797 (setq font-lock-defaults
1514 (cond 1798 (cond
1515 ((string< emacs-version "19.30") 1799 ((string< emacs-version "19.30")
1516 '(cperl-font-lock-keywords-2)) 1800 '(cperl-font-lock-keywords-2 nil nil ((?_ . "w"))))
1517 ((string< emacs-version "19.33") ; Which one to use? 1801 ((string< emacs-version "19.33") ; Which one to use?
1518 '((cperl-font-lock-keywords 1802 '((cperl-font-lock-keywords
1519 cperl-font-lock-keywords-1 1803 cperl-font-lock-keywords-1
1520 cperl-font-lock-keywords-2))) 1804 cperl-font-lock-keywords-2) nil nil ((?_ . "w"))))
1521 (t 1805 (t
1522 '((cperl-load-font-lock-keywords 1806 '((cperl-load-font-lock-keywords
1523 cperl-load-font-lock-keywords-1 1807 cperl-load-font-lock-keywords-1
1524 cperl-load-font-lock-keywords-2) 1808 cperl-load-font-lock-keywords-2) nil nil ((?_ . "w"))))))
1525 nil nil ((?_ . "w"))))))
1526 (make-local-variable 'cperl-syntax-state) 1809 (make-local-variable 'cperl-syntax-state)
1810 (setq cperl-syntax-state nil) ; reset syntaxification cache
1527 (if cperl-use-syntax-table-text-property 1811 (if cperl-use-syntax-table-text-property
1528 (progn 1812 (progn
1529 (make-local-variable 'parse-sexp-lookup-properties) 1813 (make-local-variable 'parse-sexp-lookup-properties)
@@ -1533,10 +1817,12 @@ or as help on variables `cperl-tips', `cperl-problems',
1533 (or (boundp 'font-lock-unfontify-region-function) 1817 (or (boundp 'font-lock-unfontify-region-function)
1534 (set 'font-lock-unfontify-region-function 1818 (set 'font-lock-unfontify-region-function
1535 'font-lock-default-unfontify-region)) 1819 'font-lock-default-unfontify-region))
1536 (make-local-variable 'font-lock-unfontify-region-function) 1820 (unless cperl-xemacs-p ; Our: just a plug for wrong font-lock
1537 (set 'font-lock-unfontify-region-function ; not present with old Emacs 1821 (make-local-variable 'font-lock-unfontify-region-function)
1538 'cperl-font-lock-unfontify-region-function) 1822 (set 'font-lock-unfontify-region-function ; not present with old Emacs
1823 'cperl-font-lock-unfontify-region-function))
1539 (make-local-variable 'cperl-syntax-done-to) 1824 (make-local-variable 'cperl-syntax-done-to)
1825 (setq cperl-syntax-done-to nil) ; reset syntaxification cache
1540 (make-local-variable 'font-lock-syntactic-keywords) 1826 (make-local-variable 'font-lock-syntactic-keywords)
1541 (setq font-lock-syntactic-keywords 1827 (setq font-lock-syntactic-keywords
1542 (if cperl-syntaxify-by-font-lock 1828 (if cperl-syntaxify-by-font-lock
@@ -1546,10 +1832,20 @@ or as help on variables `cperl-tips', `cperl-problems',
1546 ;; to make font-lock think that font-lock-syntactic-keywords 1832 ;; to make font-lock think that font-lock-syntactic-keywords
1547 ;; are defined. 1833 ;; are defined.
1548 '(t))))) 1834 '(t)))))
1835 (if (boundp 'font-lock-multiline) ; Newer font-lock; use its facilities
1836 (progn
1837 (setq cperl-font-lock-multiline t) ; Not localized...
1838 (set 'font-lock-multiline t)) ; not present with old Emacs; auto-local
1839 (make-local-variable 'font-lock-fontify-region-function)
1840 (set 'font-lock-fontify-region-function ; not present with old Emacs
1841 'cperl-font-lock-fontify-region-function))
1842 (make-local-variable 'font-lock-fontify-region-function)
1843 (set 'font-lock-fontify-region-function ; not present with old Emacs
1844 'cperl-font-lock-fontify-region-function)
1549 (make-local-variable 'cperl-old-style) 1845 (make-local-variable 'cperl-old-style)
1550 (if (boundp 'normal-auto-fill-function) ; 19.33 and later 1846 (if (boundp 'normal-auto-fill-function) ; 19.33 and later
1551 (set (make-local-variable 'normal-auto-fill-function) 1847 (set (make-local-variable 'normal-auto-fill-function)
1552 'cperl-do-auto-fill) ; RMS has it as #'cperl-do-auto-fill ??? 1848 'cperl-do-auto-fill)
1553 (or (fboundp 'cperl-old-auto-fill-mode) 1849 (or (fboundp 'cperl-old-auto-fill-mode)
1554 (progn 1850 (progn
1555 (fset 'cperl-old-auto-fill-mode (symbol-function 'auto-fill-mode)) 1851 (fset 'cperl-old-auto-fill-mode (symbol-function 'auto-fill-mode))
@@ -1562,12 +1858,18 @@ or as help on variables `cperl-tips', `cperl-problems',
1562 (if (cperl-val 'cperl-font-lock) 1858 (if (cperl-val 'cperl-font-lock)
1563 (progn (or cperl-faces-init (cperl-init-faces)) 1859 (progn (or cperl-faces-init (cperl-init-faces))
1564 (font-lock-mode 1)))) 1860 (font-lock-mode 1))))
1861 (set (make-local-variable 'facemenu-add-face-function)
1862 'cperl-facemenu-add-face-function) ; XXXX What this guy is for???
1565 (and (boundp 'msb-menu-cond) 1863 (and (boundp 'msb-menu-cond)
1566 (not cperl-msb-fixed) 1864 (not cperl-msb-fixed)
1567 (cperl-msb-fix)) 1865 (cperl-msb-fix))
1568 (if (featurep 'easymenu) 1866 (if (featurep 'easymenu)
1569 (easy-menu-add cperl-menu)) ; A NOP in Emacs. 1867 (easy-menu-add cperl-menu)) ; A NOP in Emacs.
1570 (run-mode-hooks 'cperl-mode-hook) 1868 (run-mode-hooks 'cperl-mode-hook)
1869 (if cperl-hook-after-change
1870 (progn
1871 (make-local-hook 'after-change-functions)
1872 (add-hook 'after-change-functions 'cperl-after-change-function nil t)))
1571 ;; After hooks since fontification will break this 1873 ;; After hooks since fontification will break this
1572 (if cperl-pod-here-scan 1874 (if cperl-pod-here-scan
1573 (or cperl-syntaxify-by-font-lock 1875 (or cperl-syntaxify-by-font-lock
@@ -1616,31 +1918,37 @@ or as help on variables `cperl-tips', `cperl-problems',
1616(defvar cperl-st-ket '(5 . ?\<)) 1918(defvar cperl-st-ket '(5 . ?\<))
1617 1919
1618 1920
1619(defun cperl-comment-indent () 1921(defun cperl-comment-indent () ; called at point at supposed comment
1620 (let ((p (point)) (c (current-column)) was phony) 1922 (let ((p (point)) (c (current-column)) was phony)
1621 (if (looking-at "^#") 0 ; Existing comment at bol stays there. 1923 (if (and (not cperl-indent-comment-at-column-0)
1924 (looking-at "^#"))
1925 0 ; Existing comment at bol stays there.
1622 ;; Wrong comment found 1926 ;; Wrong comment found
1623 (save-excursion 1927 (save-excursion
1624 (setq was (cperl-to-comment-or-eol) 1928 (setq was (cperl-to-comment-or-eol)
1625 phony (eq (get-text-property (point) 'syntax-table) 1929 phony (eq (get-text-property (point) 'syntax-table)
1626 cperl-st-cfence)) 1930 cperl-st-cfence))
1627 (if phony 1931 (if phony
1628 (progn 1932 (progn ; Too naive???
1629 (re-search-forward "#\\|$") ; Hmm, what about embedded #? 1933 (re-search-forward "#\\|$") ; Hmm, what about embedded #?
1630 (if (eq (preceding-char) ?\#) 1934 (if (eq (preceding-char) ?\#)
1631 (forward-char -1)) 1935 (forward-char -1))
1632 (setq was nil))) 1936 (setq was nil)))
1633 (if (= (point) p) 1937 (if (= (point) p) ; Our caller found a correct place
1634 (progn 1938 (progn
1635 (skip-chars-backward " \t") 1939 (skip-chars-backward " \t")
1636 (max (1+ (current-column)) ; Else indent at comment column 1940 (setq was (current-column))
1637 comment-column)) 1941 (if (eq was 0)
1942 comment-column
1943 (max (1+ was) ; Else indent at comment column
1944 comment-column)))
1945 ;; No, the caller found a random place; we need to edit ourselves
1638 (if was nil 1946 (if was nil
1639 (insert comment-start) 1947 (insert comment-start)
1640 (backward-char (length comment-start))) 1948 (backward-char (length comment-start)))
1641 (setq cperl-wrong-comment t) 1949 (setq cperl-wrong-comment t)
1642 (indent-to comment-column 1) ; Indent minimum 1 1950 (cperl-make-indent comment-column 1) ; Indent min 1
1643 c))))) ; except leave at least one space. 1951 c)))))
1644 1952
1645;;;(defun cperl-comment-indent-fallback () 1953;;;(defun cperl-comment-indent-fallback ()
1646;;; "Is called if the standard comment-search procedure fails. 1954;;; "Is called if the standard comment-search procedure fails.
@@ -1666,7 +1974,7 @@ or as help on variables `cperl-tips', `cperl-problems',
1666 (interactive) 1974 (interactive)
1667 (let (cperl-wrong-comment) 1975 (let (cperl-wrong-comment)
1668 (indent-for-comment) 1976 (indent-for-comment)
1669 (if cperl-wrong-comment 1977 (if cperl-wrong-comment ; set by `cperl-comment-indent'
1670 (progn (cperl-to-comment-or-eol) 1978 (progn (cperl-to-comment-or-eol)
1671 (forward-char (length comment-start)))))) 1979 (forward-char (length comment-start))))))
1672 1980
@@ -1966,15 +2274,10 @@ to nil."
1966 (or 2274 (or
1967 (get-text-property (point) 'in-pod) 2275 (get-text-property (point) 'in-pod)
1968 (cperl-after-expr-p nil "{;:") 2276 (cperl-after-expr-p nil "{;:")
1969 (and (re-search-backward 2277 (and (re-search-backward "\\(\\`\n?\\|^\n\\)=\\sw+" (point-min) t)
1970 ;; "\\(\\`\n?\\|\n\n\\)=\\sw+" 2278 (not (looking-at "\n*=cut"))
1971 "\\(\\`\n?\\|^\n\\)=\\sw+" 2279 (or (not cperl-use-syntax-table-text-property)
1972 (point-min) t) 2280 (eq (get-text-property (point) 'syntax-type) 'pod))))))
1973 (not (or
1974 (looking-at "=cut")
1975 (and cperl-use-syntax-table-text-property
1976 (not (eq (get-text-property (point) 'syntax-type)
1977 'pod)))))))))
1978 (progn 2281 (progn
1979 (save-excursion 2282 (save-excursion
1980 (setq notlast (re-search-forward "^\n=" nil t))) 2283 (setq notlast (re-search-forward "^\n=" nil t)))
@@ -2252,7 +2555,7 @@ key. Will untabify if `cperl-electric-backspace-untabify' is non-nil."
2252 2555
2253(put 'cperl-electric-backspace 'delete-selection 'supersede) 2556(put 'cperl-electric-backspace 'delete-selection 'supersede)
2254 2557
2255(defun cperl-inside-parens-p () 2558(defun cperl-inside-parens-p () ;; NOT USED????
2256 (condition-case () 2559 (condition-case ()
2257 (save-excursion 2560 (save-excursion
2258 (save-restriction 2561 (save-restriction
@@ -2332,8 +2635,9 @@ Return the amount the indentation changed by."
2332 (zerop shift-amt)) 2635 (zerop shift-amt))
2333 (if (> (- (point-max) pos) (point)) 2636 (if (> (- (point-max) pos) (point))
2334 (goto-char (- (point-max) pos))) 2637 (goto-char (- (point-max) pos)))
2335 (delete-region beg (point)) 2638 ;;;(delete-region beg (point))
2336 (indent-to indent) 2639 ;;;(indent-to indent)
2640 (cperl-make-indent indent)
2337 ;; If initial point was within line's indentation, 2641 ;; If initial point was within line's indentation,
2338 ;; position after the indentation. Else stay at same point in text. 2642 ;; position after the indentation. Else stay at same point in text.
2339 (if (> (- (point-max) pos) (point)) 2643 (if (> (- (point-max) pos) (point))
@@ -2380,63 +2684,55 @@ Return the amount the indentation changed by."
2380 (or state (setq state (parse-partial-sexp start start-point -1 nil start-state))) 2684 (or state (setq state (parse-partial-sexp start start-point -1 nil start-state)))
2381 (list start state depth prestart)))) 2685 (list start state depth prestart))))
2382 2686
2383(defun cperl-block-p () ; Do not C-M-q ! One string contains ";" !
2384 ;; Positions is before ?\{. Checks whether it starts a block.
2385 ;; No save-excursion!
2386 (cperl-backward-to-noncomment (point-min))
2387 (or (memq (preceding-char) (append ";){}$@&%\C-@" nil)) ; Or label! \C-@ at bobp
2388 ; Label may be mixed up with `$blah :'
2389 (save-excursion (cperl-after-label))
2390 (and (memq (char-syntax (preceding-char)) '(?w ?_))
2391 (progn
2392 (backward-sexp)
2393 ;; Need take into account `bless', `return', `tr',...
2394 (or (and (looking-at "[a-zA-Z0-9_:]+[ \t\n\f]*[{#]") ; Method call syntax
2395 (not (looking-at "\\(bless\\|return\\|q[wqrx]?\\|tr\\|[smy]\\)\\>")))
2396 (progn
2397 (skip-chars-backward " \t\n\f")
2398 (and (memq (char-syntax (preceding-char)) '(?w ?_))
2399 (progn
2400 (backward-sexp)
2401 (looking-at
2402 "sub[ \t]+[a-zA-Z0-9_:]+[ \t\n\f]*\\(([^()]*)[ \t\n\f]*\\)?[#{]")))))))))
2403
2404(defvar cperl-look-for-prop '((pod in-pod) (here-doc-delim here-doc-group))) 2687(defvar cperl-look-for-prop '((pod in-pod) (here-doc-delim here-doc-group)))
2405 2688
2406(defun cperl-calculate-indent (&optional parse-data) ; was parse-start 2689(defun cperl-beginning-of-property (p prop &optional lim)
2407 "Return appropriate indentation for current line as Perl code. 2690 "Given that P has a property PROP, find where the property starts.
2408In usual case returns an integer: the column to indent to. 2691Will not look before LIM."
2409Returns nil if line starts inside a string, t if in a comment. 2692 ;;; XXXX What to do at point-max???
2410 2693 (or (previous-single-property-change (cperl-1+ p) prop lim)
2411Will not correct the indentation for labels, but will correct it for braces 2694 (point-min))
2412and closing parentheses and brackets." 2695;;; (cond ((eq p (point-min))
2696;;; p)
2697;;; ((and lim (<= p lim))
2698;;; p)
2699;;; ((not (get-text-property (1- p) prop))
2700;;; p)
2701;;; (t (or (previous-single-property-change p look-prop lim)
2702;;; (point-min))))
2703 )
2704
2705(defun cperl-sniff-for-indent (&optional parse-data) ; was parse-start
2706 ;; Old workhorse for calculation of indentation; the major problem
2707 ;; is that it mixes the sniffer logic to understand what the current line
2708 ;; MEANS with the logic to actually calculate where to indent it.
2709 ;; The latter part should be eventually moved to `cperl-calculate-indent';
2710 ;; actually, this is mostly done now...
2413 (cperl-update-syntaxification (point) (point)) 2711 (cperl-update-syntaxification (point) (point))
2414 (save-excursion 2712 (let ((res (get-text-property (point) 'syntax-type)))
2415 (if (or 2713 (save-excursion
2416 (and (memq (get-text-property (point) 'syntax-type) 2714 (cond
2417 '(pod here-doc here-doc-delim format)) 2715 ((and (memq res '(pod here-doc here-doc-delim format))
2418 (not (get-text-property (point) 'indentable))) 2716 (not (get-text-property (point) 'indentable)))
2419 ;; before start of POD - whitespace found since do not have 'pod! 2717 (vector res))
2420 (and (looking-at "[ \t]*\n=") 2718 ;; before start of POD - whitespace found since do not have 'pod!
2421 (error "Spaces before POD section!")) 2719 ((looking-at "[ \t]*\n=")
2422 (and (not cperl-indent-left-aligned-comments) 2720 (error "Spaces before POD section!"))
2423 (looking-at "^#"))) 2721 ((and (not cperl-indent-left-aligned-comments)
2424 nil 2722 (looking-at "^#"))
2425 (beginning-of-line) 2723 [comment-special:at-beginning-of-line])
2426 (let ((indent-point (point)) 2724 ((get-text-property (point) 'in-pod)
2427 (char-after (save-excursion 2725 [in-pod])
2428 (skip-chars-forward " \t") 2726 (t
2429 (following-char))) 2727 (beginning-of-line)
2430 (in-pod (get-text-property (point) 'in-pod)) 2728 (let* ((indent-point (point))
2431 (pre-indent-point (point)) 2729 (char-after-pos (save-excursion
2432 p prop look-prop is-block delim) 2730 (skip-chars-forward " \t")
2433 (cond 2731 (point)))
2434 (in-pod 2732 (char-after (char-after char-after-pos))
2435 ;; In the verbatim part, probably code example. What to do??? 2733 (pre-indent-point (point))
2436 ) 2734 p prop look-prop is-block delim)
2437 (t 2735 (save-excursion ; Know we are not in POD, find appropriate pos before
2438 (save-excursion
2439 ;; Not in POD
2440 (cperl-backward-to-noncomment nil) 2736 (cperl-backward-to-noncomment nil)
2441 (setq p (max (point-min) (1- (point))) 2737 (setq p (max (point-min) (1- (point)))
2442 prop (get-text-property p 'syntax-type) 2738 prop (get-text-property p 'syntax-type)
@@ -2444,437 +2740,597 @@ and closing parentheses and brackets."
2444 'syntax-type)) 2740 'syntax-type))
2445 (if (memq prop '(pod here-doc format here-doc-delim)) 2741 (if (memq prop '(pod here-doc format here-doc-delim))
2446 (progn 2742 (progn
2447 (goto-char (or (previous-single-property-change p look-prop) 2743 (goto-char (cperl-beginning-of-property p look-prop))
2448 (point-min)))
2449 (beginning-of-line) 2744 (beginning-of-line)
2450 (setq pre-indent-point (point))))))) 2745 (setq pre-indent-point (point)))))
2451 (goto-char pre-indent-point) 2746 (goto-char pre-indent-point) ; Orig line skipping preceeding pod/etc
2452 (let* ((case-fold-search nil) 2747 (let* ((case-fold-search nil)
2453 (s-s (cperl-get-state (car parse-data) (nth 1 parse-data))) 2748 (s-s (cperl-get-state (car parse-data) (nth 1 parse-data)))
2454 (start (or (nth 2 parse-data) 2749 (start (or (nth 2 parse-data) ; last complete sexp terminated
2455 (nth 0 s-s))) 2750 (nth 0 s-s))) ; Good place to start parsing
2456 (state (nth 1 s-s)) 2751 (state (nth 1 s-s))
2457 (containing-sexp (car (cdr state))) 2752 (containing-sexp (car (cdr state)))
2458 old-indent) 2753 old-indent)
2459 (if (and 2754 (if (and
2460 ;;containing-sexp ;; We are buggy at toplevel :-( 2755 ;;containing-sexp ;; We are buggy at toplevel :-(
2461 parse-data) 2756 parse-data)
2462 (progn 2757 (progn
2463 (setcar parse-data pre-indent-point) 2758 (setcar parse-data pre-indent-point)
2464 (setcar (cdr parse-data) state) 2759 (setcar (cdr parse-data) state)
2465 (or (nth 2 parse-data) 2760 (or (nth 2 parse-data)
2466 (setcar (cddr parse-data) start)) 2761 (setcar (cddr parse-data) start))
2467 ;; Before this point: end of statement 2762 ;; Before this point: end of statement
2468 (setq old-indent (nth 3 parse-data)))) 2763 (setq old-indent (nth 3 parse-data))))
2469 (cond ((get-text-property (point) 'indentable) 2764 (cond ((get-text-property (point) 'indentable)
2470 ;; indent to just after the surrounding open, 2765 ;; indent to "after" the surrounding open
2471 ;; skip blanks if we do not close the expression. 2766 ;; (same offset as `cperl-beautify-regexp-piece'),
2472 (goto-char (1+ (previous-single-property-change (point) 'indentable))) 2767 ;; skip blanks if we do not close the expression.
2473 (or (memq char-after (append ")]}" nil)) 2768 (setq delim ; We do not close the expression
2474 (looking-at "[ \t]*\\(#\\|$\\)") 2769 (get-text-property
2475 (skip-chars-forward " \t")) 2770 (cperl-1+ char-after-pos) 'indentable)
2476 (current-column)) 2771 p (1+ (cperl-beginning-of-property
2477 ((or (nth 3 state) (nth 4 state)) 2772 (point) 'indentable))
2478 ;; return nil or t if should not change this line 2773 is-block ; misused for: preceeding line in REx
2479 (nth 4 state)) 2774 (save-excursion ; Find preceeding line
2480 ;; XXXX Do we need to special-case this? 2775 (cperl-backward-to-noncomment p)
2481 ((null containing-sexp) 2776 (beginning-of-line)
2482 ;; Line is at top level. May be data or function definition, 2777 (if (<= (point) p)
2483 ;; or may be function argument declaration. 2778 (progn ; get indent from the first line
2484 ;; Indent like the previous top level line 2779 (goto-char p)
2485 ;; unless that ends in a closeparen without semicolon, 2780 (skip-chars-forward " \t")
2486 ;; in which case this line is the first argument decl. 2781 (if (memq (char-after (point))
2487 (skip-chars-forward " \t") 2782 (append "#\n" nil))
2488 (+ (save-excursion 2783 nil ; Can't use intentation of this line...
2489 (goto-char start) 2784 (point)))
2490 (- (current-indentation) 2785 (skip-chars-forward " \t")
2491 (if (nth 2 s-s) cperl-indent-level 0))) 2786 (point)))
2492 (if (= char-after ?{) cperl-continued-brace-offset 0) 2787 prop (parse-partial-sexp p char-after-pos))
2493 (progn 2788 (cond ((not delim) ; End the REx, ignore is-block
2494 (cperl-backward-to-noncomment (or old-indent (point-min))) 2789 (vector 'indentable 'terminator p is-block))
2495 ;; Look at previous line that's at column 0 2790 (is-block ; Indent w.r.t. preceeding line
2496 ;; to determine whether we are in top-level decls 2791 (vector 'indentable 'cont-line char-after-pos
2497 ;; or function's arg decls. Set basic-indent accordingly. 2792 is-block char-after p))
2498 ;; Now add a little if this is a continuation line. 2793 (t ; No preceeding line...
2499 (if (or (bobp) 2794 (vector 'indentable 'first-line p))))
2500 (eq (point) old-indent) ; old-indent was at comment 2795 ((get-text-property char-after-pos 'REx-part2)
2501 (eq (preceding-char) ?\;) 2796 (vector 'REx-part2 (point)))
2502 ;; Had ?\) too 2797 ((nth 3 state)
2503 (and (eq (preceding-char) ?\}) 2798 [comment])
2504 (cperl-after-block-and-statement-beg 2799 ((nth 4 state)
2505 (point-min))) ; Was start - too close 2800 [string])
2506 (memq char-after (append ")]}" nil)) 2801 ;; XXXX Do we need to special-case this?
2507 (and (eq (preceding-char) ?\:) ; label 2802 ((null containing-sexp)
2508 (progn 2803 ;; Line is at top level. May be data or function definition,
2509 (forward-sexp -1) 2804 ;; or may be function argument declaration.
2510 (skip-chars-backward " \t") 2805 ;; Indent like the previous top level line
2511 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:"))) 2806 ;; unless that ends in a closeparen without semicolon,
2512 (get-text-property (point) 'first-format-line)) 2807 ;; in which case this line is the first argument decl.
2513 (progn 2808 (skip-chars-forward " \t")
2514 (if (and parse-data 2809 (cperl-backward-to-noncomment (or old-indent (point-min)))
2515 (not (eq char-after ?\C-j))) 2810 (setq state
2516 (setcdr (cddr parse-data) 2811 (or (bobp)
2517 (list pre-indent-point))) 2812 (eq (point) old-indent) ; old-indent was at comment
2518 0) 2813 (eq (preceding-char) ?\;)
2519 cperl-continued-statement-offset)))) 2814 ;; Had ?\) too
2520 ((not 2815 (and (eq (preceding-char) ?\})
2521 (or (setq is-block 2816 (cperl-after-block-and-statement-beg
2522 (and (setq delim (= (char-after containing-sexp) ?{)) 2817 (point-min))) ; Was start - too close
2523 (save-excursion ; Is it a hash? 2818 (memq char-after (append ")]}" nil))
2524 (goto-char containing-sexp) 2819 (and (eq (preceding-char) ?\:) ; label
2525 (cperl-block-p))))
2526 cperl-indent-parens-as-block))
2527 ;; group is an expression, not a block:
2528 ;; indent to just after the surrounding open parens,
2529 ;; skip blanks if we do not close the expression.
2530 (goto-char (1+ containing-sexp))
2531 (or (memq char-after
2532 (append (if delim "}" ")]}") nil))
2533 (looking-at "[ \t]*\\(#\\|$\\)")
2534 (skip-chars-forward " \t"))
2535 (+ (current-column)
2536 (if (and delim
2537 (eq char-after ?\}))
2538 ;; Correct indentation of trailing ?\}
2539 (+ cperl-indent-level cperl-close-paren-offset)
2540 0)))
2541;;; ((and (/= (char-after containing-sexp) ?{)
2542;;; (not cperl-indent-parens-as-block))
2543;;; ;; line is expression, not statement:
2544;;; ;; indent to just after the surrounding open,
2545;;; ;; skip blanks if we do not close the expression.
2546;;; (goto-char (1+ containing-sexp))
2547;;; (or (memq char-after (append ")]}" nil))
2548;;; (looking-at "[ \t]*\\(#\\|$\\)")
2549;;; (skip-chars-forward " \t"))
2550;;; (current-column))
2551;;; ((progn
2552;;; ;; Containing-expr starts with \{. Check whether it is a hash.
2553;;; (goto-char containing-sexp)
2554;;; (and (not (cperl-block-p))
2555;;; (not cperl-indent-parens-as-block)))
2556;;; (goto-char (1+ containing-sexp))
2557;;; (or (eq char-after ?\})
2558;;; (looking-at "[ \t]*\\(#\\|$\\)")
2559;;; (skip-chars-forward " \t"))
2560;;; (+ (current-column) ; Correct indentation of trailing ?\}
2561;;; (if (eq char-after ?\}) (+ cperl-indent-level
2562;;; cperl-close-paren-offset)
2563;;; 0)))
2564 (t
2565 ;; Statement level. Is it a continuation or a new statement?
2566 ;; Find previous non-comment character.
2567 (goto-char pre-indent-point)
2568 (cperl-backward-to-noncomment containing-sexp)
2569 ;; Back up over label lines, since they don't
2570 ;; affect whether our line is a continuation.
2571 ;; (Had \, too)
2572 (while ;;(or (eq (preceding-char) ?\,)
2573 (and (eq (preceding-char) ?:)
2574 (or ;;(eq (char-after (- (point) 2)) ?\') ; ????
2575 (memq (char-syntax (char-after (- (point) 2)))
2576 '(?w ?_))))
2577 ;;)
2578 (if (eq (preceding-char) ?\,)
2579 ;; Will go to beginning of line, essentially.
2580 ;; Will ignore embedded sexpr XXXX.
2581 (cperl-backward-to-start-of-continued-exp containing-sexp))
2582 (beginning-of-line)
2583 (cperl-backward-to-noncomment containing-sexp))
2584 ;; Now we get the answer.
2585 (if (not (or (eq (1- (point)) containing-sexp)
2586 (memq (preceding-char)
2587 (append (if is-block " ;{" " ,;{") '(nil)))
2588 (and (eq (preceding-char) ?\})
2589 (cperl-after-block-and-statement-beg
2590 containing-sexp))
2591 (get-text-property (point) 'first-format-line)))
2592 ;; This line is continuation of preceding line's statement;
2593 ;; indent `cperl-continued-statement-offset' more than the
2594 ;; previous line of the statement.
2595 ;;
2596 ;; There might be a label on this line, just
2597 ;; consider it bad style and ignore it.
2598 (progn
2599 (cperl-backward-to-start-of-continued-exp containing-sexp)
2600 (+ (if (memq char-after (append "}])" nil))
2601 0 ; Closing parenth
2602 cperl-continued-statement-offset)
2603 (if (or is-block
2604 (not delim)
2605 (not (eq char-after ?\})))
2606 0
2607 ;; Now it is a hash reference
2608 (+ cperl-indent-level cperl-close-paren-offset))
2609 (if (looking-at "\\w+[ \t]*:")
2610 (if (> (current-indentation) cperl-min-label-indent)
2611 (- (current-indentation) cperl-label-offset)
2612 ;; Do not move `parse-data', this should
2613 ;; be quick anyway (this comment comes
2614 ;; from different location):
2615 (cperl-calculate-indent))
2616 (current-column))
2617 (if (eq char-after ?\{)
2618 cperl-continued-brace-offset 0)))
2619 ;; This line starts a new statement.
2620 ;; Position following last unclosed open.
2621 (goto-char containing-sexp)
2622 ;; Is line first statement after an open-brace?
2623 (or
2624 ;; If no, find that first statement and indent like
2625 ;; it. If the first statement begins with label, do
2626 ;; not believe when the indentation of the label is too
2627 ;; small.
2628 (save-excursion
2629 (forward-char 1)
2630 (setq old-indent (current-indentation))
2631 (let ((colon-line-end 0))
2632 (while
2633 (progn (skip-chars-forward " \t\n")
2634 (looking-at "#\\|[a-zA-Z0-9_$]*:[^:]\\|=[a-zA-Z]"))
2635 ;; Skip over comments and labels following openbrace.
2636 (cond ((= (following-char) ?\#)
2637 (forward-line 1))
2638 ((= (following-char) ?\=)
2639 (goto-char
2640 (or (next-single-property-change (point) 'in-pod)
2641 (point-max)))) ; do not loop if no syntaxification
2642 ;; label:
2643 (t
2644 (save-excursion (end-of-line)
2645 (setq colon-line-end (point)))
2646 (search-forward ":"))))
2647 ;; The first following code counts
2648 ;; if it is before the line we want to indent.
2649 (and (< (point) indent-point)
2650 (if (> colon-line-end (point)) ; After label
2651 (if (> (current-indentation)
2652 cperl-min-label-indent)
2653 (- (current-indentation) cperl-label-offset)
2654 ;; Do not believe: `max' is involved
2655 (+ old-indent cperl-indent-level))
2656 (current-column)))))
2657 ;; If no previous statement,
2658 ;; indent it relative to line brace is on.
2659 ;; For open brace in column zero, don't let statement
2660 ;; start there too. If cperl-indent-level is zero,
2661 ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
2662 ;; For open-braces not the first thing in a line,
2663 ;; add in cperl-brace-imaginary-offset.
2664
2665 ;; If first thing on a line: ?????
2666 (+ (if (and (bolp) (zerop cperl-indent-level))
2667 (+ cperl-brace-offset cperl-continued-statement-offset)
2668 cperl-indent-level)
2669 (if (or is-block
2670 (not delim)
2671 (not (eq char-after ?\})))
2672 0
2673 ;; Now it is a hash reference
2674 (+ cperl-indent-level cperl-close-paren-offset))
2675 ;; Move back over whitespace before the openbrace.
2676 ;; If openbrace is not first nonwhite thing on the line,
2677 ;; add the cperl-brace-imaginary-offset.
2678 (progn (skip-chars-backward " \t")
2679 (if (bolp) 0 cperl-brace-imaginary-offset))
2680 ;; If the openbrace is preceded by a parenthesized exp,
2681 ;; move to the beginning of that;
2682 ;; possibly a different line
2683 (progn
2684 (if (eq (preceding-char) ?\))
2685 (forward-sexp -1))
2686 ;; In the case it starts a subroutine, indent with
2687 ;; respect to `sub', not with respect to the
2688 ;; first thing on the line, say in the case of
2689 ;; anonymous sub in a hash.
2690 ;;
2691 (skip-chars-backward " \t")
2692 (if (and (eq (preceding-char) ?b)
2693 (progn 2820 (progn
2694 (forward-sexp -1) 2821 (forward-sexp -1)
2695 (looking-at "sub\\>")) 2822 (skip-chars-backward " \t")
2696 (setq old-indent 2823 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:")))
2697 (nth 1 2824 (get-text-property (point) 'first-format-line)))
2698 (parse-partial-sexp 2825
2699 (save-excursion (beginning-of-line) (point)) 2826 ;; Look at previous line that's at column 0
2700 (point))))) 2827 ;; to determine whether we are in top-level decls
2701 (progn (goto-char (1+ old-indent)) 2828 ;; or function's arg decls. Set basic-indent accordingly.
2702 (skip-chars-forward " \t") 2829 ;; Now add a little if this is a continuation line.
2703 (current-column)) 2830 (and state
2704 ;; Get initial indentation of the line we are on. 2831 parse-data
2705 ;; If line starts with label, calculate label indentation 2832 (not (eq char-after ?\C-j))
2706 (if (save-excursion 2833 (setcdr (cddr parse-data)
2707 (beginning-of-line) 2834 (list pre-indent-point)))
2708 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]")) 2835 (vector 'toplevel start char-after state (nth 2 s-s)))
2709 (if (> (current-indentation) cperl-min-label-indent) 2836 ((not
2710 (- (current-indentation) cperl-label-offset) 2837 (or (setq is-block
2711 ;; Do not move `parse-data', this should 2838 (and (setq delim (= (char-after containing-sexp) ?{))
2712 ;; be quick anyway: 2839 (save-excursion ; Is it a hash?
2713 (cperl-calculate-indent)) 2840 (goto-char containing-sexp)
2714 (current-indentation)))))))))))))) 2841 (cperl-block-p))))
2715 2842 cperl-indent-parens-as-block))
2716;; (defvar cperl-indent-alist 2843 ;; group is an expression, not a block:
2717;; '((string nil) 2844 ;; indent to just after the surrounding open parens,
2718;; (comment nil) 2845 ;; skip blanks if we do not close the expression.
2719;; (toplevel 0) 2846 (goto-char (1+ containing-sexp))
2720;; (toplevel-after-parenth 2) 2847 (or (memq char-after
2721;; (toplevel-continued 2) 2848 (append (if delim "}" ")]}") nil))
2722;; (expression 1)) 2849 (looking-at "[ \t]*\\(#\\|$\\)")
2723;; "Alist of indentation rules for CPerl mode. 2850 (skip-chars-forward " \t"))
2724;; The values mean: 2851 (setq old-indent (point)) ; delim=is-brace
2725;; nil: do not indent; 2852 (vector 'in-parens char-after (point) delim containing-sexp))
2726;; number: add this amount of indentation. 2853 (t
2727 2854 ;; Statement level. Is it a continuation or a new statement?
2728;; Not finished, not used.") 2855 ;; Find previous non-comment character.
2729 2856 (goto-char pre-indent-point) ; Skip one level of POD/etc
2730;; (defun cperl-where-am-i (&optional parse-start start-state) 2857 (cperl-backward-to-noncomment containing-sexp)
2731;; ;; Unfinished 2858 ;; Back up over label lines, since they don't
2732;; "Return a list of lists ((TYPE POS)...) of good points before the point. 2859 ;; affect whether our line is a continuation.
2733;; ;; POS may be nil if it is hard to find, say, when TYPE is `string' or `comment'. 2860 ;; (Had \, too)
2734 2861 (while;;(or (eq (preceding-char) ?\,)
2735;; ;; Not finished, not used." 2862 (and (eq (preceding-char) ?:)
2736;; (save-excursion 2863 (or;;(eq (char-after (- (point) 2)) ?\') ; ????
2737;; (let* ((start-point (point)) 2864 (memq (char-syntax (char-after (- (point) 2)))
2738;; (s-s (cperl-get-state)) 2865 '(?w ?_))))
2739;; (start (nth 0 s-s)) 2866 ;;)
2740;; (state (nth 1 s-s)) 2867 ;; This is always FALSE?
2741;; (prestart (nth 3 s-s)) 2868 (if (eq (preceding-char) ?\,)
2742;; (containing-sexp (car (cdr state))) 2869 ;; Will go to beginning of line, essentially.
2743;; (case-fold-search nil) 2870 ;; Will ignore embedded sexpr XXXX.
2744;; (res (list (list 'parse-start start) (list 'parse-prestart prestart)))) 2871 (cperl-backward-to-start-of-continued-exp containing-sexp))
2745;; (cond ((nth 3 state) ; In string 2872 (beginning-of-line)
2746;; (setq res (cons (list 'string nil (nth 3 state)) res))) ; What started string 2873 (cperl-backward-to-noncomment containing-sexp))
2747;; ((nth 4 state) ; In comment 2874 ;; Now we get non-label preceeding the indent point
2748;; (setq res (cons '(comment) res))) 2875 (if (not (or (eq (1- (point)) containing-sexp)
2749;; ((null containing-sexp) 2876 (memq (preceding-char)
2750;; ;; Line is at top level. 2877 (append (if is-block " ;{" " ,;{") '(nil)))
2751;; ;; Indent like the previous top level line 2878 (and (eq (preceding-char) ?\})
2752;; ;; unless that ends in a closeparen without semicolon, 2879 (cperl-after-block-and-statement-beg
2753;; ;; in which case this line is the first argument decl. 2880 containing-sexp))
2754;; (cperl-backward-to-noncomment (or parse-start (point-min))) 2881 (get-text-property (point) 'first-format-line)))
2755;; ;;(skip-chars-backward " \t\f\n") 2882 ;; This line is continuation of preceding line's statement;
2756;; (cond 2883 ;; indent `cperl-continued-statement-offset' more than the
2757;; ((or (bobp) 2884 ;; previous line of the statement.
2758;; (memq (preceding-char) (append ";}" nil))) 2885 ;;
2759;; (setq res (cons (list 'toplevel start) res))) 2886 ;; There might be a label on this line, just
2760;; ((eq (preceding-char) ?\) ) 2887 ;; consider it bad style and ignore it.
2761;; (setq res (cons (list 'toplevel-after-parenth start) res))) 2888 (progn
2762;; (t 2889 (cperl-backward-to-start-of-continued-exp containing-sexp)
2763;; (setq res (cons (list 'toplevel-continued start) res))))) 2890 (vector 'continuation (point) char-after is-block delim))
2764;; ((/= (char-after containing-sexp) ?{) 2891 ;; This line starts a new statement.
2765;; ;; line is expression, not statement: 2892 ;; Position following last unclosed open brace
2766;; ;; indent to just after the surrounding open. 2893 (goto-char containing-sexp)
2767;; ;; skip blanks if we do not close the expression. 2894 ;; Is line first statement after an open-brace?
2768;; (setq res (cons (list 'expression-blanks 2895 (or
2769;; (progn 2896 ;; If no, find that first statement and indent like
2770;; (goto-char (1+ containing-sexp)) 2897 ;; it. If the first statement begins with label, do
2771;; (or (looking-at "[ \t]*\\(#\\|$\\)") 2898 ;; not believe when the indentation of the label is too
2772;; (skip-chars-forward " \t")) 2899 ;; small.
2773;; (point))) 2900 (save-excursion
2774;; (cons (list 'expression containing-sexp) res)))) 2901 (forward-char 1)
2775;; ((progn 2902 (let ((colon-line-end 0))
2776;; ;; Containing-expr starts with \{. Check whether it is a hash. 2903 (while
2777;; (goto-char containing-sexp) 2904 (progn (skip-chars-forward " \t\n")
2778;; (not (cperl-block-p))) 2905 (looking-at "#\\|[a-zA-Z0-9_$]*:[^:]\\|=[a-zA-Z]"))
2779;; (setq res (cons (list 'expression-blanks 2906 ;; Skip over comments and labels following openbrace.
2780;; (progn 2907 (cond ((= (following-char) ?\#)
2781;; (goto-char (1+ containing-sexp)) 2908 (forward-line 1))
2782;; (or (looking-at "[ \t]*\\(#\\|$\\)") 2909 ((= (following-char) ?\=)
2783;; (skip-chars-forward " \t")) 2910 (goto-char
2784;; (point))) 2911 (or (next-single-property-change (point) 'in-pod)
2785;; (cons (list 'expression containing-sexp) res)))) 2912 (point-max)))) ; do not loop if no syntaxification
2786;; (t 2913 ;; label:
2787;; ;; Statement level. 2914 (t
2788;; (setq res (cons (list 'in-block containing-sexp) res)) 2915 (save-excursion (end-of-line)
2789;; ;; Is it a continuation or a new statement? 2916 (setq colon-line-end (point)))
2790;; ;; Find previous non-comment character. 2917 (search-forward ":"))))
2791;; (cperl-backward-to-noncomment containing-sexp) 2918 ;; We are at beginning of code (NOT label or comment)
2792;; ;; Back up over label lines, since they don't 2919 ;; First, the following code counts
2793;; ;; affect whether our line is a continuation. 2920 ;; if it is before the line we want to indent.
2794;; ;; Back up comma-delimited lines too ????? 2921 (and (< (point) indent-point)
2795;; (while (or (eq (preceding-char) ?\,) 2922 (vector 'have-prev-sibling (point) colon-line-end
2796;; (save-excursion (cperl-after-label))) 2923 containing-sexp))))
2797;; (if (eq (preceding-char) ?\,) 2924 (progn
2798;; ;; Will go to beginning of line, essentially 2925 ;; If no previous statement,
2799;; ;; Will ignore embedded sexpr XXXX. 2926 ;; indent it relative to line brace is on.
2800;; (cperl-backward-to-start-of-continued-exp containing-sexp)) 2927
2801;; (beginning-of-line) 2928 ;; For open-braces not the first thing in a line,
2802;; (cperl-backward-to-noncomment containing-sexp)) 2929 ;; add in cperl-brace-imaginary-offset.
2803;; ;; Now we get the answer. 2930
2804;; (if (not (memq (preceding-char) (append ";}{" '(nil)))) ; Was ?\, 2931 ;; If first thing on a line: ?????
2805;; ;; This line is continuation of preceding line's statement. 2932 ;; Move back over whitespace before the openbrace.
2806;; (list (list 'statement-continued containing-sexp)) 2933 (setq ; brace first thing on a line
2807;; ;; This line starts a new statement. 2934 old-indent (progn (skip-chars-backward " \t") (bolp)))
2808;; ;; Position following last unclosed open. 2935 ;; Should we indent w.r.t. earlier than start?
2809;; (goto-char containing-sexp) 2936 ;; Move to start of control group, possibly on a different line
2810;; ;; Is line first statement after an open-brace? 2937 (or cperl-indent-wrt-brace
2811;; (or 2938 (cperl-backward-to-noncomment (point-min)))
2812;; ;; If no, find that first statement and indent like 2939 ;; If the openbrace is preceded by a parenthesized exp,
2813;; ;; it. If the first statement begins with label, do 2940 ;; move to the beginning of that;
2814;; ;; not believe when the indentation of the label is too 2941 (if (eq (preceding-char) ?\))
2815;; ;; small. 2942 (progn
2816;; (save-excursion 2943 (forward-sexp -1)
2817;; (forward-char 1) 2944 (cperl-backward-to-noncomment (point-min))))
2818;; (let ((colon-line-end 0)) 2945 ;; In the case it starts a subroutine, indent with
2819;; (while (progn (skip-chars-forward " \t\n" start-point) 2946 ;; respect to `sub', not with respect to the
2820;; (and (< (point) start-point) 2947 ;; first thing on the line, say in the case of
2821;; (looking-at 2948 ;; anonymous sub in a hash.
2822;; "#\\|[a-zA-Z_][a-zA-Z0-9_]*:[^:]"))) 2949 (if (and;; Is it a sub in group starting on this line?
2823;; ;; Skip over comments and labels following openbrace. 2950 (cond ((get-text-property (point) 'attrib-group)
2824;; (cond ((= (following-char) ?\#) 2951 (goto-char (cperl-beginning-of-property
2825;; ;;(forward-line 1) 2952 (point) 'attrib-group)))
2826;; (end-of-line)) 2953 ((eq (preceding-char) ?b)
2827;; ;; label: 2954 (forward-sexp -1)
2828;; (t 2955 (looking-at "sub\\>")))
2829;; (save-excursion (end-of-line) 2956 (setq p (nth 1 ; start of innermost containing list
2830;; (setq colon-line-end (point))) 2957 (parse-partial-sexp
2831;; (search-forward ":")))) 2958 (save-excursion (beginning-of-line)
2832;; ;; Now at the point, after label, or at start 2959 (point))
2833;; ;; of first statement in the block. 2960 (point)))))
2834;; (and (< (point) start-point) 2961 (progn
2835;; (if (> colon-line-end (point)) 2962 (goto-char (1+ p)) ; enclosing block on the same line
2836;; ;; Before statement after label 2963 (skip-chars-forward " \t")
2837;; (if (> (current-indentation) 2964 (vector 'code-start-in-block containing-sexp char-after
2838;; cperl-min-label-indent) 2965 (and delim (not is-block)) ; is a HASH
2839;; (list (list 'label-in-block (point))) 2966 old-indent ; brace first thing on a line
2840;; ;; Do not believe: `max' is involved 2967 t (point) ; have something before...
2841;; (list 2968 )
2842;; (list 'label-in-block-min-indent (point)))) 2969 ;;(current-column)
2843;; ;; Before statement 2970 )
2844;; (list 'statement-in-block (point)))))) 2971 ;; Get initial indentation of the line we are on.
2845;; ;; If no previous statement, 2972 ;; If line starts with label, calculate label indentation
2846;; ;; indent it relative to line brace is on. 2973 (vector 'code-start-in-block containing-sexp char-after
2847;; ;; For open brace in column zero, don't let statement 2974 (and delim (not is-block)) ; is a HASH
2848;; ;; start there too. If cperl-indent-level is zero, 2975 old-indent ; brace first thing on a line
2849;; ;; use cperl-brace-offset + cperl-continued-statement-offset instead. 2976 nil (point) ; nothing interesting before
2850;; ;; For open-braces not the first thing in a line, 2977 ))))))))))))))
2851;; ;; add in cperl-brace-imaginary-offset. 2978
2852 2979(defvar cperl-indent-rules-alist
2853;; ;; If first thing on a line: ????? 2980 '((pod nil) ; via `syntax-type' property
2854;; (+ (if (and (bolp) (zerop cperl-indent-level)) 2981 (here-doc nil) ; via `syntax-type' property
2855;; (+ cperl-brace-offset cperl-continued-statement-offset) 2982 (here-doc-delim nil) ; via `syntax-type' property
2856;; cperl-indent-level) 2983 (format nil) ; via `syntax-type' property
2857;; ;; Move back over whitespace before the openbrace. 2984 (in-pod nil) ; via `in-pod' property
2858;; ;; If openbrace is not first nonwhite thing on the line, 2985 (comment-special:at-beginning-of-line nil)
2859;; ;; add the cperl-brace-imaginary-offset. 2986 (string t)
2860;; (progn (skip-chars-backward " \t") 2987 (comment nil))
2861;; (if (bolp) 0 cperl-brace-imaginary-offset)) 2988 "Alist of indentation rules for CPerl mode.
2862;; ;; If the openbrace is preceded by a parenthesized exp, 2989The values mean:
2863;; ;; move to the beginning of that; 2990 nil: do not indent;
2864;; ;; possibly a different line 2991 number: add this amount of indentation.
2865;; (progn 2992
2866;; (if (eq (preceding-char) ?\)) 2993Not finished.")
2867;; (forward-sexp -1)) 2994
2868;; ;; Get initial indentation of the line we are on. 2995(defun cperl-calculate-indent (&optional parse-data) ; was parse-start
2869;; ;; If line starts with label, calculate label indentation 2996 "Return appropriate indentation for current line as Perl code.
2870;; (if (save-excursion 2997In usual case returns an integer: the column to indent to.
2871;; (beginning-of-line) 2998Returns nil if line starts inside a string, t if in a comment.
2872;; (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]")) 2999
2873;; (if (> (current-indentation) cperl-min-label-indent) 3000Will not correct the indentation for labels, but will correct it for braces
2874;; (- (current-indentation) cperl-label-offset) 3001and closing parentheses and brackets."
2875;; (cperl-calculate-indent)) 3002 ;; This code is still a broken architecture: in some cases we need to
2876;; (current-indentation)))))))) 3003 ;; compensate for some modifications which `cperl-indent-line' will add later
2877;; res))) 3004 (save-excursion
3005 (let ((i (cperl-sniff-for-indent parse-data)) what p)
3006 (cond
3007 ;;((or (null i) (eq i t) (numberp i))
3008 ;; i)
3009 ((vectorp i)
3010 (setq what (assoc (elt i 0) cperl-indent-rules-alist))
3011 (cond
3012 (what (cadr what)) ; Load from table
3013 ;;
3014 ;; Indenters for regular expressions with //x and qw()
3015 ;;
3016 ((eq 'REx-part2 (elt i 0)) ;; [self start] start of /REP in s//REP/x
3017 (goto-char (elt i 1))
3018 (condition-case nil ; Use indentation of the 1st part
3019 (forward-sexp -1))
3020 (current-column))
3021 ((eq 'indentable (elt i 0)) ; Indenter for REGEXP qw() etc
3022 (cond ;;; [indentable terminator start-pos is-block]
3023 ((eq 'terminator (elt i 1)) ; Lone terminator of "indentable string"
3024 (goto-char (elt i 2)) ; After opening parens
3025 (1- (current-column)))
3026 ((eq 'first-line (elt i 1)); [indentable first-line start-pos]
3027 (goto-char (elt i 2))
3028 (+ (or cperl-regexp-indent-step cperl-indent-level)
3029 -1
3030 (current-column)))
3031 ((eq 'cont-line (elt i 1)); [indentable cont-line pos prev-pos first-char start-pos]
3032 ;; Indent as the level after closing parens
3033 (goto-char (elt i 2)) ; indent line
3034 (skip-chars-forward " \t)") ; Skip closing parens
3035 (setq p (point))
3036 (goto-char (elt i 3)) ; previous line
3037 (skip-chars-forward " \t)") ; Skip closing parens
3038 ;; Number of parens in between:
3039 (setq p (nth 0 (parse-partial-sexp (point) p))
3040 what (elt i 4)) ; First char on current line
3041 (goto-char (elt i 3)) ; previous line
3042 (+ (* p (or cperl-regexp-indent-step cperl-indent-level))
3043 (cond ((eq what ?\) )
3044 (- cperl-close-paren-offset)) ; compensate
3045 ((eq what ?\| )
3046 (- (or cperl-regexp-indent-step cperl-indent-level)))
3047 (t 0))
3048 (if (eq (following-char) ?\| )
3049 (or cperl-regexp-indent-step cperl-indent-level)
3050 0)
3051 (current-column)))
3052 (t
3053 (error "Unrecognized value of indent: %s" i))))
3054 ;;
3055 ;; Indenter for stuff at toplevel
3056 ;;
3057 ((eq 'toplevel (elt i 0)) ;; [toplevel start char-after state immed-after-block]
3058 (+ (save-excursion ; To beg-of-defun, or end of last sexp
3059 (goto-char (elt i 1)) ; start = Good place to start parsing
3060 (- (current-indentation) ;
3061 (if (elt i 4) cperl-indent-level 0))) ; immed-after-block
3062 (if (eq (elt i 2) ?{) cperl-continued-brace-offset 0) ; char-after
3063 ;; Look at previous line that's at column 0
3064 ;; to determine whether we are in top-level decls
3065 ;; or function's arg decls. Set basic-indent accordingly.
3066 ;; Now add a little if this is a continuation line.
3067 (if (elt i 3) ; state (XXX What is the semantic???)
3068 0
3069 cperl-continued-statement-offset)))
3070 ;;
3071 ;; Indenter for stuff in "parentheses" (or brackets, braces-as-hash)
3072 ;;
3073 ((eq 'in-parens (elt i 0))
3074 ;; in-parens char-after old-indent-point is-brace containing-sexp
3075
3076 ;; group is an expression, not a block:
3077 ;; indent to just after the surrounding open parens,
3078 ;; skip blanks if we do not close the expression.
3079 (+ (progn
3080 (goto-char (elt i 2)) ; old-indent-point
3081 (current-column))
3082 (if (and (elt i 3) ; is-brace
3083 (eq (elt i 1) ?\})) ; char-after
3084 ;; Correct indentation of trailing ?\}
3085 (+ cperl-indent-level cperl-close-paren-offset)
3086 0)))
3087 ;;
3088 ;; Indenter for continuation lines
3089 ;;
3090 ((eq 'continuation (elt i 0))
3091 ;; [continuation statement-start char-after is-block is-brace]
3092 (goto-char (elt i 1)) ; statement-start
3093 (+ (if (memq (elt i 2) (append "}])" nil)) ; char-after
3094 0 ; Closing parenth
3095 cperl-continued-statement-offset)
3096 (if (or (elt i 3) ; is-block
3097 (not (elt i 4)) ; is-brace
3098 (not (eq (elt i 2) ?\}))) ; char-after
3099 0
3100 ;; Now it is a hash reference
3101 (+ cperl-indent-level cperl-close-paren-offset))
3102 ;; Labels do not take :: ...
3103 (if (looking-at "\\(\\w\\|_\\)+[ \t]*:")
3104 (if (> (current-indentation) cperl-min-label-indent)
3105 (- (current-indentation) cperl-label-offset)
3106 ;; Do not move `parse-data', this should
3107 ;; be quick anyway (this comment comes
3108 ;; from different location):
3109 (cperl-calculate-indent))
3110 (current-column))
3111 (if (eq (elt i 2) ?\{) ; char-after
3112 cperl-continued-brace-offset 0)))
3113 ;;
3114 ;; Indenter for lines in a block which are not leading lines
3115 ;;
3116 ((eq 'have-prev-sibling (elt i 0))
3117 ;; [have-prev-sibling sibling-beg colon-line-end block-start]
3118 (goto-char (elt i 1))
3119 (if (> (elt i 2) (point)) ; colon-line-end; After-label, same line
3120 (if (> (current-indentation)
3121 cperl-min-label-indent)
3122 (- (current-indentation) cperl-label-offset)
3123 ;; Do not believe: `max' was involved in calculation of indent
3124 (+ cperl-indent-level
3125 (save-excursion
3126 (goto-char (elt i 3)) ; block-start
3127 (current-indentation))))
3128 (current-column)))
3129 ;;
3130 ;; Indenter for the first line in a block
3131 ;;
3132 ((eq 'code-start-in-block (elt i 0))
3133 ;;[code-start-in-block before-brace char-after
3134 ;; is-a-HASH-ref brace-is-first-thing-on-a-line
3135 ;; group-starts-before-start-of-sub start-of-control-group]
3136 (goto-char (elt i 1))
3137 ;; For open brace in column zero, don't let statement
3138 ;; start there too. If cperl-indent-level=0,
3139 ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
3140 (+ (if (and (bolp) (zerop cperl-indent-level))
3141 (+ cperl-brace-offset cperl-continued-statement-offset)
3142 cperl-indent-level)
3143 (if (and (elt i 3) ; is-a-HASH-ref
3144 (eq (elt i 2) ?\})) ; char-after: End of a hash reference
3145 (+ cperl-indent-level cperl-close-paren-offset)
3146 0)
3147 ;; Unless openbrace is the first nonwhite thing on the line,
3148 ;; add the cperl-brace-imaginary-offset.
3149 (if (elt i 4) 0 ; brace-is-first-thing-on-a-line
3150 cperl-brace-imaginary-offset)
3151 (progn
3152 (goto-char (elt i 6)) ; start-of-control-group
3153 (if (elt i 5) ; group-starts-before-start-of-sub
3154 (current-column)
3155 ;; Get initial indentation of the line we are on.
3156 ;; If line starts with label, calculate label indentation
3157 (if (save-excursion
3158 (beginning-of-line)
3159 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
3160 (if (> (current-indentation) cperl-min-label-indent)
3161 (- (current-indentation) cperl-label-offset)
3162 ;; Do not move `parse-data', this should
3163 ;; be quick anyway:
3164 (cperl-calculate-indent))
3165 (current-indentation))))))
3166 (t
3167 (error "Unrecognized value of indent: %s" i))))
3168 (t
3169 (error "Got strange value of indent: %s" i))))))
3170
3171(defvar cperl-indent-alist
3172 '((string nil)
3173 (comment nil)
3174 (toplevel 0)
3175 (toplevel-after-parenth 2)
3176 (toplevel-continued 2)
3177 (expression 1))
3178 "Alist of indentation rules for CPerl mode.
3179The values mean:
3180 nil: do not indent;
3181 number: add this amount of indentation.
3182
3183Not finished, not used.")
3184
3185(defun cperl-where-am-i (&optional parse-start start-state)
3186 ;; Unfinished
3187 "Return a list of lists ((TYPE POS)...) of good points before the point.
3188POS may be nil if it is hard to find, say, when TYPE is `string' or `comment'.
3189
3190Not finished, not used."
3191 (save-excursion
3192 (let* ((start-point (point)) unused
3193 (s-s (cperl-get-state))
3194 (start (nth 0 s-s))
3195 (state (nth 1 s-s))
3196 (prestart (nth 3 s-s))
3197 (containing-sexp (car (cdr state)))
3198 (case-fold-search nil)
3199 (res (list (list 'parse-start start) (list 'parse-prestart prestart))))
3200 (cond ((nth 3 state) ; In string
3201 (setq res (cons (list 'string nil (nth 3 state)) res))) ; What started string
3202 ((nth 4 state) ; In comment
3203 (setq res (cons '(comment) res)))
3204 ((null containing-sexp)
3205 ;; Line is at top level.
3206 ;; Indent like the previous top level line
3207 ;; unless that ends in a closeparen without semicolon,
3208 ;; in which case this line is the first argument decl.
3209 (cperl-backward-to-noncomment (or parse-start (point-min)))
3210 ;;(skip-chars-backward " \t\f\n")
3211 (cond
3212 ((or (bobp)
3213 (memq (preceding-char) (append ";}" nil)))
3214 (setq res (cons (list 'toplevel start) res)))
3215 ((eq (preceding-char) ?\) )
3216 (setq res (cons (list 'toplevel-after-parenth start) res)))
3217 (t
3218 (setq res (cons (list 'toplevel-continued start) res)))))
3219 ((/= (char-after containing-sexp) ?{)
3220 ;; line is expression, not statement:
3221 ;; indent to just after the surrounding open.
3222 ;; skip blanks if we do not close the expression.
3223 (setq res (cons (list 'expression-blanks
3224 (progn
3225 (goto-char (1+ containing-sexp))
3226 (or (looking-at "[ \t]*\\(#\\|$\\)")
3227 (skip-chars-forward " \t"))
3228 (point)))
3229 (cons (list 'expression containing-sexp) res))))
3230 ((progn
3231 ;; Containing-expr starts with \{. Check whether it is a hash.
3232 (goto-char containing-sexp)
3233 (not (cperl-block-p)))
3234 (setq res (cons (list 'expression-blanks
3235 (progn
3236 (goto-char (1+ containing-sexp))
3237 (or (looking-at "[ \t]*\\(#\\|$\\)")
3238 (skip-chars-forward " \t"))
3239 (point)))
3240 (cons (list 'expression containing-sexp) res))))
3241 (t
3242 ;; Statement level.
3243 (setq res (cons (list 'in-block containing-sexp) res))
3244 ;; Is it a continuation or a new statement?
3245 ;; Find previous non-comment character.
3246 (cperl-backward-to-noncomment containing-sexp)
3247 ;; Back up over label lines, since they don't
3248 ;; affect whether our line is a continuation.
3249 ;; Back up comma-delimited lines too ?????
3250 (while (or (eq (preceding-char) ?\,)
3251 (save-excursion (cperl-after-label)))
3252 (if (eq (preceding-char) ?\,)
3253 ;; Will go to beginning of line, essentially
3254 ;; Will ignore embedded sexpr XXXX.
3255 (cperl-backward-to-start-of-continued-exp containing-sexp))
3256 (beginning-of-line)
3257 (cperl-backward-to-noncomment containing-sexp))
3258 ;; Now we get the answer.
3259 (if (not (memq (preceding-char) (append ";}{" '(nil)))) ; Was ?\,
3260 ;; This line is continuation of preceding line's statement.
3261 (list (list 'statement-continued containing-sexp))
3262 ;; This line starts a new statement.
3263 ;; Position following last unclosed open.
3264 (goto-char containing-sexp)
3265 ;; Is line first statement after an open-brace?
3266 (or
3267 ;; If no, find that first statement and indent like
3268 ;; it. If the first statement begins with label, do
3269 ;; not believe when the indentation of the label is too
3270 ;; small.
3271 (save-excursion
3272 (forward-char 1)
3273 (let ((colon-line-end 0))
3274 (while (progn (skip-chars-forward " \t\n" start-point)
3275 (and (< (point) start-point)
3276 (looking-at
3277 "#\\|[a-zA-Z_][a-zA-Z0-9_]*:[^:]")))
3278 ;; Skip over comments and labels following openbrace.
3279 (cond ((= (following-char) ?\#)
3280 ;;(forward-line 1)
3281 (end-of-line))
3282 ;; label:
3283 (t
3284 (save-excursion (end-of-line)
3285 (setq colon-line-end (point)))
3286 (search-forward ":"))))
3287 ;; Now at the point, after label, or at start
3288 ;; of first statement in the block.
3289 (and (< (point) start-point)
3290 (if (> colon-line-end (point))
3291 ;; Before statement after label
3292 (if (> (current-indentation)
3293 cperl-min-label-indent)
3294 (list (list 'label-in-block (point)))
3295 ;; Do not believe: `max' is involved
3296 (list
3297 (list 'label-in-block-min-indent (point))))
3298 ;; Before statement
3299 (list 'statement-in-block (point))))))
3300 ;; If no previous statement,
3301 ;; indent it relative to line brace is on.
3302 ;; For open brace in column zero, don't let statement
3303 ;; start there too. If cperl-indent-level is zero,
3304 ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
3305 ;; For open-braces not the first thing in a line,
3306 ;; add in cperl-brace-imaginary-offset.
3307
3308 ;; If first thing on a line: ?????
3309 (setq unused ; This is not finished...
3310 (+ (if (and (bolp) (zerop cperl-indent-level))
3311 (+ cperl-brace-offset cperl-continued-statement-offset)
3312 cperl-indent-level)
3313 ;; Move back over whitespace before the openbrace.
3314 ;; If openbrace is not first nonwhite thing on the line,
3315 ;; add the cperl-brace-imaginary-offset.
3316 (progn (skip-chars-backward " \t")
3317 (if (bolp) 0 cperl-brace-imaginary-offset))
3318 ;; If the openbrace is preceded by a parenthesized exp,
3319 ;; move to the beginning of that;
3320 ;; possibly a different line
3321 (progn
3322 (if (eq (preceding-char) ?\))
3323 (forward-sexp -1))
3324 ;; Get initial indentation of the line we are on.
3325 ;; If line starts with label, calculate label indentation
3326 (if (save-excursion
3327 (beginning-of-line)
3328 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
3329 (if (> (current-indentation) cperl-min-label-indent)
3330 (- (current-indentation) cperl-label-offset)
3331 (cperl-calculate-indent))
3332 (current-indentation)))))))))
3333 res)))
2878 3334
2879(defun cperl-calculate-indent-within-comment () 3335(defun cperl-calculate-indent-within-comment ()
2880 "Return the indentation amount for line, assuming that 3336 "Return the indentation amount for line, assuming that
@@ -2894,14 +3350,22 @@ the current line is to be regarded as part of a block comment."
2894 3350
2895(defun cperl-to-comment-or-eol () 3351(defun cperl-to-comment-or-eol ()
2896 "Go to position before comment on the current line, or to end of line. 3352 "Go to position before comment on the current line, or to end of line.
2897Returns true if comment is found." 3353Returns true if comment is found. In POD will not move the point."
2898 (let (state stop-in cpoint (lim (progn (end-of-line) (point)))) 3354 ;; If the line is inside other syntax groups (qq-style strings, HERE-docs)
3355 ;; then looks for literal # or end-of-line.
3356 (let (state stop-in cpoint (lim (progn (end-of-line) (point))) pr e)
3357 (or cperl-font-locking
3358 (cperl-update-syntaxification lim lim))
2899 (beginning-of-line) 3359 (beginning-of-line)
2900 (if (or 3360 (if (setq pr (get-text-property (point) 'syntax-type))
2901 (eq (get-text-property (point) 'syntax-type) 'pod) 3361 (setq e (next-single-property-change (point) 'syntax-type nil (point-max))))
2902 (re-search-forward "\\=[ \t]*\\(#\\|$\\)" lim t)) 3362 (if (or (eq pr 'pod)
3363 (if (or (not e) (> e lim)) ; deep inside a group
3364 (re-search-forward "\\=[ \t]*\\(#\\|$\\)" lim t)))
2903 (if (eq (preceding-char) ?\#) (progn (backward-char 1) t)) 3365 (if (eq (preceding-char) ?\#) (progn (backward-char 1) t))
2904 ;; Else 3366 ;; Else - need to do it the hard way
3367 (and (and e (<= e lim))
3368 (goto-char e))
2905 (while (not stop-in) 3369 (while (not stop-in)
2906 (setq state (parse-partial-sexp (point) lim nil nil nil t)) 3370 (setq state (parse-partial-sexp (point) lim nil nil nil t))
2907 ; stop at comment 3371 ; stop at comment
@@ -2933,17 +3397,11 @@ Returns true if comment is found."
2933 (setq stop-in t))) ; Finish 3397 (setq stop-in t))) ; Finish
2934 (nth 4 state)))) 3398 (nth 4 state))))
2935 3399
2936(defsubst cperl-1- (p)
2937 (max (point-min) (1- p)))
2938
2939(defsubst cperl-1+ (p)
2940 (min (point-max) (1+ p)))
2941
2942(defsubst cperl-modify-syntax-type (at how) 3400(defsubst cperl-modify-syntax-type (at how)
2943 (if (< at (point-max)) 3401 (if (< at (point-max))
2944 (progn 3402 (progn
2945 (put-text-property at (1+ at) 'syntax-table how) 3403 (put-text-property at (1+ at) 'syntax-table how)
2946 (put-text-property at (1+ at) 'rear-nonsticky t)))) 3404 (put-text-property at (1+ at) 'rear-nonsticky '(syntax-table)))))
2947 3405
2948(defun cperl-protect-defun-start (s e) 3406(defun cperl-protect-defun-start (s e)
2949 ;; C code looks for "^\\s(" to skip comment backward in "hard" situations 3407 ;; C code looks for "^\\s(" to skip comment backward in "hard" situations
@@ -2978,35 +3436,53 @@ Returns true if comment is found."
2978 ( ?\{ . ?\} ) 3436 ( ?\{ . ?\} )
2979 ( ?\< . ?\> ))) 3437 ( ?\< . ?\> )))
2980 3438
2981(defun cperl-forward-re (lim end is-2arg set-st st-l err-l argument 3439(defun cperl-cached-syntax-table (st)
3440 "Get a syntax table cached in ST, or create and cache into ST a syntax table.
3441All the entries of the syntax table are \".\", except for a backslash, which
3442is quoting."
3443 (if (car-safe st)
3444 (car st)
3445 (setcar st (make-syntax-table))
3446 (setq st (car st))
3447 (let ((i 0))
3448 (while (< i 256)
3449 (modify-syntax-entry i "." st)
3450 (setq i (1+ i))))
3451 (modify-syntax-entry ?\\ "\\" st)
3452 st))
3453
3454(defun cperl-forward-re (lim end is-2arg st-l err-l argument
2982 &optional ostart oend) 3455 &optional ostart oend)
2983 ;; Works *before* syntax recognition is done 3456"Find the end of a regular expression or a stringish construct (q[] etc).
2984 ;; May modify syntax-type text property if the situation is too hard 3457The point should be before the starting delimiter.
2985 (let (b starter ender st i i2 go-forward reset-st) 3458
3459Goes to LIM if none is found. If IS-2ARG is non-nil, assumes that it
3460is s/// or tr/// like expression. If END is nil, generates an error
3461message if needed. If SET-ST is non-nil, will use (or generate) a
3462cached syntax table in ST-L. If ERR-L is non-nil, will store the
3463error message in its CAR (unless it already contains some error
3464message). ARGUMENT should be the name of the construct (used in error
3465messages). OSTART, OEND may be set in recursive calls when processing
3466the second argument of 2ARG construct.
3467
3468Works *before* syntax recognition is done. In IS-2ARG situation may
3469modify syntax-type text property if the situation is too hard."
3470 (let (b starter ender st i i2 go-forward reset-st set-st)
2986 (skip-chars-forward " \t") 3471 (skip-chars-forward " \t")
2987 ;; ender means matching-char matcher. 3472 ;; ender means matching-char matcher.
2988 (setq b (point) 3473 (setq b (point)
2989 starter (if (eobp) 0 (char-after b)) 3474 starter (if (eobp) 0 (char-after b))
2990 ender (cdr (assoc starter cperl-starters))) 3475 ender (cdr (assoc starter cperl-starters)))
2991 ;; What if starter == ?\\ ???? 3476 ;; What if starter == ?\\ ????
2992 (if set-st 3477 (setq st (cperl-cached-syntax-table st-l))
2993 (if (car st-l)
2994 (setq st (car st-l))
2995 (setcar st-l (make-syntax-table))
2996 (setq i 0 st (car st-l))
2997 (while (< i 256)
2998 (modify-syntax-entry i "." st)
2999 (setq i (1+ i)))
3000 (modify-syntax-entry ?\\ "\\" st)))
3001 (setq set-st t) 3478 (setq set-st t)
3002 ;; Whether we have an intermediate point 3479 ;; Whether we have an intermediate point
3003 (setq i nil) 3480 (setq i nil)
3004 ;; Prepare the syntax table: 3481 ;; Prepare the syntax table:
3005 (and set-st 3482 (if (not ender) ; m/blah/, s/x//, s/x/y/
3006 (if (not ender) ; m/blah/, s/x//, s/x/y/ 3483 (modify-syntax-entry starter "$" st)
3007 (modify-syntax-entry starter "$" st) 3484 (modify-syntax-entry starter (concat "(" (list ender)) st)
3008 (modify-syntax-entry starter (concat "(" (list ender)) st) 3485 (modify-syntax-entry ender (concat ")" (list starter)) st))
3009 (modify-syntax-entry ender (concat ")" (list starter)) st)))
3010 (condition-case bb 3486 (condition-case bb
3011 (progn 3487 (progn
3012 ;; We use `$' syntax class to find matching stuff, but $$ 3488 ;; We use `$' syntax class to find matching stuff, but $$
@@ -3053,7 +3529,7 @@ Returns true if comment is found."
3053 (modify-syntax-entry starter (if (eq starter ?\\) "\\" ".") st) 3529 (modify-syntax-entry starter (if (eq starter ?\\) "\\" ".") st)
3054 (if ender (modify-syntax-entry ender "." st)) 3530 (if ender (modify-syntax-entry ender "." st))
3055 (setq set-st nil) 3531 (setq set-st nil)
3056 (setq ender (cperl-forward-re lim end nil t st-l err-l 3532 (setq ender (cperl-forward-re lim end nil st-l err-l
3057 argument starter ender) 3533 argument starter ender)
3058 ender (nth 2 ender))))) 3534 ender (nth 2 ender)))))
3059 (error (goto-char lim) 3535 (error (goto-char lim)
@@ -3078,6 +3554,33 @@ Returns true if comment is found."
3078 ;; go-forward: has 2 args, and the second part is empty 3554 ;; go-forward: has 2 args, and the second part is empty
3079 (list i i2 ender starter go-forward))) 3555 (list i i2 ender starter go-forward)))
3080 3556
3557(defun cperl-forward-group-in-re (&optional st-l)
3558 "Find the end of a group in a REx.
3559Return the error message (if any). Does not work if delimiter is `)'.
3560Works before syntax recognition is done."
3561 ;; Works *before* syntax recognition is done
3562 (or st-l (setq st-l (list nil))) ; Avoid overwriting '()
3563 (let (st b reset-st)
3564 (condition-case b
3565 (progn
3566 (setq st (cperl-cached-syntax-table st-l))
3567 (modify-syntax-entry ?\( "()" st)
3568 (modify-syntax-entry ?\) ")(" st)
3569 (setq reset-st (syntax-table))
3570 (set-syntax-table st)
3571 (forward-sexp 1))
3572 (error (message
3573 "cperl-forward-group-in-re: error %s" b)))
3574 ;; now restore the initial state
3575 (if st
3576 (progn
3577 (modify-syntax-entry ?\( "." st)
3578 (modify-syntax-entry ?\) "." st)))
3579 (if reset-st
3580 (set-syntax-table reset-st))
3581 b))
3582
3583
3081(defvar font-lock-string-face) 3584(defvar font-lock-string-face)
3082;;(defvar font-lock-reference-face) 3585;;(defvar font-lock-reference-face)
3083(defvar font-lock-constant-face) 3586(defvar font-lock-constant-face)
@@ -3103,13 +3606,24 @@ Returns true if comment is found."
3103;; d) 'Q'uoted string: 3606;; d) 'Q'uoted string:
3104;; part between markers inclusive is marked `syntax-type' ==> `string' 3607;; part between markers inclusive is marked `syntax-type' ==> `string'
3105;; part between `q' and the first marker is marked `syntax-type' ==> `prestring' 3608;; part between `q' and the first marker is marked `syntax-type' ==> `prestring'
3609;; second part of s///e is marked `syntax-type' ==> `multiline'
3610;; e) Attributes of subroutines: `attrib-group' ==> t
3611;; (or 0 if declaration); up to `{' or ';': `syntax-type' => `sub-decl'.
3612;; f) Multiline my/our declaration lists etc: `syntax-type' => `multiline'
3613
3614;;; In addition, some parts of RExes may be marked as `REx-interpolated'
3615;;; (value: 0 in //o, 1 if "interpolated variable" is whole-REx, t otherwise).
3106 3616
3107(defun cperl-unwind-to-safe (before &optional end) 3617(defun cperl-unwind-to-safe (before &optional end)
3108 ;; if BEFORE, go to the previous start-of-line on each step of unwinding 3618 ;; if BEFORE, go to the previous start-of-line on each step of unwinding
3109 (let ((pos (point)) opos) 3619 (let ((pos (point)) opos)
3110 (setq opos pos) 3620 (while (and pos (progn
3111 (while (and pos (get-text-property pos 'syntax-type)) 3621 (beginning-of-line)
3112 (setq pos (previous-single-property-change pos 'syntax-type)) 3622 (get-text-property (setq pos (point)) 'syntax-type)))
3623 (setq opos pos
3624 pos (cperl-beginning-of-property pos 'syntax-type))
3625 (if (eq pos (point-min))
3626 (setq pos nil))
3113 (if pos 3627 (if pos
3114 (if before 3628 (if before
3115 (progn 3629 (progn
@@ -3126,32 +3640,117 @@ Returns true if comment is found."
3126 (setq pos (point)) 3640 (setq pos (point))
3127 (if end 3641 (if end
3128 ;; Do the same for end, going small steps 3642 ;; Do the same for end, going small steps
3129 (progn 3643 (save-excursion
3130 (while (and end (get-text-property end 'syntax-type)) 3644 (while (and end (get-text-property end 'syntax-type))
3131 (setq pos end 3645 (setq pos end
3132 end (next-single-property-change end 'syntax-type))) 3646 end (next-single-property-change end 'syntax-type nil (point-max)))
3647 (if end (progn (goto-char end)
3648 (or (bolp) (forward-line 1))
3649 (setq end (point)))))
3133 (or end pos))))) 3650 (or end pos)))))
3134 3651
3652;;; These are needed for byte-compile (at least with v19)
3135(defvar cperl-nonoverridable-face) 3653(defvar cperl-nonoverridable-face)
3654(defvar font-lock-variable-name-face)
3136(defvar font-lock-function-name-face) 3655(defvar font-lock-function-name-face)
3656(defvar font-lock-keyword-face)
3657(defvar font-lock-builtin-face)
3658(defvar font-lock-type-face)
3137(defvar font-lock-comment-face) 3659(defvar font-lock-comment-face)
3660(defvar font-lock-warning-face)
3138 3661
3139(defun cperl-find-pods-heres (&optional min max non-inter end ignore-max) 3662(defun cperl-find-sub-attrs (&optional st-l b-fname e-fname pos)
3663 "Syntaxically mark (and fontify) attributes of a subroutine.
3664Should be called with the point before leading colon of an attribute."
3665 ;; Works *before* syntax recognition is done
3666 (or st-l (setq st-l (list nil))) ; Avoid overwriting '()
3667 (let (st b p reset-st after-first (start (point)) start1 end1)
3668 (condition-case b
3669 (while (looking-at
3670 (concat
3671 "\\(" ; 1=optional? colon
3672 ":" cperl-maybe-white-and-comment-rex ; 2=whitespace/comment?
3673 "\\)"
3674 (if after-first "?" "")
3675 ;; No space between name and paren allowed...
3676 "\\(\\sw+\\)" ; 3=name
3677 "\\((\\)?")) ; 4=optional paren
3678 (and (match-beginning 1)
3679 (cperl-postpone-fontification
3680 (match-beginning 0) (cperl-1+ (match-beginning 0))
3681 'face font-lock-constant-face))
3682 (setq start1 (match-beginning 3) end1 (match-end 3))
3683 (cperl-postpone-fontification start1 end1
3684 'face font-lock-constant-face)
3685 (goto-char end1) ; end or before `('
3686 (if (match-end 4) ; Have attribute arguments...
3687 (progn
3688 (if st nil
3689 (setq st (cperl-cached-syntax-table st-l))
3690 (modify-syntax-entry ?\( "()" st)
3691 (modify-syntax-entry ?\) ")(" st))
3692 (setq reset-st (syntax-table) p (point))
3693 (set-syntax-table st)
3694 (forward-sexp 1)
3695 (set-syntax-table reset-st)
3696 (setq reset-st nil)
3697 (cperl-commentify p (point) t))) ; mark as string
3698 (forward-comment (buffer-size))
3699 (setq after-first t))
3700 (error (message
3701 "L%d: attribute `%s': %s"
3702 (count-lines (point-min) (point))
3703 (and start1 end1 (buffer-substring start1 end1)) b)
3704 (setq start nil)))
3705 (and start
3706 (progn
3707 (put-text-property start (point)
3708 'attrib-group (if (looking-at "{") t 0))
3709 (and pos
3710 (< 1 (count-lines (+ 3 pos) (point))) ; end of `sub'
3711 ;; Apparently, we do not need `multiline': faces added now
3712 (put-text-property (+ 3 pos) (cperl-1+ (point))
3713 'syntax-type 'sub-decl))
3714 (and b-fname ; Fontify here: the following condition
3715 (cperl-postpone-fontification ; is too hard to determine by
3716 b-fname e-fname 'face ; a REx, so do it here
3717 (if (looking-at "{")
3718 font-lock-function-name-face
3719 font-lock-variable-name-face)))))
3720 ;; now restore the initial state
3721 (if st
3722 (progn
3723 (modify-syntax-entry ?\( "." st)
3724 (modify-syntax-entry ?\) "." st)))
3725 (if reset-st
3726 (set-syntax-table reset-st))))
3727
3728(defsubst cperl-look-at-leading-count (is-x-REx e)
3729 (if (re-search-forward (concat "\\=" (if is-x-REx "[ \t\n]*" "") "[{?+*]")
3730 (1- e) t) ; return nil on failure, no moving
3731 (if (eq ?\{ (preceding-char)) nil
3732 (cperl-postpone-fontification
3733 (1- (point)) (point)
3734 'face font-lock-warning-face))))
3735
3736;;; Debugging this may require (setq max-specpdl-size 2000)...
3737(defun cperl-find-pods-heres (&optional min max non-inter end ignore-max end-of-here-doc)
3140 "Scans the buffer for hard-to-parse Perl constructions. 3738 "Scans the buffer for hard-to-parse Perl constructions.
3141If `cperl-pod-here-fontify' is not-nil after evaluation, will fontify 3739If `cperl-pod-here-fontify' is not-nil after evaluation, will fontify
3142the sections using `cperl-pod-head-face', `cperl-pod-face', 3740the sections using `cperl-pod-head-face', `cperl-pod-face',
3143`cperl-here-face'." 3741`cperl-here-face'."
3144 (interactive) 3742 (interactive)
3145 (or min (setq min (point-min) 3743 (or min (setq min (point-min)
3146 cperl-syntax-state nil 3744 cperl-syntax-state nil
3147 cperl-syntax-done-to min)) 3745 cperl-syntax-done-to min))
3148 (or max (setq max (point-max))) 3746 (or max (setq max (point-max)))
3149 (let* ((cperl-pod-here-fontify (eval cperl-pod-here-fontify)) go tmpend 3747 (let* ((cperl-pod-here-fontify (eval cperl-pod-here-fontify)) go tmpend
3150 face head-face here-face b e bb tag qtag b1 e1 argument i c tail tb 3748 face head-face here-face b e bb tag qtag b1 e1 argument i c tail tb
3151 is-REx is-x-REx REx-comment-start REx-comment-end was-comment i2 3749 is-REx is-x-REx REx-subgr-start REx-subgr-end was-subgr i2 hairy-RE
3152 (case-fold-search nil) (inhibit-read-only t) (buffer-undo-list t) 3750 (case-fold-search nil) (inhibit-read-only t) (buffer-undo-list t)
3153 (modified (buffer-modified-p)) 3751 (modified (buffer-modified-p)) overshoot is-o-REx
3154 (after-change-functions nil) 3752 (after-change-functions nil)
3753 (cperl-font-locking t)
3155 (use-syntax-state (and cperl-syntax-state 3754 (use-syntax-state (and cperl-syntax-state
3156 (>= min (car cperl-syntax-state)))) 3755 (>= min (car cperl-syntax-state))))
3157 (state-point (if use-syntax-state 3756 (state-point (if use-syntax-state
@@ -3162,33 +3761,62 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3162 ;; (st-l '(nil)) (err-l '(nil)) ; Would overwrite - propagates from a function call to a function call! 3761 ;; (st-l '(nil)) (err-l '(nil)) ; Would overwrite - propagates from a function call to a function call!
3163 (st-l (list nil)) (err-l (list nil)) 3762 (st-l (list nil)) (err-l (list nil))
3164 ;; Somehow font-lock may be not loaded yet... 3763 ;; Somehow font-lock may be not loaded yet...
3764 ;; (e.g., when building TAGS via command-line call)
3165 (font-lock-string-face (if (boundp 'font-lock-string-face) 3765 (font-lock-string-face (if (boundp 'font-lock-string-face)
3166 font-lock-string-face 3766 font-lock-string-face
3167 'font-lock-string-face)) 3767 'font-lock-string-face))
3168 (font-lock-constant-face (if (boundp 'font-lock-constant-face) 3768 (my-cperl-delimiters-face (if (boundp 'font-lock-constant-face)
3169 font-lock-constant-face 3769 font-lock-constant-face
3170 'font-lock-constant-face)) 3770 'font-lock-constant-face))
3171 (font-lock-function-name-face 3771 (my-cperl-REx-spec-char-face ; [] ^.$ and wrapper-of ({})
3172 (if (boundp 'font-lock-function-name-face) 3772 (if (boundp 'font-lock-function-name-face)
3173 font-lock-function-name-face 3773 font-lock-function-name-face
3174 'font-lock-function-name-face)) 3774 'font-lock-function-name-face))
3775 (font-lock-variable-name-face ; interpolated vars and ({})-code
3776 (if (boundp 'font-lock-variable-name-face)
3777 font-lock-variable-name-face
3778 'font-lock-variable-name-face))
3779 (font-lock-function-name-face ; used in `cperl-find-sub-attrs'
3780 (if (boundp 'font-lock-function-name-face)
3781 font-lock-function-name-face
3782 'font-lock-function-name-face))
3783 (font-lock-constant-face ; used in `cperl-find-sub-attrs'
3784 (if (boundp 'font-lock-constant-face)
3785 font-lock-constant-face
3786 'font-lock-constant-face))
3787 (my-cperl-REx-0length-face ; 0-length, (?:)etc, non-literal \
3788 (if (boundp 'font-lock-builtin-face)
3789 font-lock-builtin-face
3790 'font-lock-builtin-face))
3175 (font-lock-comment-face 3791 (font-lock-comment-face
3176 (if (boundp 'font-lock-comment-face) 3792 (if (boundp 'font-lock-comment-face)
3177 font-lock-comment-face 3793 font-lock-comment-face
3178 'font-lock-comment-face)) 3794 'font-lock-comment-face))
3179 (cperl-nonoverridable-face 3795 (font-lock-warning-face
3796 (if (boundp 'font-lock-warning-face)
3797 font-lock-warning-face
3798 'font-lock-warning-face))
3799 (my-cperl-REx-ctl-face ; (|)
3800 (if (boundp 'font-lock-keyword-face)
3801 font-lock-keyword-face
3802 'font-lock-keyword-face))
3803 (my-cperl-REx-modifiers-face ; //gims
3180 (if (boundp 'cperl-nonoverridable-face) 3804 (if (boundp 'cperl-nonoverridable-face)
3181 cperl-nonoverridable-face 3805 cperl-nonoverridable-face
3182 'cperl-nonoverridable)) 3806 'cperl-nonoverridable-face))
3807 (my-cperl-REx-length1-face ; length=1 escaped chars, POSIX classes
3808 (if (boundp 'font-lock-type-face)
3809 font-lock-type-face
3810 'font-lock-type-face))
3183 (stop-point (if ignore-max 3811 (stop-point (if ignore-max
3184 (point-max) 3812 (point-max)
3185 max)) 3813 max))
3186 (search 3814 (search
3187 (concat 3815 (concat
3188 "\\(\\`\n?\\|^\n\\)=" 3816 "\\(\\`\n?\\|^\n\\)=" ; POD
3189 "\\|" 3817 "\\|"
3190 ;; One extra () before this: 3818 ;; One extra () before this:
3191 "<<" 3819 "<<" ; HERE-DOC
3192 "\\(" ; 1 + 1 3820 "\\(" ; 1 + 1
3193 ;; First variant "BLAH" or just ``. 3821 ;; First variant "BLAH" or just ``.
3194 "[ \t]*" ; Yes, whitespace is allowed! 3822 "[ \t]*" ; Yes, whitespace is allowed!
@@ -3204,36 +3832,44 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3204 "\\)" 3832 "\\)"
3205 "\\|" 3833 "\\|"
3206 ;; 1+6 extra () before this: 3834 ;; 1+6 extra () before this:
3207 "^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$" 3835 "^[ \t]*\\(format\\)[ \t]*\\([a-zA-Z0-9_]+\\)?[ \t]*=[ \t]*$" ;FRMAT
3208 (if cperl-use-syntax-table-text-property 3836 (if cperl-use-syntax-table-text-property
3209 (concat 3837 (concat
3210 "\\|" 3838 "\\|"
3211 ;; 1+6+2=9 extra () before this: 3839 ;; 1+6+2=9 extra () before this:
3212 "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>" 3840 "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>" ; QUOTED CONSTRUCT
3213 "\\|" 3841 "\\|"
3214 ;; 1+6+2+1=10 extra () before this: 3842 ;; 1+6+2+1=10 extra () before this:
3215 "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob> 3843 "\\([?/<]\\)" ; /blah/ or ?blah? or <file*glob>
3216 "\\|" 3844 "\\|"
3217 ;; 1+6+2+1+1=11 extra () before this: 3845 ;; 1+6+2+1+1=11 extra () before this
3218 "\\<sub\\>[ \t]*\\([a-zA-Z_:'0-9]+[ \t]*\\)?\\(([^()]*)\\)" 3846 "\\<sub\\>" ; sub with proto/attr
3847 "\\("
3848 cperl-white-and-comment-rex
3849 "\\(::[a-zA-Z_:'0-9]*\\|[a-zA-Z_'][a-zA-Z_:'0-9]*\\)\\)?" ; name
3850 "\\("
3851 cperl-maybe-white-and-comment-rex
3852 "\\(([^()]*)\\|:[^:]\\)\\)" ; prototype or attribute start
3219 "\\|" 3853 "\\|"
3220 ;; 1+6+2+1+1+2=13 extra () before this: 3854 ;; 1+6+2+1+1+6=17 extra () before this:
3221 "\\$\\(['{]\\)" 3855 "\\$\\(['{]\\)" ; $' or ${foo}
3222 "\\|" 3856 "\\|"
3223 ;; 1+6+2+1+1+2+1=14 extra () before this: 3857 ;; 1+6+2+1+1+6+1=18 extra () before this (old pack'var syntax;
3858 ;; we do not support intervening comments...):
3224 "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'" 3859 "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'"
3225 ;; 1+6+2+1+1+2+1+1=15 extra () before this: 3860 ;; 1+6+2+1+1+6+1+1=19 extra () before this:
3226 "\\|" 3861 "\\|"
3227 "__\\(END\\|DATA\\)__" 3862 "__\\(END\\|DATA\\)__" ; __END__ or __DATA__
3228 ;; 1+6+2+1+1+2+1+1+1=16 extra () before this: 3863 ;; 1+6+2+1+1+6+1+1+1=20 extra () before this:
3229 "\\|" 3864 "\\|"
3230 "\\\\\\(['`\"($]\\)") 3865 "\\\\\\(['`\"($]\\)") ; BACKWACKED something-hairy
3231 "")))) 3866 ""))))
3232 (unwind-protect 3867 (unwind-protect
3233 (progn 3868 (progn
3234 (save-excursion 3869 (save-excursion
3235 (or non-inter 3870 (or non-inter
3236 (message "Scanning for \"hard\" Perl constructions...")) 3871 (message "Scanning for \"hard\" Perl constructions..."))
3872 ;;(message "find: %s --> %s" min max)
3237 (and cperl-pod-here-fontify 3873 (and cperl-pod-here-fontify
3238 ;; We had evals here, do not know why... 3874 ;; We had evals here, do not know why...
3239 (setq face cperl-pod-face 3875 (setq face cperl-pod-face
@@ -3241,16 +3877,22 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3241 here-face cperl-here-face)) 3877 here-face cperl-here-face))
3242 (remove-text-properties min max 3878 (remove-text-properties min max
3243 '(syntax-type t in-pod t syntax-table t 3879 '(syntax-type t in-pod t syntax-table t
3880 attrib-group t
3881 REx-interpolated t
3244 cperl-postpone t 3882 cperl-postpone t
3245 syntax-subtype t 3883 syntax-subtype t
3246 rear-nonsticky t 3884 rear-nonsticky t
3885 front-sticky t
3247 here-doc-group t 3886 here-doc-group t
3248 first-format-line t 3887 first-format-line t
3888 REx-part2 t
3249 indentable t)) 3889 indentable t))
3250 ;; Need to remove face as well... 3890 ;; Need to remove face as well...
3251 (goto-char min) 3891 (goto-char min)
3252 (and (eq system-type 'emx) 3892 (and (eq system-type 'emx)
3253 (looking-at "extproc[ \t]") ; Analogue of #! 3893 (eq (point) 1)
3894 (let ((case-fold-search t))
3895 (looking-at "extproc[ \t]")) ; Analogue of #!
3254 (cperl-commentify min 3896 (cperl-commentify min
3255 (save-excursion (end-of-line) (point)) 3897 (save-excursion (end-of-line) (point))
3256 nil)) 3898 nil))
@@ -3258,11 +3900,38 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3258 (< (point) max) 3900 (< (point) max)
3259 (re-search-forward search max t)) 3901 (re-search-forward search max t))
3260 (setq tmpend nil) ; Valid for most cases 3902 (setq tmpend nil) ; Valid for most cases
3903 (setq b (match-beginning 0)
3904 state (save-excursion (parse-partial-sexp
3905 state-point b nil nil state))
3906 state-point b)
3261 (cond 3907 (cond
3908 ;; 1+6+2+1+1+6=17 extra () before this:
3909 ;; "\\$\\(['{]\\)"
3910 ((match-beginning 18) ; $' or ${foo}
3911 (if (eq (preceding-char) ?\') ; $'
3912 (progn
3913 (setq b (1- (point))
3914 state (parse-partial-sexp
3915 state-point (1- b) nil nil state)
3916 state-point (1- b))
3917 (if (nth 3 state) ; in string
3918 (cperl-modify-syntax-type (1- b) cperl-st-punct))
3919 (goto-char (1+ b)))
3920 ;; else: ${
3921 (setq bb (match-beginning 0))
3922 (cperl-modify-syntax-type bb cperl-st-punct)))
3923 ;; No processing in strings/comments beyond this point:
3924 ((or (nth 3 state) (nth 4 state))
3925 t) ; Do nothing in comment/string
3262 ((match-beginning 1) ; POD section 3926 ((match-beginning 1) ; POD section
3263 ;; "\\(\\`\n?\\|^\n\\)=" 3927 ;; "\\(\\`\n?\\|^\n\\)="
3264 (if (looking-at "cut\\>") 3928 (setq b (match-beginning 0)
3265 (if ignore-max 3929 state (parse-partial-sexp
3930 state-point b nil nil state)
3931 state-point b)
3932 (if (or (nth 3 state) (nth 4 state)
3933 (looking-at "cut\\>"))
3934 (if (or (nth 3 state) (nth 4 state) ignore-max)
3266 nil ; Doing a chunk only 3935 nil ; Doing a chunk only
3267 (message "=cut is not preceded by a POD section") 3936 (message "=cut is not preceded by a POD section")
3268 (or (car err-l) (setcar err-l (point)))) 3937 (or (car err-l) (setcar err-l (point))))
@@ -3288,11 +3957,15 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3288 (progn 3957 (progn
3289 (remove-text-properties 3958 (remove-text-properties
3290 max e '(syntax-type t in-pod t syntax-table t 3959 max e '(syntax-type t in-pod t syntax-table t
3960 attrib-group t
3961 REx-interpolated t
3291 cperl-postpone t 3962 cperl-postpone t
3292 syntax-subtype t 3963 syntax-subtype t
3293 here-doc-group t 3964 here-doc-group t
3294 rear-nonsticky t 3965 rear-nonsticky t
3966 front-sticky t
3295 first-format-line t 3967 first-format-line t
3968 REx-part2 t
3296 indentable t)) 3969 indentable t))
3297 (setq tmpend tb))) 3970 (setq tmpend tb)))
3298 (put-text-property b e 'in-pod t) 3971 (put-text-property b e 'in-pod t)
@@ -3335,7 +4008,8 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3335 (or (eq e (point-max)) 4008 (or (eq e (point-max))
3336 (forward-char -1)))) ; Prepare for immediate POD start. 4009 (forward-char -1)))) ; Prepare for immediate POD start.
3337 ;; Here document 4010 ;; Here document
3338 ;; We do only one here-per-line 4011 ;; We can do many here-per-line;
4012 ;; but multiline quote on the same line as <<HERE confuses us...
3339 ;; ;; One extra () before this: 4013 ;; ;; One extra () before this:
3340 ;;"<<" 4014 ;;"<<"
3341 ;; "\\(" ; 1 + 1 4015 ;; "\\(" ; 1 + 1
@@ -3352,21 +4026,42 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3352 ;; "\\(\\)" ; To preserve count of pars :-( 6 + 1 4026 ;; "\\(\\)" ; To preserve count of pars :-( 6 + 1
3353 ;; "\\)" 4027 ;; "\\)"
3354 ((match-beginning 2) ; 1 + 1 4028 ((match-beginning 2) ; 1 + 1
3355 ;; Abort in comment: 4029 (setq b (point)
3356 (setq b (point))
3357 (setq state (parse-partial-sexp state-point b nil nil state)
3358 state-point b
3359 tb (match-beginning 0) 4030 tb (match-beginning 0)
3360 i (or (nth 3 state) (nth 4 state))) 4031 c (and ; not HERE-DOC
3361 (if i 4032 (match-beginning 5)
3362 (setq c t) 4033 (save-match-data
3363 (setq c (and 4034 (or (looking-at "[ \t]*(") ; << function_call()
3364 (match-beginning 5) 4035 (save-excursion ; 1 << func_name, or $foo << 10
3365 (not (match-beginning 6)) ; Empty 4036 (condition-case nil
3366 (looking-at 4037 (progn
3367 "[ \t]*[=0-9$@%&(]")))) 4038 (goto-char tb)
4039 ;;; XXX What to do: foo <<bar ???
4040 ;;; XXX Need to support print {a} <<B ???
4041 (forward-sexp -1)
4042 (save-match-data
4043 ; $foo << b; $f .= <<B;
4044 ; ($f+1) << b; a($f) . <<B;
4045 ; foo 1, <<B; $x{a} <<b;
4046 (cond
4047 ((looking-at "[0-9$({]")
4048 (forward-sexp 1)
4049 (and
4050 (looking-at "[ \t]*<<")
4051 (condition-case nil
4052 ;; print $foo <<EOF
4053 (progn
4054 (forward-sexp -2)
4055 (not
4056 (looking-at "\\(printf?\\|system\\|exec\\|sort\\)\\>")))
4057 (error t)))))))
4058 (error nil))) ; func(<<EOF)
4059 (and (not (match-beginning 6)) ; Empty
4060 (looking-at
4061 "[ \t]*[=0-9$@%&(]"))))))
3368 (if c ; Not here-doc 4062 (if c ; Not here-doc
3369 nil ; Skip it. 4063 nil ; Skip it.
4064 (setq c (match-end 2)) ; 1 + 1
3370 (if (match-beginning 5) ;4 + 1 4065 (if (match-beginning 5) ;4 + 1
3371 (setq b1 (match-beginning 5) ; 4 + 1 4066 (setq b1 (match-beginning 5) ; 4 + 1
3372 e1 (match-end 5)) ; 4 + 1 4067 e1 (match-end 5)) ; 4 + 1
@@ -3376,15 +4071,20 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3376 qtag (regexp-quote tag)) 4071 qtag (regexp-quote tag))
3377 (cond (cperl-pod-here-fontify 4072 (cond (cperl-pod-here-fontify
3378 ;; Highlight the starting delimiter 4073 ;; Highlight the starting delimiter
3379 (cperl-postpone-fontification b1 e1 'face font-lock-constant-face) 4074 (cperl-postpone-fontification
4075 b1 e1 'face my-cperl-delimiters-face)
3380 (cperl-put-do-not-fontify b1 e1 t))) 4076 (cperl-put-do-not-fontify b1 e1 t)))
3381 (forward-line) 4077 (forward-line)
4078 (setq i (point))
4079 (if end-of-here-doc
4080 (goto-char end-of-here-doc))
3382 (setq b (point)) 4081 (setq b (point))
3383 ;; We do not search to max, since we may be called from 4082 ;; We do not search to max, since we may be called from
3384 ;; some hook of fontification, and max is random 4083 ;; some hook of fontification, and max is random
3385 (or (and (re-search-forward (concat "^" qtag "$") 4084 (or (and (re-search-forward (concat "^" qtag "$")
3386 stop-point 'toend) 4085 stop-point 'toend)
3387 (eq (following-char) ?\n)) 4086 ;;;(eq (following-char) ?\n) ; XXXX WHY???
4087 )
3388 (progn ; Pretend we matched at the end 4088 (progn ; Pretend we matched at the end
3389 (goto-char (point-max)) 4089 (goto-char (point-max))
3390 (re-search-forward "\\'") 4090 (re-search-forward "\\'")
@@ -3393,8 +4093,9 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3393 (if cperl-pod-here-fontify 4093 (if cperl-pod-here-fontify
3394 (progn 4094 (progn
3395 ;; Highlight the ending delimiter 4095 ;; Highlight the ending delimiter
3396 (cperl-postpone-fontification (match-beginning 0) (match-end 0) 4096 (cperl-postpone-fontification
3397 'face font-lock-constant-face) 4097 (match-beginning 0) (match-end 0)
4098 'face my-cperl-delimiters-face)
3398 (cperl-put-do-not-fontify b (match-end 0) t) 4099 (cperl-put-do-not-fontify b (match-end 0) t)
3399 ;; Highlight the HERE-DOC 4100 ;; Highlight the HERE-DOC
3400 (cperl-postpone-fontification b (match-beginning 0) 4101 (cperl-postpone-fontification b (match-beginning 0)
@@ -3404,10 +4105,21 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3404 'syntax-type 'here-doc) 4105 'syntax-type 'here-doc)
3405 (put-text-property (match-beginning 0) e1 4106 (put-text-property (match-beginning 0) e1
3406 'syntax-type 'here-doc-delim) 4107 'syntax-type 'here-doc-delim)
3407 (put-text-property b e1 4108 (put-text-property b e1 'here-doc-group t)
3408 'here-doc-group t) 4109 ;; This makes insertion at the start of HERE-DOC update
4110 ;; the whole construct:
4111 (put-text-property b (cperl-1+ b) 'front-sticky '(syntax-type))
3409 (cperl-commentify b e1 nil) 4112 (cperl-commentify b e1 nil)
3410 (cperl-put-do-not-fontify b (match-end 0) t) 4113 (cperl-put-do-not-fontify b (match-end 0) t)
4114 ;; Cache the syntax info...
4115 (setq cperl-syntax-state (cons state-point state))
4116 ;; ... and process the rest of the line...
4117 (setq overshoot
4118 (elt ; non-inter ignore-max
4119 (cperl-find-pods-heres c i t end t e1) 1))
4120 (if (and overshoot (> overshoot (point)))
4121 (goto-char overshoot)
4122 (setq overshoot e1))
3411 (if (> e1 max) 4123 (if (> e1 max)
3412 (setq tmpend tb)))) 4124 (setq tmpend tb))))
3413 ;; format 4125 ;; format
@@ -3462,7 +4174,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3462 (if (> (point) max) 4174 (if (> (point) max)
3463 (setq tmpend tb)) 4175 (setq tmpend tb))
3464 (put-text-property b (point) 'syntax-type 'format)) 4176 (put-text-property b (point) 'syntax-type 'format))
3465 ;; Regexp: 4177 ;; qq-like String or Regexp:
3466 ((or (match-beginning 10) (match-beginning 11)) 4178 ((or (match-beginning 10) (match-beginning 11))
3467 ;; 1+6+2=9 extra () before this: 4179 ;; 1+6+2=9 extra () before this:
3468 ;; "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>" 4180 ;; "\\<\\(q[wxqr]?\\|[msy]\\|tr\\)\\>"
@@ -3471,10 +4183,10 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3471 (setq b1 (if (match-beginning 10) 10 11) 4183 (setq b1 (if (match-beginning 10) 10 11)
3472 argument (buffer-substring 4184 argument (buffer-substring
3473 (match-beginning b1) (match-end b1)) 4185 (match-beginning b1) (match-end b1))
3474 b (point) 4186 b (point) ; end of qq etc
3475 i b 4187 i b
3476 c (char-after (match-beginning b1)) 4188 c (char-after (match-beginning b1))
3477 bb (char-after (1- (match-beginning b1))) ; tmp holder 4189 bb (char-after (1- (match-beginning b1))) ; tmp holder
3478 ;; bb == "Not a stringy" 4190 ;; bb == "Not a stringy"
3479 bb (if (eq b1 10) ; user variables/whatever 4191 bb (if (eq b1 10) ; user variables/whatever
3480 (and (memq bb (append "$@%*#_:-&>" nil)) ; $#y) 4192 (and (memq bb (append "$@%*#_:-&>" nil)) ; $#y)
@@ -3488,7 +4200,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3488 (- (match-beginning b1) 2)) 4200 (- (match-beginning b1) 2))
3489 ?\-)) 4201 ?\-))
3490 ((eq bb ?\&) 4202 ((eq bb ?\&)
3491 (not (eq (char-after ; &&m/blah/ 4203 (not (eq (char-after ; &&m/blah/
3492 (- (match-beginning b1) 2)) 4204 (- (match-beginning b1) 2))
3493 ?\&))) 4205 ?\&)))
3494 (t t))) 4206 (t t)))
@@ -3506,41 +4218,40 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3506 (setq argument "" 4218 (setq argument ""
3507 b1 nil 4219 b1 nil
3508 bb ; Not a regexp? 4220 bb ; Not a regexp?
3509 (progn 4221 (not
3510 (not 4222 ;; What is below: regexp-p?
3511 ;; What is below: regexp-p? 4223 (and
3512 (and 4224 (or (memq (preceding-char)
3513 (or (memq (preceding-char) 4225 (append (if (memq c '(?\? ?\<))
3514 (append (if (memq c '(?\? ?\<)) 4226 ;; $a++ ? 1 : 2
3515 ;; $a++ ? 1 : 2 4227 "~{(=|&*!,;:["
3516 "~{(=|&*!,;:" 4228 "~{(=|&+-*!,;:[") nil))
3517 "~{(=|&+-*!,;:") nil)) 4229 (and (eq (preceding-char) ?\})
3518 (and (eq (preceding-char) ?\}) 4230 (cperl-after-block-p (point-min)))
3519 (cperl-after-block-p (point-min))) 4231 (and (eq (char-syntax (preceding-char)) ?w)
3520 (and (eq (char-syntax (preceding-char)) ?w) 4232 (progn
3521 (progn 4233 (forward-sexp -1)
3522 (forward-sexp -1)
3523;; After these keywords `/' starts a RE. One should add all the 4234;; After these keywords `/' starts a RE. One should add all the
3524;; functions/builtins which expect an argument, but ... 4235;; functions/builtins which expect an argument, but ...
3525 (if (eq (preceding-char) ?-) 4236 (if (eq (preceding-char) ?-)
3526 ;; -d ?foo? is a RE 4237 ;; -d ?foo? is a RE
3527 (looking-at "[a-zA-Z]\\>") 4238 (looking-at "[a-zA-Z]\\>")
3528 (and 4239 (and
3529 (not (memq (preceding-char) 4240 (not (memq (preceding-char)
3530 '(?$ ?@ ?& ?%))) 4241 '(?$ ?@ ?& ?%)))
3531 (looking-at 4242 (looking-at
3532 "\\(while\\|if\\|unless\\|until\\|and\\|or\\|not\\|xor\\|split\\|grep\\|map\\|print\\)\\>"))))) 4243 "\\(while\\|if\\|unless\\|until\\|and\\|or\\|not\\|xor\\|split\\|grep\\|map\\|print\\)\\>")))))
3533 (and (eq (preceding-char) ?.) 4244 (and (eq (preceding-char) ?.)
3534 (eq (char-after (- (point) 2)) ?.)) 4245 (eq (char-after (- (point) 2)) ?.))
3535 (bobp)) 4246 (bobp))
3536 ;; m|blah| ? foo : bar; 4247 ;; m|blah| ? foo : bar;
3537 (not 4248 (not
3538 (and (eq c ?\?) 4249 (and (eq c ?\?)
3539 cperl-use-syntax-table-text-property 4250 cperl-use-syntax-table-text-property
3540 (not (bobp)) 4251 (not (bobp))
3541 (progn 4252 (progn
3542 (forward-char -1) 4253 (forward-char -1)
3543 (looking-at "\\s|"))))))) 4254 (looking-at "\\s|"))))))
3544 b (1- b)) 4255 b (1- b))
3545 ;; s y tr m 4256 ;; s y tr m
3546 ;; Check for $a -> y 4257 ;; Check for $a -> y
@@ -3550,13 +4261,9 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3550 (eq (char-after (- go 2)) ?-)) 4261 (eq (char-after (- go 2)) ?-))
3551 ;; Not a regexp 4262 ;; Not a regexp
3552 (setq bb t)))) 4263 (setq bb t))))
3553 (or bb (setq state (parse-partial-sexp
3554 state-point b nil nil state)
3555 state-point b))
3556 (setq bb (or bb (nth 3 state) (nth 4 state)))
3557 (goto-char b)
3558 (or bb 4264 (or bb
3559 (progn 4265 (progn
4266 (goto-char b)
3560 (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+") 4267 (if (looking-at "[ \t\n\f]+\\(#[^\n]*\n[ \t\n\f]*\\)+")
3561 (goto-char (match-end 0)) 4268 (goto-char (match-end 0))
3562 (skip-chars-forward " \t\n\f")) 4269 (skip-chars-forward " \t\n\f"))
@@ -3593,6 +4300,8 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3593 (skip-chars-backward " \t\n\f") 4300 (skip-chars-backward " \t\n\f")
3594 (memq (preceding-char) 4301 (memq (preceding-char)
3595 (append "$@%&*" nil)))) 4302 (append "$@%&*" nil))))
4303 (setq bb t))
4304 ((eobp)
3596 (setq bb t))))) 4305 (setq bb t)))))
3597 (if bb 4306 (if bb
3598 (goto-char i) 4307 (goto-char i)
@@ -3605,15 +4314,16 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3605 ;; qtag means two-arg matcher, may be reset to 4314 ;; qtag means two-arg matcher, may be reset to
3606 ;; 2 or 3 later if some special quoting is needed. 4315 ;; 2 or 3 later if some special quoting is needed.
3607 ;; e1 means matching-char matcher. 4316 ;; e1 means matching-char matcher.
3608 (setq b (point) 4317 (setq b (point) ; before the first delimiter
3609 ;; has 2 args 4318 ;; has 2 args
3610 i2 (string-match "^\\([sy]\\|tr\\)$" argument) 4319 i2 (string-match "^\\([sy]\\|tr\\)$" argument)
3611 ;; We do not search to max, since we may be called from 4320 ;; We do not search to max, since we may be called from
3612 ;; some hook of fontification, and max is random 4321 ;; some hook of fontification, and max is random
3613 i (cperl-forward-re stop-point end 4322 i (cperl-forward-re stop-point end
3614 i2 4323 i2
3615 t st-l err-l argument) 4324 st-l err-l argument)
3616 ;; Note that if `go', then it is considered as 1-arg 4325 ;; If `go', then it is considered as 1-arg, `b1' is nil
4326 ;; as in s/foo//x; the point is before final "slash"
3617 b1 (nth 1 i) ; start of the second part 4327 b1 (nth 1 i) ; start of the second part
3618 tag (nth 2 i) ; ender-char, true if second part 4328 tag (nth 2 i) ; ender-char, true if second part
3619 ; is with matching chars [] 4329 ; is with matching chars []
@@ -3625,13 +4335,18 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3625 (1- e1)) 4335 (1- e1))
3626 e (if i i e1) ; end of the first part 4336 e (if i i e1) ; end of the first part
3627 qtag nil ; need to preserve backslashitis 4337 qtag nil ; need to preserve backslashitis
3628 is-x-REx nil) ; REx has //x modifier 4338 is-x-REx nil is-o-REx nil); REx has //x //o modifiers
4339 ;; If s{} (), then b/b1 are at "{", "(", e1/i after ")", "}"
3629 ;; Commenting \\ is dangerous, what about ( ? 4340 ;; Commenting \\ is dangerous, what about ( ?
3630 (and i tail 4341 (and i tail
3631 (eq (char-after i) ?\\) 4342 (eq (char-after i) ?\\)
3632 (setq qtag t)) 4343 (setq qtag t))
3633 (if (looking-at "\\sw*x") ; qr//x 4344 (and (if go (looking-at ".\\sw*x")
3634 (setq is-x-REx t)) 4345 (looking-at "\\sw*x")) ; qr//x
4346 (setq is-x-REx t))
4347 (and (if go (looking-at ".\\sw*o")
4348 (looking-at "\\sw*o")) ; //o
4349 (setq is-o-REx t))
3635 (if (null i) 4350 (if (null i)
3636 ;; Considered as 1arg form 4351 ;; Considered as 1arg form
3637 (progn 4352 (progn
@@ -3648,9 +4363,11 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3648 (cperl-commentify b i t) 4363 (cperl-commentify b i t)
3649 (if (looking-at "\\sw*e") ; s///e 4364 (if (looking-at "\\sw*e") ; s///e
3650 (progn 4365 (progn
4366 ;; Cache the syntax info...
4367 (setq cperl-syntax-state (cons state-point state))
3651 (and 4368 (and
3652 ;; silent: 4369 ;; silent:
3653 (cperl-find-pods-heres b1 (1- (point)) t end) 4370 (car (cperl-find-pods-heres b1 (1- (point)) t end))
3654 ;; Error 4371 ;; Error
3655 (goto-char (1+ max))) 4372 (goto-char (1+ max)))
3656 (if (and tag (eq (preceding-char) ?\>)) 4373 (if (and tag (eq (preceding-char) ?\>))
@@ -3658,6 +4375,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3658 (cperl-modify-syntax-type (1- (point)) cperl-st-ket) 4375 (cperl-modify-syntax-type (1- (point)) cperl-st-ket)
3659 (cperl-modify-syntax-type i cperl-st-bra))) 4376 (cperl-modify-syntax-type i cperl-st-bra)))
3660 (put-text-property b i 'syntax-type 'string) 4377 (put-text-property b i 'syntax-type 'string)
4378 (put-text-property i (point) 'syntax-type 'multiline)
3661 (if is-x-REx 4379 (if is-x-REx
3662 (put-text-property b i 'indentable t))) 4380 (put-text-property b i 'indentable t)))
3663 (cperl-commentify b1 (point) t) 4381 (cperl-commentify b1 (point) t)
@@ -3673,7 +4391,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3673 (forward-word 1) ; skip modifiers s///s 4391 (forward-word 1) ; skip modifiers s///s
3674 (if tail (cperl-commentify tail (point) t)) 4392 (if tail (cperl-commentify tail (point) t))
3675 (cperl-postpone-fontification 4393 (cperl-postpone-fontification
3676 e1 (point) 'face 'cperl-nonoverridable))) 4394 e1 (point) 'face my-cperl-REx-modifiers-face)))
3677 ;; Check whether it is m// which means "previous match" 4395 ;; Check whether it is m// which means "previous match"
3678 ;; and highlight differently 4396 ;; and highlight differently
3679 (setq is-REx 4397 (setq is-REx
@@ -3691,7 +4409,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3691 (not (looking-at "split\\>"))) 4409 (not (looking-at "split\\>")))
3692 (error t)))) 4410 (error t))))
3693 (cperl-postpone-fontification 4411 (cperl-postpone-fontification
3694 b e 'face font-lock-function-name-face) 4412 b e 'face font-lock-warning-face)
3695 (if (or i2 ; Has 2 args 4413 (if (or i2 ; Has 2 args
3696 (and cperl-fontify-m-as-s 4414 (and cperl-fontify-m-as-s
3697 (or 4415 (or
@@ -3700,135 +4418,417 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3700 (not (eq ?\< (char-after b))))))) 4418 (not (eq ?\< (char-after b)))))))
3701 (progn 4419 (progn
3702 (cperl-postpone-fontification 4420 (cperl-postpone-fontification
3703 b (cperl-1+ b) 'face font-lock-constant-face) 4421 b (cperl-1+ b) 'face my-cperl-delimiters-face)
3704 (cperl-postpone-fontification 4422 (cperl-postpone-fontification
3705 (1- e) e 'face font-lock-constant-face))) 4423 (1- e) e 'face my-cperl-delimiters-face)))
3706 (if (and is-REx cperl-regexp-scan) 4424 (if (and is-REx cperl-regexp-scan)
3707 ;; Process RExen better 4425 ;; Process RExen: embedded comments, charclasses and ]
4426;;;/\3333\xFg\x{FFF}a\ppp\PPP\qqq\C\99f(?{ foo })(??{ foo })/;
4427;;;/a\.b[^a[:ff:]b]x$ab->$[|$,$ab->[cd]->[ef]|$ab[xy].|^${a,b}{c,d}/;
4428;;;/(?<=foo)(?<!bar)(x)(?:$ab|\$\/)$|\\\b\x888\776\[\:$/xxx;
4429;;;m?(\?\?{b,a})? + m/(??{aa})(?(?=xx)aa|bb)(?#aac)/;
4430;;;m$(^ab[c]\$)$ + m+(^ab[c]\$\+)+ + m](^ab[c\]$|.+)] + m)(^ab[c]$|.+\));
4431;;;m^a[\^b]c^ + m.a[^b]\.c.;
3708 (save-excursion 4432 (save-excursion
3709 (goto-char (1+ b)) 4433 (goto-char (1+ b))
4434 ;; First
4435 (cperl-look-at-leading-count is-x-REx e)
4436 (setq hairy-RE
4437 (concat
4438 (if is-x-REx
4439 (if (eq (char-after b) ?\#)
4440 "\\((\\?\\\\#\\)\\|\\(\\\\#\\)"
4441 "\\((\\?#\\)\\|\\(#\\)")
4442 ;; keep the same count: add a fake group
4443 (if (eq (char-after b) ?\#)
4444 "\\((\\?\\\\#\\)\\(\\)"
4445 "\\((\\?#\\)\\(\\)"))
4446 "\\|"
4447 "\\(\\[\\)" ; 3=[
4448 "\\|"
4449 "\\(]\\)" ; 4=]
4450 "\\|"
4451 ;; XXXX Will not be able to use it in s)))
4452 (if (eq (char-after b) ?\) )
4453 "\\())))\\)" ; Will never match
4454 (if (eq (char-after b) ?? )
4455 ;;"\\((\\\\\\?\\(\\\\\\?\\)?{\\)"
4456 "\\((\\\\\\?\\\\\\?{\\|()\\\\\\?{\\)"
4457 "\\((\\?\\??{\\)")) ; 5= (??{ (?{
4458 "\\|" ; 6= 0-length, 7: name, 8,9:code, 10:group
4459 "\\(" ;; XXXX 1-char variables, exc. |()\s
4460 "[$@]"
4461 "\\("
4462 "[_a-zA-Z:][_a-zA-Z0-9:]*"
4463 "\\|"
4464 "{[^{}]*}" ; only one-level allowed
4465 "\\|"
4466 "[^{(|) \t\r\n\f]"
4467 "\\)"
4468 "\\(" ;;8,9:code part of array/hash elt
4469 "\\(" "->" "\\)?"
4470 "\\[[^][]*\\]"
4471 "\\|"
4472 "{[^{}]*}"
4473 "\\)*"
4474 ;; XXXX: what if u is delim?
4475 "\\|"
4476 "[)^|$.*?+]"
4477 "\\|"
4478 "{[0-9]+}"
4479 "\\|"
4480 "{[0-9]+,[0-9]*}"
4481 "\\|"
4482 "\\\\[luLUEQbBAzZG]"
4483 "\\|"
4484 "(" ; Group opener
4485 "\\(" ; 10 group opener follower
4486 "\\?\\((\\?\\)" ; 11: in (?(?=C)A|B)
4487 "\\|"
4488 "\\?[:=!>?{]" ; "?" something
4489 "\\|"
4490 "\\?[-imsx]+[:)]" ; (?i) (?-s:.)
4491 "\\|"
4492 "\\?([0-9]+)" ; (?(1)foo|bar)
4493 "\\|"
4494 "\\?<[=!]"
4495 ;;;"\\|"
4496 ;;; "\\?"
4497 "\\)?"
4498 "\\)"
4499 "\\|"
4500 "\\\\\\(.\\)" ; 12=\SYMBOL
4501 ))
3710 (while 4502 (while
3711 (and (< (point) e) 4503 (and (< (point) (1- e))
3712 (re-search-forward 4504 (re-search-forward hairy-RE (1- e) 'to-end))
3713 (if is-x-REx
3714 (if (eq (char-after b) ?\#)
3715 "\\((\\?\\\\#\\)\\|\\(\\\\#\\)"
3716 "\\((\\?#\\)\\|\\(#\\)")
3717 (if (eq (char-after b) ?\#)
3718 "\\((\\?\\\\#\\)"
3719 "\\((\\?#\\)"))
3720 (1- e) 'to-end))
3721 (goto-char (match-beginning 0)) 4505 (goto-char (match-beginning 0))
3722 (setq REx-comment-start (point) 4506 (setq REx-subgr-start (point)
3723 was-comment t) 4507 was-subgr (following-char))
3724 (if (save-excursion 4508 (cond
3725 (and 4509 ((match-beginning 6) ; 0-length builtins, groups
3726 ;; XXX not working if outside delimiter is # 4510 (goto-char (match-end 0))
3727 (eq (preceding-char) ?\\) 4511 (if (match-beginning 11)
3728 (= (% (skip-chars-backward "$\\\\") 2) -1))) 4512 (goto-char (match-beginning 11)))
3729 ;; Not a comment, avoid loop: 4513 (if (>= (point) e)
3730 (progn (setq was-comment nil) 4514 (goto-char (1- e)))
3731 (forward-char 1)) 4515 (cperl-postpone-fontification
3732 (if (match-beginning 2) 4516 (match-beginning 0) (point)
4517 'face
4518 (cond
4519 ((eq was-subgr ?\) )
4520 (condition-case nil
4521 (save-excursion
4522 (forward-sexp -1)
4523 (if (> (point) b)
4524 (if (if (eq (char-after b) ?? )
4525 (looking-at "(\\\\\\?")
4526 (eq (char-after (1+ (point))) ?\?))
4527 my-cperl-REx-0length-face
4528 my-cperl-REx-ctl-face)
4529 font-lock-warning-face))
4530 (error font-lock-warning-face)))
4531 ((eq was-subgr ?\| )
4532 my-cperl-REx-ctl-face)
4533 ((eq was-subgr ?\$ )
4534 (if (> (point) (1+ REx-subgr-start))
4535 (progn
4536 (put-text-property
4537 (match-beginning 0) (point)
4538 'REx-interpolated
4539 (if is-o-REx 0
4540 (if (and (eq (match-beginning 0)
4541 (1+ b))
4542 (eq (point)
4543 (1- e))) 1 t)))
4544 font-lock-variable-name-face)
4545 my-cperl-REx-spec-char-face))
4546 ((memq was-subgr (append "^." nil) )
4547 my-cperl-REx-spec-char-face)
4548 ((eq was-subgr ?\( )
4549 (if (not (match-beginning 10))
4550 my-cperl-REx-ctl-face
4551 my-cperl-REx-0length-face))
4552 (t my-cperl-REx-0length-face)))
4553 (if (and (memq was-subgr (append "(|" nil))
4554 (not (string-match "(\\?[-imsx]+)"
4555 (match-string 0))))
4556 (cperl-look-at-leading-count is-x-REx e))
4557 (setq was-subgr nil)) ; We do stuff here
4558 ((match-beginning 12) ; \SYMBOL
4559 (forward-char 2)
4560 (if (>= (point) e)
4561 (goto-char (1- e))
4562 ;; How many chars to not highlight:
4563 ;; 0-len special-alnums in other branch =>
4564 ;; Generic: \non-alnum (1), \alnum (1+face)
4565 ;; Is-delim: \non-alnum (1/spec-2) alnum-1 (=what hai)
4566 (setq REx-subgr-start (point)
4567 qtag (preceding-char))
4568 (cperl-postpone-fontification
4569 (- (point) 2) (- (point) 1) 'face
4570 (if (memq qtag
4571 (append "ghijkmoqvFHIJKMORTVY" nil))
4572 font-lock-warning-face
4573 my-cperl-REx-0length-face))
4574 (if (and (eq (char-after b) qtag)
4575 (memq qtag (append ".])^$|*?+" nil)))
4576 (progn
4577 (if (and cperl-use-syntax-table-text-property
4578 (eq qtag ?\) ))
4579 (put-text-property
4580 REx-subgr-start (1- (point))
4581 'syntax-table cperl-st-punct))
4582 (cperl-postpone-fontification
4583 (1- (point)) (point) 'face
4584 ; \] can't appear below
4585 (if (memq qtag (append ".]^$" nil))
4586 'my-cperl-REx-spec-char-face
4587 (if (memq qtag (append "*?+" nil))
4588 'my-cperl-REx-0length-face
4589 'my-cperl-REx-ctl-face))))) ; )|
4590 ;; Test for arguments:
4591 (cond
4592 ;; This is not pretty: the 5.8.7 logic:
4593 ;; \0numx -> octal (up to total 3 dig)
4594 ;; \DIGIT -> backref unless \0
4595 ;; \DIGITs -> backref if legal
4596 ;; otherwise up to 3 -> octal
4597 ;; Do not try to distinguish, we guess
4598 ((or (and (memq qtag (append "01234567" nil))
4599 (re-search-forward
4600 "\\=[01234567]?[01234567]?"
4601 (1- e) 'to-end))
4602 (and (memq qtag (append "89" nil))
4603 (re-search-forward
4604 "\\=[0123456789]*" (1- e) 'to-end))
4605 (and (eq qtag ?x)
4606 (re-search-forward
4607 "\\=[0-9a-fA-F][0-9a-fA-F]?\\|\\={[0-9a-fA-F]+}"
4608 (1- e) 'to-end))
4609 (and (memq qtag (append "pPN" nil))
4610 (re-search-forward "\\={[^{}]+}\\|."
4611 (1- e) 'to-end))
4612 (eq (char-syntax qtag) ?w))
4613 (cperl-postpone-fontification
4614 (1- REx-subgr-start) (point)
4615 'face my-cperl-REx-length1-face))))
4616 (setq was-subgr nil)) ; We do stuff here
4617 ((match-beginning 3) ; [charclass]
4618 (forward-char 1)
4619 (if (eq (char-after b) ?^ )
4620 (and (eq (following-char) ?\\ )
4621 (eq (char-after (cperl-1+ (point)))
4622 ?^ )
4623 (forward-char 2))
4624 (and (eq (following-char) ?^ )
4625 (forward-char 1)))
4626 (setq argument b ; continue?
4627 tag nil ; list of POSIX classes
4628 qtag (point))
4629 (if (eq (char-after b) ?\] )
4630 (and (eq (following-char) ?\\ )
4631 (eq (char-after (cperl-1+ (point)))
4632 ?\] )
4633 (setq qtag (1+ qtag))
4634 (forward-char 2))
4635 (and (eq (following-char) ?\] )
4636 (forward-char 1)))
4637 ;; Apparently, I can't put \] into a charclass
4638 ;; in m]]: m][\\\]\]] produces [\\]]
4639;;; POSIX? [:word:] [:^word:] only inside []
4640;;; "\\=\\(\\\\.\\|[^][\\\\]\\|\\[:\\^?\sw+:]\\|\\[[^:]\\)*]")
4641 (while
4642 (and argument
4643 (re-search-forward
4644 (if (eq (char-after b) ?\] )
4645 "\\=\\(\\\\[^]]\\|[^]\\\\]\\)*\\\\]"
4646 "\\=\\(\\\\.\\|[^]\\\\]\\)*]")
4647 (1- e) 'toend))
4648 ;; Is this ] an end of POSIX class?
4649 (if (save-excursion
4650 (and
4651 (search-backward "[" argument t)
4652 (< REx-subgr-start (point))
4653 (not
4654 (and ; Should work with delim = \
4655 (eq (preceding-char) ?\\ )
4656 (= (% (skip-chars-backward
4657 "\\\\") 2) 0)))
4658 (looking-at
4659 (cond
4660 ((eq (char-after b) ?\] )
4661 "\\\\*\\[:\\^?\\sw+:\\\\\\]")
4662 ((eq (char-after b) ?\: )
4663 "\\\\*\\[\\\\:\\^?\\sw+\\\\:]")
4664 ((eq (char-after b) ?^ )
4665 "\\\\*\\[:\\(\\\\\\^\\)?\\sw+:\]")
4666 ((eq (char-syntax (char-after b))
4667 ?w)
4668 (concat
4669 "\\\\*\\[:\\(\\\\\\^\\)?\\(\\\\"
4670 (char-to-string (char-after b))
4671 "\\|\\sw\\)+:\]"))
4672 (t "\\\\*\\[:\\^?\\sw*:]")))
4673 (setq argument (point))))
4674 (setq tag (cons (cons argument (point))
4675 tag)
4676 argument (point)) ; continue
4677 (setq argument nil)))
4678 (and argument
4679 (message "Couldn't find end of charclass in a REx, pos=%s"
4680 REx-subgr-start))
4681 (if (and cperl-use-syntax-table-text-property
4682 (> (- (point) 2) REx-subgr-start))
4683 (put-text-property
4684 (1+ REx-subgr-start) (1- (point))
4685 'syntax-table cperl-st-punct))
4686 (cperl-postpone-fontification
4687 REx-subgr-start qtag
4688 'face my-cperl-REx-spec-char-face)
4689 (cperl-postpone-fontification
4690 (1- (point)) (point) 'face
4691 my-cperl-REx-spec-char-face)
4692 (if (eq (char-after b) ?\] )
4693 (cperl-postpone-fontification
4694 (- (point) 2) (1- (point))
4695 'face my-cperl-REx-0length-face))
4696 (while tag
4697 (cperl-postpone-fontification
4698 (car (car tag)) (cdr (car tag))
4699 'face my-cperl-REx-length1-face)
4700 (setq tag (cdr tag)))
4701 (setq was-subgr nil)) ; did facing already
4702 ;; Now rare stuff:
4703 ((and (match-beginning 2) ; #-comment
4704 (/= (match-beginning 2) (match-end 2)))
4705 (beginning-of-line 2)
4706 (if (> (point) e)
4707 (goto-char (1- e))))
4708 ((match-beginning 4) ; character "]"
4709 (setq was-subgr nil) ; We do stuff here
4710 (goto-char (match-end 0))
4711 (if cperl-use-syntax-table-text-property
4712 (put-text-property
4713 (1- (point)) (point)
4714 'syntax-table cperl-st-punct))
4715 (cperl-postpone-fontification
4716 (1- (point)) (point)
4717 'face font-lock-warning-face))
4718 ((match-beginning 5) ; before (?{}) (??{})
4719 (setq tag (match-end 0))
4720 (if (or (setq qtag
4721 (cperl-forward-group-in-re st-l))
4722 (and (>= (point) e)
4723 (setq qtag "no matching `)' found"))
4724 (and (not (eq (char-after (- (point) 2))
4725 ?\} ))
4726 (setq qtag "Can't find })")))
3733 (progn 4727 (progn
3734 (beginning-of-line 2) 4728 (goto-char (1- e))
3735 (if (> (point) e) 4729 (message qtag))
3736 (goto-char (1- e)))) 4730 (cperl-postpone-fontification
3737 ;; Works also if the outside delimiters are (). 4731 (1- tag) (1- (point))
3738 (or (search-forward ")" (1- e) 'toend) 4732 'face font-lock-variable-name-face)
3739 (message 4733 (cperl-postpone-fontification
3740 "Couldn't find end of (?#...)-comment in a REx, pos=%s" 4734 REx-subgr-start (1- tag)
3741 REx-comment-start)))) 4735 'face my-cperl-REx-spec-char-face)
4736 (cperl-postpone-fontification
4737 (1- (point)) (point)
4738 'face my-cperl-REx-spec-char-face)
4739 (if cperl-use-syntax-table-text-property
4740 (progn
4741 (put-text-property
4742 (- (point) 2) (1- (point))
4743 'syntax-table cperl-st-cfence)
4744 (put-text-property
4745 (+ REx-subgr-start 2)
4746 (+ REx-subgr-start 3)
4747 'syntax-table cperl-st-cfence))))
4748 (setq was-subgr nil))
4749 (t ; (?#)-comment
4750 ;; Inside "(" and "\" arn't special in any way
4751 ;; Works also if the outside delimiters are ().
4752 (or;;(if (eq (char-after b) ?\) )
4753 ;;(re-search-forward
4754 ;; "[^\\\\]\\(\\\\\\\\\\)*\\\\)"
4755 ;; (1- e) 'toend)
4756 (search-forward ")" (1- e) 'toend)
4757 ;;)
4758 (message
4759 "Couldn't find end of (?#...)-comment in a REx, pos=%s"
4760 REx-subgr-start))))
3742 (if (>= (point) e) 4761 (if (>= (point) e)
3743 (goto-char (1- e))) 4762 (goto-char (1- e)))
3744 (if was-comment 4763 (cond
3745 (progn 4764 (was-subgr
3746 (setq REx-comment-end (point)) 4765 (setq REx-subgr-end (point))
3747 (cperl-commentify 4766 (cperl-commentify
3748 REx-comment-start REx-comment-end nil) 4767 REx-subgr-start REx-subgr-end nil)
3749 (cperl-postpone-fontification 4768 (cperl-postpone-fontification
3750 REx-comment-start REx-comment-end 4769 REx-subgr-start REx-subgr-end
3751 'face font-lock-comment-face)))))) 4770 'face font-lock-comment-face))))))
3752 (if (and is-REx is-x-REx) 4771 (if (and is-REx is-x-REx)
3753 (put-text-property (1+ b) (1- e) 4772 (put-text-property (1+ b) (1- e)
3754 'syntax-subtype 'x-REx))) 4773 'syntax-subtype 'x-REx)))
3755 (if i2 4774 (if i2
3756 (progn 4775 (progn
3757 (cperl-postpone-fontification 4776 (cperl-postpone-fontification
3758 (1- e1) e1 'face font-lock-constant-face) 4777 (1- e1) e1 'face my-cperl-delimiters-face)
3759 (if (assoc (char-after b) cperl-starters) 4778 (if (assoc (char-after b) cperl-starters)
3760 (cperl-postpone-fontification 4779 (progn
3761 b1 (1+ b1) 'face font-lock-constant-face)))) 4780 (cperl-postpone-fontification
4781 b1 (1+ b1) 'face my-cperl-delimiters-face)
4782 (put-text-property b1 (1+ b1)
4783 'REx-part2 t)))))
3762 (if (> (point) max) 4784 (if (> (point) max)
3763 (setq tmpend tb)))) 4785 (setq tmpend tb))))
3764 ((match-beginning 13) ; sub with prototypes 4786 ((match-beginning 17) ; sub with prototype or attribute
3765 (setq b (match-beginning 0)) 4787 ;; 1+6+2+1+1=11 extra () before this (sub with proto/attr):
4788 ;;"\\<sub\\>\\(" ;12
4789 ;; cperl-white-and-comment-rex ;13
4790 ;; "\\([a-zA-Z_:'0-9]+\\)\\)?" ; name ;14
4791 ;;"\\(" cperl-maybe-white-and-comment-rex ;15,16
4792 ;; "\\(([^()]*)\\|:[^:]\\)\\)" ; 17:proto or attribute start
4793 (setq b1 (match-beginning 14) e1 (match-end 14))
3766 (if (memq (char-after (1- b)) 4794 (if (memq (char-after (1- b))
3767 '(?\$ ?\@ ?\% ?\& ?\*)) 4795 '(?\$ ?\@ ?\% ?\& ?\*))
3768 nil 4796 nil
3769 (setq state (parse-partial-sexp 4797 (goto-char b)
3770 state-point b nil nil state) 4798 (if (eq (char-after (match-beginning 17)) ?\( )
3771 state-point b) 4799 (progn
3772 (if (or (nth 3 state) (nth 4 state)) 4800 (cperl-commentify ; Prototypes; mark as string
3773 nil 4801 (match-beginning 17) (match-end 17) t)
3774 ;; Mark as string 4802 (goto-char (match-end 0))
3775 (cperl-commentify (match-beginning 13) (match-end 13) t)) 4803 ;; Now look for attributes after prototype:
3776 (goto-char (match-end 0)))) 4804 (forward-comment (buffer-size))
3777 ;; 1+6+2+1+1+2=13 extra () before this: 4805 (and (looking-at ":[^:]")
3778 ;; "\\$\\(['{]\\)" 4806 (cperl-find-sub-attrs st-l b1 e1 b)))
3779 ((and (match-beginning 14) 4807 ;; treat attributes without prototype
3780 (eq (preceding-char) ?\')) ; $' 4808 (goto-char (match-beginning 17))
3781 (setq b (1- (point)) 4809 (cperl-find-sub-attrs st-l b1 e1 b))))
3782 state (parse-partial-sexp 4810 ;; 1+6+2+1+1+6+1=18 extra () before this:
3783 state-point (1- b) nil nil state)
3784 state-point (1- b))
3785 (if (nth 3 state) ; in string
3786 (cperl-modify-syntax-type (1- b) cperl-st-punct))
3787 (goto-char (1+ b)))
3788 ;; 1+6+2+1+1+2=13 extra () before this:
3789 ;; "\\$\\(['{]\\)"
3790 ((match-beginning 14) ; ${
3791 (setq bb (match-beginning 0))
3792 (cperl-modify-syntax-type bb cperl-st-punct))
3793 ;; 1+6+2+1+1+2+1=14 extra () before this:
3794 ;; "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'") 4811 ;; "\\(\\<sub[ \t\n\f]+\\|[&*$@%]\\)[a-zA-Z0-9_]*'")
3795 ((match-beginning 15) ; old $abc'efg syntax 4812 ((match-beginning 19) ; old $abc'efg syntax
3796 (setq bb (match-end 0) 4813 (setq bb (match-end 0))
3797 b (match-beginning 0) 4814 ;;;(if (nth 3 state) nil ; in string
3798 state (parse-partial-sexp 4815 (put-text-property (1- bb) bb 'syntax-table cperl-st-word)
3799 state-point b nil nil state)
3800 state-point b)
3801 (if (nth 3 state) ; in string
3802 nil
3803 (put-text-property (1- bb) bb 'syntax-table cperl-st-word))
3804 (goto-char bb)) 4816 (goto-char bb))
3805 ;; 1+6+2+1+1+2+1+1=15 extra () before this: 4817 ;; 1+6+2+1+1+6+1+1=19 extra () before this:
3806 ;; "__\\(END\\|DATA\\)__" 4818 ;; "__\\(END\\|DATA\\)__"
3807 ((match-beginning 16) ; __END__, __DATA__ 4819 ((match-beginning 20) ; __END__, __DATA__
3808 (setq bb (match-end 0) 4820 (setq bb (match-end 0))
3809 b (match-beginning 0) 4821 ;; (put-text-property b (1+ bb) 'syntax-type 'pod) ; Cheat
3810 state (parse-partial-sexp 4822 (cperl-commentify b bb nil)
3811 state-point b nil nil state) 4823 (setq end t))
3812 state-point b) 4824 ;; "\\\\\\(['`\"($]\\)"
3813 (if (or (nth 3 state) (nth 4 state)) 4825 ((match-beginning 21)
3814 nil 4826 ;; Trailing backslash; make non-quoting outside string/comment
3815 ;; (put-text-property b (1+ bb) 'syntax-type 'pod) ; Cheat 4827 (setq bb (match-end 0))
3816 (cperl-commentify b bb nil)
3817 (setq end t))
3818 (goto-char bb))
3819 ((match-beginning 17) ; "\\\\\\(['`\"($]\\)"
3820 ;; Trailing backslash ==> non-quoting outside string/comment
3821 (setq bb (match-end 0)
3822 b (match-beginning 0))
3823 (goto-char b) 4828 (goto-char b)
3824 (skip-chars-backward "\\\\") 4829 (skip-chars-backward "\\\\")
3825 ;;;(setq i2 (= (% (skip-chars-backward "\\\\") 2) -1)) 4830 ;;;(setq i2 (= (% (skip-chars-backward "\\\\") 2) -1))
3826 (setq state (parse-partial-sexp 4831 (cperl-modify-syntax-type b cperl-st-punct)
3827 state-point b nil nil state)
3828 state-point b)
3829 (if (or (nth 3 state) (nth 4 state) )
3830 nil
3831 (cperl-modify-syntax-type b cperl-st-punct))
3832 (goto-char bb)) 4832 (goto-char bb))
3833 (t (error "Error in regexp of the sniffer"))) 4833 (t (error "Error in regexp of the sniffer")))
3834 (if (> (point) stop-point) 4834 (if (> (point) stop-point)
@@ -3839,7 +4839,10 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3839 (or (car err-l) (setcar err-l b))) 4839 (or (car err-l) (setcar err-l b)))
3840 (goto-char stop-point)))) 4840 (goto-char stop-point))))
3841 (setq cperl-syntax-state (cons state-point state) 4841 (setq cperl-syntax-state (cons state-point state)
3842 cperl-syntax-done-to (or tmpend (max (point) max)))) 4842 ;; Do not mark syntax as done past tmpend???
4843 cperl-syntax-done-to (or tmpend (max (point) max)))
4844 ;;(message "state-at=%s, done-to=%s" state-point cperl-syntax-done-to)
4845 )
3843 (if (car err-l) (goto-char (car err-l)) 4846 (if (car err-l) (goto-char (car err-l))
3844 (or non-inter 4847 (or non-inter
3845 (message "Scanning for \"hard\" Perl constructions... done")))) 4848 (message "Scanning for \"hard\" Perl constructions... done"))))
@@ -3851,48 +4854,91 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3851 ;; cperl-mode-syntax-table. 4854 ;; cperl-mode-syntax-table.
3852 ;; (set-syntax-table cperl-mode-syntax-table) 4855 ;; (set-syntax-table cperl-mode-syntax-table)
3853 ) 4856 )
3854 (car err-l))) 4857 (list (car err-l) overshoot)))
4858
4859(defun cperl-find-pods-heres-region (min max)
4860 (interactive "r")
4861 (cperl-find-pods-heres min max))
3855 4862
3856(defun cperl-backward-to-noncomment (lim) 4863(defun cperl-backward-to-noncomment (lim)
3857 ;; Stops at lim or after non-whitespace that is not in comment 4864 ;; Stops at lim or after non-whitespace that is not in comment
4865 ;; XXXX Wrongly understands end-of-multiline strings with # as comment
3858 (let (stop p pr) 4866 (let (stop p pr)
3859 (while (and (not stop) (> (point) (or lim 1))) 4867 (while (and (not stop) (> (point) (or lim (point-min))))
3860 (skip-chars-backward " \t\n\f" lim) 4868 (skip-chars-backward " \t\n\f" lim)
3861 (setq p (point)) 4869 (setq p (point))
3862 (beginning-of-line) 4870 (beginning-of-line)
3863 (if (memq (setq pr (get-text-property (point) 'syntax-type)) 4871 (if (memq (setq pr (get-text-property (point) 'syntax-type))
3864 '(pod here-doc here-doc-delim)) 4872 '(pod here-doc here-doc-delim))
3865 (cperl-unwind-to-safe nil) 4873 (cperl-unwind-to-safe nil)
3866 (or (looking-at "^[ \t]*\\(#\\|$\\)") 4874 (or (and (looking-at "^[ \t]*\\(#\\|$\\)")
3867 (progn (cperl-to-comment-or-eol) (bolp)) 4875 (not (memq pr '(string prestring))))
3868 (progn 4876 (progn (cperl-to-comment-or-eol) (bolp))
3869 (skip-chars-backward " \t") 4877 (progn
3870 (if (< p (point)) (goto-char p)) 4878 (skip-chars-backward " \t")
3871 (setq stop t))))))) 4879 (if (< p (point)) (goto-char p))
4880 (setq stop t)))))))
3872 4881
4882;; Used only in `cperl-calculate-indent'...
4883(defun cperl-block-p () ; Do not C-M-q ! One string contains ";" !
4884 ;; Positions is before ?\{. Checks whether it starts a block.
4885 ;; No save-excursion! This is more a distinguisher of a block/hash ref...
4886 (cperl-backward-to-noncomment (point-min))
4887 (or (memq (preceding-char) (append ";){}$@&%\C-@" nil)) ; Or label! \C-@ at bobp
4888 ; Label may be mixed up with `$blah :'
4889 (save-excursion (cperl-after-label))
4890 (get-text-property (cperl-1- (point)) 'attrib-group)
4891 (and (memq (char-syntax (preceding-char)) '(?w ?_))
4892 (progn
4893 (backward-sexp)
4894 ;; sub {BLK}, print {BLK} $data, but NOT `bless', `return', `tr'
4895 (or (and (looking-at "[a-zA-Z0-9_:]+[ \t\n\f]*[{#]") ; Method call syntax
4896 (not (looking-at "\\(bless\\|return\\|q[wqrx]?\\|tr\\|[smy]\\)\\>")))
4897 ;; sub bless::foo {}
4898 (progn
4899 (cperl-backward-to-noncomment (point-min))
4900 (and (eq (preceding-char) ?b)
4901 (progn
4902 (forward-sexp -1)
4903 (looking-at "sub[ \t\n\f#]")))))))))
4904
4905;;; What is the difference of (cperl-after-block-p lim t) and (cperl-block-p)?
4906;;; No save-excursion; condition-case ... In (cperl-block-p) the block
4907;;; may be a part of an in-statement construct, such as
4908;;; ${something()}, print {FH} $data.
4909;;; Moreover, one takes positive approach (looks for else,grep etc)
4910;;; another negative (looks for bless,tr etc)
3873(defun cperl-after-block-p (lim &optional pre-block) 4911(defun cperl-after-block-p (lim &optional pre-block)
3874 "Return true if the preceeding } ends a block or a following { starts one. 4912 "Return true if the preceeding } (if PRE-BLOCK, following {) delimits a block.
3875Would not look before LIM. If PRE-BLOCK is nil checks preceeding }. 4913Would not look before LIM. Assumes that LIM is a good place to begin a
3876otherwise following {." 4914statement. The kind of block we treat here is one after which a new
3877 ;; We suppose that the preceding char is }. 4915statement would start; thus the block in ${func()} does not count."
3878 (save-excursion 4916 (save-excursion
3879 (condition-case nil 4917 (condition-case nil
3880 (progn 4918 (progn
3881 (or pre-block (forward-sexp -1)) 4919 (or pre-block (forward-sexp -1))
3882 (cperl-backward-to-noncomment lim) 4920 (cperl-backward-to-noncomment lim)
3883 (or (eq (point) lim) 4921 (or (eq (point) lim)
3884 (eq (preceding-char) ?\) ) ; if () {} sub f () {} 4922 ;; if () {} // sub f () {} // sub f :a(') {}
3885 (if (eq (char-syntax (preceding-char)) ?w) ; else {} 4923 (eq (preceding-char) ?\) )
4924 ;; label: {}
4925 (save-excursion (cperl-after-label))
4926 ;; sub :attr {}
4927 (get-text-property (cperl-1- (point)) 'attrib-group)
4928 (if (memq (char-syntax (preceding-char)) '(?w ?_)) ; else {}
3886 (save-excursion 4929 (save-excursion
3887 (forward-sexp -1) 4930 (forward-sexp -1)
3888 (or (looking-at "\\(else\\|continue\\|grep\\|map\\|BEGIN\\|END\\|CHECK\\|INIT\\)\\>") 4931 ;; else {} but not else::func {}
4932 (or (and (looking-at "\\(else\\|continue\\|grep\\|map\\|BEGIN\\|END\\|CHECK\\|INIT\\)\\>")
4933 (not (looking-at "\\(\\sw\\|_\\)+::")))
3889 ;; sub f {} 4934 ;; sub f {}
3890 (progn 4935 (progn
3891 (cperl-backward-to-noncomment lim) 4936 (cperl-backward-to-noncomment lim)
3892 (and (eq (char-syntax (preceding-char)) ?w) 4937 (and (eq (preceding-char) ?b)
3893 (progn 4938 (progn
3894 (forward-sexp -1) 4939 (forward-sexp -1)
3895 (looking-at "sub\\>")))))) 4940 (looking-at "sub[ \t\n\f#]"))))))
4941 ;; What preceeds is not word... XXXX Last statement in sub???
3896 (cperl-after-expr-p lim)))) 4942 (cperl-after-expr-p lim))))
3897 (error nil)))) 4943 (error nil))))
3898 4944
@@ -3914,14 +4960,12 @@ CHARS is a string that contains good characters to have before us (however,
3914 (if (get-text-property (point) 'here-doc-group) 4960 (if (get-text-property (point) 'here-doc-group)
3915 (progn 4961 (progn
3916 (goto-char 4962 (goto-char
3917 (or (previous-single-property-change (point) 'here-doc-group) 4963 (cperl-beginning-of-property (point) 'here-doc-group))
3918 (point)))
3919 (beginning-of-line 0))) 4964 (beginning-of-line 0)))
3920 (if (get-text-property (point) 'in-pod) 4965 (if (get-text-property (point) 'in-pod)
3921 (progn 4966 (progn
3922 (goto-char 4967 (goto-char
3923 (or (previous-single-property-change (point) 'in-pod) 4968 (cperl-beginning-of-property (point) 'in-pod))
3924 (point)))
3925 (beginning-of-line 0))) 4969 (beginning-of-line 0)))
3926 (if (looking-at "^[ \t]*\\(#\\|$\\)") nil ; Only comment, skip 4970 (if (looking-at "^[ \t]*\\(#\\|$\\)") nil ; Only comment, skip
3927 ;; Else: last iteration, or a label 4971 ;; Else: last iteration, or a label
@@ -3933,7 +4977,7 @@ CHARS is a string that contains good characters to have before us (however,
3933 (progn 4977 (progn
3934 (forward-char -1) 4978 (forward-char -1)
3935 (skip-chars-backward " \t\n\f" lim) 4979 (skip-chars-backward " \t\n\f" lim)
3936 (eq (char-syntax (preceding-char)) ?w))) 4980 (memq (char-syntax (preceding-char)) '(?w ?_))))
3937 (forward-sexp -1) ; Possibly label. Skip it 4981 (forward-sexp -1) ; Possibly label. Skip it
3938 (goto-char p) 4982 (goto-char p)
3939 (setq stop t)))) 4983 (setq stop t))))
@@ -3949,6 +4993,44 @@ CHARS is a string that contains good characters to have before us (however,
3949 (eq (get-text-property (point) 'syntax-type) 4993 (eq (get-text-property (point) 'syntax-type)
3950 'format))))))))) 4994 'format)))))))))
3951 4995
4996(defun cperl-backward-to-start-of-expr (&optional lim)
4997 (condition-case nil
4998 (progn
4999 (while (and (or (not lim)
5000 (> (point) lim))
5001 (not (cperl-after-expr-p lim)))
5002 (forward-sexp -1)
5003 ;; May be after $, @, $# etc of a variable
5004 (skip-chars-backward "$@%#")))
5005 (error nil)))
5006
5007(defun cperl-at-end-of-expr (&optional lim)
5008 ;; Since the SEXP approach below is very fragile, do some overengineering
5009 (or (looking-at (concat cperl-maybe-white-and-comment-rex "[;}]"))
5010 (condition-case nil
5011 (save-excursion
5012 ;; If nothing interesting after, does as (forward-sexp -1);
5013 ;; otherwise fails, or ends at a start of following sexp.
5014 ;; XXXX PROBLEMS: if what follows (after ";") @FOO, or ${bar}
5015 ;; may be stuck after @ or $; just put some stupid workaround now:
5016 (let ((p (point)))
5017 (forward-sexp 1)
5018 (forward-sexp -1)
5019 (while (memq (preceding-char) (append "%&@$*" nil))
5020 (forward-char -1))
5021 (or (< (point) p)
5022 (cperl-after-expr-p lim))))
5023 (error t))))
5024
5025(defun cperl-forward-to-end-of-expr (&optional lim)
5026 (let ((p (point))))
5027 (condition-case nil
5028 (progn
5029 (while (and (< (point) (or lim (point-max)))
5030 (not (cperl-at-end-of-expr)))
5031 (forward-sexp 1)))
5032 (error nil)))
5033
3952(defun cperl-backward-to-start-of-continued-exp (lim) 5034(defun cperl-backward-to-start-of-continued-exp (lim)
3953 (if (memq (preceding-char) (append ")]}\"'`" nil)) 5035 (if (memq (preceding-char) (append ")]}\"'`" nil))
3954 (forward-sexp -1)) 5036 (forward-sexp -1))
@@ -3989,18 +5071,51 @@ conditional/loop constructs."
3989 (beginning-of-line) 5071 (beginning-of-line)
3990 (while (null done) 5072 (while (null done)
3991 (setq top (point)) 5073 (setq top (point))
3992 (while (= (nth 0 (parse-partial-sexp (point) tmp-end 5074 ;; Plan A: if line has an unfinished paren-group, go to end-of-group
3993 -1)) -1) 5075 (while (= -1 (nth 0 (parse-partial-sexp (point) tmp-end -1)))
3994 (setq top (point))) ; Get the outermost parenths in line 5076 (setq top (point))) ; Get the outermost parenths in line
3995 (goto-char top) 5077 (goto-char top)
3996 (while (< (point) tmp-end) 5078 (while (< (point) tmp-end)
3997 (parse-partial-sexp (point) tmp-end nil t) ; To start-sexp or eol 5079 (parse-partial-sexp (point) tmp-end nil t) ; To start-sexp or eol
3998 (or (eolp) (forward-sexp 1))) 5080 (or (eolp) (forward-sexp 1)))
3999 (if (> (point) tmp-end) 5081 (if (> (point) tmp-end) ; Yes, there an unfinished block
4000 (save-excursion 5082 nil
4001 (end-of-line) 5083 (if (eq ?\) (preceding-char))
4002 (setq tmp-end (point))) 5084 (progn ;; Plan B: find by REGEXP block followup this line
4003 (setq done t))) 5085 (setq top (point))
5086 (condition-case nil
5087 (progn
5088 (forward-sexp -2)
5089 (if (eq (following-char) ?$ ) ; for my $var (list)
5090 (progn
5091 (forward-sexp -1)
5092 (if (looking-at "\\(my\\|local\\|our\\)\\>")
5093 (forward-sexp -1))))
5094 (if (looking-at
5095 (concat "\\(\\elsif\\|if\\|unless\\|while\\|until"
5096 "\\|for\\(each\\)?\\>\\(\\("
5097 cperl-maybe-white-and-comment-rex
5098 "\\(my\\|local\\|our\\)\\)?"
5099 cperl-maybe-white-and-comment-rex
5100 "\\$[_a-zA-Z0-9]+\\)?\\)\\>"))
5101 (progn
5102 (goto-char top)
5103 (forward-sexp 1)
5104 (setq top (point)))))
5105 (error (setq done t)))
5106 (goto-char top))
5107 (if (looking-at ; Try Plan C: continuation block
5108 (concat cperl-maybe-white-and-comment-rex
5109 "\\<\\(else\\|elsif\|continue\\)\\>"))
5110 (progn
5111 (goto-char (match-end 0))
5112 (save-excursion
5113 (end-of-line)
5114 (setq tmp-end (point))))
5115 (setq done t))))
5116 (save-excursion
5117 (end-of-line)
5118 (setq tmp-end (point))))
4004 (goto-char tmp-end) 5119 (goto-char tmp-end)
4005 (setq tmp-end (point-marker))) 5120 (setq tmp-end (point-marker)))
4006 (if cperl-indent-region-fix-constructs 5121 (if cperl-indent-region-fix-constructs
@@ -4029,16 +5144,26 @@ Returns some position at the last line."
4029 ;; Looking at: 5144 ;; Looking at:
4030 ;; } 5145 ;; }
4031 ;; else 5146 ;; else
4032 (if (and cperl-merge-trailing-else 5147 (if cperl-merge-trailing-else
4033 (looking-at 5148 (if (looking-at
4034 "[ \t]*}[ \t]*\n[ \t\n]*\\(els\\(e\\|if\\)\\|continue\\)\\>")) 5149 "[ \t]*}[ \t]*\n[ \t\n]*\\(els\\(e\\|if\\)\\|continue\\)\\>")
4035 (progn 5150 (progn
4036 (search-forward "}") 5151 (search-forward "}")
4037 (setq p (point)) 5152 (setq p (point))
4038 (skip-chars-forward " \t\n") 5153 (skip-chars-forward " \t\n")
4039 (delete-region p (point)) 5154 (delete-region p (point))
4040 (insert (make-string cperl-indent-region-fix-constructs ?\s)) 5155 (insert (make-string cperl-indent-region-fix-constructs ?\s))
4041 (beginning-of-line))) 5156 (beginning-of-line)))
5157 (if (looking-at "[ \t]*}[ \t]*\\(els\\(e\\|if\\)\\|continue\\)\\>")
5158 (save-excursion
5159 (search-forward "}")
5160 (delete-horizontal-space)
5161 (insert "\n")
5162 (setq ret (point))
5163 (if (cperl-indent-line parse-data)
5164 (progn
5165 (cperl-fix-line-spacing end parse-data)
5166 (setq ret (point)))))))
4042 ;; Looking at: 5167 ;; Looking at:
4043 ;; } else 5168 ;; } else
4044 (if (looking-at "[ \t]*}\\(\t*\\|[ \t][ \t]+\\)\\<\\(els\\(e\\|if\\)\\|continue\\)\\>") 5169 (if (looking-at "[ \t]*}\\(\t*\\|[ \t][ \t]+\\)\\<\\(els\\(e\\|if\\)\\|continue\\)\\>")
@@ -4075,19 +5200,19 @@ Returns some position at the last line."
4075 (insert 5200 (insert
4076 (make-string cperl-indent-region-fix-constructs ?\s)) 5201 (make-string cperl-indent-region-fix-constructs ?\s))
4077 (beginning-of-line))) 5202 (beginning-of-line)))
4078 ;; Looking at: 5203 ;; Looking at (with or without "}" at start, ending after "({"):
4079 ;; } foreach my $var () { 5204 ;; } foreach my $var () OR {
4080 (if (looking-at 5205 (if (looking-at
4081 "[ \t]*\\(}[ \t]*\\)?\\<\\(\\els\\(e\\|if\\)\\|continue\\|if\\|unless\\|while\\|for\\(each\\)?\\(\\([ \t]+\\(my\\|local\\|our\\)\\)?[ \t]*\\$[_a-zA-Z0-9]+\\)?\\|until\\)\\>\\([ \t]*(\\|[ \t\n]*{\\)\\|[ \t]*{") 5206 "[ \t]*\\(}[ \t]*\\)?\\<\\(\\els\\(e\\|if\\)\\|continue\\|if\\|unless\\|while\\|for\\(each\\)?\\(\\([ \t]+\\(my\\|local\\|our\\)\\)?[ \t]*\\$[_a-zA-Z0-9]+\\)?\\|until\\)\\>\\([ \t]*(\\|[ \t\n]*{\\)\\|[ \t]*{")
4082 (progn 5207 (progn
4083 (setq ml (match-beginning 8)) 5208 (setq ml (match-beginning 8)) ; "(" or "{" after control word
4084 (re-search-forward "[({]") 5209 (re-search-forward "[({]")
4085 (forward-char -1) 5210 (forward-char -1)
4086 (setq p (point)) 5211 (setq p (point))
4087 (if (eq (following-char) ?\( ) 5212 (if (eq (following-char) ?\( )
4088 (progn 5213 (progn
4089 (forward-sexp 1) 5214 (forward-sexp 1)
4090 (setq pp (point))) 5215 (setq pp (point))) ; past parenth-group
4091 ;; after `else' or nothing 5216 ;; after `else' or nothing
4092 (if ml ; after `else' 5217 (if ml ; after `else'
4093 (skip-chars-backward " \t\n") 5218 (skip-chars-backward " \t\n")
@@ -4097,13 +5222,13 @@ Returns some position at the last line."
4097 ;; Multiline expr should be special 5222 ;; Multiline expr should be special
4098 (setq ml (and pp (save-excursion (goto-char p) 5223 (setq ml (and pp (save-excursion (goto-char p)
4099 (search-forward "\n" pp t)))) 5224 (search-forward "\n" pp t))))
4100 (if (and (or (not pp) (< pp end)) 5225 (if (and (or (not pp) (< pp end)) ; Do not go too far...
4101 (looking-at "[ \t\n]*{")) 5226 (looking-at "[ \t\n]*{"))
4102 (progn 5227 (progn
4103 (cond 5228 (cond
4104 ((bolp) ; Were before `{', no if/else/etc 5229 ((bolp) ; Were before `{', no if/else/etc
4105 nil) 5230 nil)
4106 ((looking-at "\\(\t*\\| [ \t]+\\){") 5231 ((looking-at "\\(\t*\\| [ \t]+\\){") ; Not exactly 1 SPACE
4107 (delete-horizontal-space) 5232 (delete-horizontal-space)
4108 (if (if ml 5233 (if (if ml
4109 cperl-extra-newline-before-brace-multiline 5234 cperl-extra-newline-before-brace-multiline
@@ -4126,7 +5251,17 @@ Returns some position at the last line."
4126 (skip-chars-forward " \t\n") 5251 (skip-chars-forward " \t\n")
4127 (delete-region pp (point)) 5252 (delete-region pp (point))
4128 (insert 5253 (insert
4129 (make-string cperl-indent-region-fix-constructs ?\s)))) 5254 (make-string cperl-indent-region-fix-constructs ?\ )))
5255 ((and (looking-at "[\t ]*{")
5256 (if ml cperl-extra-newline-before-brace-multiline
5257 cperl-extra-newline-before-brace))
5258 (delete-horizontal-space)
5259 (insert "\n")
5260 (setq ret (point))
5261 (if (cperl-indent-line parse-data)
5262 (progn
5263 (cperl-fix-line-spacing end parse-data)
5264 (setq ret (point))))))
4130 ;; Now we are before `{' 5265 ;; Now we are before `{'
4131 (if (looking-at "[ \t\n]*{[ \t]*[^ \t\n#]") 5266 (if (looking-at "[ \t\n]*{[ \t]*[^ \t\n#]")
4132 (progn 5267 (progn
@@ -4278,7 +5413,7 @@ indentation and initial hashes. Behaves usually outside of comment."
4278 ;; (interactive "P") ; Only works when called from fill-paragraph. -stef 5413 ;; (interactive "P") ; Only works when called from fill-paragraph. -stef
4279 (let (;; Non-nil if the current line contains a comment. 5414 (let (;; Non-nil if the current line contains a comment.
4280 has-comment 5415 has-comment
4281 5416 fill-paragraph-function ; do not recurse
4282 ;; If has-comment, the appropriate fill-prefix for the comment. 5417 ;; If has-comment, the appropriate fill-prefix for the comment.
4283 comment-fill-prefix 5418 comment-fill-prefix
4284 ;; Line that contains code and comment (or nil) 5419 ;; Line that contains code and comment (or nil)
@@ -4310,7 +5445,7 @@ indentation and initial hashes. Behaves usually outside of comment."
4310 dc (- c (current-column)) len (- start (point)) 5445 dc (- c (current-column)) len (- start (point))
4311 start (point-marker)) 5446 start (point-marker))
4312 (delete-char len) 5447 (delete-char len)
4313 (insert (make-string dc ?-))))) 5448 (insert (make-string dc ?-))))) ; Placeholder (to avoid splitting???)
4314 (if (not has-comment) 5449 (if (not has-comment)
4315 (fill-paragraph justify) ; Do the usual thing outside of comment 5450 (fill-paragraph justify) ; Do the usual thing outside of comment
4316 ;; Narrow to include only the comment, and then fill the region. 5451 ;; Narrow to include only the comment, and then fill the region.
@@ -4332,11 +5467,16 @@ indentation and initial hashes. Behaves usually outside of comment."
4332 (point))) 5467 (point)))
4333 ;; Remove existing hashes 5468 ;; Remove existing hashes
4334 (save-excursion 5469 (save-excursion
4335 (goto-char (point-min)) 5470 (goto-char (point-min))
4336 (while (progn (forward-line 1) (< (point) (point-max))) 5471 (while (progn (forward-line 1) (< (point) (point-max)))
4337 (skip-chars-forward " \t") 5472 (skip-chars-forward " \t")
4338 (and (looking-at "#+") 5473 (if (looking-at "#+")
4339 (delete-char (- (match-end 0) (match-beginning 0)))))) 5474 (progn
5475 (if (and (eq (point) (match-beginning 0))
5476 (not (eq (point) (match-end 0)))) nil
5477 (error
5478 "Bug in Emacs: `looking-at' in `narrow-to-region': match-data is garbage"))
5479 (delete-char (- (match-end 0) (match-beginning 0)))))))
4340 5480
4341 ;; Lines with only hashes on them can be paragraph boundaries. 5481 ;; Lines with only hashes on them can be paragraph boundaries.
4342 (let ((paragraph-start (concat paragraph-start "\\|^[ \t#]*$")) 5482 (let ((paragraph-start (concat paragraph-start "\\|^[ \t#]*$"))
@@ -4352,7 +5492,8 @@ indentation and initial hashes. Behaves usually outside of comment."
4352 (setq comment-column c) 5492 (setq comment-column c)
4353 (indent-for-comment) 5493 (indent-for-comment)
4354 ;; Repeat once more, flagging as iteration 5494 ;; Repeat once more, flagging as iteration
4355 (cperl-fill-paragraph justify t))))))) 5495 (cperl-fill-paragraph justify t))))))
5496 t)
4356 5497
4357(defun cperl-do-auto-fill () 5498(defun cperl-do-auto-fill ()
4358 ;; Break out if the line is short enough 5499 ;; Break out if the line is short enough
@@ -4403,8 +5544,8 @@ indentation and initial hashes. Behaves usually outside of comment."
4403 (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '()) 5544 (let ((index-alist '()) (index-pack-alist '()) (index-pod-alist '())
4404 (index-unsorted-alist '()) (i-s-f (default-value 'imenu-sort-function)) 5545 (index-unsorted-alist '()) (i-s-f (default-value 'imenu-sort-function))
4405 (index-meth-alist '()) meth 5546 (index-meth-alist '()) meth
4406 packages ends-ranges p marker 5547 packages ends-ranges p marker is-proto
4407 (prev-pos 0) char fchar index index1 name (end-range 0) package) 5548 (prev-pos 0) is-pack index index1 name (end-range 0) package)
4408 (goto-char (point-min)) 5549 (goto-char (point-min))
4409 (cperl-update-syntaxification (point-max) (point-max)) 5550 (cperl-update-syntaxification (point-max) (point-max))
4410 ;; Search for the function 5551 ;; Search for the function
@@ -4412,72 +5553,81 @@ indentation and initial hashes. Behaves usually outside of comment."
4412 (while (re-search-forward 5553 (while (re-search-forward
4413 (or regexp cperl-imenu--function-name-regexp-perl) 5554 (or regexp cperl-imenu--function-name-regexp-perl)
4414 nil t) 5555 nil t)
5556 ;; 2=package-group, 5=package-name 8=sub-name
4415 (cond 5557 (cond
4416 ((and ; Skip some noise if building tags 5558 ((and ; Skip some noise if building tags
4417 (match-beginning 2) ; package or sub 5559 (match-beginning 5) ; package name
4418 (eq (char-after (match-beginning 2)) ?p) ; package 5560 ;;(eq (char-after (match-beginning 2)) ?p) ; package
4419 (not (save-match-data 5561 (not (save-match-data
4420 (looking-at "[ \t\n]*;")))) ; Plain text word 'package' 5562 (looking-at "[ \t\n]*;")))) ; Plain text word 'package'
4421 nil) 5563 nil)
4422 ((and 5564 ((and
4423 (match-beginning 2) ; package or sub 5565 (or (match-beginning 2)
5566 (match-beginning 8)) ; package or sub
4424 ;; Skip if quoted (will not skip multi-line ''-strings :-(): 5567 ;; Skip if quoted (will not skip multi-line ''-strings :-():
4425 (null (get-text-property (match-beginning 1) 'syntax-table)) 5568 (null (get-text-property (match-beginning 1) 'syntax-table))
4426 (null (get-text-property (match-beginning 1) 'syntax-type)) 5569 (null (get-text-property (match-beginning 1) 'syntax-type))
4427 (null (get-text-property (match-beginning 1) 'in-pod))) 5570 (null (get-text-property (match-beginning 1) 'in-pod)))
4428 (save-excursion 5571 (setq is-pack (match-beginning 2))
4429 (goto-char (match-beginning 2))
4430 (setq fchar (following-char)))
4431 ;; (if (looking-at "([^()]*)[ \t\n\f]*") 5572 ;; (if (looking-at "([^()]*)[ \t\n\f]*")
4432 ;; (goto-char (match-end 0))) ; Messes what follows 5573 ;; (goto-char (match-end 0))) ; Messes what follows
4433 (setq char (following-char) ; ?\; for "sub foo () ;" 5574 (setq meth nil
4434 meth nil
4435 p (point)) 5575 p (point))
4436 (while (and ends-ranges (>= p (car ends-ranges))) 5576 (while (and ends-ranges (>= p (car ends-ranges)))
4437 ;; delete obsolete entries 5577 ;; delete obsolete entries
4438 (setq ends-ranges (cdr ends-ranges) packages (cdr packages))) 5578 (setq ends-ranges (cdr ends-ranges) packages (cdr packages)))
4439 (setq package (or (car packages) "") 5579 (setq package (or (car packages) "")
4440 end-range (or (car ends-ranges) 0)) 5580 end-range (or (car ends-ranges) 0))
4441 (if (eq fchar ?p) 5581 (if is-pack ; doing "package"
4442 (setq name (buffer-substring (match-beginning 3) (match-end 3)) 5582 (progn
4443 name (progn 5583 (if (match-beginning 5) ; named package
4444 (set-text-properties 0 (length name) nil name) 5584 (setq name (buffer-substring (match-beginning 5)
4445 name) 5585 (match-end 5))
4446 package (concat name "::") 5586 name (progn
4447 name (concat "package " name) 5587 (set-text-properties 0 (length name) nil name)
4448 end-range 5588 name)
4449 (save-excursion 5589 package (concat name "::")
4450 (parse-partial-sexp (point) (point-max) -1) (point)) 5590 name (concat "package " name))
4451 ends-ranges (cons end-range ends-ranges) 5591 ;; Support nameless packages
4452 packages (cons package packages))) 5592 (setq name "package;" package ""))
4453 ;; ) 5593 (setq end-range
5594 (save-excursion
5595 (parse-partial-sexp (point) (point-max) -1) (point))
5596 ends-ranges (cons end-range ends-ranges)
5597 packages (cons package packages)))
5598 (setq is-proto
5599 (or (eq (following-char) ?\;)
5600 (eq 0 (get-text-property (point) 'attrib-group)))))
4454 ;; Skip this function name if it is a prototype declaration. 5601 ;; Skip this function name if it is a prototype declaration.
4455 (if (and (eq fchar ?s) (eq char ?\;)) nil 5602 (if (and is-proto (not is-pack)) nil
4456 (setq name (buffer-substring (match-beginning 3) (match-end 3)) 5603 (or is-pack
4457 marker (make-marker)) 5604 (setq name
4458 (set-text-properties 0 (length name) nil name) 5605 (buffer-substring (match-beginning 8) (match-end 8)))
4459 (set-marker marker (match-end 3)) 5606 (set-text-properties 0 (length name) nil name))
4460 (if (eq fchar ?p) 5607 (setq marker (make-marker))
4461 (setq name (concat "package " name)) 5608 (set-marker marker (match-end (if is-pack 2 8)))
4462 (cond ((string-match "[:']" name) 5609 (cond (is-pack nil)
4463 (setq meth t)) 5610 ((string-match "[:']" name)
4464 ((> p end-range) nil) 5611 (setq meth t))
4465 (t 5612 ((> p end-range) nil)
4466 (setq name (concat package name) meth t)))) 5613 (t
5614 (setq name (concat package name) meth t)))
4467 (setq index (cons name marker)) 5615 (setq index (cons name marker))
4468 (if (eq fchar ?p) 5616 (if is-pack
4469 (push index index-pack-alist) 5617 (push index index-pack-alist)
4470 (push index index-alist)) 5618 (push index index-alist))
4471 (if meth (push index index-meth-alist)) 5619 (if meth (push index index-meth-alist))
4472 (push index index-unsorted-alist))) 5620 (push index index-unsorted-alist)))
4473 ((match-beginning 5) ; POD section 5621 ((match-beginning 16) ; POD section
4474 ;; (beginning-of-line) 5622 (setq name (buffer-substring (match-beginning 17) (match-end 17))
4475 (setq index (imenu-example--name-and-position) 5623 marker (make-marker))
4476 name (buffer-substring (match-beginning 6) (match-end 6))) 5624 (set-marker marker (match-beginning 17))
4477 (set-text-properties 0 (length name) nil name) 5625 (set-text-properties 0 (length name) nil name)
4478 (if (eq (char-after (match-beginning 5)) ?2) 5626 (setq name (concat (make-string
4479 (setq name (concat " " name))) 5627 (* 3 (- (char-after (match-beginning 16)) ?1))
4480 (setcar index name) 5628 ?\ )
5629 name)
5630 index (cons name marker))
4481 (setq index1 (cons (concat "=" name) (cdr index))) 5631 (setq index1 (cons (concat "=" name) (cdr index)))
4482 (push index index-pod-alist) 5632 (push index index-pod-alist)
4483 (push index1 index-unsorted-alist))))) 5633 (push index1 index-unsorted-alist)))))
@@ -4541,29 +5691,20 @@ indentation and initial hashes. Behaves usually outside of comment."
4541(defun cperl-outline-level () 5691(defun cperl-outline-level ()
4542 (looking-at outline-regexp) 5692 (looking-at outline-regexp)
4543 (cond ((not (match-beginning 1)) 0) ; beginning-of-file 5693 (cond ((not (match-beginning 1)) 0) ; beginning-of-file
4544 ((match-beginning 2) 5694;;;; 2=package-group, 5=package-name 8=sub-name 16=head-level
4545 (if (eq (char-after (match-beginning 2)) ?p) 5695 ((match-beginning 2) 0) ; package
4546 0 ; package 5696 ((match-beginning 8) 1) ; sub
4547 1)) ; sub 5697 ((match-beginning 16)
4548 ((match-beginning 5) 5698 (- (char-after (match-beginning 16)) ?0)) ; headN ==> N
4549 (if (eq (char-after (match-beginning 5)) ?1) 5699 (t 5))) ; should not happen
4550 1 ; head1
4551 2)) ; head2
4552 (t 3))) ; should not happen
4553 5700
4554 5701
4555(defvar cperl-compilation-error-regexp-alist 5702(defvar cperl-compilation-error-regexp-alist
4556 ;; This look like a paranoiac regexp: could anybody find a better one? (which WORK). 5703 ;; This look like a paranoiac regexp: could anybody find a better one? (which WORKS).
4557 '(("^[^\n]* \\(file\\|at\\) \\([^ \t\n]+\\) [^\n]*line \\([0-9]+\\)[\\., \n]" 5704 '(("^[^\n]* \\(file\\|at\\) \\([^ \t\n]+\\) [^\n]*line \\([0-9]+\\)[\\., \n]"
4558 2 3)) 5705 2 3))
4559 "Alist that specifies how to match errors in perl output.") 5706 "Alist that specifies how to match errors in perl output.")
4560 5707
4561(if (fboundp 'eval-after-load)
4562 (eval-after-load
4563 "mode-compile"
4564 '(setq perl-compilation-error-regexp-alist
4565 cperl-compilation-error-regexp-alist)))
4566
4567 5708
4568(defun cperl-windowed-init () 5709(defun cperl-windowed-init ()
4569 "Initialization under windowed version." 5710 "Initialization under windowed version."
@@ -4604,9 +5745,12 @@ indentation and initial hashes. Behaves usually outside of comment."
4604 ;; Allow `cperl-find-pods-heres' to run. 5745 ;; Allow `cperl-find-pods-heres' to run.
4605 (or (boundp 'font-lock-constant-face) 5746 (or (boundp 'font-lock-constant-face)
4606 (cperl-force-face font-lock-constant-face 5747 (cperl-force-face font-lock-constant-face
4607 "Face for constant and label names") 5748 "Face for constant and label names"))
4608 ;;(setq font-lock-constant-face 'font-lock-constant-face) 5749 (or (boundp 'font-lock-warning-face)
4609 )) 5750 (cperl-force-face font-lock-warning-face
5751 "Face for things which should stand out"))
5752 ;;(setq font-lock-constant-face 'font-lock-constant-face)
5753 )
4610 5754
4611(defun cperl-init-faces () 5755(defun cperl-init-faces ()
4612 (condition-case errs 5756 (condition-case errs
@@ -4629,7 +5773,7 @@ indentation and initial hashes. Behaves usually outside of comment."
4629 'identity 5773 'identity
4630 '("if" "until" "while" "elsif" "else" "unless" "for" 5774 '("if" "until" "while" "elsif" "else" "unless" "for"
4631 "foreach" "continue" "exit" "die" "last" "goto" "next" 5775 "foreach" "continue" "exit" "die" "last" "goto" "next"
4632 "redo" "return" "local" "exec" "sub" "do" "dump" "use" 5776 "redo" "return" "local" "exec" "sub" "do" "dump" "use" "our"
4633 "require" "package" "eval" "my" "BEGIN" "END" "CHECK" "INIT") 5777 "require" "package" "eval" "my" "BEGIN" "END" "CHECK" "INIT")
4634 "\\|") ; Flow control 5778 "\\|") ; Flow control
4635 "\\)\\>") 2) ; was "\\)[ \n\t;():,\|&]" 5779 "\\)\\>") 2) ; was "\\)[ \n\t;():,\|&]"
@@ -4713,7 +5857,7 @@ indentation and initial hashes. Behaves usually outside of comment."
4713 ;; "chop" "defined" "delete" "do" "each" "else" "elsif" 5857 ;; "chop" "defined" "delete" "do" "each" "else" "elsif"
4714 ;; "eval" "exists" "for" "foreach" "format" "goto" 5858 ;; "eval" "exists" "for" "foreach" "format" "goto"
4715 ;; "grep" "if" "keys" "last" "local" "map" "my" "next" 5859 ;; "grep" "if" "keys" "last" "local" "map" "my" "next"
4716 ;; "no" "package" "pop" "pos" "print" "printf" "push" 5860 ;; "no" "our" "package" "pop" "pos" "print" "printf" "push"
4717 ;; "q" "qq" "qw" "qx" "redo" "return" "scalar" "shift" 5861 ;; "q" "qq" "qw" "qx" "redo" "return" "scalar" "shift"
4718 ;; "sort" "splice" "split" "study" "sub" "tie" "tr" 5862 ;; "sort" "splice" "split" "study" "sub" "tie" "tr"
4719 ;; "undef" "unless" "unshift" "untie" "until" "use" 5863 ;; "undef" "unless" "unshift" "untie" "until" "use"
@@ -4728,15 +5872,38 @@ indentation and initial hashes. Behaves usually outside of comment."
4728 "u\\(se\\|n\\(shift\\|ti\\(l\\|e\\)\\|def\\|less\\)\\)\\|" 5872 "u\\(se\\|n\\(shift\\|ti\\(l\\|e\\)\\|def\\|less\\)\\)\\|"
4729 "while\\|y\\|__\\(END\\|DATA\\)__" ;__DATA__ added manually 5873 "while\\|y\\|__\\(END\\|DATA\\)__" ;__DATA__ added manually
4730 "\\|[sm]" ; Added manually 5874 "\\|[sm]" ; Added manually
4731 "\\)\\>") 2 'cperl-nonoverridable) 5875 "\\)\\>") 2 'cperl-nonoverridable-face)
4732 ;; (mapconcat 'identity 5876 ;; (mapconcat 'identity
4733 ;; '("#endif" "#else" "#ifdef" "#ifndef" "#if" 5877 ;; '("#endif" "#else" "#ifdef" "#ifndef" "#if"
4734 ;; "#include" "#define" "#undef") 5878 ;; "#include" "#define" "#undef")
4735 ;; "\\|") 5879 ;; "\\|")
4736 '("-[rwxoRWXOezsfdlpSbctugkTBMAC]\\>\\([ \t]+_\\>\\)?" 0 5880 '("-[rwxoRWXOezsfdlpSbctugkTBMAC]\\>\\([ \t]+_\\>\\)?" 0
4737 font-lock-function-name-face keep) ; Not very good, triggers at "[a-z]" 5881 font-lock-function-name-face keep) ; Not very good, triggers at "[a-z]"
4738 '("\\<sub[ \t]+\\([^ \t{;()]+\\)[ \t]*\\(([^()]*)[ \t]*\\)?[#{\n]" 1 5882 ;; This highlights declarations and definitions differenty.
4739 font-lock-function-name-face) 5883 ;; We do not try to highlight in the case of attributes:
5884 ;; it is already done by `cperl-find-pods-heres'
5885 (list (concat "\\<sub"
5886 cperl-white-and-comment-rex ; whitespace/comments
5887 "\\([^ \n\t{;()]+\\)" ; 2=name (assume non-anonymous)
5888 "\\("
5889 cperl-maybe-white-and-comment-rex ;whitespace/comments?
5890 "([^()]*)\\)?" ; prototype
5891 cperl-maybe-white-and-comment-rex ; whitespace/comments?
5892 "[{;]")
5893 2 (if cperl-font-lock-multiline
5894 '(if (eq (char-after (cperl-1- (match-end 0))) ?\{ )
5895 'font-lock-function-name-face
5896 'font-lock-variable-name-face)
5897 ;; need to manually set 'multiline' for older font-locks
5898 '(progn
5899 (if (< 1 (count-lines (match-beginning 0)
5900 (match-end 0)))
5901 (put-text-property
5902 (+ 3 (match-beginning 0)) (match-end 0)
5903 'syntax-type 'multiline))
5904 (if (eq (char-after (cperl-1- (match-end 0))) ?\{ )
5905 'font-lock-function-name-face
5906 'font-lock-variable-name-face))))
4740 '("\\<\\(package\\|require\\|use\\|import\\|no\\|bootstrap\\)[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t;]" ; require A if B; 5907 '("\\<\\(package\\|require\\|use\\|import\\|no\\|bootstrap\\)[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t;]" ; require A if B;
4741 2 font-lock-function-name-face) 5908 2 font-lock-function-name-face)
4742 '("^[ \t]*format[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t]*=[ \t]*$" 5909 '("^[ \t]*format[ \t]+\\([a-zA-z_][a-zA-z_0-9:]*\\)[ \t]*=[ \t]*$"
@@ -4772,12 +5939,56 @@ indentation and initial hashes. Behaves usually outside of comment."
4772 (2 '(restart 2 nil) nil t))) 5939 (2 '(restart 2 nil) nil t)))
4773 nil t))) ; local variables, multiple 5940 nil t))) ; local variables, multiple
4774 (font-lock-anchored 5941 (font-lock-anchored
4775 '("^[ \t{}]*\\(my\\|local\\|our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)" 5942 ;; 1=my_etc, 2=white? 3=(+white? 4=white? 5=var
4776 (3 font-lock-variable-name-face) 5943 (` ((, (concat "\\<\\(my\\|local\\|our\\)"
4777 ("\\=[ \t]*,[ \t]*\\([$@%*][a-zA-Z0-9_:]+\\)" 5944 cperl-maybe-white-and-comment-rex
4778 nil nil 5945 "\\(("
4779 (1 font-lock-variable-name-face)))) 5946 cperl-maybe-white-and-comment-rex
4780 (t '("^[ \t{}]*\\(my\\|local\\our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)" 5947 "\\)?\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)"))
5948 (5 (, (if cperl-font-lock-multiline
5949 'font-lock-variable-name-face
5950 '(progn (setq cperl-font-lock-multiline-start
5951 (match-beginning 0))
5952 'font-lock-variable-name-face))))
5953 ((, (concat "\\="
5954 cperl-maybe-white-and-comment-rex
5955 ","
5956 cperl-maybe-white-and-comment-rex
5957 "\\([$@%*]\\([a-zA-Z0-9_:]+\\|[^a-zA-Z0-9_]\\)\\)"))
5958 ;; Bug in font-lock: limit is used not only to limit
5959 ;; searches, but to set the "extend window for
5960 ;; facification" property. Thus we need to minimize.
5961 (, (if cperl-font-lock-multiline
5962 '(if (match-beginning 3)
5963 (save-excursion
5964 (goto-char (match-beginning 3))
5965 (condition-case nil
5966 (forward-sexp 1)
5967 (error
5968 (condition-case nil
5969 (forward-char 200)
5970 (error nil)))) ; typeahead
5971 (1- (point))) ; report limit
5972 (forward-char -2)) ; disable continued expr
5973 '(if (match-beginning 3)
5974 (point-max) ; No limit for continuation
5975 (forward-char -2)))) ; disable continued expr
5976 (, (if cperl-font-lock-multiline
5977 nil
5978 '(progn ; Do at end
5979 ;; "my" may be already fontified (POD),
5980 ;; so cperl-font-lock-multiline-start is nil
5981 (if (or (not cperl-font-lock-multiline-start)
5982 (> 2 (count-lines
5983 cperl-font-lock-multiline-start
5984 (point))))
5985 nil
5986 (put-text-property
5987 (1+ cperl-font-lock-multiline-start) (point)
5988 'syntax-type 'multiline))
5989 (setq cperl-font-lock-multiline-start nil))))
5990 (3 font-lock-variable-name-face)))))
5991 (t '("^[ \t{}]*\\(my\\|local\\|our\\)[ \t]*\\(([ \t]*\\)?\\([$@%*][a-zA-Z0-9_:]+\\)"
4781 3 font-lock-variable-name-face))) 5992 3 font-lock-variable-name-face)))
4782 '("\\<for\\(each\\)?\\([ \t]+\\(my\\|local\\|our\\)\\)?[ \t]*\\(\\$[a-zA-Z_][a-zA-Z_0-9]*\\)[ \t]*(" 5993 '("\\<for\\(each\\)?\\([ \t]+\\(my\\|local\\|our\\)\\)?[ \t]*\\(\\$[a-zA-Z_][a-zA-Z_0-9]*\\)[ \t]*("
4783 4 font-lock-variable-name-face) 5994 4 font-lock-variable-name-face)
@@ -4787,21 +5998,32 @@ indentation and initial hashes. Behaves usually outside of comment."
4787 (setq 5998 (setq
4788 t-font-lock-keywords-1 5999 t-font-lock-keywords-1
4789 (and (fboundp 'turn-on-font-lock) ; Check for newer font-lock 6000 (and (fboundp 'turn-on-font-lock) ; Check for newer font-lock
4790 (not cperl-xemacs-p) ; not yet as of XEmacs 19.12 6001 ;; not yet as of XEmacs 19.12, works with 21.1.11
6002 (or
6003 (not cperl-xemacs-p)
6004 (string< "21.1.9" emacs-version)
6005 (and (string< "21.1.10" emacs-version)
6006 (string< emacs-version "21.1.2")))
4791 '( 6007 '(
4792 ("\\(\\([@%]\\|\$#\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)" 1 6008 ("\\(\\([@%]\\|\$#\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)" 1
4793 (if (eq (char-after (match-beginning 2)) ?%) 6009 (if (eq (char-after (match-beginning 2)) ?%)
4794 'cperl-hash 6010 'cperl-hash-face
4795 'cperl-array) 6011 'cperl-array-face)
4796 t) ; arrays and hashes 6012 t) ; arrays and hashes
4797 ("\\(\\([$@]+\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)[ \t]*\\([[{]\\)" 6013 ("\\(\\([$@]+\\)[a-zA-Z_:][a-zA-Z0-9_:]*\\)[ \t]*\\([[{]\\)"
4798 1 6014 1
4799 (if (= (- (match-end 2) (match-beginning 2)) 1) 6015 (if (= (- (match-end 2) (match-beginning 2)) 1)
4800 (if (eq (char-after (match-beginning 3)) ?{) 6016 (if (eq (char-after (match-beginning 3)) ?{)
4801 'cperl-hash 6017 'cperl-hash-face
4802 'cperl-array) ; arrays and hashes 6018 'cperl-array-face) ; arrays and hashes
4803 font-lock-variable-name-face) ; Just to put something 6019 font-lock-variable-name-face) ; Just to put something
4804 t) 6020 t)
6021 ("\\(@\\|\\$#\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
6022 (1 cperl-array-face)
6023 (2 font-lock-variable-name-face))
6024 ("\\(%\\)\\(\\$+\\([a-zA-Z_:][a-zA-Z0-9_:]*\\|[^ \t\n]\\)\\)"
6025 (1 cperl-hash-face)
6026 (2 font-lock-variable-name-face))
4805 ;;("\\([smy]\\|tr\\)\\([^a-z_A-Z0-9]\\)\\(\\([^\n\\]*||\\)\\)\\2") 6027 ;;("\\([smy]\\|tr\\)\\([^a-z_A-Z0-9]\\)\\(\\([^\n\\]*||\\)\\)\\2")
4806 ;;; Too much noise from \s* @s[ and friends 6028 ;;; Too much noise from \s* @s[ and friends
4807 ;;("\\(\\<\\([msy]\\|tr\\)[ \t]*\\([^ \t\na-zA-Z0-9_]\\)\\|\\(/\\)\\)" 6029 ;;("\\(\\<\\([msy]\\|tr\\)[ \t]*\\([^ \t\na-zA-Z0-9_]\\)\\|\\(/\\)\\)"
@@ -4813,7 +6035,7 @@ indentation and initial hashes. Behaves usually outside of comment."
4813 (if cperl-highlight-variables-indiscriminately 6035 (if cperl-highlight-variables-indiscriminately
4814 (setq t-font-lock-keywords-1 6036 (setq t-font-lock-keywords-1
4815 (append t-font-lock-keywords-1 6037 (append t-font-lock-keywords-1
4816 (list '("[$*]{?\\(\\sw+\\)" 1 6038 (list '("\\([$*]{?\\sw+\\)" 1
4817 font-lock-variable-name-face))))) 6039 font-lock-variable-name-face)))))
4818 (setq cperl-font-lock-keywords-1 6040 (setq cperl-font-lock-keywords-1
4819 (if cperl-syntaxify-by-font-lock 6041 (if cperl-syntaxify-by-font-lock
@@ -4866,27 +6088,35 @@ indentation and initial hashes. Behaves usually outside of comment."
4866 [nil nil t t t] 6088 [nil nil t t t]
4867 nil 6089 nil
4868 [nil nil t t t]) 6090 [nil nil t t t])
6091 (list 'font-lock-warning-face
6092 ["Pink" "Red" "Gray50" "LightGray"]
6093 ["gray20" "gray90"
6094 "gray80" "gray20"]
6095 [nil nil t t t]
6096 nil
6097 [nil nil t t t]
6098 )
4869 (list 'font-lock-constant-face 6099 (list 'font-lock-constant-face
4870 ["CadetBlue" "Aquamarine" "Gray50" "LightGray"] 6100 ["CadetBlue" "Aquamarine" "Gray50" "LightGray"]
4871 nil 6101 nil
4872 [nil nil t t t] 6102 [nil nil t t t]
4873 nil 6103 nil
4874 [nil nil t t t]) 6104 [nil nil t t t])
4875 (list 'cperl-nonoverridable 6105 (list 'cperl-nonoverridable-face
4876 ["chartreuse3" ("orchid1" "orange") 6106 ["chartreuse3" ("orchid1" "orange")
4877 nil "Gray80"] 6107 nil "Gray80"]
4878 [nil nil "gray90"] 6108 [nil nil "gray90"]
4879 [nil nil nil t t] 6109 [nil nil nil t t]
4880 [nil nil t t] 6110 [nil nil t t]
4881 [nil nil t t t]) 6111 [nil nil t t t])
4882 (list 'cperl-array 6112 (list 'cperl-array-face
4883 ["blue" "yellow" nil "Gray80"] 6113 ["blue" "yellow" nil "Gray80"]
4884 ["lightyellow2" ("navy" "os2blue" "darkgreen") 6114 ["lightyellow2" ("navy" "os2blue" "darkgreen")
4885 "gray90"] 6115 "gray90"]
4886 t 6116 t
4887 nil 6117 nil
4888 nil) 6118 nil)
4889 (list 'cperl-hash 6119 (list 'cperl-hash-face
4890 ["red" "red" nil "Gray80"] 6120 ["red" "red" nil "Gray80"]
4891 ["lightyellow2" ("navy" "os2blue" "darkgreen") 6121 ["lightyellow2" ("navy" "os2blue" "darkgreen")
4892 "gray90"] 6122 "gray90"]
@@ -4909,15 +6139,17 @@ indentation and initial hashes. Behaves usually outside of comment."
4909 "Face for variable names") 6139 "Face for variable names")
4910 (cperl-force-face font-lock-type-face 6140 (cperl-force-face font-lock-type-face
4911 "Face for data types") 6141 "Face for data types")
4912 (cperl-force-face cperl-nonoverridable 6142 (cperl-force-face cperl-nonoverridable-face
4913 "Face for data types from another group") 6143 "Face for data types from another group")
6144 (cperl-force-face font-lock-warning-face
6145 "Face for things which should stand out")
4914 (cperl-force-face font-lock-comment-face 6146 (cperl-force-face font-lock-comment-face
4915 "Face for comments") 6147 "Face for comments")
4916 (cperl-force-face font-lock-function-name-face 6148 (cperl-force-face font-lock-function-name-face
4917 "Face for function names") 6149 "Face for function names")
4918 (cperl-force-face cperl-hash 6150 (cperl-force-face cperl-hash-face
4919 "Face for hashes") 6151 "Face for hashes")
4920 (cperl-force-face cperl-array 6152 (cperl-force-face cperl-array-face
4921 "Face for arrays") 6153 "Face for arrays")
4922 ;;(defvar font-lock-constant-face 'font-lock-constant-face) 6154 ;;(defvar font-lock-constant-face 'font-lock-constant-face)
4923 ;;(defvar font-lock-variable-name-face 'font-lock-variable-name-face) 6155 ;;(defvar font-lock-variable-name-face 'font-lock-variable-name-face)
@@ -4927,7 +6159,7 @@ indentation and initial hashes. Behaves usually outside of comment."
4927 ;; "Face to use for data types.")) 6159 ;; "Face to use for data types."))
4928 ;;(or (boundp 'cperl-nonoverridable-face) 6160 ;;(or (boundp 'cperl-nonoverridable-face)
4929 ;; (defconst cperl-nonoverridable-face 6161 ;; (defconst cperl-nonoverridable-face
4930 ;; 'cperl-nonoverridable 6162 ;; 'cperl-nonoverridable-face
4931 ;; "Face to use for data types from another group.")) 6163 ;; "Face to use for data types from another group."))
4932 ;;(if (not cperl-xemacs-p) nil 6164 ;;(if (not cperl-xemacs-p) nil
4933 ;; (or (boundp 'font-lock-comment-face) 6165 ;; (or (boundp 'font-lock-comment-face)
@@ -4943,24 +6175,24 @@ indentation and initial hashes. Behaves usually outside of comment."
4943 ;; 'font-lock-function-name-face 6175 ;; 'font-lock-function-name-face
4944 ;; "Face to use for function names."))) 6176 ;; "Face to use for function names.")))
4945 (if (and 6177 (if (and
4946 (not (cperl-is-face 'cperl-array)) 6178 (not (cperl-is-face 'cperl-array-face))
4947 (cperl-is-face 'font-lock-emphasized-face)) 6179 (cperl-is-face 'font-lock-emphasized-face))
4948 (copy-face 'font-lock-emphasized-face 'cperl-array)) 6180 (copy-face 'font-lock-emphasized-face 'cperl-array-face))
4949 (if (and 6181 (if (and
4950 (not (cperl-is-face 'cperl-hash)) 6182 (not (cperl-is-face 'cperl-hash-face))
4951 (cperl-is-face 'font-lock-other-emphasized-face)) 6183 (cperl-is-face 'font-lock-other-emphasized-face))
4952 (copy-face 'font-lock-other-emphasized-face 'cperl-hash)) 6184 (copy-face 'font-lock-other-emphasized-face 'cperl-hash-face))
4953 (if (and 6185 (if (and
4954 (not (cperl-is-face 'cperl-nonoverridable)) 6186 (not (cperl-is-face 'cperl-nonoverridable-face))
4955 (cperl-is-face 'font-lock-other-type-face)) 6187 (cperl-is-face 'font-lock-other-type-face))
4956 (copy-face 'font-lock-other-type-face 'cperl-nonoverridable)) 6188 (copy-face 'font-lock-other-type-face 'cperl-nonoverridable-face))
4957 ;;(or (boundp 'cperl-hash-face) 6189 ;;(or (boundp 'cperl-hash-face)
4958 ;; (defconst cperl-hash-face 6190 ;; (defconst cperl-hash-face
4959 ;; 'cperl-hash 6191 ;; 'cperl-hash-face
4960 ;; "Face to use for hashes.")) 6192 ;; "Face to use for hashes."))
4961 ;;(or (boundp 'cperl-array-face) 6193 ;;(or (boundp 'cperl-array-face)
4962 ;; (defconst cperl-array-face 6194 ;; (defconst cperl-array-face
4963 ;; 'cperl-array 6195 ;; 'cperl-array-face
4964 ;; "Face to use for arrays.")) 6196 ;; "Face to use for arrays."))
4965 ;; Here we try to guess background 6197 ;; Here we try to guess background
4966 (let ((background 6198 (let ((background
@@ -4999,17 +6231,17 @@ indentation and initial hashes. Behaves usually outside of comment."
4999 "pink"))) 6231 "pink")))
5000 (t 6232 (t
5001 (set-face-background 'font-lock-type-face "gray90")))) 6233 (set-face-background 'font-lock-type-face "gray90"))))
5002 (if (cperl-is-face 'cperl-nonoverridable) 6234 (if (cperl-is-face 'cperl-nonoverridable-face)
5003 nil 6235 nil
5004 (copy-face 'font-lock-type-face 'cperl-nonoverridable) 6236 (copy-face 'font-lock-type-face 'cperl-nonoverridable-face)
5005 (cond 6237 (cond
5006 ((eq background 'light) 6238 ((eq background 'light)
5007 (set-face-foreground 'cperl-nonoverridable 6239 (set-face-foreground 'cperl-nonoverridable-face
5008 (if (x-color-defined-p "chartreuse3") 6240 (if (x-color-defined-p "chartreuse3")
5009 "chartreuse3" 6241 "chartreuse3"
5010 "chartreuse"))) 6242 "chartreuse")))
5011 ((eq background 'dark) 6243 ((eq background 'dark)
5012 (set-face-foreground 'cperl-nonoverridable 6244 (set-face-foreground 'cperl-nonoverridable-face
5013 (if (x-color-defined-p "orchid1") 6245 (if (x-color-defined-p "orchid1")
5014 "orchid1" 6246 "orchid1"
5015 "orange"))))) 6247 "orange")))))
@@ -5061,15 +6293,15 @@ indentation and initial hashes. Behaves usually outside of comment."
5061 '(setq ps-bold-faces 6293 '(setq ps-bold-faces
5062 ;; font-lock-variable-name-face 6294 ;; font-lock-variable-name-face
5063 ;; font-lock-constant-face 6295 ;; font-lock-constant-face
5064 (append '(cperl-array cperl-hash) 6296 (append '(cperl-array-face cperl-hash-face)
5065 ps-bold-faces) 6297 ps-bold-faces)
5066 ps-italic-faces 6298 ps-italic-faces
5067 ;; font-lock-constant-face 6299 ;; font-lock-constant-face
5068 (append '(cperl-nonoverridable cperl-hash) 6300 (append '(cperl-nonoverridable-face cperl-hash-face)
5069 ps-italic-faces) 6301 ps-italic-faces)
5070 ps-underlined-faces 6302 ps-underlined-faces
5071 ;; font-lock-type-face 6303 ;; font-lock-type-face
5072 (append '(cperl-array cperl-hash underline cperl-nonoverridable) 6304 (append '(cperl-array-face cperl-hash-face underline cperl-nonoverridable-face)
5073 ps-underlined-faces)))) 6305 ps-underlined-faces))))
5074 6306
5075(defvar ps-print-face-extension-alist) 6307(defvar ps-print-face-extension-alist)
@@ -5102,27 +6334,27 @@ Style of printout regulated by the variable `cperl-ps-print-face-properties'."
5102;;; (defvar ps-italic-faces nil) 6334;;; (defvar ps-italic-faces nil)
5103;;; (setq ps-bold-faces 6335;;; (setq ps-bold-faces
5104;;; (append '(font-lock-emphasized-face 6336;;; (append '(font-lock-emphasized-face
5105;;; cperl-array 6337;;; cperl-array-face
5106;;; font-lock-keyword-face 6338;;; font-lock-keyword-face
5107;;; font-lock-variable-name-face 6339;;; font-lock-variable-name-face
5108;;; font-lock-constant-face 6340;;; font-lock-constant-face
5109;;; font-lock-reference-face 6341;;; font-lock-reference-face
5110;;; font-lock-other-emphasized-face 6342;;; font-lock-other-emphasized-face
5111;;; cperl-hash) 6343;;; cperl-hash-face)
5112;;; ps-bold-faces)) 6344;;; ps-bold-faces))
5113;;; (setq ps-italic-faces 6345;;; (setq ps-italic-faces
5114;;; (append '(cperl-nonoverridable 6346;;; (append '(cperl-nonoverridable-face
5115;;; font-lock-constant-face 6347;;; font-lock-constant-face
5116;;; font-lock-reference-face 6348;;; font-lock-reference-face
5117;;; font-lock-other-emphasized-face 6349;;; font-lock-other-emphasized-face
5118;;; cperl-hash) 6350;;; cperl-hash-face)
5119;;; ps-italic-faces)) 6351;;; ps-italic-faces))
5120;;; (setq ps-underlined-faces 6352;;; (setq ps-underlined-faces
5121;;; (append '(font-lock-emphasized-face 6353;;; (append '(font-lock-emphasized-face
5122;;; cperl-array 6354;;; cperl-array-face
5123;;; font-lock-other-emphasized-face 6355;;; font-lock-other-emphasized-face
5124;;; cperl-hash 6356;;; cperl-hash-face
5125;;; cperl-nonoverridable font-lock-type-face) 6357;;; cperl-nonoverridable-face font-lock-type-face)
5126;;; ps-underlined-faces)) 6358;;; ps-underlined-faces))
5127;;; (cons 'font-lock-type-face ps-underlined-faces)) 6359;;; (cons 'font-lock-type-face ps-underlined-faces))
5128 6360
@@ -5132,79 +6364,211 @@ Style of printout regulated by the variable `cperl-ps-print-face-properties'."
5132(defconst cperl-styles-entries 6364(defconst cperl-styles-entries
5133 '(cperl-indent-level cperl-brace-offset cperl-continued-brace-offset 6365 '(cperl-indent-level cperl-brace-offset cperl-continued-brace-offset
5134 cperl-label-offset cperl-extra-newline-before-brace 6366 cperl-label-offset cperl-extra-newline-before-brace
6367 cperl-extra-newline-before-brace-multiline
5135 cperl-merge-trailing-else 6368 cperl-merge-trailing-else
5136 cperl-continued-statement-offset)) 6369 cperl-continued-statement-offset))
5137 6370
6371(defconst cperl-style-examples
6372"##### Numbers etc are: cperl-indent-level cperl-brace-offset
6373##### cperl-continued-brace-offset cperl-label-offset
6374##### cperl-continued-statement-offset
6375##### cperl-merge-trailing-else cperl-extra-newline-before-brace
6376
6377########### (Do not forget cperl-extra-newline-before-brace-multiline)
6378
6379### CPerl (=GNU - extra-newline-before-brace + merge-trailing-else) 2/0/0/-2/2/t/nil
6380if (foo) {
6381 bar
6382 baz;
6383 label:
6384 {
6385 boon;
6386 }
6387} else {
6388 stop;
6389}
6390
6391### PerlStyle (=CPerl with 4 as indent) 4/0/0/-4/4/t/nil
6392if (foo) {
6393 bar
6394 baz;
6395 label:
6396 {
6397 boon;
6398 }
6399} else {
6400 stop;
6401}
6402
6403### GNU 2/0/0/-2/2/nil/t
6404if (foo)
6405 {
6406 bar
6407 baz;
6408 label:
6409 {
6410 boon;
6411 }
6412 }
6413else
6414 {
6415 stop;
6416 }
6417
6418### C++ (=PerlStyle with braces aligned with control words) 4/0/-4/-4/4/nil/t
6419if (foo)
6420{
6421 bar
6422 baz;
6423 label:
6424 {
6425 boon;
6426 }
6427}
6428else
6429{
6430 stop;
6431}
6432
6433### BSD (=C++, but will not change preexisting merge-trailing-else
6434### and extra-newline-before-brace ) 4/0/-4/-4/4
6435if (foo)
6436{
6437 bar
6438 baz;
6439 label:
6440 {
6441 boon;
6442 }
6443}
6444else
6445{
6446 stop;
6447}
6448
6449### K&R (=C++ with indent 5 - merge-trailing-else, but will not
6450### change preexisting extra-newline-before-brace) 5/0/-5/-5/5/nil
6451if (foo)
6452{
6453 bar
6454 baz;
6455 label:
6456 {
6457 boon;
6458 }
6459}
6460else
6461{
6462 stop;
6463}
6464
6465### Whitesmith (=PerlStyle, but will not change preexisting
6466### extra-newline-before-brace and merge-trailing-else) 4/0/0/-4/4
6467if (foo)
6468 {
6469 bar
6470 baz;
6471 label:
6472 {
6473 boon;
6474 }
6475 }
6476else
6477 {
6478 stop;
6479 }
6480"
6481"Examples of if/else with different indent styles (with v4.23).")
6482
5138(defconst cperl-style-alist 6483(defconst cperl-style-alist
5139 '(("CPerl" ; =GNU without extra-newline-before-brace 6484 '(("CPerl" ;; =GNU - extra-newline-before-brace + cperl-merge-trailing-else
5140 (cperl-indent-level . 2) 6485 (cperl-indent-level . 2)
5141 (cperl-brace-offset . 0) 6486 (cperl-brace-offset . 0)
5142 (cperl-continued-brace-offset . 0) 6487 (cperl-continued-brace-offset . 0)
5143 (cperl-label-offset . -2) 6488 (cperl-label-offset . -2)
6489 (cperl-continued-statement-offset . 2)
5144 (cperl-extra-newline-before-brace . nil) 6490 (cperl-extra-newline-before-brace . nil)
5145 (cperl-merge-trailing-else . t) 6491 (cperl-extra-newline-before-brace-multiline . nil)
5146 (cperl-continued-statement-offset . 2)) 6492 (cperl-merge-trailing-else . t))
6493
5147 ("PerlStyle" ; CPerl with 4 as indent 6494 ("PerlStyle" ; CPerl with 4 as indent
5148 (cperl-indent-level . 4) 6495 (cperl-indent-level . 4)
5149 (cperl-brace-offset . 0) 6496 (cperl-brace-offset . 0)
5150 (cperl-continued-brace-offset . 0) 6497 (cperl-continued-brace-offset . 0)
5151 (cperl-label-offset . -4) 6498 (cperl-label-offset . -4)
6499 (cperl-continued-statement-offset . 4)
5152 (cperl-extra-newline-before-brace . nil) 6500 (cperl-extra-newline-before-brace . nil)
5153 (cperl-merge-trailing-else . t) 6501 (cperl-extra-newline-before-brace-multiline . nil)
5154 (cperl-continued-statement-offset . 4)) 6502 (cperl-merge-trailing-else . t))
6503
5155 ("GNU" 6504 ("GNU"
5156 (cperl-indent-level . 2) 6505 (cperl-indent-level . 2)
5157 (cperl-brace-offset . 0) 6506 (cperl-brace-offset . 0)
5158 (cperl-continued-brace-offset . 0) 6507 (cperl-continued-brace-offset . 0)
5159 (cperl-label-offset . -2) 6508 (cperl-label-offset . -2)
6509 (cperl-continued-statement-offset . 2)
5160 (cperl-extra-newline-before-brace . t) 6510 (cperl-extra-newline-before-brace . t)
5161 (cperl-merge-trailing-else . nil) 6511 (cperl-extra-newline-before-brace-multiline . t)
5162 (cperl-continued-statement-offset . 2)) 6512 (cperl-merge-trailing-else . nil))
6513
5163 ("K&R" 6514 ("K&R"
5164 (cperl-indent-level . 5) 6515 (cperl-indent-level . 5)
5165 (cperl-brace-offset . 0) 6516 (cperl-brace-offset . 0)
5166 (cperl-continued-brace-offset . -5) 6517 (cperl-continued-brace-offset . -5)
5167 (cperl-label-offset . -5) 6518 (cperl-label-offset . -5)
6519 (cperl-continued-statement-offset . 5)
5168 ;;(cperl-extra-newline-before-brace . nil) ; ??? 6520 ;;(cperl-extra-newline-before-brace . nil) ; ???
5169 (cperl-merge-trailing-else . nil) 6521 ;;(cperl-extra-newline-before-brace-multiline . nil)
5170 (cperl-continued-statement-offset . 5)) 6522 (cperl-merge-trailing-else . nil))
6523
5171 ("BSD" 6524 ("BSD"
5172 (cperl-indent-level . 4) 6525 (cperl-indent-level . 4)
5173 (cperl-brace-offset . 0) 6526 (cperl-brace-offset . 0)
5174 (cperl-continued-brace-offset . -4) 6527 (cperl-continued-brace-offset . -4)
5175 (cperl-label-offset . -4) 6528 (cperl-label-offset . -4)
6529 (cperl-continued-statement-offset . 4)
5176 ;;(cperl-extra-newline-before-brace . nil) ; ??? 6530 ;;(cperl-extra-newline-before-brace . nil) ; ???
5177 (cperl-continued-statement-offset . 4)) 6531 ;;(cperl-extra-newline-before-brace-multiline . nil)
6532 ;;(cperl-merge-trailing-else . nil) ; ???
6533 )
6534
5178 ("C++" 6535 ("C++"
5179 (cperl-indent-level . 4) 6536 (cperl-indent-level . 4)
5180 (cperl-brace-offset . 0) 6537 (cperl-brace-offset . 0)
5181 (cperl-continued-brace-offset . -4) 6538 (cperl-continued-brace-offset . -4)
5182 (cperl-label-offset . -4) 6539 (cperl-label-offset . -4)
5183 (cperl-continued-statement-offset . 4) 6540 (cperl-continued-statement-offset . 4)
5184 (cperl-merge-trailing-else . nil) 6541 (cperl-extra-newline-before-brace . t)
5185 (cperl-extra-newline-before-brace . t)) 6542 (cperl-extra-newline-before-brace-multiline . t)
5186 ("Current") 6543 (cperl-merge-trailing-else . nil))
6544
5187 ("Whitesmith" 6545 ("Whitesmith"
5188 (cperl-indent-level . 4) 6546 (cperl-indent-level . 4)
5189 (cperl-brace-offset . 0) 6547 (cperl-brace-offset . 0)
5190 (cperl-continued-brace-offset . 0) 6548 (cperl-continued-brace-offset . 0)
5191 (cperl-label-offset . -4) 6549 (cperl-label-offset . -4)
6550 (cperl-continued-statement-offset . 4)
5192 ;;(cperl-extra-newline-before-brace . nil) ; ??? 6551 ;;(cperl-extra-newline-before-brace . nil) ; ???
5193 (cperl-continued-statement-offset . 4))) 6552 ;;(cperl-extra-newline-before-brace-multiline . nil)
5194 "(Experimental) list of variables to set to get a particular indentation style. 6553 ;;(cperl-merge-trailing-else . nil) ; ???
5195Should be used via `cperl-set-style' or via Perl menu.") 6554 )
6555 ("Current"))
6556 "List of variables to set to get a particular indentation style.
6557Should be used via `cperl-set-style' or via Perl menu.
6558
6559See examples in `cperl-style-examples'.")
5196 6560
5197(defun cperl-set-style (style) 6561(defun cperl-set-style (style)
5198 "Set CPerl mode variables to use one of several different indentation styles. 6562 "Set CPerl mode variables to use one of several different indentation styles.
5199The arguments are a string representing the desired style. 6563The arguments are a string representing the desired style.
5200The list of styles is in `cperl-style-alist', available styles 6564The list of styles is in `cperl-style-alist', available styles
5201are GNU, K&R, BSD, C++ and Whitesmith. 6565are CPerl, PerlStyle, GNU, K&R, BSD, C++ and Whitesmith.
5202 6566
5203The current value of style is memorized (unless there is a memorized 6567The current value of style is memorized (unless there is a memorized
5204data already), may be restored by `cperl-set-style-back'. 6568data already), may be restored by `cperl-set-style-back'.
5205 6569
5206Chosing \"Current\" style will not change style, so this may be used for 6570Chosing \"Current\" style will not change style, so this may be used for
5207side-effect of memorizing only." 6571side-effect of memorizing only. Examples in `cperl-style-examples'."
5208 (interactive 6572 (interactive
5209 (let ((list (mapcar (function (lambda (elt) (list (car elt)))) 6573 (let ((list (mapcar (function (lambda (elt) (list (car elt))))
5210 cperl-style-alist))) 6574 cperl-style-alist)))
@@ -5375,6 +6739,8 @@ Customized by setting variables `cperl-shrink-wrap-info-frame',
5375 (match-beginning 1) (match-end 1))) 6739 (match-beginning 1) (match-end 1)))
5376 6740
5377(defun cperl-imenu-on-info () 6741(defun cperl-imenu-on-info ()
6742 "Shows imenu for Perl Info Buffer.
6743Opens Perl Info buffer if needed."
5378 (interactive) 6744 (interactive)
5379 (let* ((buffer (current-buffer)) 6745 (let* ((buffer (current-buffer))
5380 imenu-create-index-function 6746 imenu-create-index-function
@@ -5414,7 +6780,7 @@ If STEP is nil, `cperl-lineup-step' will be used
5414\(or `cperl-indent-level', if `cperl-lineup-step' is nil). 6780\(or `cperl-indent-level', if `cperl-lineup-step' is nil).
5415Will not move the position at the start to the left." 6781Will not move the position at the start to the left."
5416 (interactive "r") 6782 (interactive "r")
5417 (let (search col tcol seen b e) 6783 (let (search col tcol seen b)
5418 (save-excursion 6784 (save-excursion
5419 (goto-char end) 6785 (goto-char end)
5420 (end-of-line) 6786 (end-of-line)
@@ -5452,22 +6818,25 @@ Will not move the position at the start to the left."
5452 (if (/= (% col step) 0) (setq step (* step (1+ (/ col step))))) 6818 (if (/= (% col step) 0) (setq step (* step (1+ (/ col step)))))
5453 (while 6819 (while
5454 (progn 6820 (progn
5455 (setq e (point)) 6821 (cperl-make-indent col)
5456 (skip-chars-backward " \t")
5457 (delete-region (point) e)
5458 (indent-to-column col) ;(make-string (- col (current-column)) ?\s))
5459 (beginning-of-line 2) 6822 (beginning-of-line 2)
5460 (and (< (point) end) 6823 (and (< (point) end)
5461 (re-search-forward search end t) 6824 (re-search-forward search end t)
5462 (goto-char (match-beginning 0)))))))) ; No body 6825 (goto-char (match-beginning 0)))))))) ; No body
5463 6826
5464(defun cperl-etags (&optional add all files) 6827(defun cperl-etags (&optional add all files) ;; NOT USED???
5465 "Run etags with appropriate options for Perl files. 6828 "Run etags with appropriate options for Perl files.
5466If optional argument ALL is `recursive', will process Perl files 6829If optional argument ALL is `recursive', will process Perl files
5467in subdirectories too." 6830in subdirectories too."
5468 (interactive) 6831 (interactive)
5469 (let ((cmd "etags") 6832 (let ((cmd "etags")
5470 (args '("-l" "none" "-r" "/\\<\\(package\\|sub\\)[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)[ \\t]*\\(([^()]*)[ \t]*\\)?\\([{#]\\|$\\)\\)/\\4/")) 6833 (args '("-l" "none" "-r"
6834 ;; 1=fullname 2=package? 3=name 4=proto? 5=attrs? (VERY APPROX!)
6835 "/\\<sub[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)\\)[ \\t]*\\(([^()]*)[ \t]*\\)?\\([ \t]*:[^#{;]*\\)?\\([{#]\\|$\\)/\\3/"
6836 "-r"
6837 "/\\<package[ \\t]+\\(\\([a-zA-Z0-9:_]*::\\)?\\([a-zA-Z0-9_]+\\)\\)[ \\t]*\\([#;]\\|$\\)/\\1/"
6838 "-r"
6839 "/\\<\\(package\\)[ \\t]*;/\\1;/"))
5471 res) 6840 res)
5472 (if add (setq args (cons "-a" args))) 6841 (if add (setq args (cons "-a" args)))
5473 (or files (setq files (list buffer-file-name))) 6842 (or files (setq files (list buffer-file-name)))
@@ -5539,6 +6908,29 @@ Delay of auto-help controlled by `cperl-lazy-help-time'."
5539 (message "indent-region/indent-sexp will %sbe automatically fix whitespace." 6908 (message "indent-region/indent-sexp will %sbe automatically fix whitespace."
5540 (if cperl-indent-region-fix-constructs "" "not "))) 6909 (if cperl-indent-region-fix-constructs "" "not ")))
5541 6910
6911(defun cperl-toggle-set-debug-unwind (arg &optional backtrace)
6912 "Toggle (or, with numeric argument, set) debugging state of syntaxification.
6913Nonpositive numeric argument disables debugging messages. The message
6914summarizes which regions it was decided to rescan for syntactic constructs.
6915
6916The message looks like this:
6917
6918 Syxify req=123..138 actual=101..146 done-to: 112=>146 statepos: 73=>117
6919
6920Numbers are character positions in the buffer. REQ provides the range to
6921rescan requested by `font-lock'. ACTUAL is the range actually resyntaxified;
6922for correct operation it should start and end outside any special syntactic
6923construct. DONE-TO and STATEPOS indicate changes to internal caches maintained
6924by CPerl."
6925 (interactive "P")
6926 (or arg
6927 (setq arg (if (eq cperl-syntaxify-by-font-lock
6928 (if backtrace 'backtrace 'message)) 0 1)))
6929 (setq arg (if (> arg 0) (if backtrace 'backtrace 'message) t))
6930 (setq cperl-syntaxify-by-font-lock arg)
6931 (message "Debugging messages of syntax unwind %sabled."
6932 (if (eq arg t) "dis" "en")))
6933
5542;;;; Tags file creation. 6934;;;; Tags file creation.
5543 6935
5544(defvar cperl-tmp-buffer " *cperl-tmp*") 6936(defvar cperl-tmp-buffer " *cperl-tmp*")
@@ -5679,13 +7071,22 @@ Delay of auto-help controlled by `cperl-lazy-help-time'."
5679 ret)))) 7071 ret))))
5680 7072
5681(defun cperl-add-tags-recurse-noxs () 7073(defun cperl-add-tags-recurse-noxs ()
5682 "Add to TAGS data for Perl and XSUB files in the current directory and kids. 7074 "Add to TAGS data for \"pure\" Perl files in the current directory and kids.
5683Use as 7075Use as
5684 emacs -batch -q -no-site-file -l emacs/cperl-mode.el \ 7076 emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
5685 -f cperl-add-tags-recurse 7077 -f cperl-add-tags-recurse-noxs
5686" 7078"
5687 (cperl-write-tags nil nil t t nil t)) 7079 (cperl-write-tags nil nil t t nil t))
5688 7080
7081(defun cperl-add-tags-recurse-noxs-fullpath ()
7082 "Add to TAGS data for \"pure\" Perl in the current directory and kids.
7083Writes down fullpath, so TAGS is relocatable (but if the build directory
7084is relocated, the file TAGS inside it breaks). Use as
7085 emacs -batch -q -no-site-file -l emacs/cperl-mode.el \
7086 -f cperl-add-tags-recurse-noxs-fullpath
7087"
7088 (cperl-write-tags nil nil t t nil t ""))
7089
5689(defun cperl-add-tags-recurse () 7090(defun cperl-add-tags-recurse ()
5690 "Add to TAGS file data for Perl files in the current directory and kids. 7091 "Add to TAGS file data for Perl files in the current directory and kids.
5691Use as 7092Use as
@@ -5855,9 +7256,9 @@ One may build such TAGS files from CPerl mode menu."
5855 (cperl-tags-hier-fill)) 7256 (cperl-tags-hier-fill))
5856 (or tags-table-list 7257 (or tags-table-list
5857 (call-interactively 'visit-tags-table)) 7258 (call-interactively 'visit-tags-table))
5858 (mapcar 7259 (mapcar
5859 (function 7260 (function
5860 (lambda (tagsfile) 7261 (lambda (tagsfile)
5861 (message "Updating list of classes... %s" tagsfile) 7262 (message "Updating list of classes... %s" tagsfile)
5862 (set-buffer (get-file-buffer tagsfile)) 7263 (set-buffer (get-file-buffer tagsfile))
5863 (cperl-tags-hier-fill))) 7264 (cperl-tags-hier-fill)))
@@ -6019,7 +7420,7 @@ One may build such TAGS files from CPerl mode menu."
6019 '("[^-\t <>=+]\\(--\\|\\+\\+\\)" ; var-- var++ 7420 '("[^-\t <>=+]\\(--\\|\\+\\+\\)" ; var-- var++
6020 "[a-zA-Z0-9_][|&][a-zA-Z0-9_$]" ; abc|def abc&def are often used. 7421 "[a-zA-Z0-9_][|&][a-zA-Z0-9_$]" ; abc|def abc&def are often used.
6021 "&[(a-zA-Z0-9_$]" ; &subroutine &(var->field) 7422 "&[(a-zA-Z0-9_$]" ; &subroutine &(var->field)
6022 "<\\$?\\sw+\\(\\.\\sw+\\)?>" ; <IN> <stdin.h> 7423 "<\\$?\\sw+\\(\\.\\(\\sw\\|_\\)+\\)?>" ; <IN> <stdin.h>
6023 "-[a-zA-Z][ \t]+[_$\"'`a-zA-Z]" ; -f file, -t STDIN 7424 "-[a-zA-Z][ \t]+[_$\"'`a-zA-Z]" ; -f file, -t STDIN
6024 "-[0-9]" ; -5 7425 "-[0-9]" ; -5
6025 "\\+\\+" ; ++var 7426 "\\+\\+" ; ++var
@@ -6051,8 +7452,7 @@ Currently it is tuned to C and Perl syntax."
6051 (interactive) 7452 (interactive)
6052 (let (found-bad (p (point))) 7453 (let (found-bad (p (point)))
6053 (setq last-nonmenu-event 13) ; To disable popup 7454 (setq last-nonmenu-event 13) ; To disable popup
6054 (with-no-warnings ; It is useful to push the mark here. 7455 (goto-char (point-min))
6055 (beginning-of-buffer))
6056 (map-y-or-n-p "Insert space here? " 7456 (map-y-or-n-p "Insert space here? "
6057 (lambda (arg) (insert " ")) 7457 (lambda (arg) (insert " "))
6058 'cperl-next-bad-style 7458 'cperl-next-bad-style
@@ -6448,7 +7848,7 @@ endservent
6448eof[([FILEHANDLE])] 7848eof[([FILEHANDLE])]
6449... eq ... String equality. 7849... eq ... String equality.
6450eval(EXPR) or eval { BLOCK } 7850eval(EXPR) or eval { BLOCK }
6451exec(LIST) 7851exec([TRUENAME] ARGV0, ARGVs) or exec(SHELL_COMMAND_LINE)
6452exit(EXPR) 7852exit(EXPR)
6453exp(EXPR) 7853exp(EXPR)
6454fcntl(FILEHANDLE,FUNCTION,SCALAR) 7854fcntl(FILEHANDLE,FUNCTION,SCALAR)
@@ -6584,7 +7984,7 @@ substr(EXPR,OFFSET[,LEN])
6584symlink(OLDFILE,NEWFILE) 7984symlink(OLDFILE,NEWFILE)
6585syscall(LIST) 7985syscall(LIST)
6586sysread(FILEHANDLE,SCALAR,LENGTH[,OFFSET]) 7986sysread(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
6587system(LIST) 7987system([TRUENAME] ARGV0 [,ARGV]) or system(SHELL_COMMAND_LINE)
6588syswrite(FILEHANDLE,SCALAR,LENGTH[,OFFSET]) 7988syswrite(FILEHANDLE,SCALAR,LENGTH[,OFFSET])
6589tell[(FILEHANDLE)] 7989tell[(FILEHANDLE)]
6590telldir(DIRHANDLE) 7990telldir(DIRHANDLE)
@@ -6685,7 +8085,7 @@ prototype \\&SUB Returns prototype of the function given a reference.
6685 ;; b is before the starting delimiter, e before the ending 8085 ;; b is before the starting delimiter, e before the ending
6686 ;; e should be a marker, may be changed, but remains "correct". 8086 ;; e should be a marker, may be changed, but remains "correct".
6687 ;; EMBED is nil iff we process the whole REx. 8087 ;; EMBED is nil iff we process the whole REx.
6688 ;; The REx is guarantied to have //x 8088 ;; The REx is guaranteed to have //x
6689 ;; LEVEL shows how many levels deep to go 8089 ;; LEVEL shows how many levels deep to go
6690 ;; position at enter and at leave is not defined 8090 ;; position at enter and at leave is not defined
6691 (let (s c tmp (m (make-marker)) (m1 (make-marker)) c1 spaces inline code pos) 8091 (let (s c tmp (m (make-marker)) (m1 (make-marker)) c1 spaces inline code pos)
@@ -6714,7 +8114,7 @@ prototype \\&SUB Returns prototype of the function given a reference.
6714 (goto-char e) 8114 (goto-char e)
6715 (delete-horizontal-space) 8115 (delete-horizontal-space)
6716 (insert "\n") 8116 (insert "\n")
6717 (indent-to-column c) 8117 (cperl-make-indent c)
6718 (set-marker e (point)))) 8118 (set-marker e (point))))
6719 (goto-char b) 8119 (goto-char b)
6720 (end-of-line 2) 8120 (end-of-line 2)
@@ -6724,7 +8124,7 @@ prototype \\&SUB Returns prototype of the function given a reference.
6724 inline t) 8124 inline t)
6725 (skip-chars-forward " \t") 8125 (skip-chars-forward " \t")
6726 (delete-region s (point)) 8126 (delete-region s (point))
6727 (indent-to-column c1) 8127 (cperl-make-indent c1)
6728 (while (and 8128 (while (and
6729 inline 8129 inline
6730 (looking-at 8130 (looking-at
@@ -6750,6 +8150,16 @@ prototype \\&SUB Returns prototype of the function given a reference.
6750 (eq (preceding-char) ?\{))) 8150 (eq (preceding-char) ?\{)))
6751 (forward-char -1) 8151 (forward-char -1)
6752 (forward-sexp 1)) 8152 (forward-sexp 1))
8153 ((and ; [], already syntaxified
8154 (match-beginning 6)
8155 cperl-regexp-scan
8156 cperl-use-syntax-table-text-property)
8157 (forward-char -1)
8158 (forward-sexp 1)
8159 (or (eq (preceding-char) ?\])
8160 (error "[]-group not terminated"))
8161 (re-search-forward
8162 "\\=\\([*+?]\\|{[0-9]+\\(,[0-9]*\\)?}\\)\\??" e t))
6753 ((match-beginning 6) ; [] 8163 ((match-beginning 6) ; []
6754 (setq tmp (point)) 8164 (setq tmp (point))
6755 (if (looking-at "\\^?\\]") 8165 (if (looking-at "\\^?\\]")
@@ -6763,12 +8173,8 @@ prototype \\&SUB Returns prototype of the function given a reference.
6763 (setq pos t))) 8173 (setq pos t)))
6764 (or (eq (preceding-char) ?\]) 8174 (or (eq (preceding-char) ?\])
6765 (error "[]-group not terminated")) 8175 (error "[]-group not terminated"))
6766 (if (eq (following-char) ?\{) 8176 (re-search-forward
6767 (progn 8177 "\\=\\([*+?]\\|{[0-9]+\\(,[0-9]*\\)?}\\)\\??" e t))
6768 (forward-sexp 1)
6769 (and (eq (following-char) ??)
6770 (forward-char 1)))
6771 (re-search-forward "\\=\\([*+?]\\??\\)" e t)))
6772 ((match-beginning 7) ; () 8178 ((match-beginning 7) ; ()
6773 (goto-char (match-beginning 0)) 8179 (goto-char (match-beginning 0))
6774 (setq pos (current-column)) 8180 (setq pos (current-column))
@@ -6776,7 +8182,7 @@ prototype \\&SUB Returns prototype of the function given a reference.
6776 (progn 8182 (progn
6777 (delete-horizontal-space) 8183 (delete-horizontal-space)
6778 (insert "\n") 8184 (insert "\n")
6779 (indent-to-column c1))) 8185 (cperl-make-indent c1)))
6780 (setq tmp (point)) 8186 (setq tmp (point))
6781 (forward-sexp 1) 8187 (forward-sexp 1)
6782 ;; (or (forward-sexp 1) 8188 ;; (or (forward-sexp 1)
@@ -6836,7 +8242,7 @@ prototype \\&SUB Returns prototype of the function given a reference.
6836 (insert "\n")) 8242 (insert "\n"))
6837 ;; first at line 8243 ;; first at line
6838 (delete-region (point) tmp)) 8244 (delete-region (point) tmp))
6839 (indent-to-column c) 8245 (cperl-make-indent c)
6840 (forward-char 1) 8246 (forward-char 1)
6841 (skip-chars-forward " \t") 8247 (skip-chars-forward " \t")
6842 (setq spaces nil) 8248 (setq spaces nil)
@@ -6859,10 +8265,7 @@ prototype \\&SUB Returns prototype of the function given a reference.
6859 (/= (current-indentation) c)) 8265 (/= (current-indentation) c))
6860 (progn 8266 (progn
6861 (beginning-of-line) 8267 (beginning-of-line)
6862 (setq s (point)) 8268 (cperl-make-indent c)))))
6863 (skip-chars-forward " \t")
6864 (delete-region s (point))
6865 (indent-to-column c)))))
6866 8269
6867(defun cperl-make-regexp-x () 8270(defun cperl-make-regexp-x ()
6868 ;; Returns position of the start 8271 ;; Returns position of the start
@@ -6931,7 +8334,7 @@ We suppose that the regexp is scanned already."
6931 (interactive) 8334 (interactive)
6932 ;; (save-excursion ; Can't, breaks `cperl-contract-levels' 8335 ;; (save-excursion ; Can't, breaks `cperl-contract-levels'
6933 (cperl-regext-to-level-start) 8336 (cperl-regext-to-level-start)
6934 (let ((b (point)) (e (make-marker)) s c) 8337 (let ((b (point)) (e (make-marker)) c)
6935 (forward-sexp 1) 8338 (forward-sexp 1)
6936 (set-marker e (1- (point))) 8339 (set-marker e (1- (point)))
6937 (goto-char b) 8340 (goto-char b)
@@ -6940,10 +8343,7 @@ We suppose that the regexp is scanned already."
6940 ((match-beginning 1) ; #-comment 8343 ((match-beginning 1) ; #-comment
6941 (or c (setq c (current-indentation))) 8344 (or c (setq c (current-indentation)))
6942 (beginning-of-line 2) ; Skip 8345 (beginning-of-line 2) ; Skip
6943 (setq s (point)) 8346 (cperl-make-indent c))
6944 (skip-chars-forward " \t")
6945 (delete-region s (point))
6946 (indent-to-column c))
6947 (t 8347 (t
6948 (delete-char -1) 8348 (delete-char -1)
6949 (just-one-space)))))) 8349 (just-one-space))))))
@@ -6982,96 +8382,197 @@ We suppose that the regexp is scanned already."
6982 (set-marker e (1- (point))) 8382 (set-marker e (1- (point)))
6983 (cperl-beautify-regexp-piece b e nil deep)))) 8383 (cperl-beautify-regexp-piece b e nil deep))))
6984 8384
8385(defun cperl-invert-if-unless-modifiers ()
8386 "Change `B if A;' into `if (A) {B}' etc if possible.
8387\(Unfinished.)"
8388 (interactive) ;
8389 (let (A B pre-B post-B pre-if post-if pre-A post-A if-string
8390 (w-rex "\\<\\(if\\|unless\\|while\\|until\\|for\\|foreach\\)\\>"))
8391 (and (= (char-syntax (preceding-char)) ?w)
8392 (forward-sexp -1))
8393 (setq pre-if (point))
8394 (cperl-backward-to-start-of-expr)
8395 (setq pre-B (point))
8396 (forward-sexp 1) ; otherwise forward-to-end-of-expr is NOP
8397 (cperl-forward-to-end-of-expr)
8398 (setq post-A (point))
8399 (goto-char pre-if)
8400 (or (looking-at w-rex)
8401 ;; Find the position
8402 (progn (goto-char post-A)
8403 (while (and
8404 (not (looking-at w-rex))
8405 (> (point) pre-B))
8406 (forward-sexp -1))
8407 (setq pre-if (point))))
8408 (or (looking-at w-rex)
8409 (error "Can't find `if', `unless', `while', `until', `for' or `foreach'"))
8410 ;; 1 B 2 ... 3 B-com ... 4 if 5 ... if-com 6 ... 7 A 8
8411 (setq if-string (buffer-substring (match-beginning 0) (match-end 0)))
8412 ;; First, simple part: find code boundaries
8413 (forward-sexp 1)
8414 (setq post-if (point))
8415 (forward-sexp -2)
8416 (forward-sexp 1)
8417 (setq post-B (point))
8418 (cperl-backward-to-start-of-expr)
8419 (setq pre-B (point))
8420 (setq B (buffer-substring pre-B post-B))
8421 (goto-char pre-if)
8422 (forward-sexp 2)
8423 (forward-sexp -1)
8424 ;; May be after $, @, $# etc of a variable
8425 (skip-chars-backward "$@%#")
8426 (setq pre-A (point))
8427 (cperl-forward-to-end-of-expr)
8428 (setq post-A (point))
8429 (setq A (buffer-substring pre-A post-A))
8430 ;; Now modify (from end, to not break the stuff)
8431 (skip-chars-forward " \t;")
8432 (delete-region pre-A (point)) ; we move to pre-A
8433 (insert "\n" B ";\n}")
8434 (and (looking-at "[ \t]*#") (cperl-indent-for-comment))
8435 (delete-region pre-if post-if)
8436 (delete-region pre-B post-B)
8437 (goto-char pre-B)
8438 (insert if-string " (" A ") {")
8439 (setq post-B (point))
8440 (if (looking-at "[ \t]+$")
8441 (delete-horizontal-space)
8442 (if (looking-at "[ \t]*#")
8443 (cperl-indent-for-comment)
8444 (just-one-space)))
8445 (forward-line 1)
8446 (if (looking-at "[ \t]*$")
8447 (progn ; delete line
8448 (delete-horizontal-space)
8449 (delete-region (point) (1+ (point)))))
8450 (cperl-indent-line)
8451 (goto-char (1- post-B))
8452 (forward-sexp 1)
8453 (cperl-indent-line)
8454 (goto-char pre-B)))
8455
6985(defun cperl-invert-if-unless () 8456(defun cperl-invert-if-unless ()
6986 "Change `if (A) {B}' into `B if A;' etc if possible." 8457 "Change `if (A) {B}' into `B if A;' etc (or visa versa) if possible.
8458If the cursor is not on the leading keyword of the BLOCK flavor of
8459construct, will assume it is the STATEMENT flavor, so will try to find
8460the appropriate statement modifier."
6987 (interactive) 8461 (interactive)
6988 (or (looking-at "\\<") 8462 (and (= (char-syntax (preceding-char)) ?w)
6989 (forward-sexp -1)) 8463 (forward-sexp -1))
6990 (if (looking-at "\\<\\(if\\|unless\\|while\\|until\\|for\\|foreach\\)\\>") 8464 (if (looking-at "\\<\\(if\\|unless\\|while\\|until\\|for\\|foreach\\)\\>")
6991 (let ((pos1 (point)) 8465 (let ((pre-if (point))
6992 pos2 pos3 pos4 pos5 s1 s2 state p pos45 8466 pre-A post-A pre-B post-B A B state p end-B-code is-block B-comment
6993 (s0 (buffer-substring (match-beginning 0) (match-end 0)))) 8467 (if-string (buffer-substring (match-beginning 0) (match-end 0))))
6994 (forward-sexp 2) 8468 (forward-sexp 2)
6995 (setq pos3 (point)) 8469 (setq post-A (point))
6996 (forward-sexp -1) 8470 (forward-sexp -1)
6997 (setq pos2 (point)) 8471 (setq pre-A (point))
6998 (if (eq (following-char) ?\( ) 8472 (setq is-block (and (eq (following-char) ?\( )
8473 (save-excursion
8474 (condition-case nil
8475 (progn
8476 (forward-sexp 2)
8477 (forward-sexp -1)
8478 (eq (following-char) ?\{ ))
8479 (error nil)))))
8480 (if is-block
6999 (progn 8481 (progn
7000 (goto-char pos3) 8482 (goto-char post-A)
7001 (forward-sexp 1) 8483 (forward-sexp 1)
7002 (setq pos5 (point)) 8484 (setq post-B (point))
7003 (forward-sexp -1) 8485 (forward-sexp -1)
7004 (setq pos4 (point)) 8486 (setq pre-B (point))
7005 ;; XXXX In fact may be `A if (B); {C}' ...
7006 (if (and (eq (following-char) ?\{ ) 8487 (if (and (eq (following-char) ?\{ )
7007 (progn 8488 (progn
7008 (cperl-backward-to-noncomment pos3) 8489 (cperl-backward-to-noncomment post-A)
7009 (eq (preceding-char) ?\) ))) 8490 (eq (preceding-char) ?\) )))
7010 (if (condition-case nil 8491 (if (condition-case nil
7011 (progn 8492 (progn
7012 (goto-char pos5) 8493 (goto-char post-B)
7013 (forward-sexp 1) 8494 (forward-sexp 1)
7014 (forward-sexp -1) 8495 (forward-sexp -1)
7015 (looking-at "\\<els\\(e\\|if\\)\\>")) 8496 (looking-at "\\<els\\(e\\|if\\)\\>"))
7016 (error nil)) 8497 (error nil))
7017 (error 8498 (error
7018 "`%s' (EXPR) {BLOCK} with `else'/`elsif'" s0) 8499 "`%s' (EXPR) {BLOCK} with `else'/`elsif'" if-string)
7019 (goto-char (1- pos5)) 8500 (goto-char (1- post-B))
7020 (cperl-backward-to-noncomment pos4) 8501 (cperl-backward-to-noncomment pre-B)
7021 (if (eq (preceding-char) ?\;) 8502 (if (eq (preceding-char) ?\;)
7022 (forward-char -1)) 8503 (forward-char -1))
7023 (setq pos45 (point)) 8504 (setq end-B-code (point))
7024 (goto-char pos4) 8505 (goto-char pre-B)
7025 (while (re-search-forward "\\<\\(for\\|foreach\\|if\\|unless\\|while\\|until\\)\\>\\|;" pos45 t) 8506 (while (re-search-forward "\\<\\(for\\|foreach\\|if\\|unless\\|while\\|until\\)\\>\\|;" end-B-code t)
7026 (setq p (match-beginning 0) 8507 (setq p (match-beginning 0)
7027 s1 (buffer-substring p (match-end 0)) 8508 A (buffer-substring p (match-end 0))
7028 state (parse-partial-sexp pos4 p)) 8509 state (parse-partial-sexp pre-B p))
7029 (or (nth 3 state) 8510 (or (nth 3 state)
7030 (nth 4 state) 8511 (nth 4 state)
7031 (nth 5 state) 8512 (nth 5 state)
7032 (error "`%s' inside `%s' BLOCK" s1 s0)) 8513 (error "`%s' inside `%s' BLOCK" A if-string))
7033 (goto-char (match-end 0))) 8514 (goto-char (match-end 0)))
7034 ;; Finally got it 8515 ;; Finally got it
7035 (goto-char (1+ pos4)) 8516 (goto-char (1+ pre-B))
7036 (skip-chars-forward " \t\n") 8517 (skip-chars-forward " \t\n")
7037 (setq s2 (buffer-substring (point) pos45)) 8518 (setq B (buffer-substring (point) end-B-code))
7038 (goto-char pos45) 8519 (goto-char end-B-code)
7039 (or (looking-at ";?[ \t\n]*}") 8520 (or (looking-at ";?[ \t\n]*}")
7040 (progn 8521 (progn
7041 (skip-chars-forward "; \t\n") 8522 (skip-chars-forward "; \t\n")
7042 (setq s2 (concat s2 "\n" (buffer-substring (point) (1- pos5)))))) 8523 (setq B-comment
7043 (and (equal s2 "") 8524 (buffer-substring (point) (1- post-B)))))
7044 (setq s2 "1")) 8525 (and (equal B "")
7045 (goto-char (1- pos3)) 8526 (setq B "1"))
7046 (cperl-backward-to-noncomment pos2) 8527 (goto-char (1- post-A))
8528 (cperl-backward-to-noncomment pre-A)
7047 (or (looking-at "[ \t\n]*)") 8529 (or (looking-at "[ \t\n]*)")
7048 (goto-char (1- pos3))) 8530 (goto-char (1- post-A)))
7049 (setq p (point)) 8531 (setq p (point))
7050 (goto-char (1+ pos2)) 8532 (goto-char (1+ pre-A))
7051 (skip-chars-forward " \t\n") 8533 (skip-chars-forward " \t\n")
7052 (setq s1 (buffer-substring (point) p)) 8534 (setq A (buffer-substring (point) p))
7053 (delete-region pos4 pos5) 8535 (delete-region pre-B post-B)
7054 (delete-region pos2 pos3) 8536 (delete-region pre-A post-A)
7055 (goto-char pos1) 8537 (goto-char pre-if)
7056 (insert s2 " ") 8538 (insert B " ")
8539 (and B-comment (insert B-comment " "))
7057 (just-one-space) 8540 (just-one-space)
7058 (forward-word 1) 8541 (forward-word 1)
7059 (setq pos1 (point)) 8542 (setq pre-A (point))
7060 (insert " " s1 ";") 8543 (insert " " A ";")
7061 (delete-horizontal-space) 8544 (delete-horizontal-space)
8545 (setq post-B (point))
8546 (if (looking-at "#")
8547 (indent-for-comment))
8548 (goto-char post-B)
7062 (forward-char -1) 8549 (forward-char -1)
7063 (delete-horizontal-space) 8550 (delete-horizontal-space)
7064 (goto-char pos1) 8551 (goto-char pre-A)
7065 (just-one-space) 8552 (just-one-space)
7066 (cperl-indent-line)) 8553 (goto-char pre-if)
7067 (error "`%s' (EXPR) not with an {BLOCK}" s0))) 8554 (setq pre-A (set-marker (make-marker) pre-A))
7068 (error "`%s' not with an (EXPR)" s0))) 8555 (while (<= (point) (marker-position pre-A))
7069 (error "Not at `if', `unless', `while', `until', `for' or `foreach'"))) 8556 (cperl-indent-line)
8557 (forward-line 1))
8558 (goto-char (marker-position pre-A))
8559 (if B-comment
8560 (progn
8561 (forward-line -1)
8562 (indent-for-comment)
8563 (goto-char (marker-position pre-A)))))
8564 (error "`%s' (EXPR) not with an {BLOCK}" if-string)))
8565 ;; (error "`%s' not with an (EXPR)" if-string)
8566 (forward-sexp -1)
8567 (cperl-invert-if-unless-modifiers)))
8568 ;;(error "Not at `if', `unless', `while', `until', `for' or `foreach'")
8569 (cperl-invert-if-unless-modifiers)))
7070 8570
7071;;; By Anthony Foiani <afoiani@uswest.com> 8571;;; By Anthony Foiani <afoiani@uswest.com>
7072;;; Getting help on modules in C-h f ? 8572;;; Getting help on modules in C-h f ?
7073;;; This is a modified version of `man'. 8573;;; This is a modified version of `man'.
7074;;; Need to teach it how to lookup functions 8574;;; Need to teach it how to lookup functions
8575;;;###autoload
7075(defun cperl-perldoc (word) 8576(defun cperl-perldoc (word)
7076 "Run `perldoc' on WORD." 8577 "Run `perldoc' on WORD."
7077 (interactive 8578 (interactive
@@ -7103,6 +8604,7 @@ We suppose that the regexp is scanned already."
7103 (t 8604 (t
7104 (Man-getpage-in-background word))))) 8605 (Man-getpage-in-background word)))))
7105 8606
8607;;;###autoload
7106(defun cperl-perldoc-at-point () 8608(defun cperl-perldoc-at-point ()
7107 "Run a `perldoc' on the word around point." 8609 "Run a `perldoc' on the word around point."
7108 (interactive) 8610 (interactive)
@@ -7147,7 +8649,7 @@ We suppose that the regexp is scanned already."
7147(defun cperl-pod2man-build-command () 8649(defun cperl-pod2man-build-command ()
7148 "Builds the entire background manpage and cleaning command." 8650 "Builds the entire background manpage and cleaning command."
7149 (let ((command (concat pod2man-program " %s 2>/dev/null")) 8651 (let ((command (concat pod2man-program " %s 2>/dev/null"))
7150 (flist Man-filter-list)) 8652 (flist (and (boundp 'Man-filter-list) Man-filter-list)))
7151 (while (and flist (car flist)) 8653 (while (and flist (car flist))
7152 (let ((pcom (car (car flist))) 8654 (let ((pcom (car (car flist)))
7153 (pargs (cdr (car flist)))) 8655 (pargs (cdr (car flist))))
@@ -7161,6 +8663,205 @@ We suppose that the regexp is scanned already."
7161 (setq flist (cdr flist)))) 8663 (setq flist (cdr flist))))
7162 command)) 8664 command))
7163 8665
8666
8667(defun cperl-next-interpolated-REx-1 ()
8668 "Move point to next REx which has interpolated parts without //o.
8669Skips RExes consisting of one interpolated variable.
8670
8671Note that skipped RExen are not performance hits."
8672 (interactive "")
8673 (cperl-next-interpolated-REx 1))
8674
8675(defun cperl-next-interpolated-REx-0 ()
8676 "Move point to next REx which has interpolated parts without //o."
8677 (interactive "")
8678 (cperl-next-interpolated-REx 0))
8679
8680(defun cperl-next-interpolated-REx (&optional skip beg limit)
8681 "Move point to next REx which has interpolated parts.
8682SKIP is a list of possible types to skip, BEG and LIMIT are the starting
8683point and the limit of search (default to point and end of buffer).
8684
8685SKIP may be a number, then it behaves as list of numbers up to SKIP; this
8686semantic may be used as a numeric argument.
8687
8688Types are 0 for / $rex /o (interpolated once), 1 for /$rex/ (if $rex is
8689a result of qr//, this is not a performance hit), t for the rest."
8690 (interactive "P")
8691 (if (numberp skip) (setq skip (list 0 skip)))
8692 (or beg (setq beg (point)))
8693 (or limit (setq limit (point-max))) ; needed for n-s-p-c
8694 (let (pp)
8695 (and (eq (get-text-property beg 'syntax-type) 'string)
8696 (setq beg (next-single-property-change beg 'syntax-type nil limit)))
8697 (cperl-map-pods-heres
8698 (function (lambda (s e p)
8699 (if (memq (get-text-property s 'REx-interpolated) skip)
8700 t
8701 (setq pp s)
8702 nil))) ; nil stops
8703 'REx-interpolated beg limit)
8704 (if pp (goto-char pp)
8705 (message "No more interpolated REx"))))
8706
8707;;; Initial version contributed by Trey Belew
8708(defun cperl-here-doc-spell (&optional beg end)
8709 "Spell-check HERE-documents in the Perl buffer.
8710If a region is highlighted, restricts to the region."
8711 (interactive "")
8712 (cperl-pod-spell t beg end))
8713
8714(defun cperl-pod-spell (&optional do-heres beg end)
8715 "Spell-check POD documentation.
8716If invoked with prefix argument, will do HERE-DOCs instead.
8717If a region is highlighted, restricts to the region."
8718 (interactive "P")
8719 (save-excursion
8720 (let (beg end)
8721 (if (cperl-mark-active)
8722 (setq beg (min (mark) (point))
8723 end (max (mark) (point)))
8724 (setq beg (point-min)
8725 end (point-max)))
8726 (cperl-map-pods-heres (function
8727 (lambda (s e p)
8728 (if do-heres
8729 (setq e (save-excursion
8730 (goto-char e)
8731 (forward-line -1)
8732 (point))))
8733 (ispell-region s e)
8734 t))
8735 (if do-heres 'here-doc-group 'in-pod)
8736 beg end))))
8737
8738(defun cperl-map-pods-heres (func &optional prop s end)
8739 "Executes a function over regions of pods or here-documents.
8740PROP is the text-property to search for; default to `in-pod'. Stop when
8741function returns nil."
8742 (let (pos posend has-prop (cont t))
8743 (or prop (setq prop 'in-pod))
8744 (or s (setq s (point-min)))
8745 (or end (setq end (point-max)))
8746 (cperl-update-syntaxification end end)
8747 (save-excursion
8748 (goto-char (setq pos s))
8749 (while (and cont (< pos end))
8750 (setq has-prop (get-text-property pos prop))
8751 (setq posend (next-single-property-change pos prop nil end))
8752 (and has-prop
8753 (setq cont (funcall func pos posend prop)))
8754 (setq pos posend)))))
8755
8756;;; Based on code by Masatake YAMATO:
8757(defun cperl-get-here-doc-region (&optional pos pod)
8758 "Return HERE document region around the point.
8759Return nil if the point is not in a HERE document region. If POD is non-nil,
8760will return a POD section if point is in a POD section."
8761 (or pos (setq pos (point)))
8762 (cperl-update-syntaxification pos pos)
8763 (if (or (eq 'here-doc (get-text-property pos 'syntax-type))
8764 (and pod
8765 (eq 'pod (get-text-property pos 'syntax-type))))
8766 (let ((b (cperl-beginning-of-property pos 'syntax-type))
8767 (e (next-single-property-change pos 'syntax-type)))
8768 (cons b (or e (point-max))))))
8769
8770(defun cperl-narrow-to-here-doc (&optional pos)
8771 "Narrows editing region to the HERE-DOC at POS.
8772POS defaults to the point."
8773 (interactive "d")
8774 (or pos (setq pos (point)))
8775 (let ((p (cperl-get-here-doc-region pos)))
8776 (or p (error "Not inside a HERE document"))
8777 (narrow-to-region (car p) (cdr p))
8778 (message
8779 "When you are finished with narrow editing, type C-x n w")))
8780
8781(defun cperl-select-this-pod-or-here-doc (&optional pos)
8782 "Select the HERE-DOC (or POD section) at POS.
8783POS defaults to the point."
8784 (interactive "d")
8785 (let ((p (cperl-get-here-doc-region pos t)))
8786 (if p
8787 (progn
8788 (goto-char (car p))
8789 (push-mark (cdr p) nil t)) ; Message, activate in transient-mode
8790 (message "I do not think POS is in POD or a HERE-doc..."))))
8791
8792(defun cperl-facemenu-add-face-function (face end)
8793 "A callback to process user-initiated font-change requests.
8794Translates `bold', `italic', and `bold-italic' requests to insertion of
8795corresponding POD directives, and `underline' to C<> POD directive.
8796
8797Such requests are usually bound to M-o LETTER."
8798 (or (get-text-property (point) 'in-pod)
8799 (error "Faces can only be set within POD"))
8800 (setq facemenu-end-add-face (if (eq face 'bold-italic) ">>" ">"))
8801 (cdr (or (assq face '((bold . "B<")
8802 (italic . "I<")
8803 (bold-italic . "B<I<")
8804 (underline . "C<")))
8805 (error "Face %s not configured for cperl-mode"
8806 face))))
8807
8808(defun cperl-time-fontification (&optional l step lim)
8809 "Times how long it takes to do incremental fontification in a region.
8810L is the line to start at, STEP is the number of lines to skip when
8811doing next incremental fontification, LIM is the maximal number of
8812incremental fontification to perform. Messages are accumulated in
8813*Messages* buffer.
8814
8815May be used for pinpointing which construct slows down buffer fontification:
8816start with default arguments, then refine the slowdown regions."
8817 (interactive "nLine to start at: \nnStep to do incremental fontification: ")
8818 (or l (setq l 1))
8819 (or step (setq step 500))
8820 (or lim (setq lim 40))
8821 (let* ((timems (function (lambda ()
8822 (let ((tt (current-time)))
8823 (+ (* 1000 (nth 1 tt)) (/ (nth 2 tt) 1000))))))
8824 (tt (funcall timems)) (c 0) delta tot)
8825 (goto-line l)
8826 (cperl-mode)
8827 (setq tot (- (- tt (setq tt (funcall timems)))))
8828 (message "cperl-mode at %s: %s" l tot)
8829 (while (and (< c lim) (not (eobp)))
8830 (forward-line step)
8831 (setq l (+ l step))
8832 (setq c (1+ c))
8833 (cperl-update-syntaxification (point) (point))
8834 (setq delta (- (- tt (setq tt (funcall timems)))) tot (+ tot delta))
8835 (message "to %s:%6s,%7s" l delta tot))
8836 tot))
8837
8838(defun cperl-emulate-lazy-lock (&optional window-size)
8839 "Emulate `lazy-lock' without `condition-case', so `debug-on-error' works.
8840Start fontifying the buffer from the start (or end) using the given
8841WINDOW-SIZE (units is lines). Negative WINDOW-SIZE starts at end, and
8842goes backwards; default is -50. This function is not CPerl-specific; it
8843may be used to debug problems with delayed incremental fontification."
8844 (interactive
8845 "nSize of window for incremental fontification, negative goes backwards: ")
8846 (or window-size (setq window-size -50))
8847 (let ((pos (if (> window-size 0)
8848 (point-min)
8849 (point-max)))
8850 p)
8851 (goto-char pos)
8852 (normal-mode)
8853 ;; Why needed??? With older font-locks???
8854 (set (make-local-variable 'font-lock-cache-position) (make-marker))
8855 (while (if (> window-size 0)
8856 (< pos (point-max))
8857 (> pos (point-min)))
8858 (setq p (progn
8859 (forward-line window-size)
8860 (point)))
8861 (font-lock-fontify-region (min p pos) (max p pos))
8862 (setq pos p))))
8863
8864
7164(defun cperl-lazy-install ()) ; Avoid a warning 8865(defun cperl-lazy-install ()) ; Avoid a warning
7165(defun cperl-lazy-unstall ()) ; Avoid a warning 8866(defun cperl-lazy-unstall ()) ; Avoid a warning
7166 8867
@@ -7176,7 +8877,7 @@ We suppose that the regexp is scanned already."
7176 "Switches on Auto-Help on Perl constructs (put in the message area). 8877 "Switches on Auto-Help on Perl constructs (put in the message area).
7177Delay of auto-help controlled by `cperl-lazy-help-time'." 8878Delay of auto-help controlled by `cperl-lazy-help-time'."
7178 (interactive) 8879 (interactive)
7179 (make-variable-buffer-local 'cperl-help-shown) 8880 (make-local-variable 'cperl-help-shown)
7180 (if (and (cperl-val 'cperl-lazy-help-time) 8881 (if (and (cperl-val 'cperl-lazy-help-time)
7181 (not cperl-lazy-installed)) 8882 (not cperl-lazy-installed))
7182 (progn 8883 (progn
@@ -7209,48 +8910,109 @@ Delay of auto-help controlled by `cperl-lazy-help-time'."
7209;;; Plug for wrong font-lock: 8910;;; Plug for wrong font-lock:
7210 8911
7211(defun cperl-font-lock-unfontify-region-function (beg end) 8912(defun cperl-font-lock-unfontify-region-function (beg end)
7212 ;; Simplified now that font-lock-unfontify-region uses save-buffer-state. 8913 (let* ((modified (buffer-modified-p)) (buffer-undo-list t)
7213 (let (before-change-functions after-change-functions) 8914 (inhibit-read-only t) (inhibit-point-motion-hooks t)
7214 (remove-text-properties beg end '(face nil)))) 8915 before-change-functions after-change-functions
8916 deactivate-mark buffer-file-name buffer-file-truename)
8917 (remove-text-properties beg end '(face nil))
8918 (if (and (not modified) (buffer-modified-p))
8919 (set-buffer-modified-p nil))))
8920
8921(defun cperl-font-lock-fontify-region-function (beg end loudly)
8922 "Extends the region to safe positions, then calls the default function.
8923Newer `font-lock's can do it themselves.
8924We unwind only as far as needed for fontification. Syntaxification may
8925do extra unwind via `cperl-unwind-to-safe'."
8926 (save-excursion
8927 (goto-char beg)
8928 (while (and beg
8929 (progn
8930 (beginning-of-line)
8931 (eq (get-text-property (setq beg (point)) 'syntax-type)
8932 'multiline)))
8933 (if (setq beg (cperl-beginning-of-property beg 'syntax-type))
8934 (goto-char beg)))
8935 (setq beg (point))
8936 (goto-char end)
8937 (while (and end
8938 (progn
8939 (or (bolp) (condition-case nil
8940 (forward-line 1)
8941 (error nil)))
8942 (eq (get-text-property (setq end (point)) 'syntax-type)
8943 'multiline)))
8944 (setq end (next-single-property-change end 'syntax-type nil (point-max)))
8945 (goto-char end))
8946 (setq end (point)))
8947 (font-lock-default-fontify-region beg end loudly))
7215 8948
7216(defvar cperl-d-l nil) 8949(defvar cperl-d-l nil)
7217(defun cperl-fontify-syntaxically (end) 8950(defun cperl-fontify-syntaxically (end)
7218 ;; Some vars for debugging only 8951 ;; Some vars for debugging only
7219 ;; (message "Syntaxifying...") 8952 ;; (message "Syntaxifying...")
7220 (let ((dbg (point)) (iend end) 8953 (let ((dbg (point)) (iend end) (idone cperl-syntax-done-to)
7221 (istate (car cperl-syntax-state)) 8954 (istate (car cperl-syntax-state))
7222 start) 8955 start from-start edebug-backtrace-buffer)
7223 (and cperl-syntaxify-unwind 8956 (if (eq cperl-syntaxify-by-font-lock 'backtrace)
7224 (setq end (cperl-unwind-to-safe t end))) 8957 (progn
7225 (setq start (point)) 8958 (require 'edebug)
8959 (let ((f 'edebug-backtrace))
8960 (funcall f)))) ; Avoid compile-time warning
7226 (or cperl-syntax-done-to 8961 (or cperl-syntax-done-to
7227 (setq cperl-syntax-done-to (point-min))) 8962 (setq cperl-syntax-done-to (point-min)
7228 (if (or (not (boundp 'font-lock-hot-pass)) 8963 from-start t))
7229 (eval 'font-lock-hot-pass) 8964 (setq start (if (and cperl-hook-after-change
7230 t) ; Not debugged otherwise 8965 (not from-start))
7231 ;; Need to forget what is after `start' 8966 cperl-syntax-done-to ; Fontify without change; ignore start
7232 (setq start (min cperl-syntax-done-to start)) 8967 ;; Need to forget what is after `start'
7233 ;; Fontification without a change 8968 (min cperl-syntax-done-to (point))))
7234 (setq start (max cperl-syntax-done-to start))) 8969 (goto-char start)
8970 (beginning-of-line)
8971 (setq start (point))
8972 (and cperl-syntaxify-unwind
8973 (setq end (cperl-unwind-to-safe t end)
8974 start (point)))
7235 (and (> end start) 8975 (and (> end start)
7236 (setq cperl-syntax-done-to start) ; In case what follows fails 8976 (setq cperl-syntax-done-to start) ; In case what follows fails
7237 (cperl-find-pods-heres start end t nil t)) 8977 (cperl-find-pods-heres start end t nil t))
7238 (if (eq cperl-syntaxify-by-font-lock 'message) 8978 (if (memq cperl-syntaxify-by-font-lock '(backtrace message))
7239 (message "Syntaxified %s..%s from %s to %s(%s), state %s-->%s" 8979 (message "Syxify req=%s..%s actual=%s..%s done-to: %s=>%s statepos: %s=>%s"
7240 dbg iend 8980 dbg iend start end idone cperl-syntax-done-to
7241 start end cperl-syntax-done-to
7242 istate (car cperl-syntax-state))) ; For debugging 8981 istate (car cperl-syntax-state))) ; For debugging
7243 nil)) ; Do not iterate 8982 nil)) ; Do not iterate
7244 8983
7245(defun cperl-fontify-update (end) 8984(defun cperl-fontify-update (end)
7246 (let ((pos (point)) prop posend) 8985 (let ((pos (point-min)) prop posend)
8986 (setq end (point-max))
7247 (while (< pos end) 8987 (while (< pos end)
7248 (setq prop (get-text-property pos 'cperl-postpone)) 8988 (setq prop (get-text-property pos 'cperl-postpone)
7249 (setq posend (next-single-property-change pos 'cperl-postpone nil end)) 8989 posend (next-single-property-change pos 'cperl-postpone nil end))
7250 (and prop (put-text-property pos posend (car prop) (cdr prop))) 8990 (and prop (put-text-property pos posend (car prop) (cdr prop)))
7251 (setq pos posend))) 8991 (setq pos posend)))
7252 nil) ; Do not iterate 8992 nil) ; Do not iterate
7253 8993
8994(defun cperl-fontify-update-bad (end)
8995 ;; Since fontification happens with different region than syntaxification,
8996 ;; do to the end of buffer, not to END;;; likewise, start earlier if needed
8997 (let* ((pos (point)) (prop (get-text-property pos 'cperl-postpone)) posend)
8998 (if prop
8999 (setq pos (or (cperl-beginning-of-property
9000 (cperl-1+ pos) 'cperl-postpone)
9001 (point-min))))
9002 (while (< pos end)
9003 (setq posend (next-single-property-change pos 'cperl-postpone))
9004 (and prop (put-text-property pos posend (car prop) (cdr prop)))
9005 (setq pos posend)
9006 (setq prop (get-text-property pos 'cperl-postpone))))
9007 nil) ; Do not iterate
9008
9009;; Called when any modification is made to buffer text.
9010(defun cperl-after-change-function (beg end old-len)
9011 ;; We should have been informed about changes by `font-lock'. Since it
9012 ;; does not inform as which calls are defered, do it ourselves
9013 (if cperl-syntax-done-to
9014 (setq cperl-syntax-done-to (min cperl-syntax-done-to beg))))
9015
7254(defun cperl-update-syntaxification (from to) 9016(defun cperl-update-syntaxification (from to)
7255 (if (and cperl-use-syntax-table-text-property 9017 (if (and cperl-use-syntax-table-text-property
7256 cperl-syntaxify-by-font-lock 9018 cperl-syntaxify-by-font-lock
@@ -7262,7 +9024,7 @@ Delay of auto-help controlled by `cperl-lazy-help-time'."
7262 (cperl-fontify-syntaxically to))))) 9024 (cperl-fontify-syntaxically to)))))
7263 9025
7264(defvar cperl-version 9026(defvar cperl-version
7265 (let ((v "Revision: 5.0")) 9027 (let ((v "Revision: 5.22"))
7266 (string-match ":\\s *\\([0-9.]+\\)" v) 9028 (string-match ":\\s *\\([0-9.]+\\)" v)
7267 (substring v (match-beginning 1) (match-end 1))) 9029 (substring v (match-beginning 1) (match-end 1)))
7268 "Version of IZ-supported CPerl package this file is based on.") 9030 "Version of IZ-supported CPerl package this file is based on.")