Anonymous avatar Anonymous committed 4c37137

Sync cperl-mode with upstream 5.23 <200705271452.49222.scop@xemacs.org>;

Comments (0)

Files changed (2)

+2007-05-27  Ville Skyttä  <scop@xemacs.org>
+
+	* cperl-mode.el: Sync with upstream version 5.23.
+
 2006-05-01  Norbert Koch  <viteno@xemacs.org>
 
 	* Makefile (VERSION): XEmacs package 1.09 released.
-;;; cperl-mode.el --- Perl code editing commands for XEmacs
-
-;; Copyright (C) 1985, 86, 87, 91, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2003
+;;; cperl-mode.el --- Perl code editing commands for Emacs
+
+;; Copyright (C) 1985, 86, 87, 91, 92, 93, 94, 95, 96, 97, 98, 99,
+;;               2000, 2003, 2005, 2006
 ;;     Free Software Foundation, Inc.
 
 ;; Author: Ilya Zakharevich and Bob Olson
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-;;; Corrections made by Ilya Zakharevich cperl@ilyaz.org
+;;; Corrections made by Ilya Zakharevich ilyaz@cpan.org
 ;;; XEmacs changes by Peter Arius arius@informatik.uni-erlangen.de
 ;;; XEmacs 'delete key behavior handling added for XEmacs 20.x by
 ;;; Gary D. Foster <Gary.Foster@corp.sun.com>
 ;; `cperl-non-problems', `cperl-praise', `cperl-speed'.            <<<<<<
 
 ;; Additional useful commands to put into your .emacs file (before
-;; Emacs 20.3):
+;; RMS Emacs 20.3):
 
 ;; (setq auto-mode-alist
 ;;      (append '(("\\.\\([pP][Llm]\\|al\\)$" . perl-mode))  auto-mode-alist ))
 
 ;; (setq font-lock-display-type 'grayscale)
 
-;; into your .emacs file (this is relevant before Emacs 20).
+;; into your .emacs file (this is relevant before RMS Emacs 20).
 
 ;; This mode supports font-lock, imenu and mode-compile.  In the
 ;; hairy version font-lock is on, but you should activate imenu
 ;;; Fontification updated to 19.30 style.
 ;;; The change 19.29->30 did not add all the required functionality,
 ;;;     but broke "font-lock-extra.el". Get "choose-color.el" from
-;;;       ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs
+;;;       http://ilyaz.org/software/emacs
 
 ;;;; After 1.16:
 ;;;       else # comment
 ;;;  Debugging code in `cperl-electric-keywords' was leaking a message;
 
 ;;;; After 1.41:
-;;;  XEmacs: added 'pod-spell' and 'make-pod-list'
-;;;  XEmacs: Two functions used to run ispell only on pod/here regions
 ;;;  RMS changes for 20.3 merged
 
 ;;;; 2.0.1.0: RMS mode (has 3 misprints)
 ;;;				Now works for else/continue/sub blocks
 ;;;  (`cperl-short-docs'):	Minor edits; make messages fit 80-column screen
 
-;;;; After 4.37:
-;;;  `cperl-add-tags-recurse-noxs-fullpath'
-;;;    added (for -batch mode);
+;;;; 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
+
+;;; After 5.22:
+;;; `cperl-where-am-i':		Remove function
+;;; `cperl-backward-to-noncomment': Would go too far when skipping POD/HEREs
+;;; `cperl-sniff-for-indent':	[string] and [comment] were inverted
+;;;				When looking for label, skip s:m:y:tr
+;;; `cperl-indent-line':	Likewise.
+;;; `cperl-mode':		`font-lock-multiline' was assumed auto-local
+;;; `cperl-windowed-init':	Wrong `ps-print' handling
+;;;				 (both thanks to Chong Yidong)
+;;; `cperl-look-at-leading-count': Could fail with unfinished RExen
+;;; `cperl-find-pods-heres':	If the second part of s()[] is missing,
+;;;					could try to highlight delimiters...
 
 ;;; Code:
-
 
 (if (fboundp 'eval-when-compile)
     (eval-when-compile
       (defvar gud-perldb-history)
       (defvar font-lock-background-mode) ; not in Emacs
       (defvar font-lock-display-type)	; ditto
+      (defvar paren-backwards-message)	; Not in newer XEmacs?
+      (defvar vc-rcs-header)		; likewise?
+      (defvar vc-sccs-header)		; likewise?
       (or (fboundp 'defgroup)
 	  (defmacro defgroup (name val doc &rest arr)
 	    nil))
   :type 'integer
   :group 'cperl-indentation-details)
 
+(defcustom cperl-indent-wrt-brace t
+  "*Non-nil means indent statements in if/etc block relative brace, not if/etc.
+Versions 5.2 ... 5.20 behaved as if this were `nil'."
+  :type 'boolean
+  :group 'cperl-indentation-details)
+
 (defcustom cperl-auto-newline nil
   "*Non-nil means automatically newline before and after braces,
 and after colons and semicolons, inserted in CPerl code.  The following
   :type 'integer
   :group 'cperl-indentation-details)
 
-(defcustom cperl-vc-header-alist '((SCCS "($sccs) = ('%W\%' =~ /(\\d+(\\.\\d+)+)/) ;")
-				   (RCS "($rcs) = (' $Id\$ ' =~ /(\\d+(\\.\\d+)+)/) ;"))
-  "*What to use as `vc-header-alist' in CPerl."
+(defcustom cperl-indent-comment-at-column-0 nil
+  "*Non-nil means that comment started at column 0 should be indentable."
+  :type 'boolean
+  :group 'cperl-indentation-details)
+
+(defcustom cperl-vc-sccs-header '("($sccs) = ('%W\%' =~ /(\\d+(\\.\\d+)+)/) ;")
+  "*Special version of `vc-sccs-header' that is used in CPerl mode buffers."
+  :type '(repeat string)
+  :group 'cperl)
+
+(defcustom cperl-vc-rcs-header '("($rcs) = (' $Id\$ ' =~ /(\\d+(\\.\\d+)+)/);")
+  "*Special version of `vc-rcs-header' that is used in CPerl mode buffers."
+  :type '(repeat string)
+     :group 'cperl)
+
+;; This became obsolete...
+(defcustom cperl-vc-header-alist '()
+  "*What to use as `vc-header-alist' in CPerl.
+Obsolete, with newer Emacsen use `cperl-vc-rcs-header' or
+`cperl-vc-sccs-header' instead.  If this list is empty, `vc-header-alist'
+will be reconstructed basing on these two variables."
   :type '(repeat (list symbol string))
   :group 'cperl)
 
   :type 'face
   :group 'cperl-faces)
 
-;; XEmacs change: removed extra ' from ''underline
-(defcustom cperl-invalid-face 'underline ; later evaluated by `font-lock'
-  "*The result of evaluation of this expression highlights trailing whitespace."
+;;; Some double-evaluation happened with font-locks...  Needed with 21.2...
+(defvar cperl-singly-quote-face cperl-xemacs-p)
+
+(defcustom cperl-invalid-face		; Does not customize with '' on XEmacs
+  (if cperl-singly-quote-face
+      'underline ''underline) ; On older Emacsen was evaluated by `font-lock'
+  (if cperl-singly-quote-face
+      "*This face is used for highlighting trailing whitespace."
+    "*The result of evaluation of this expression highlights trailing whitespace.")
   :type 'face
   :group 'cperl-faces)
 
 
 (defcustom cperl-regexp-scan t
   "*Not-nil means make marking of regular expression more thorough.
-Effective only with `cperl-pod-here-scan'.  Not implemented yet."
+Effective only with `cperl-pod-here-scan'."
+  :type 'boolean
+  :group 'cperl-speed)
+
+(defcustom cperl-hook-after-change t
+  "*Not-nil means install hook to know which regions of buffer are changed.
+May significantly speed up delayed fontification.  Changes take effect
+after reload."
   :type 'boolean
   :group 'cperl-speed)
 
   :type 'boolean
   :group 'cperl-speed)
 
+(defcustom cperl-syntaxify-for-menu
+  t
+  "*Non-nil means that CPerl syntaxifies up to the point before showing menu.
+This way enabling/disabling of menu items is more correct."
+  :type 'boolean
+  :group 'cperl-speed)
+
 (defcustom cperl-ps-print-face-properties
   '((font-lock-keyword-face		nil nil		bold shadow)
     (font-lock-variable-name-face	nil nil		bold)
     (font-lock-string-face		nil nil		italic underline)
     (cperl-nonoverridable-face		nil nil		italic underline)
     (font-lock-type-face		nil nil		underline)
+    (font-lock-warning-face		nil "LightGray"	bold italic box)
     (underline				nil "LightGray"	strikeout))
   "List given as an argument to `ps-extend-face-list' in `cperl-ps-print'."
   :type '(repeat (cons symbol
 
 (defvar cperl-tips 'please-ignore-this-line
   "Get maybe newer version of this package from
-  ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs
-and/or
-  ftp://ftp.math.ohio-state.edu/pub/users/ilya/perl
+  http://ilyaz.org/software/emacs
 Subdirectory `cperl-mode' may contain yet newer development releases and/or
 patches to related files.
 
 For best results apply to an older Emacs the patches from
   ftp://ftp.math.ohio-state.edu/pub/users/ilya/cperl-mode/patches
-\(this upgrades syntax-parsing abilities of Emaxen v19.34 and
-v20.2 up to the level of Emacs v20.3 - a must for a good Perl
+\(this upgrades syntax-parsing abilities of RMS Emaxen v19.34 and
+v20.2 up to the level of RMS Emacs v20.3 - a must for a good Perl
 mode.)  As of beginning of 2003, XEmacs may provide a similar ability.
 
 Get support packages choose-color.el (or font-lock-extra.el before
   (defalias 'perl-mode 'cperl-mode)
 
 Get perl5-info from
-  $CPAN/doc/manual/info/perl-info.tar.gz
-older version was on
-  http://www.metronet.com:70/9/perlinfo/perl5/manual/perl5-info.tar.gz
+  $CPAN/doc/manual/info/perl5-old/perl5-info.tar.gz
+Also, one can generate a newer documentation running `pod2texi' converter
+  $CPAN/doc/manual/info/perl5/pod2texi-0.1.tar.gz
 
 If you use imenu-go, run imenu on perl5-info buffer (you can do it
 from Perl menu).  If many files are related, generate TAGS files from
   "Description of problems in CPerl mode.
 Some faces will not be shown on some versions of Emacs unless you
 install choose-color.el, available from
-   ftp://ftp.math.ohio-state.edu/pub/users/ilya/emacs/
+  http://ilyaz.org/software/emacs
 
 `fill-paragraph' on a comment may leave the point behind the
-paragraph.  Parsing of lines with several <<EOF is not implemented
-yet.
-
-Emacs had a _very_ restricted syntax parsing engine until version
+paragraph.  It also triggers a bug in some versions of Emacs (CPerl tries
+to detect it and bulk out).
+
+See documentation of a variable `cperl-problems-old-emaxen' for the
+problems which disappear if you upgrade Emacs to a reasonably new
+version (20.3 for RMS Emacs, and those of 2004 for XEmacs).")
+
+(defvar cperl-problems-old-emaxen 'please-ignore-this-line
+  "Description of problems in CPerl mode specific for older Emacs versions.
+
+Emacs had a _very_ restricted syntax parsing engine until RMS's Emacs
 20.1.  Most problems below are corrected starting from this version of
-Emacs, and all of them should be fixed in version 20.3.  (Or apply
+Emacs, and all of them should be fixed in RMS's version 20.3.  (Or apply
 patches to Emacs 19.33/34 - see tips.)  XEmacs was very backward in
 this respect (until 2003).
 
 as /($|\\s)/.  Note that such a transposition is not always possible.
 
 The solution is to upgrade your Emacs or patch an older one.  Note
-that Emacs 20.2 has some bugs related to `syntax-table' text
+that RMS's 20.2 has some bugs related to `syntax-table' text
 properties.  Patches are available on the main CPerl download site,
 and on CPAN.
 
 via `cperl-use-syntax-table-text-property'.")
 
 (defvar cperl-non-problems 'please-ignore-this-line
-"As you know from `problems' section, Perl syntax is too hard for CPerl on 
+"As you know from `problems' section, Perl syntax is too hard for CPerl on
 older Emacsen.  Here is what you can do if you cannot upgrade, or if
-you want to switch off these capabilities on Emacs 20.2 (+patches) or 20.3
+you want to switch off these capabilities on RMS Emacs 20.2 (+patches) or 20.3
 or better.  Please skip this docs if you run a capable Emacs already.
 
 Most of the time, if you write your own code, you may find an equivalent
 
 Imenu in 19.31 is broken.  Set `imenu-use-keymap-menu' to t, and remove
 `car' before `imenu-choose-buffer-index' in `imenu'.
-`imenu-add-to-menubar' in 20.2 is broken.  
+`imenu-add-to-menubar' in 20.2 is broken.
 A lot of things on XEmacs may be broken too, judging by bug reports I
 receive.  Note that some releases of XEmacs are better than the others
 as far as bugs reports I see are concerned.")
 	o) Highlights trailing whitespace;
 	p) Is able to manipulate Perl Regular Expressions to ease
 	   conversion to a more readable form.
+        q) Can ispell POD sections and HERE-DOCs.
+	r) Understands comments and character classes inside regular
+	   expressions; can find matching () and [] in a regular expression.
+	s) Allows indentation of //x-style regular expressions;
+	t) Highlights different symbols in regular expressions according
+	   to their function; much less problems with backslashitis;
+	u) Allows to find regular expressions which contain interpolated parts.
 
 5) The indentation engine was very smart, but most of tricks may be
 not needed anymore with the support for `syntax-table' property.  Has
 line-breaks/spacing between elements of the construct.
 
 10) Uses a linear-time algorith for indentation of regions (on Emaxen with
-capable syntax engines).")
+capable syntax engines).
+
+11) Syntax-highlight, indentation, sexp-recognition inside regular expressions.
+")
 
 (defvar cperl-speed 'please-ignore-this-line
   "This is an incomplete compendium of what is available in other parts
 				syntaxically to be not code
   `font-lock-constant-face'	HERE-doc delimiters, labels, delimiters of
 				2-arg operators s/y/tr/ or of RExen,
-  `font-lock-function-name-face' Special-cased m// and s//foo/, _ as
-				a target of a file tests, file tests,
+  `font-lock-warning-face'	Special-cased m// and s//foo/,
+  `font-lock-function-name-face' _ as a target of a file tests, file tests,
 				subroutine names at the moment of definition
 				(except those conflicting with Perl operators),
 				package names (when recognized), format names
 Help with best setup of these faces for printout requested (for each of
 the faces: please specify bold, italic, underline, shadow and box.)
 
-\(Not finished.)")
+In regular expressions (except character classes):
+  `font-lock-string-face'	\"Normal\" stuff and non-0-length constructs
+  `font-lock-constant-face':	Delimiters
+  `font-lock-warning-face'	Special-cased m// and s//foo/,
+				Mismatched closing delimiters, parens
+				we couldn't match, misplaced quantifiers,
+				unrecognized escape sequences
+  `cperl-nonoverridable-face'	Modifiers, as gism in m/REx/gism
+  `font-lock-type-face'		POSIX classes inside charclasses,
+				escape sequences with arguments (\x \23 \p \N)
+				and others match-a-char escape sequences
+  `font-lock-keyword-face'	Capturing parens, and |
+  `font-lock-function-name-face' Special symbols: $ ^ . [ ] [^ ] (?{ }) (??{ })
+  `font-lock-builtin-face'	\"Remaining\" 0-length constructs, executable
+				parts of a REx, not-capturing parens
+  `font-lock-variable-name-face' Interpolated constructs, embedded code
+  `font-lock-comment-face'	Embedded comments
+
+")
 
 
 
    (cperl-hairy (or hairy t))
    (t (symbol-value symbol))))
 
+
+(defun cperl-make-indent (column &optional minimum keep)
+  "Makes indent of the current line the requested amount.
+Unless KEEP, removes the old indentation.  Works around a bug in ancient
+versions of Emacs."
+  (let ((prop (get-text-property (point) 'syntax-type)))
+    (or keep
+	(delete-horizontal-space))
+    (indent-to column minimum)
+    ;; In old versions (e.g., 19.33) `indent-to' would not inherit properties
+    (and prop
+	 (> (current-column) 0)
+	 (save-excursion
+	   (beginning-of-line)
+	   (or (get-text-property (point) 'syntax-type)
+	       (and (looking-at "\\=[ \t]")
+		      (put-text-property (point) (match-end 0)
+					 'syntax-type prop)))))))
+
 ;;; Probably it is too late to set these guys already, but it can help later:
 
 (and cperl-clobber-mode-lists
   (cperl-define-key "\C-c\C-w" 'cperl-toggle-construct-fix)
   (cperl-define-key "\C-c\C-f" 'auto-fill-mode)
   (cperl-define-key "\C-c\C-e" 'cperl-toggle-electric)
+  (cperl-define-key "\C-c\C-b" 'cperl-find-bad-style)
+  (cperl-define-key "\C-c\C-p" 'cperl-pod-spell)
+  (cperl-define-key "\C-c\C-d" 'cperl-here-doc-spell)
+  (cperl-define-key "\C-c\C-n" 'cperl-narrow-to-here-doc)
+  (cperl-define-key "\C-c\C-v" 'cperl-next-interpolated-REx)
+  (cperl-define-key "\C-c\C-x" 'cperl-next-interpolated-REx-0)
+  (cperl-define-key "\C-c\C-y" 'cperl-next-interpolated-REx-1)
   (cperl-define-key "\C-c\C-ha" 'cperl-toggle-autohelp)
+  (cperl-define-key "\C-c\C-hp" 'cperl-perldoc)
+  (cperl-define-key "\C-c\C-hP" 'cperl-perldoc-at-point)
   (cperl-define-key "\e\C-q" 'cperl-indent-exp) ; Usually not bound
   (cperl-define-key [?\C-\M-\|] 'cperl-lineup
 		    [(control meta |)])
 			  [(control c) (control h) v]))
     (cperl-define-key "\C-c\C-hf" 'cperl-info-on-current-command
 		      [(control c) (control h) f])
-    ;;; XEmacs change: added bindings for cperl-perldoc, 
-    ;;; cperl-perldoc-at-point.
-    (cperl-define-key "\C-c\C-hp" 'cperl-perldoc
-		      [(control c) (control h) p])
-    (cperl-define-key "\C-c\C-hP" 'cperl-perldoc-at-point
-		      [(control c) (control h) P])
     (cperl-define-key "\C-c\C-hv"
 		      ;;(concat (char-to-string help-char) "v") ; does not work
 		      'cperl-get-help
 	   (<= emacs-minor-version 11) (<= emacs-major-version 19))
       (progn
 	;; substitute-key-definition is usefulness-deenhanced...
-	(cperl-define-key "\M-q" 'cperl-fill-paragraph)
+	;;;;;(cperl-define-key "\M-q" 'cperl-fill-paragraph)
 	(cperl-define-key "\e;" 'cperl-indent-for-comment)
 	(cperl-define-key "\e\C-\\" 'cperl-indent-region))
+    (or (boundp 'fill-paragraph-function)
+	(substitute-key-definition
+	 'fill-paragraph 'cperl-fill-paragraph
+	 cperl-mode-map global-map))
     (substitute-key-definition
      'indent-sexp 'cperl-indent-exp
      cperl-mode-map global-map)
     (substitute-key-definition
-     'fill-paragraph 'cperl-fill-paragraph
-     cperl-mode-map global-map)
-    (substitute-key-definition
      'indent-region 'cperl-indent-region
      cperl-mode-map global-map)
     (substitute-key-definition
 	  ["Contract a group" cperl-contract-level
 	   cperl-use-syntax-table-text-property]
 	  ["Contract groups" cperl-contract-levels
-	   cperl-use-syntax-table-text-property])
+	   cperl-use-syntax-table-text-property]
+	  "----"
+	  ["Find next interpolated" cperl-next-interpolated-REx 
+	   (next-single-property-change (point-min) 'REx-interpolated)]
+	  ["Find next interpolated (no //o)"
+	   cperl-next-interpolated-REx-0
+	   (or (text-property-any (point-min) (point-max) 'REx-interpolated t)
+	       (text-property-any (point-min) (point-max) 'REx-interpolated 1))]
+	  ["Find next interpolated (neither //o nor whole-REx)"
+	   cperl-next-interpolated-REx-1
+	   (text-property-any (point-min) (point-max) 'REx-interpolated t)])
+	 ["Insert spaces if needed to fix style" cperl-find-bad-style t]
 	 ["Refresh \"hard\" constructions" cperl-find-pods-heres t]
 	 "----"
 	 ["Indent region" cperl-indent-region (cperl-use-region-p)]
 	 "----"
 	 ("Tools"
 	  ["Imenu" imenu (fboundp 'imenu)]
-	  ["Insert spaces if needed" cperl-find-bad-style t]
+	  ["Imenu on Perl Info" cperl-imenu-on-info (featurep 'imenu)]
+	  "----"
+	  ["Ispell PODs" cperl-pod-spell
+	   ;; Better not to update syntaxification here:
+	   ;; debugging syntaxificatio can be broken by this???
+	   (or
+	    (get-text-property (point-min) 'in-pod)
+	    (< (progn
+		 (and cperl-syntaxify-for-menu
+		      (cperl-update-syntaxification (point-max) (point-max)))
+		 (next-single-property-change (point-min) 'in-pod nil (point-max)))
+	       (point-max)))]
+	  ["Ispell HERE-DOCs" cperl-here-doc-spell
+	   (< (progn
+		(and cperl-syntaxify-for-menu
+		     (cperl-update-syntaxification (point-max) (point-max)))
+		(next-single-property-change (point-min) 'here-doc-group nil (point-max)))
+	      (point-max))]
+	  ["Narrow to this HERE-DOC" cperl-narrow-to-here-doc
+	   (eq 'here-doc  (progn
+		(and cperl-syntaxify-for-menu
+		     (cperl-update-syntaxification (point) (point)))
+		(get-text-property (point) 'syntax-type)))]
+	  ["Select this HERE-DOC or POD section"
+	   cperl-select-this-pod-or-here-doc
+	   (memq (progn
+		   (and cperl-syntaxify-for-menu
+			(cperl-update-syntaxification (point) (point)))
+		   (get-text-property (point) 'syntax-type))
+		 '(here-doc pod))]
+	  "----"
+	  ["CPerl pretty print (exprmntl)" cperl-ps-print
+	   (fboundp 'ps-extend-face-list)]
+	  "----"
+	  ["Syntaxify region" cperl-find-pods-heres-region
+	   (cperl-use-region-p)]
+	  ["Profile syntaxification" cperl-time-fontification t]
+	  ["Debug errors in delayed fontification" cperl-emulate-lazy-lock t]
+	  ["Debug unwind for syntactic scan" cperl-toggle-set-debug-unwind t]
+	  ["Debug backtrace on syntactic scan (BEWARE!!!)"
+	   (cperl-toggle-set-debug-unwind nil t) t]
+	  "----"
 	  ["Class Hierarchy from TAGS" cperl-tags-hier-init t]
 	  ;;["Update classes" (cperl-tags-hier-init t) tags-table-list]
-	  ["CPerl pretty print (exprmntl)" cperl-ps-print 
-	   (fboundp 'ps-extend-face-list)]
-	  ["Imenu on info" cperl-imenu-on-info (featurep 'imenu)]
 	  ("Tags"
 ;;;	     ["Create tags for current file" cperl-etags t]
 ;;;	     ["Add tags for current file" (cperl-etags t) t]
 	   ["Add tags for Perl files in (sub)directories"
 	    (cperl-write-tags nil nil t t) t]))
 	 ("Perl docs"
-	  ["Define word at point" imenu-go-find-at-position 
+	  ["Define word at point" imenu-go-find-at-position
 	   (fboundp 'imenu-go-find-at-position)]
 	  ["Help on function" cperl-info-on-command t]
 	  ["Help on function at point" cperl-info-on-current-command t]
 	  ["Perldoc" cperl-perldoc t]
 	  ["Perldoc on word at point" cperl-perldoc-at-point t]
 	  ["View manpage of POD in this file" cperl-build-manpage t]
-	  ["Auto-help on" cperl-lazy-install 
+	  ["Auto-help on" cperl-lazy-install
 	   (and (fboundp 'run-with-idle-timer)
 		(not cperl-lazy-installed))]
 	  ["Auto-help off" cperl-lazy-unstall
 	  ["Electric keywords" cperl-toggle-abbrev t]
 	  ["Fix whitespace on indent" cperl-toggle-construct-fix t]
 	  ["Auto-help on Perl constructs" cperl-toggle-autohelp t]
-	  ["Auto fill" auto-fill-mode t]) 
+	  ["Auto fill" auto-fill-mode t])
 	 ("Indent styles..."
 	  ["CPerl" (cperl-set-style "CPerl") t]
 	  ["PerlStyle" (cperl-set-style "PerlStyle") t]
 	  ["GNU" (cperl-set-style "GNU") t]
 	  ["C++" (cperl-set-style "C++") t]
-	  ["FSF" (cperl-set-style "FSF") t]
+	  ["K&R" (cperl-set-style "K&R") t]
 	  ["BSD" (cperl-set-style "BSD") t]
 	  ["Whitesmith" (cperl-set-style "Whitesmith") t]
-	  ["Current" (cperl-set-style "Current") t]
+	  ["Memorize Current" (cperl-set-style "Current") t]
 	  ["Memorized" (cperl-set-style-back) cperl-old-style])
 	 ("Micro-docs"
 	  ["Tips" (describe-variable 'cperl-tips) t]
 	  ["Praise" (describe-variable 'cperl-praise) t]
 	  ["Faces" (describe-variable 'cperl-tips-faces) t]
 	  ["CPerl mode" (describe-function 'cperl-mode) t]
-	  ["CPerl version" 
-	   (message "The version of master-file for this CPerl is %s" 
+	  ["CPerl version"
+	   (message "The version of master-file for this CPerl is %s"
 		    cperl-version) t]))))
   (error nil))
 
 The expansion is entirely correct because it uses the C preprocessor."
   t)
 
+;;; These two must be unwound, otherwise take exponential time
+(defconst cperl-maybe-white-and-comment-rex "[ \t\n]*\\(#[^\n]*\n[ \t\n]*\\)*"
+"Regular expression to match optional whitespace with interpspersed comments.
+Should contain exactly one group.")
+
+;;; This one is tricky to unwind; still very inefficient...
+(defconst cperl-white-and-comment-rex "\\([ \t\n]\\|#[^\n]*\n\\)+"
+"Regular expression to match whitespace with interpspersed comments.
+Should contain exactly one group.")
+
+
+;;; Is incorporated in `cperl-imenu--function-name-regexp-perl'
+;;; `cperl-outline-regexp', `defun-prompt-regexp'.
+;;; Details of groups in this may be used in several functions; see comments
+;;; near mentioned above variable(s)...
+;;; sub($$):lvalue{}  sub:lvalue{} Both allowed...
+(defsubst cperl-after-sub-regexp (named attr) ; 9 groups without attr...
+  "Match the text after `sub' in a subroutine declaration.
+If NAMED is nil, allows anonymous subroutines.  Matches up to the first \":\"
+of attributes (if present), or end of the name or prototype (whatever is
+the last)."
+  (concat				; Assume n groups before this...
+   "\\("				; n+1=name-group
+     cperl-white-and-comment-rex	; n+2=pre-name
+     "\\(::[a-zA-Z_0-9:']+\\|[a-zA-Z_'][a-zA-Z_0-9:']*\\)" ; n+3=name
+   "\\)"				; END n+1=name-group
+   (if named "" "?")
+   "\\("				; n+4=proto-group
+     cperl-maybe-white-and-comment-rex	; n+5=pre-proto
+     "\\(([^()]*)\\)"			; n+6=prototype
+   "\\)?"				; END n+4=proto-group
+   "\\("				; n+7=attr-group
+     cperl-maybe-white-and-comment-rex	; n+8=pre-attr
+     "\\("				; n+9=start-attr
+        ":"
+	(if attr (concat
+		  "\\("
+		     cperl-maybe-white-and-comment-rex ; whitespace-comments
+		     "\\(\\sw\\|_\\)+"	; attr-name
+		     ;; attr-arg (1 level of internal parens allowed!)
+		     "\\((\\(\\\\.\\|[^\\\\()]\\|([^\\\\()]*)\\)*)\\)?"
+		     "\\("		; optional : (XXX allows trailing???)
+		        cperl-maybe-white-and-comment-rex ; whitespace-comments
+		     ":\\)?"
+		  "\\)+")
+	  "[^:]")
+     "\\)"
+   "\\)?"				; END n+6=proto-group
+   ))
+
+;;; Details of groups in this are used in `cperl-imenu--create-perl-index'
+;;;  and `cperl-outline-level'.
+;;;; Was: 2=sub|package; now 2=package-group, 5=package-name 8=sub-name (+3)
 (defvar cperl-imenu--function-name-regexp-perl
   (concat
-   "^\\("
-	"[ \t]*\\(sub\\|package\\)[ \t\n]+\\([a-zA-Z_0-9:']+\\)[ \t]*\\(([^()]*)[ \t]*\\)?"
+   "^\\("				; 1 = all
+       "\\([ \t]*package"		; 2 = package-group
+          "\\("				; 3 = package-name-group
+	    cperl-white-and-comment-rex ; 4 = pre-package-name
+	       "\\([a-zA-Z_0-9:']+\\)\\)?\\)" ; 5 = package-name
+       "\\|"
+          "[ \t]*sub"
+	  (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
+	  cperl-maybe-white-and-comment-rex	; 15=pre-block
    "\\|"
-	"=head\\([12]\\)[ \t]+\\([^\n]+\\)$"
+     "=head\\([1-4]\\)[ \t]+"		; 16=level
+     "\\([^\n]+\\)$"			; 17=text
    "\\)"))
 
 (defvar cperl-outline-regexp
 (defvar cperl-string-syntax-table nil
   "Syntax table in use in CPerl mode string-like chunks.")
 
+(defsubst cperl-1- (p)
+  (max (point-min) (1- p)))
+
+(defsubst cperl-1+ (p)
+  (min (point-max) (1+ p)))
+
 (if cperl-mode-syntax-table
     ()
   (setq cperl-mode-syntax-table (make-syntax-table))
   (modify-syntax-entry ?| "." cperl-mode-syntax-table)
   (setq cperl-string-syntax-table (copy-syntax-table cperl-mode-syntax-table))
   (modify-syntax-entry ?$ "." cperl-string-syntax-table)
+  (modify-syntax-entry ?\{ "." cperl-string-syntax-table)
+  (modify-syntax-entry ?\} "." cperl-string-syntax-table)
   (modify-syntax-entry ?# "." cperl-string-syntax-table)) ; (?# comment )
 
 
       (funcall f 'cperl-font-lock-keywords-2 'perl-font-lock-keywords-2)))
 
 (defvar cperl-use-major-mode 'perl-mode)
+(defvar cperl-font-lock-multiline-start nil)
+(defvar cperl-font-lock-multiline nil)
+(defvar cperl-compilation-error-regexp-alist nil)
+(defvar cperl-font-locking nil)
 
 ;;;###autoload
 (defun cperl-mode ()
  `cperl-min-label-indent'
     Minimal indentation for line that is a label.
 
-Settings for K&R and BSD indentation styles are
-  `cperl-indent-level'                5    8
-  `cperl-continued-statement-offset'  5    8
-  `cperl-brace-offset'               -5   -8
-  `cperl-label-offset'               -5   -8
+Settings for classic indent-styles: K&R BSD=C++ GNU PerlStyle=Whitesmith
+  `cperl-indent-level'                5   4       2   4
+  `cperl-brace-offset'                0   0       0   0
+  `cperl-continued-brace-offset'     -5  -4       0   0
+  `cperl-label-offset'               -5  -4      -2  -4
+  `cperl-continued-statement-offset'  5   4       2   4
 
 CPerl knows several indentation styles, and may bulk set the
 corresponding variables.  Use \\[cperl-set-style] to do this.  Use
 \\[cperl-set-style-back] to restore the memorized preexisting values
-\(both available from menu).
+\(both available from menu).  See examples in `cperl-style-examples'.
+
+Part of the indentation style is how different parts of if/elsif/else
+statements are broken into lines; in CPerl, this is reflected on how
+templates for these constructs are created (controlled by
+`cperl-extra-newline-before-brace'), and how reflow-logic should treat \"continuation\" blocks of else/elsif/continue, controlled by the same variable,
+and by `cperl-extra-newline-before-brace-multiline',
+`cperl-merge-trailing-else', `cperl-indent-region-fix-constructs'.
 
 If `cperl-indent-level' is 0, the statement after opening brace in
 column 0 is indented on
 		("head2" "head2" cperl-electric-pod 0)))
 	(setq abbrevs-changed prev-a-c)))
   (setq local-abbrev-table cperl-mode-abbrev-table)
-  (abbrev-mode (if (cperl-val 'cperl-electric-keywords) 1 0))
+  (if (cperl-val 'cperl-electric-keywords)
+      (abbrev-mode 1))
   (set-syntax-table cperl-mode-syntax-table)
+  ;; Until Emacs is multi-threaded, we do not actually need it local:
+  (make-local-variable 'cperl-font-lock-multiline-start)
+  (make-local-variable 'cperl-font-locking)
   (make-local-variable 'outline-regexp)
   ;; (setq outline-regexp imenu-example--function-name-regexp-perl)
   (setq outline-regexp cperl-outline-regexp)
   (setq paragraph-separate paragraph-start)
   (make-local-variable 'paragraph-ignore-fill-prefix)
   (setq paragraph-ignore-fill-prefix t)
-  ;; XEmacs addition
-  (when cperl-xemacs-p
-    (make-local-variable 'paren-backwards-message)
-    (setq paren-backwards-message t))
+  (if cperl-xemacs-p
+    (progn
+      (make-local-variable 'paren-backwards-message)
+      (set 'paren-backwards-message t)))
   (make-local-variable 'indent-line-function)
   (setq indent-line-function 'cperl-indent-line)
   (make-local-variable 'require-final-newline)
   (make-local-variable 'comment-start-skip)
   (setq comment-start-skip "#+ *")
   (make-local-variable 'defun-prompt-regexp)
-  (setq defun-prompt-regexp "^[ \t]*sub[ \t]+\\([^ \t\n{(;]+\\)\\([ \t]*([^()]*)[ \t]*\\)?[ \t]*")
+;;;       "[ \t]*sub"
+;;;	  (cperl-after-sub-regexp 'named nil) ; 8=name 11=proto 14=attr-start
+;;;	  cperl-maybe-white-and-comment-rex	; 15=pre-block
+  (setq defun-prompt-regexp
+	(concat "[ \t]*\\(sub"
+		(cperl-after-sub-regexp 'named 'attr-groups)
+		"\\|"			; per toke.c
+		"\\(BEGIN\\|CHECK\\|INIT\\|END\\|AUTOLOAD\\|DESTROY\\)"
+		"\\)"
+		cperl-maybe-white-and-comment-rex))
   (make-local-variable 'comment-indent-function)
   (setq comment-indent-function 'cperl-comment-indent)
+  (and (boundp 'fill-paragraph-function)
+      (progn
+	(make-local-variable 'fill-paragraph-function)
+	(set 'fill-paragraph-function 'cperl-fill-paragraph)))
   (make-local-variable 'parse-sexp-ignore-comments)
   (setq parse-sexp-ignore-comments t)
   (make-local-variable 'indent-region-function)
 	(function cperl-imenu--create-perl-index))
   (make-local-variable 'imenu-sort-function)
   (setq imenu-sort-function nil)
+  (make-local-variable 'vc-rcs-header)
+  (set 'vc-rcs-header cperl-vc-rcs-header)
+  (make-local-variable 'vc-sccs-header)
+  (set 'vc-sccs-header cperl-vc-sccs-header)
+  ;; This one is obsolete...
   (make-local-variable 'vc-header-alist)
-  (set 'vc-header-alist cperl-vc-header-alist) ; Avoid warning
+  (set 'vc-header-alist (or cperl-vc-header-alist ; Avoid warning
+			    (` ((SCCS (, (car cperl-vc-sccs-header)))
+				     (RCS (, (car cperl-vc-rcs-header)))))))
+  (cond ((boundp 'compilation-error-regexp-alist-alist);; xemacs 20.x
+	 (make-local-variable 'compilation-error-regexp-alist-alist)
+	 (set 'compilation-error-regexp-alist-alist
+	      (cons (cons 'cperl cperl-compilation-error-regexp-alist)
+		    (symbol-value 'compilation-error-regexp-alist-alist)))
+	 (let ((f 'compilation-build-compilation-error-regexp-alist))
+	   (funcall f)))
+	((boundp 'compilation-error-regexp-alist);; xmeacs 19.x
+	 (make-local-variable 'compilation-error-regexp-alist)
+	 (set 'compilation-error-regexp-alist
+	       (cons cperl-compilation-error-regexp-alist
+		     (symbol-value 'compilation-error-regexp-alist)))))
   (make-local-variable 'font-lock-defaults)
   (setq	font-lock-defaults
 	(cond
 	 ((string< emacs-version "19.30")
-	  '(perl-font-lock-keywords-2))
+	  '(perl-font-lock-keywords-2 nil nil ((?_ . "w"))))
 	 ((string< emacs-version "19.33") ; Which one to use?
 	  '((perl-font-lock-keywords
 	     perl-font-lock-keywords-1
-	     perl-font-lock-keywords-2)))
+	     perl-font-lock-keywords-2) nil nil ((?_ . "w"))))
 	 (t
 	  '((cperl-load-font-lock-keywords
 	     cperl-load-font-lock-keywords-1
-	     cperl-load-font-lock-keywords-2)))))
+	     cperl-load-font-lock-keywords-2) nil nil ((?_ . "w"))))))
   (make-local-variable 'cperl-syntax-state)
+  (setq cperl-syntax-state nil)		; reset syntaxification cache
   (if cperl-use-syntax-table-text-property
       (progn
 	(make-local-variable 'parse-sexp-lookup-properties)
 	(or (boundp 'font-lock-unfontify-region-function)
 	    (set 'font-lock-unfontify-region-function
 		 'font-lock-default-unfontify-region))
-        ;; XEmacs change: no unfontify stuff
-	(unless cperl-xemacs-p
+	(unless cperl-xemacs-p		; Our: just a plug for wrong font-lock
 	  (make-local-variable 'font-lock-unfontify-region-function)
-	  (set 'font-lock-unfontify-region-function ;not present with old Emacs
+	  (set 'font-lock-unfontify-region-function ; not present with old Emacs
 	       'cperl-font-lock-unfontify-region-function))
 	(make-local-variable 'cperl-syntax-done-to)
+	(setq cperl-syntax-done-to nil)	; reset syntaxification cache
 	;; Another bug: unless font-lock-syntactic-keywords, font-lock
 	;;  ignores syntax-table text-property.  (t) is a hack
 	;;  to make font-lock think that font-lock-syntactic-keywords
 	      (if cperl-syntaxify-by-font-lock
 		  '(t (cperl-fontify-syntaxically))
 		'(t)))))
+  (if (boundp 'font-lock-multiline)	; Newer font-lock; use its facilities
+      (progn
+	(setq cperl-font-lock-multiline t) ; Not localized...
+	(set (make-local-variable 'font-lock-multiline) t))
+    (make-local-variable 'font-lock-fontify-region-function)
+    (set 'font-lock-fontify-region-function ; not present with old Emacs
+	 'cperl-font-lock-fontify-region-function))
+  (make-local-variable 'font-lock-fontify-region-function)
+  (set 'font-lock-fontify-region-function ; not present with old Emacs
+       'cperl-font-lock-fontify-region-function)
   (make-local-variable 'cperl-old-style)
-  ;; XEmacs addition: set fill-paragraph-function.  Note that older versions
-  ;; of our fill.el don't buffer-localize it.
-  (make-local-variable 'fill-paragraph-function)
-  (setq fill-paragraph-function 'cperl-fill-paragraph)
   (if (boundp 'normal-auto-fill-function) ; 19.33 and later
       (set (make-local-variable 'normal-auto-fill-function)
 	   'cperl-do-auto-fill)	      ; RMS has it as #'cperl-do-auto-fill ???
       (if (cperl-val 'cperl-font-lock)
 	  (progn (or cperl-faces-init (cperl-init-faces))
 		 (font-lock-mode 1))))
+  (set (make-local-variable 'facemenu-add-face-function)
+       'cperl-facemenu-add-face-function) ; XXXX What this guy is for???
   (and (boundp 'msb-menu-cond)
        (not cperl-msb-fixed)
        (cperl-msb-fix))
   (if (featurep 'easymenu)
-      (easy-menu-add cperl-menu))	; A NOP in Emacs.
+      (easy-menu-add cperl-menu))	; A NOP in RMS Emacs.
   (run-hooks 'cperl-mode-hook)
+  (if cperl-hook-after-change
+      (progn
+	(make-local-hook 'after-change-functions)
+	(add-hook 'after-change-functions 'cperl-after-change-function nil t)))
   ;; After hooks since fontification will break this
   (if cperl-pod-here-scan
       (or cperl-syntaxify-by-font-lock
 (defvar cperl-st-ket '(5 . ?\<))
 
 
-(defun cperl-comment-indent ()
+(defun cperl-comment-indent ()		; called at point at supposed comment
   (let ((p (point)) (c (current-column)) was phony)
-    (if (looking-at "^#") 0		; Existing comment at bol stays there.
+    (if (and (not cperl-indent-comment-at-column-0)
+	     (looking-at "^#"))
+	0	; Existing comment at bol stays there.
       ;; Wrong comment found
       (save-excursion
 	(setq was (cperl-to-comment-or-eol)
 	      phony (eq (get-text-property (point) 'syntax-table)
 			cperl-st-cfence))
 	(if phony
-	    (progn
+	    (progn			; Too naive???
 	      (re-search-forward "#\\|$") ; Hmm, what about embedded #?
 	      (if (eq (preceding-char) ?\#)
 		  (forward-char -1))
 	      (setq was nil)))
-	(if (= (point) p)
+	(if (= (point) p)		; Our caller found a correct place
 	    (progn
 	      (skip-chars-backward " \t")
-	      (max (1+ (current-column)) ; Else indent at comment column
-		   comment-column))
+	      (setq was (current-column))
+	      (if (eq was 0)
+		  comment-column
+		(max (1+ was) ; Else indent at comment column
+		     comment-column)))
+	  ;; No, the caller found a random place; we need to edit ourselves
 	  (if was nil
 	    (insert comment-start)
 	    (backward-char (length comment-start)))
 	  (setq cperl-wrong-comment t)
-	  (indent-to comment-column 1)	; Indent minimum 1
-	  c)))))			; except leave at least one space.
+	  (cperl-make-indent comment-column 1) ; Indent min 1
+	  c)))))
 
 ;;;(defun cperl-comment-indent-fallback ()
 ;;;  "Is called if the standard comment-search procedure fails.
   (interactive)
   (let (cperl-wrong-comment)
     (indent-for-comment)
-    (if cperl-wrong-comment
+    (if cperl-wrong-comment		; set by `cperl-comment-indent'
 	(progn (cperl-to-comment-or-eol)
 	       (forward-char (length comment-start))))))
 
 				   (not (eq (get-text-property (point)
 							       'syntax-type)
 					    'pod))))))
-	 (save-excursion (forward-sexp -1) 
+	 (save-excursion (forward-sexp -1)
 			 (not (memq (following-char) (append "$@%&*" nil))))
 	 (progn
 	   (and (eq (preceding-char) ?y)
 	    (or
 	     (get-text-property (point) 'in-pod)
 	     (cperl-after-expr-p nil "{;:")
-	     (and (re-search-backward
-		   ;; "\\(\\`\n?\\|\n\n\\)=\\sw+"
-		   "\\(\\`\n?\\|^\n\\)=\\sw+"
-		   (point-min) t)
-		  (not (or
-			(looking-at "=cut")
-			(and cperl-use-syntax-table-text-property
-			     (not (eq (get-text-property (point) 'syntax-type)
-				      'pod)))))))))
+	     (and (re-search-backward "\\(\\`\n?\\|^\n\\)=\\sw+" (point-min) t)
+		  (not (looking-at "\n*=cut"))
+		  (or (not cperl-use-syntax-table-text-property)
+		      (eq (get-text-property (point) 'syntax-type) 'pod))))))
 	 (progn
 	   (save-excursion
 	     (setq notlast (re-search-forward "^\n=" nil t)))
 	(backward-or-forward-delete-char arg)
       (backward-delete-char-untabify arg))))
 
-(defun cperl-inside-parens-p ()
+(defun cperl-inside-parens-p ()		;; NOT USED????
   (condition-case ()
       (save-excursion
 	(save-restriction
 	  (t
 	   (skip-chars-forward " \t")
 	   (if (listp indent) (setq indent (car indent)))
-	   (cond ((looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]")
+	   (cond ((and (looking-at "[A-Za-z_][A-Za-z_0-9]*:[^:]")
+		       (not (looking-at "[smy]:\\|tr:")))
 		  (and (> indent 0)
 		       (setq indent (max cperl-min-label-indent
 					 (+ indent cperl-label-offset)))))
 	    (zerop shift-amt))
 	(if (> (- (point-max) pos) (point))
 	    (goto-char (- (point-max) pos)))
-      (delete-region beg (point))
-      (indent-to indent)
+      ;;;(delete-region beg (point))
+      ;;;(indent-to indent)
+      (cperl-make-indent indent)
       ;; If initial point was within line's indentation,
       ;; position after the indentation.  Else stay at same point in text.
       (if (> (- (point-max) pos) (point))
       (or state (setq state (parse-partial-sexp start start-point -1 nil start-state)))
       (list start state depth prestart))))
 
-(defun cperl-block-p ()		   ; Do not C-M-q !  One string contains ";" !
-  ;; Positions is before ?\{.  Checks whether it starts a block.
-  ;; No save-excursion!
-  (cperl-backward-to-noncomment (point-min))
-  (or (memq (preceding-char) (append ";){}$@&%\C-@" nil)) ; Or label!  \C-@ at bobp
-					; Label may be mixed up with `$blah :'
-      (save-excursion (cperl-after-label))
-      (and (memq (char-syntax (preceding-char)) '(?w ?_))
-	   (progn
-	     (backward-sexp)
-	     ;; Need take into account `bless', `return', `tr',...
-	     (or (and (looking-at "[a-zA-Z0-9_:]+[ \t\n\f]*[{#]") ; Method call syntax
-		      (not (looking-at "\\(bless\\|return\\|q[wqrx]?\\|tr\\|[smy]\\)\\>")))
-		 (progn
-		   (skip-chars-backward " \t\n\f")
-		   (and (memq (char-syntax (preceding-char)) '(?w ?_))
-			(progn
-			  (backward-sexp)
-			  (looking-at
-			   "sub[ \t]+[a-zA-Z0-9_:]+[ \t\n\f]*\\(([^()]*)[ \t\n\f]*\\)?[#{]")))))))))
-
 (defvar cperl-look-for-prop '((pod in-pod) (here-doc-delim here-doc-group)))
 
-(defun cperl-calculate-indent (&optional parse-data) ; was parse-start
-  "Return appropriate indentation for current line as Perl code.
-In usual case returns an integer: the column to indent to.
-Returns nil if line starts inside a string, t if in a comment.
-
-Will not correct the indentation for labels, but will correct it for braces
-and closing parentheses and brackets."
+(defun cperl-beginning-of-property (p prop &optional lim)
+  "Given that P has a property PROP, find where the property starts.
+Will not look before LIM."
+  ;;; XXXX What to do at point-max???
+  (or (previous-single-property-change (cperl-1+ p) prop lim)
+      (point-min))
+;;;  (cond ((eq p (point-min))
+;;;	 p)
+;;;	((and lim (<= p lim))
+;;;	 p)
+;;;	((not (get-text-property (1- p) prop))
+;;;	 p)
+;;;	(t (or (previous-single-property-change p look-prop lim)
+;;;	       (point-min))))
+  )
+
+(defun cperl-sniff-for-indent (&optional parse-data) ; was parse-start
+  ;; Old workhorse for calculation of indentation; the major problem
+  ;; is that it mixes the sniffer logic to understand what the current line
+  ;; MEANS with the logic to actually calculate where to indent it.
+  ;; The latter part should be eventually moved to `cperl-calculate-indent';
+  ;; actually, this is mostly done now...
   (cperl-update-syntaxification (point) (point))
-  (save-excursion
-    (if (or
-	 (and (memq (get-text-property (point) 'syntax-type)
-		    '(pod here-doc here-doc-delim format))
-	      (not (get-text-property (point) 'indentable)))
-	 ;; before start of POD - whitespace found since do not have 'pod!
-	 (and (looking-at "[ \t]*\n=")
-	      (error "Spaces before POD section!"))
-	 (and (not cperl-indent-left-aligned-comments)
-	      (looking-at "^#")))
-	nil
-      (beginning-of-line)
-      (let ((indent-point (point))
-	    (char-after (save-excursion
-			  (skip-chars-forward " \t")
-			  (following-char)))
-	    (in-pod (get-text-property (point) 'in-pod))
-	    (pre-indent-point (point))
-	    p prop look-prop is-block delim)
-	(cond
-	 (in-pod
-	  ;; In the verbatim part, probably code example.  What to do???
-	  )
-	 (t
-	  (save-excursion
-	    ;; Not in POD
+  (let ((res (get-text-property (point) 'syntax-type)))
+    (save-excursion
+      (cond
+       ((and (memq res '(pod here-doc here-doc-delim format))
+	     (not (get-text-property (point) 'indentable)))
+	(vector res))
+       ;; before start of POD - whitespace found since do not have 'pod!
+       ((looking-at "[ \t]*\n=")
+	(error "Spaces before POD section!"))
+       ((and (not cperl-indent-left-aligned-comments)
+	     (looking-at "^#"))
+	[comment-special:at-beginning-of-line])
+       ((get-text-property (point) 'in-pod)
+	[in-pod])
+       (t
+	(beginning-of-line)
+	(let* ((indent-point (point))
+	       (char-after-pos (save-excursion
+				 (skip-chars-forward " \t")
+				 (point)))
+	       (char-after (char-after char-after-pos))
+	       (pre-indent-point (point))
+	       p prop look-prop is-block delim)
+	  (save-excursion		; Know we are not in POD, find appropriate pos before
 	    (cperl-backward-to-noncomment nil)
 	    (setq p (max (point-min) (1- (point)))
 		  prop (get-text-property p 'syntax-type)
 				'syntax-type))
 	    (if (memq prop '(pod here-doc format here-doc-delim))
 		(progn
-		  (goto-char (or (previous-single-property-change p look-prop)
-				 (point-min)))
+		  (goto-char (cperl-beginning-of-property p look-prop))
 		  (beginning-of-line)
-		  (setq pre-indent-point (point)))))))
-	(goto-char pre-indent-point)
-	(let* ((case-fold-search nil)
-	       (s-s (cperl-get-state (car parse-data) (nth 1 parse-data)))
-	       (start (or (nth 2 parse-data)
-			  (nth 0 s-s)))
-	       (state (nth 1 s-s))
-	       (containing-sexp (car (cdr state)))
-	       old-indent)
-	  (if (and
-	       ;;containing-sexp		;; We are buggy at toplevel :-(
-	       parse-data)
-	      (progn
-		(setcar parse-data pre-indent-point)
-		(setcar (cdr parse-data) state)
-		(or (nth 2 parse-data)
-		    (setcar (cddr parse-data) start))
-		;; Before this point: end of statement
-		(setq old-indent (nth 3 parse-data))))
-	  (cond ((get-text-property (point) 'indentable)
-		 ;; indent to just after the surrounding open,
-		 ;; skip blanks if we do not close the expression.
-		 (goto-char (1+ (previous-single-property-change (point) 'indentable)))
-		 (or (memq char-after (append ")]}" nil))
-		     (looking-at "[ \t]*\\(#\\|$\\)")
-		     (skip-chars-forward " \t"))
-		 (current-column))
-		((or (nth 3 state) (nth 4 state))
-		 ;; return nil or t if should not change this line
-		 (nth 4 state))
-		;; XXXX Do we need to special-case this?
-		((null containing-sexp)
-		 ;; Line is at top level.  May be data or function definition,
-		 ;; or may be function argument declaration.
-		 ;; Indent like the previous top level line
-		 ;; unless that ends in a closeparen without semicolon,
-		 ;; in which case this line is the first argument decl.
-		 (skip-chars-forward " \t")
-		 (+ (save-excursion
-		      (goto-char start)
-		      (- (current-indentation)
-			 (if (nth 2 s-s) cperl-indent-level 0)))
-		    (if (= char-after ?{) cperl-continued-brace-offset 0)
-		    (progn
-		      (cperl-backward-to-noncomment (or old-indent (point-min)))
-		      ;; Look at previous line that's at column 0
-		      ;; to determine whether we are in top-level decls
-		      ;; or function's arg decls.  Set basic-indent accordingly.
-		      ;; Now add a little if this is a continuation line.
-		      (if (or (bobp)
-			      (eq (point) old-indent) ; old-indent was at comment
-			      (eq (preceding-char) ?\;)
-			      ;;  Had ?\) too
-			      (and (eq (preceding-char) ?\})
-				   (cperl-after-block-and-statement-beg
-				    (point-min))) ; Was start - too close
-			      (memq char-after (append ")]}" nil))
-			      (and (eq (preceding-char) ?\:) ; label
-				   (progn
-				     (forward-sexp -1)
-				     (skip-chars-backward " \t")
-				     (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:")))
-			      (get-text-property (point) 'first-format-line))
-			  (progn
-			    (if (and parse-data
-				     (not (eq char-after ?\C-j)))
-				(setcdr (cddr parse-data)
-					(list pre-indent-point)))
-			    0)
-			cperl-continued-statement-offset))))
-		((not
-		  (or (setq is-block
-			    (and (setq delim (= (char-after containing-sexp) ?{))
-				 (save-excursion ; Is it a hash?
-				   (goto-char containing-sexp)
-				   (cperl-block-p))))
-		      cperl-indent-parens-as-block))
-		 ;; group is an expression, not a block:
-		 ;; indent to just after the surrounding open parens,
-		 ;; skip blanks if we do not close the expression.
-		 (goto-char (1+ containing-sexp))
-		 (or (memq char-after
-			   (append (if delim "}" ")]}") nil))
-		     (looking-at "[ \t]*\\(#\\|$\\)")
-		     (skip-chars-forward " \t"))
-		 (+ (current-column)
-		    (if (and delim
-			     (eq char-after ?\}))
-			;; Correct indentation of trailing ?\}
-			(+ cperl-indent-level cperl-close-paren-offset)
-		      0)))
-;;;	      ((and (/= (char-after containing-sexp) ?{)
-;;;		    (not cperl-indent-parens-as-block))
-;;;	       ;; line is expression, not statement:
-;;;	       ;; indent to just after the surrounding open,
-;;;	       ;; skip blanks if we do not close the expression.
-;;;	       (goto-char (1+ containing-sexp))
-;;;	       (or (memq char-after (append ")]}" nil))
-;;;		   (looking-at "[ \t]*\\(#\\|$\\)")
-;;;		   (skip-chars-forward " \t"))
-;;;	       (current-column))
-;;;	      ((progn
-;;;		 ;; Containing-expr starts with \{.  Check whether it is a hash.
-;;;		 (goto-char containing-sexp)
-;;;		 (and (not (cperl-block-p))
-;;;		      (not cperl-indent-parens-as-block)))
-;;;	       (goto-char (1+ containing-sexp))
-;;;	       (or (eq char-after ?\})
-;;;		   (looking-at "[ \t]*\\(#\\|$\\)")
-;;;		   (skip-chars-forward " \t"))
-;;;	       (+ (current-column)	; Correct indentation of trailing ?\}
-;;;		  (if (eq char-after ?\}) (+ cperl-indent-level
-;;;					     cperl-close-paren-offset)
-;;;		    0)))
-		(t
-		 ;; Statement level.  Is it a continuation or a new statement?
-		 ;; Find previous non-comment character.
-		 (goto-char pre-indent-point)
-		 (cperl-backward-to-noncomment containing-sexp)
-		 ;; Back up over label lines, since they don't
-		 ;; affect whether our line is a continuation.
-		 ;; (Had \, too)
-		 (while	;;(or (eq (preceding-char) ?\,)
-		     (and (eq (preceding-char) ?:)
-			  (or ;;(eq (char-after (- (point) 2)) ?\') ; ????
-			   (memq (char-syntax (char-after (- (point) 2)))
-				 '(?w ?_))))
-		   ;;)
-		   (if (eq (preceding-char) ?\,)
-		       ;; Will go to beginning of line, essentially.
-		       ;; Will ignore embedded sexpr XXXX.
-		       (cperl-backward-to-start-of-continued-exp containing-sexp))
-		   (beginning-of-line)
-		   (cperl-backward-to-noncomment containing-sexp))
-		 ;; Now we get the answer.
-		 (if (not (or (eq (1- (point)) containing-sexp)
-			      (memq (preceding-char)
-				    (append (if is-block " ;{" " ,;{") '(nil)))
-			      (and (eq (preceding-char) ?\})
-				   (cperl-after-block-and-statement-beg
-				    containing-sexp))
-			      (get-text-property (point) 'first-format-line)))
-		     ;; This line is continuation of preceding line's statement;
-		     ;; indent  `cperl-continued-statement-offset'  more than the
-		     ;; previous line of the statement.
-		     ;;
-		     ;; There might be a label on this line, just
-		     ;; consider it bad style and ignore it.
-		     (progn
-		       (cperl-backward-to-start-of-continued-exp containing-sexp)
-		       (+ (if (memq char-after (append "}])" nil))
-			      0		; Closing parenth
-			    cperl-continued-statement-offset)
-			  (if (or is-block
-				  (not delim)
-				  (not (eq char-after ?\})))
-			      0
-			    ;; Now it is a hash reference
-			    (+ cperl-indent-level cperl-close-paren-offset))
-			  (if (looking-at "\\w+[ \t]*:")
-			      (if (> (current-indentation) cperl-min-label-indent)
-				  (- (current-indentation) cperl-label-offset)
-				;; Do not move `parse-data', this should
-				;; be quick anyway (this comment comes
-				;; from different location):
-				(cperl-calculate-indent))
-			    (current-column))
-			  (if (eq char-after ?\{)
-			      cperl-continued-brace-offset 0)))
-		   ;; This line starts a new statement.
-		   ;; Position following last unclosed open.
-		   (goto-char containing-sexp)
-		   ;; Is line first statement after an open-brace?
-		   (or
-		    ;; If no, find that first statement and indent like
-		    ;; it.  If the first statement begins with label, do
-		    ;; not believe when the indentation of the label is too
-		    ;; small.
-		    (save-excursion
-		      (forward-char 1)
-		      (setq old-indent (current-indentation))
-		      (let ((colon-line-end 0))
-			(while
-			    (progn (skip-chars-forward " \t\n")
-				   (looking-at "#\\|[a-zA-Z0-9_$]*:[^:]\\|=[a-zA-Z]"))
-			  ;; Skip over comments and labels following openbrace.
-			  (cond ((= (following-char) ?\#)
-				 (forward-line 1))
-				((= (following-char) ?\=)
-				 (goto-char
-				  (or (next-single-property-change (point) 'in-pod)
-				      (point-max)))) ; do not loop if no syntaxification
-				;; label:
-				(t
-				 (save-excursion (end-of-line)
-						 (setq colon-line-end (point)))
-				 (search-forward ":"))))
-			;; The first following code counts
-			;; if it is before the line we want to indent.
-			(and (< (point) indent-point)
-			     (if (> colon-line-end (point)) ; After label
-				 (if (> (current-indentation)
-					cperl-min-label-indent)
-				     (- (current-indentation) cperl-label-offset)
-				   ;; Do not believe: `max' is involved
-				   (+ old-indent cperl-indent-level))
-			       (current-column)))))
-		    ;; If no previous statement,
-		    ;; indent it relative to line brace is on.
-		    ;; For open brace in column zero, don't let statement
-		    ;; start there too.  If cperl-indent-level is zero,
-		    ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
-		    ;; For open-braces not the first thing in a line,
-		    ;; add in cperl-brace-imaginary-offset.
-
-		    ;; If first thing on a line:  ?????
-		    (+ (if (and (bolp) (zerop cperl-indent-level))
-			   (+ cperl-brace-offset cperl-continued-statement-offset)
-			 cperl-indent-level)
-		       (if (or is-block
-			       (not delim)
-			       (not (eq char-after ?\})))
-			   0
-			 ;; Now it is a hash reference
-			 (+ cperl-indent-level cperl-close-paren-offset))
-		       ;; Move back over whitespace before the openbrace.
-		       ;; If openbrace is not first nonwhite thing on the line,
-		       ;; add the cperl-brace-imaginary-offset.
-		       (progn (skip-chars-backward " \t")
-			      (if (bolp) 0 cperl-brace-imaginary-offset))
-		       ;; If the openbrace is preceded by a parenthesized exp,
-		       ;; move to the beginning of that;
-		       ;; possibly a different line
-		       (progn
-			 (if (eq (preceding-char) ?\))
-			     (forward-sexp -1))
-			 ;; In the case it starts a subroutine, indent with
-			 ;; respect to `sub', not with respect to the
-			 ;; first thing on the line, say in the case of
-			 ;; anonymous sub in a hash.
-			 ;;
-			 (skip-chars-backward " \t")
-			 (if (and (eq (preceding-char) ?b)
+		  (setq pre-indent-point (point)))))
+	  (goto-char pre-indent-point)	; Orig line skipping preceeding pod/etc
+	  (let* ((case-fold-search nil)
+		 (s-s (cperl-get-state (car parse-data) (nth 1 parse-data)))
+		 (start (or (nth 2 parse-data) ; last complete sexp terminated
+			    (nth 0 s-s))) ; Good place to start parsing
+		 (state (nth 1 s-s))
+		 (containing-sexp (car (cdr state)))
+		 old-indent)
+	    (if (and
+		 ;;containing-sexp		;; We are buggy at toplevel :-(
+		 parse-data)
+		(progn
+		  (setcar parse-data pre-indent-point)
+		  (setcar (cdr parse-data) state)
+		  (or (nth 2 parse-data)
+		      (setcar (cddr parse-data) start))
+		  ;; Before this point: end of statement
+		  (setq old-indent (nth 3 parse-data))))
+	    (cond ((get-text-property (point) 'indentable)
+		   ;; indent to "after" the surrounding open
+		   ;; (same offset as `cperl-beautify-regexp-piece'),
+		   ;; skip blanks if we do not close the expression.
+		   (setq delim		; We do not close the expression
+			 (get-text-property
+			  (cperl-1+ char-after-pos) 'indentable)
+			 p (1+ (cperl-beginning-of-property
+				(point) 'indentable))
+			 is-block	; misused for: preceeding line in REx
+			 (save-excursion ; Find preceeding line
+			   (cperl-backward-to-noncomment p)
+			   (beginning-of-line)
+			   (if (<= (point) p)
+			       (progn	; get indent from the first line
+				 (goto-char p)
+				 (skip-chars-forward " \t")
+				 (if (memq (char-after (point))
+					   (append "#\n" nil))
+				     nil ; Can't use intentation of this line...
+				   (point)))
+			     (skip-chars-forward " \t")
+			     (point)))
+			 prop (parse-partial-sexp p char-after-pos))
+		   (cond ((not delim)	; End the REx, ignore is-block
+			  (vector 'indentable 'terminator p is-block))
+			 (is-block	; Indent w.r.t. preceeding line
+			  (vector 'indentable 'cont-line char-after-pos
+				  is-block char-after p))
+			 (t		; No preceeding line...
+			  (vector 'indentable 'first-line p))))
+		  ((get-text-property char-after-pos 'REx-part2)
+		   (vector 'REx-part2 (point)))
+		  ((nth 4 state)
+		   [comment])
+		  ((nth 3 state)
+		   [string])
+		  ;; XXXX Do we need to special-case this?
+		  ((null containing-sexp)
+		   ;; Line is at top level.  May be data or function definition,
+		   ;; or may be function argument declaration.
+		   ;; Indent like the previous top level line
+		   ;; unless that ends in a closeparen without semicolon,
+		   ;; in which case this line is the first argument decl.
+		   (skip-chars-forward " \t")
+		   (cperl-backward-to-noncomment (or old-indent (point-min)))
+		   (setq state
+			 (or (bobp)
+			     (eq (point) old-indent) ; old-indent was at comment
+			     (eq (preceding-char) ?\;)
+			     ;;  Had ?\) too
+			     (and (eq (preceding-char) ?\})
+				  (cperl-after-block-and-statement-beg
+				   (point-min))) ; Was start - too close
+			     (memq char-after (append ")]}" nil))
+			     (and (eq (preceding-char) ?\:) ; label
 				  (progn
 				    (forward-sexp -1)
-				    (looking-at "sub\\>"))
-				  (setq old-indent
-					(nth 1
-					     (parse-partial-sexp
-					      (save-excursion (beginning-of-line) (point))
-					      (point)))))
-			     (progn (goto-char (1+ old-indent))
-				    (skip-chars-forward " \t")
-				    (current-column))
-			   ;; Get initial indentation of the line we are on.
-			   ;; If line starts with label, calculate label indentation
-			   (if (save-excursion
-				 (beginning-of-line)
-				 (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
-			       (if (> (current-indentation) cperl-min-label-indent)
-				   (- (current-indentation) cperl-label-offset)
-				 ;; Do not move `parse-data', this should
-				 ;; be quick anyway:
-				 (cperl-calculate-indent))
-			     (current-indentation))))))))))))))
-
-(defvar cperl-indent-alist
-  '((string nil)
-    (comment nil)
-    (toplevel 0)
-    (toplevel-after-parenth 2)
-    (toplevel-continued 2)
-    (expression 1))
+				    (skip-chars-backward " \t")
+				    (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*[ \t]*:")))
+			     (get-text-property (point) 'first-format-line)))
+		   
+		   ;; Look at previous line that's at column 0
+		   ;; to determine whether we are in top-level decls
+		   ;; or function's arg decls.  Set basic-indent accordingly.
+		   ;; Now add a little if this is a continuation line.
+		   (and state
+			parse-data
+			(not (eq char-after ?\C-j))
+			(setcdr (cddr parse-data)
+				(list pre-indent-point)))
+		   (vector 'toplevel start char-after state (nth 2 s-s)))
+		  ((not
+		    (or (setq is-block
+			      (and (setq delim (= (char-after containing-sexp) ?{))
+				   (save-excursion ; Is it a hash?
+				     (goto-char containing-sexp)
+				     (cperl-block-p))))
+			cperl-indent-parens-as-block))
+		   ;; group is an expression, not a block:
+		   ;; indent to just after the surrounding open parens,
+		   ;; skip blanks if we do not close the expression.
+		   (goto-char (1+ containing-sexp))
+		   (or (memq char-after
+			     (append (if delim "}" ")]}") nil))
+		       (looking-at "[ \t]*\\(#\\|$\\)")
+		       (skip-chars-forward " \t"))
+		   (setq old-indent (point)) ; delim=is-brace
+		   (vector 'in-parens char-after (point) delim containing-sexp))
+		  (t
+		   ;; Statement level.  Is it a continuation or a new statement?
+		   ;; Find previous non-comment character.
+		   (goto-char pre-indent-point) ; Skip one level of POD/etc
+		   (cperl-backward-to-noncomment containing-sexp)
+		   ;; Back up over label lines, since they don't
+		   ;; affect whether our line is a continuation.
+		   ;; (Had \, too)
+		   (while;;(or (eq (preceding-char) ?\,)
+		       (and (eq (preceding-char) ?:)
+			    (or;;(eq (char-after (- (point) 2)) ?\') ; ????
+			     (memq (char-syntax (char-after (- (point) 2)))
+				   '(?w ?_))))
+		     ;;)
+		     ;; This is always FALSE?
+		     (if (eq (preceding-char) ?\,)
+			 ;; Will go to beginning of line, essentially.
+			 ;; Will ignore embedded sexpr XXXX.
+			 (cperl-backward-to-start-of-continued-exp containing-sexp))
+		     (beginning-of-line)
+		     (cperl-backward-to-noncomment containing-sexp))
+		   ;; Now we get non-label preceeding the indent point
+		   (if (not (or (eq (1- (point)) containing-sexp)
+				(memq (preceding-char)
+				      (append (if is-block " ;{" " ,;{") '(nil)))
+				(and (eq (preceding-char) ?\})
+				     (cperl-after-block-and-statement-beg
+				      containing-sexp))
+				(get-text-property (point) 'first-format-line)))
+		       ;; This line is continuation of preceding line's statement;
+		       ;; indent  `cperl-continued-statement-offset'  more than the
+		       ;; previous line of the statement.
+		       ;;
+		       ;; There might be a label on this line, just
+		       ;; consider it bad style and ignore it.
+		       (progn
+			 (cperl-backward-to-start-of-continued-exp containing-sexp)
+			 (vector 'continuation (point) char-after is-block delim))
+		     ;; This line starts a new statement.
+		     ;; Position following last unclosed open brace
+		     (goto-char containing-sexp)
+		     ;; Is line first statement after an open-brace?
+		     (or
+		      ;; If no, find that first statement and indent like
+		      ;; it.  If the first statement begins with label, do
+		      ;; not believe when the indentation of the label is too
+		      ;; small.
+		      (save-excursion
+			(forward-char 1)
+			(let ((colon-line-end 0))
+			  (while
+			      (progn (skip-chars-forward " \t\n")
+				     ;; s: foo : bar :x is NOT label
+				     (and (looking-at "#\\|\\([a-zA-Z0-9_$]+\\):[^:]\\|=[a-zA-Z]")
+					  (not (looking-at "[sym]:\\|tr:"))))
+			    ;; Skip over comments and labels following openbrace.
+			    (cond ((= (following-char) ?\#)
+				   (forward-line 1))
+				  ((= (following-char) ?\=)
+				   (goto-char
+				    (or (next-single-property-change (point) 'in-pod)
+					(point-max)))) ; do not loop if no syntaxification
+				  ;; label:
+				  (t
+				   (save-excursion (end-of-line)
+						   (setq colon-line-end (point)))
+				   (search-forward ":"))))
+			  ;; We are at beginning of code (NOT label or comment)
+			  ;; First, the following code counts
+			  ;; if it is before the line we want to indent.
+			  (and (< (point) indent-point)
+			       (vector 'have-prev-sibling (point) colon-line-end
+				       containing-sexp))))
+		      (progn
+			;; If no previous statement,
+			;; indent it relative to line brace is on.
+
+			;; For open-braces not the first thing in a line,
+			;; add in cperl-brace-imaginary-offset.
+
+			;; If first thing on a line:  ?????
+			;; Move back over whitespace before the openbrace.
+			(setq		; brace first thing on a line
+			 old-indent (progn (skip-chars-backward " \t") (bolp)))
+			;; Should we indent w.r.t. earlier than start?
+			;; Move to start of control group, possibly on a different line
+			(or cperl-indent-wrt-brace
+			    (cperl-backward-to-noncomment (point-min)))
+			;; If the openbrace is preceded by a parenthesized exp,
+			;; move to the beginning of that;
+			(if (eq (preceding-char) ?\))
+			    (progn
+			      (forward-sexp -1)
+			      (cperl-backward-to-noncomment (point-min))))
+			;; In the case it starts a subroutine, indent with
+			;; respect to `sub', not with respect to the
+			;; first thing on the line, say in the case of
+			;; anonymous sub in a hash.
+			(if (and;; Is it a sub in group starting on this line?
+			     (cond ((get-text-property (point) 'attrib-group)
+				    (goto-char (cperl-beginning-of-property
+						(point) 'attrib-group)))
+				   ((eq (preceding-char) ?b)
+				    (forward-sexp -1)
+				    (looking-at "sub\\>")))
+			     (setq p (nth 1 ; start of innermost containing list
+					  (parse-partial-sexp
+					   (save-excursion (beginning-of-line)
+							   (point))
+					   (point)))))
+			    (progn
+			      (goto-char (1+ p)) ; enclosing block on the same line
+			      (skip-chars-forward " \t")
+			      (vector 'code-start-in-block containing-sexp char-after
+				      (and delim (not is-block)) ; is a HASH
+				      old-indent ; brace first thing on a line
+				      t (point) ; have something before...
+				      )
+			      ;;(current-column)
+			      )
+			  ;; Get initial indentation of the line we are on.
+			  ;; If line starts with label, calculate label indentation
+			  (vector 'code-start-in-block containing-sexp char-after
+				  (and delim (not is-block)) ; is a HASH
+				  old-indent ; brace first thing on a line
+				  nil (point))))))))))))))) ; nothing interesting before
+
+(defvar cperl-indent-rules-alist
+  '((pod nil)				; via `syntax-type' property
+    (here-doc nil)			; via `syntax-type' property
+    (here-doc-delim nil)		; via `syntax-type' property
+    (format nil)			; via `syntax-type' property
+    (in-pod nil)			; via `in-pod' property
+    (comment-special:at-beginning-of-line nil)
+    (string t)
+    (comment nil))
   "Alist of indentation rules for CPerl mode.
 The values mean:
   nil: do not indent;
-  number: add this amount of indentation.
-
-Not finished, not used.")
-
-(defun cperl-where-am-i (&optional parse-start start-state)
-  ;; Unfinished
-  "Return a list of lists ((TYPE POS)...) of good points before the point.
-POS may be nil if it is hard to find, say, when TYPE is `string' or `comment'.
-
-Not finished, not used."
+  number: add this amount of indentation.")
+
+(defun cperl-calculate-indent (&optional parse-data) ; was parse-start
+  "Return appropriate indentation for current line as Perl code.
+In usual case returns an integer: the column to indent to.
+Returns nil if line starts inside a string, t if in a comment.
+
+Will not correct the indentation for labels, but will correct it for braces
+and closing parentheses and brackets."
+  ;; This code is still a broken architecture: in some cases we need to
+  ;; compensate for some modifications which `cperl-indent-line' will add later
   (save-excursion
-    (let* ((start-point (point))
-	   (s-s (cperl-get-state))
-	   (start (nth 0 s-s))
-	   (state (nth 1 s-s))
-	   (prestart (nth 3 s-s))
-	   (containing-sexp (car (cdr state)))
-	   (case-fold-search nil)
-	   (res (list (list 'parse-start start) (list 'parse-prestart prestart))))
-      (cond ((nth 3 state)		; In string
-	     (setq res (cons (list 'string nil (nth 3 state)) res))) ; What started string
-	    ((nth 4 state)		; In comment
-	     (setq res (cons '(comment) res)))
-	    ((null containing-sexp)
-	     ;; Line is at top level.
-	     ;; Indent like the previous top level line
-	     ;; unless that ends in a closeparen without semicolon,
-	     ;; in which case this line is the first argument decl.
-	     (cperl-backward-to-noncomment (or parse-start (point-min)))
-	     ;;(skip-chars-backward " \t\f\n")
-	     (cond
-	      ((or (bobp)
-		   (memq (preceding-char) (append ";}" nil)))
-	       (setq res (cons (list 'toplevel start) res)))
-	      ((eq (preceding-char) ?\) )
-	       (setq res (cons (list 'toplevel-after-parenth start) res)))
-	      (t
-	       (setq res (cons (list 'toplevel-continued start) res)))))
-	    ((/= (char-after containing-sexp) ?{)
-	     ;; line is expression, not statement:
-	     ;; indent to just after the surrounding open.
-	     ;; skip blanks if we do not close the expression.
-	     (setq res (cons (list 'expression-blanks
-				   (progn
-				     (goto-char (1+ containing-sexp))
-				     (or (looking-at "[ \t]*\\(#\\|$\\)")
-					 (skip-chars-forward " \t"))
-				     (point)))
-			     (cons (list 'expression containing-sexp) res))))
-	    ((progn
-	       ;; Containing-expr starts with \{.  Check whether it is a hash.
-	       (goto-char containing-sexp)
-	       (not (cperl-block-p)))
-	     (setq res (cons (list 'expression-blanks
-				   (progn
-				     (goto-char (1+ containing-sexp))
-				     (or (looking-at "[ \t]*\\(#\\|$\\)")
-					 (skip-chars-forward " \t"))
-				     (point)))
-			     (cons (list 'expression containing-sexp) res))))
-	    (t
-	     ;; Statement level.
-	     (setq res (cons (list 'in-block containing-sexp) res))
-	     ;; Is it a continuation or a new statement?
-	     ;; Find previous non-comment character.
-	     (cperl-backward-to-noncomment containing-sexp)
-	     ;; Back up over label lines, since they don't
-	     ;; affect whether our line is a continuation.
-	     ;; Back up comma-delimited lines too ?????
-	     (while (or (eq (preceding-char) ?\,)
-			(save-excursion (cperl-after-label)))
-	       (if (eq (preceding-char) ?\,)
-		   ;; Will go to beginning of line, essentially
-		   ;; Will ignore embedded sexpr XXXX.
-		   (cperl-backward-to-start-of-continued-exp containing-sexp))
-	       (beginning-of-line)
-	       (cperl-backward-to-noncomment containing-sexp))
-	     ;; Now we get the answer.
-	     (if (not (memq (preceding-char) (append ";}{" '(nil)))) ; Was ?\,
-		 ;; This line is continuation of preceding line's statement.
-		 (list (list 'statement-continued containing-sexp))
-	       ;; This line starts a new statement.
-	       ;; Position following last unclosed open.
-	       (goto-char containing-sexp)
-	       ;; Is line first statement after an open-brace?
-	       (or
-		;; If no, find that first statement and indent like
-		;; it.  If the first statement begins with label, do
-		;; not believe when the indentation of the label is too
-		;; small.
-		(save-excursion
-		  (forward-char 1)
-		  (let ((colon-line-end 0))
-		    (while (progn (skip-chars-forward " \t\n" start-point)
-				  (and (< (point) start-point)
-				       (looking-at
-					"#\\|[a-zA-Z_][a-zA-Z0-9_]*:[^:]")))
-		      ;; Skip over comments and labels following openbrace.
-		      (cond ((= (following-char) ?\#)
-			     ;;(forward-line 1)
-			     (end-of-line))
-			    ;; label:
-			    (t
-			     (save-excursion (end-of-line)
-					     (setq colon-line-end (point)))
-			     (search-forward ":"))))
-		    ;; Now at the point, after label, or at start
-		    ;; of first statement in the block.
-		    (and (< (point) start-point)
-			 (if (> colon-line-end (point))
-			     ;; Before statement after label
-			     (if (> (current-indentation)
-				    cperl-min-label-indent)
-				 (list (list 'label-in-block (point)))
-			       ;; Do not believe: `max' is involved
-			       (list
-				(list 'label-in-block-min-indent (point))))
-			   ;; Before statement
-			   (list 'statement-in-block (point))))))
-		;; If no previous statement,
-		;; indent it relative to line brace is on.
-		;; For open brace in column zero, don't let statement
-		;; start there too.  If cperl-indent-level is zero,
-		;; use cperl-brace-offset + cperl-continued-statement-offset instead.
-		;; For open-braces not the first thing in a line,
-		;; add in cperl-brace-imaginary-offset.
-
-		;; If first thing on a line:  ?????
-		(+ (if (and (bolp) (zerop cperl-indent-level))
-		       (+ cperl-brace-offset cperl-continued-statement-offset)
-		     cperl-indent-level)
-		   ;; Move back over whitespace before the openbrace.
-		   ;; If openbrace is not first nonwhite thing on the line,
-		   ;; add the cperl-brace-imaginary-offset.
-		   (progn (skip-chars-backward " \t")
-			  (if (bolp) 0 cperl-brace-imaginary-offset))
-		   ;; If the openbrace is preceded by a parenthesized exp,
-		   ;; move to the beginning of that;
-		   ;; possibly a different line
-		   (progn
-		     (if (eq (preceding-char) ?\))
-			 (forward-sexp -1))
-		     ;; Get initial indentation of the line we are on.
-		     ;; If line starts with label, calculate label indentation
-		     (if (save-excursion
-			   (beginning-of-line)
-			   (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
-			 (if (> (current-indentation) cperl-min-label-indent)
-			     (- (current-indentation) cperl-label-offset)
-			   (cperl-calculate-indent))
-		       (current-indentation))))))))
-      res)))
+    (let ((i (cperl-sniff-for-indent parse-data)) what p)
+      (cond
+       ;;((or (null i) (eq i t) (numberp i))
+       ;;  i)
+       ((vectorp i)
+	(setq what (assoc (elt i 0) cperl-indent-rules-alist))
+	(cond
+	 (what (cadr what))		; Load from table
+	 ;;
+	 ;; Indenters for regular expressions with //x and qw()
+	 ;;
+	 ((eq 'REx-part2 (elt i 0)) ;; [self start] start of /REP in s//REP/x
+	  (goto-char (elt i 1))
+	  (condition-case nil	; Use indentation of the 1st part
+	      (forward-sexp -1))
+	  (current-column))
+	 ((eq 'indentable (elt i 0))	; Indenter for REGEXP qw() etc
+	  (cond		       ;;; [indentable terminator start-pos is-block]
+	   ((eq 'terminator (elt i 1)) ; Lone terminator of "indentable string"
+	    (goto-char (elt i 2))	; After opening parens
+	    (1- (current-column)))
+	   ((eq 'first-line (elt i 1)); [indentable first-line start-pos]
+	    (goto-char (elt i 2))
+	    (+ (or cperl-regexp-indent-step cperl-indent-level)
+	       -1
+	       (current-column)))
+	   ((eq 'cont-line (elt i 1)); [indentable cont-line pos prev-pos first-char start-pos]
+	    ;; Indent as the level after closing parens
+	    (goto-char (elt i 2))	; indent line
+	    (skip-chars-forward " \t)") ; Skip closing parens
+	    (setq p (point))
+	    (goto-char (elt i 3))	; previous line
+	    (skip-chars-forward " \t)") ; Skip closing parens
+	    ;; Number of parens in between:
+	    (setq p (nth 0 (parse-partial-sexp (point) p))
+		  what (elt i 4))	; First char on current line
+	    (goto-char (elt i 3))	; previous line
+	    (+ (* p (or cperl-regexp-indent-step cperl-indent-level))
+	       (cond ((eq what ?\) )
+		      (- cperl-close-paren-offset)) ; compensate
+		     ((eq what ?\| )
+		      (- (or cperl-regexp-indent-step cperl-indent-level)))
+		     (t 0))
+	       (if (eq (following-char) ?\| )
+		   (or cperl-regexp-indent-step cperl-indent-level)
+		 0)
+	       (current-column)))
+	   (t
+	    (error "Unrecognized value of indent: " i))))
+	 ;;
+	 ;; Indenter for stuff at toplevel
+	 ;;
+	 ((eq 'toplevel (elt i 0)) ;; [toplevel start char-after state immed-after-block]
+	  (+ (save-excursion		; To beg-of-defun, or end of last sexp
+	       (goto-char (elt i 1))	; start = Good place to start parsing
+	       (- (current-indentation) ; 
+		  (if (elt i 4) cperl-indent-level 0)))	; immed-after-block
+	     (if (eq (elt i 2) ?{) cperl-continued-brace-offset 0) ; char-after
+	     ;; Look at previous line that's at column 0
+	     ;; to determine whether we are in top-level decls
+	     ;; or function's arg decls.  Set basic-indent accordingly.
+	     ;; Now add a little if this is a continuation line.
+	     (if (elt i 3)		; state (XXX What is the semantic???)
+		 0
+	       cperl-continued-statement-offset)))
+	 ;;
+	 ;; Indenter for stuff in "parentheses" (or brackets, braces-as-hash)
+	 ;;
+	 ((eq 'in-parens (elt i 0))
+	  ;; in-parens char-after old-indent-point is-brace containing-sexp
+
+	  ;; group is an expression, not a block:
+	  ;; indent to just after the surrounding open parens,
+	  ;; skip blanks if we do not close the expression.
+	  (+ (progn
+	       (goto-char (elt i 2))		; old-indent-point
+	       (current-column))
+	     (if (and (elt i 3)		; is-brace
+		      (eq (elt i 1) ?\})) ; char-after
+		 ;; Correct indentation of trailing ?\}
+		 (+ cperl-indent-level cperl-close-paren-offset)
+	       0)))
+	 ;;
+	 ;; Indenter for continuation lines
+	 ;;
+	 ((eq 'continuation (elt i 0))
+	  ;; [continuation statement-start char-after is-block is-brace]
+	  (goto-char (elt i 1))		; statement-start
+	  (+ (if (memq (elt i 2) (append "}])" nil)) ; char-after
+		 0			; Closing parenth
+	       cperl-continued-statement-offset)
+	     (if (or (elt i 3)		; is-block
+		     (not (elt i 4))		; is-brace
+		     (not (eq (elt i 2) ?\}))) ; char-after
+		 0
+	       ;; Now it is a hash reference
+	       (+ cperl-indent-level cperl-close-paren-offset))
+	     ;; Labels do not take :: ...
+	     (if (looking-at "\\(\\w\\|_\\)+[ \t]*:")
+		 (if (> (current-indentation) cperl-min-label-indent)
+		     (- (current-indentation) cperl-label-offset)
+		   ;; Do not move `parse-data', this should
+		   ;; be quick anyway (this comment comes
+		   ;; from different location):
+		   (cperl-calculate-indent))
+	       (current-column))
+	     (if (eq (elt i 2) ?\{)	; char-after
+		 cperl-continued-brace-offset 0)))
+	 ;;
+	 ;; Indenter for lines in a block which are not leading lines
+	 ;;
+	 ((eq 'have-prev-sibling (elt i 0))
+	  ;; [have-prev-sibling sibling-beg colon-line-end block-start]
+	  (goto-char (elt i 1))		; sibling-beg
+	  (if (> (elt i 2) (point)) ; colon-line-end; have label before point
+	      (if (> (current-indentation)
+		     cperl-min-label-indent)
+		  (- (current-indentation) cperl-label-offset)
+		;; Do not believe: `max' was involved in calculation of indent
+		(+ cperl-indent-level
+		   (save-excursion
+		     (goto-char (elt i 3)) ; block-start
+		     (current-indentation))))
+	    (current-column)))
+	 ;;
+	 ;; Indenter for the first line in a block
+	 ;;
+	 ((eq 'code-start-in-block (elt i 0))
+	  ;;[code-start-in-block before-brace char-after
+	  ;; is-a-HASH-ref brace-is-first-thing-on-a-line
+	  ;; group-starts-before-start-of-sub start-of-control-group]
+	  (goto-char (elt i 1))
+	  ;; For open brace in column zero, don't let statement
+	  ;; start there too.  If cperl-indent-level=0,
+	  ;; use cperl-brace-offset + cperl-continued-statement-offset instead.
+	  (+ (if (and (bolp) (zerop cperl-indent-level))
+		 (+ cperl-brace-offset cperl-continued-statement-offset)
+	       cperl-indent-level)
+	     (if (and (elt i 3)	; is-a-HASH-ref
+		      (eq (elt i 2) ?\})) ; char-after: End of a hash reference
+		 (+ cperl-indent-level cperl-close-paren-offset)
+	       0)
+	     ;; Unless openbrace is the first nonwhite thing on the line,
+	     ;; add the cperl-brace-imaginary-offset.
+	     (if (elt i 4) 0		; brace-is-first-thing-on-a-line
+	       cperl-brace-imaginary-offset)
+	     (progn
+	       (goto-char (elt i 6))	; start-of-control-group
+	       (if (elt i 5)		; group-starts-before-start-of-sub
+		   (current-column)
+		 ;; Get initial indentation of the line we are on.
+		 ;; If line starts with label, calculate label indentation
+		 (if (save-excursion
+		       (beginning-of-line)
+		       (looking-at "[ \t]*[a-zA-Z_][a-zA-Z_0-9]*:[^:]"))
+		     (if (> (current-indentation) cperl-min-label-indent)
+			 (- (current-indentation) cperl-label-offset)
+		       ;; Do not move `parse-data', this should
+		       ;; be quick anyway:
+		       (cperl-calculate-indent))
+		   (current-indentation))))))
+	 (t
+	  (error "Unrecognized value of indent: " i))))
+       (t
+	(error (format "Got strange value of indent: " i)))))))
 
 (defun cperl-calculate-indent-within-comment ()
   "Return the indentation amount for line, assuming that
 
 (defun cperl-to-comment-or-eol ()
   "Go to position before comment on the current line, or to end of line.
-Returns true if comment is found."
-  (let (state stop-in cpoint (lim (progn (end-of-line) (point))))
+Returns true if comment is found.  In POD will not move the point."
+  ;; If the line is inside other syntax groups (qq-style strings, HERE-docs)
+  ;; then looks for literal # or end-of-line.
+  (let (state stop-in cpoint (lim (progn (end-of-line) (point))) pr e)
+    (or cperl-font-locking
+	(cperl-update-syntaxification lim lim))