1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075 |
- (eval-when-compile (require 'cl))
- (defvar font-lock-comment-face)
- (defvar font-lock-doc-face)
- (defvar font-lock-string-face)
- (defgroup perl nil
- "Major mode for editing Perl code."
- :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
- :prefix "perl-"
- :group 'languages)
- (defvar perl-mode-abbrev-table nil
- "Abbrev table in use in perl-mode buffers.")
- (define-abbrev-table 'perl-mode-abbrev-table ())
- (defvar perl-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "{" 'perl-electric-terminator)
- (define-key map "}" 'perl-electric-terminator)
- (define-key map ";" 'perl-electric-terminator)
- (define-key map ":" 'perl-electric-terminator)
- (define-key map "\e\C-a" 'perl-beginning-of-function)
- (define-key map "\e\C-e" 'perl-end-of-function)
- (define-key map "\e\C-h" 'perl-mark-function)
- (define-key map "\e\C-q" 'perl-indent-exp)
- (define-key map "\177" 'backward-delete-char-untabify)
- (define-key map "\t" 'perl-indent-command)
- map)
- "Keymap used in Perl mode.")
- (autoload 'c-macro-expand "cmacexp"
- "Display the result of expanding all C macros occurring in the region.
- The expansion is entirely correct because it uses the C preprocessor."
- t)
- (defvar perl-mode-syntax-table
- (let ((st (make-syntax-table (standard-syntax-table))))
- (modify-syntax-entry ?\n ">" st)
- (modify-syntax-entry ?# "<" st)
-
-
- (modify-syntax-entry ?$ "/" st)
- (modify-syntax-entry ?% ". p" st)
- (modify-syntax-entry ?@ ". p" st)
- (modify-syntax-entry ?& "." st)
- (modify-syntax-entry ?\' "\"" st)
- (modify-syntax-entry ?* "." st)
- (modify-syntax-entry ?+ "." st)
- (modify-syntax-entry ?- "." st)
- (modify-syntax-entry ?/ "." st)
- (modify-syntax-entry ?< "." st)
- (modify-syntax-entry ?= "." st)
- (modify-syntax-entry ?> "." st)
- (modify-syntax-entry ?\\ "\\" st)
- (modify-syntax-entry ?` "\"" st)
- (modify-syntax-entry ?| "." st)
- st)
- "Syntax table in use in `perl-mode' buffers.")
- (defvar perl-imenu-generic-expression
- '(
- (nil "^sub\\s-+\\([-A-Za-z0-9+_:]+\\)" 1)
-
- ("Variables" "^\\(?:my\\|our\\)\\s-+\\([$@%][-A-Za-z0-9+_:]+\\)\\s-*=" 1)
- ("Packages" "^package\\s-+\\([-A-Za-z0-9+_:]+\\);" 1)
- ("Doc sections" "^=head[0-9][ \t]+\\(.*\\)" 1))
- "Imenu generic expression for Perl mode. See `imenu-generic-expression'.")
- (defconst perl-font-lock-keywords-1
- '(
-
-
-
-
-
-
-
-
-
-
-
-
-
- ("\\<\\(package\\|sub\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
- ("\\<\\(import\\|no\\|require\\|use\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)))
- "Subdued level highlighting for Perl mode.")
- (defconst perl-font-lock-keywords-2
- (append perl-font-lock-keywords-1
- (list
-
-
- (concat "\\<"
- (regexp-opt '("if" "until" "while" "elsif" "else" "unless"
- "do" "dump" "for" "foreach" "exit" "die"
- "BEGIN" "END" "return" "exec" "eval") t)
- "\\>")
-
-
- '("\\<\\(local\\|my\\)\\>" . font-lock-type-face)
-
-
- '("&\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-function-name-face)
-
-
- '("[$*]{?\\(\\sw+\\(::\\sw+\\)*\\)" 1 font-lock-variable-name-face)
- '("\\([@%]\\|\\$#\\)\\(\\sw+\\(::\\sw+\\)*\\)"
- (2 (cons font-lock-variable-name-face '(underline))))
- '("<\\(\\sw+\\)>" 1 font-lock-constant-face)
-
-
- '("\\<\\(continue\\|goto\\|last\\|next\\|redo\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-constant-face nil t))
- '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-constant-face)))
- "Gaudy level highlighting for Perl mode.")
- (defvar perl-font-lock-keywords perl-font-lock-keywords-1
- "Default expressions to highlight in Perl mode.")
- (defvar perl-quote-like-pairs
- '((?\( . ?\)) (?\[ . ?\]) (?\{ . ?\}) (?\< . ?\>)))
- (defun perl-syntax-propertize-function (start end)
- (let ((case-fold-search nil))
- (goto-char start)
- (perl-syntax-propertize-special-constructs end)
-
- (funcall
- (syntax-propertize-rules
-
-
- ("^=cut\\>.*\\(\n\\)" (1 "> b"))
- ("^\\(=\\)\\sw" (1 "< b"))
-
-
-
- ("\\(\\$\\)[{']" (1 ". p"))
-
- ("\\$ ?{?^?[_a-zA-Z][_a-zA-Z0-9]*\\('\\)[_a-zA-Z]" (1 "_"))
-
- ("^[ \t]*format.*=[ \t]*\\(\n\\)"
- (1 (prog1 "\"" (perl-syntax-propertize-special-constructs end))))
-
-
- ("\\<sub\\(?:[[:space:]]+[^{}[:punct:][:space:]]+\\)?[[:space:]]*(\\([^)]+\\))"
- (1 "."))
-
- ("^\\(_\\)_\\(?:DATA\\|END\\)__[ \t]*\\(?:\\(\n\\)#.-\\*-.*perl.*-\\*-\\|\n.*\\)"
- (1 "< c") (2 "> c")
- (0 (ignore (put-text-property (match-beginning 0) (match-end 0)
- 'syntax-multiline t))))
-
-
-
-
-
-
-
-
-
- ((concat "\\(?:\\(?:^\\|[^$@&%[:word:]]\\)"
- (regexp-opt '("split" "if" "unless" "until" "while" "split"
- "grep" "map" "not" "or" "and"))
- "\\|[?:.,;=!~({[]\\|\\(^\\)\\)[ \t\n]*\\(/\\)")
- (2 (ignore
- (if (and (match-end 1)
- (save-excursion
- (goto-char (match-end 1))
- (forward-comment (- (point-max)))
- (put-text-property (point) (match-end 2)
- 'syntax-multiline t)
- (not (memq (char-before)
- '(?? ?: ?. ?, ?\
- nil
- (put-text-property (match-beginning 2) (match-end 2)
- 'syntax-table (string-to-syntax "\""))
- (perl-syntax-propertize-special-constructs end)))))
- ("\\(^\\|[?:.,;=!~({[ \t]\\)\\([msy]\\|q[qxrw]?\\|tr\\)\\>\\s-*\\(?:\\([^])}>= \n\t]\\)\\|\\(?3:=\\)[^>]\\)"
-
-
-
-
-
-
- (3 (ignore
- (if (save-excursion (goto-char (match-beginning 0))
- (forward-word -1)
- (looking-at-p "sub[ \t\n]"))
-
- nil
- (put-text-property (match-beginning 3) (match-end 3)
- 'syntax-table
- (if (assoc (char-after (match-beginning 3))
- perl-quote-like-pairs)
- (string-to-syntax "|")
- (string-to-syntax "\"")))
- (perl-syntax-propertize-special-constructs end))))))
- (point) end)))
- (defvar perl-empty-syntax-table
- (let ((st (copy-syntax-table)))
-
- (dotimes (i 256) (aset st i '(1)))
- (modify-syntax-entry ?\\ "\\" st)
- st)
- "Syntax table used internally for processing quote-like operators.")
- (defun perl-quote-syntax-table (char)
- (let ((close (cdr (assq char perl-quote-like-pairs)))
- (st (copy-syntax-table perl-empty-syntax-table)))
- (if (not close)
- (modify-syntax-entry char "\"" st)
- (modify-syntax-entry char "(" st)
- (modify-syntax-entry close ")" st))
- st))
- (defun perl-syntax-propertize-special-constructs (limit)
- "Propertize special constructs like regexps and formats."
- (let ((state (syntax-ppss))
- char)
- (cond
- ((or (null (setq char (nth 3 state)))
- (and (characterp char) (eq (char-syntax (nth 3 state)) ?\")))
- ;; Normal text, or comment, or docstring, or normal string.
- nil)
- ((eq (nth 3 state) ?\n)
- ;; A `format' command.
- (when (re-search-forward "^\\s *\\.\\s *\n" limit 'move)
- (put-text-property (1- (point)) (point)
- 'syntax-table (string-to-syntax "\""))))
- (t
-
- (setq char (char-after (nth 8 state)))
- (let ((startpos (point))
- (twoargs (save-excursion
- (goto-char (nth 8 state))
- (skip-syntax-backward " ")
- (skip-syntax-backward "w")
- (member (buffer-substring
- (point) (progn (forward-word 1) (point)))
- '("tr" "s" "y"))))
- (close (cdr (assq char perl-quote-like-pairs)))
- (st (perl-quote-syntax-table char)))
- (when (with-syntax-table st
- (if close
-
-
-
-
-
- (condition-case nil
- (progn
-
-
-
- (goto-char (1+ (nth 8 state)))
- (up-list 1)
- t)
-
- (scan-error (goto-char startpos) nil))
- (not (or (nth 8 (parse-partial-sexp
-
-
-
- (if twoargs (1+ (nth 8 state)) (point))
- limit nil nil state 'syntax-table))
-
-
-
-
-
- (when (and twoargs (not close))
- (nth 8 (parse-partial-sexp
- (point) limit
- nil nil state 'syntax-table)))))))
-
- (when (eq (char-before (1- (point))) ?$)
- (put-text-property (- (point) 2) (1- (point))
- 'syntax-table '(1)))
- (put-text-property (1- (point)) (point)
- 'syntax-table
- (if close
- (string-to-syntax "|")
- (string-to-syntax "\"")))
-
-
-
- (when (and twoargs close)
-
-
- (put-text-property
- (point) (progn (forward-comment (point-max)) (point))
- 'syntax-multiline t)
-
- (when (< (point) limit)
- (put-text-property (point) (1+ (point))
- 'syntax-table
- (if (assoc (char-after)
- perl-quote-like-pairs)
-
-
- (string-to-syntax "|e")
- (string-to-syntax "\"e")))
- (forward-char 1)
-
-
-
-
- (perl-syntax-propertize-special-constructs limit)))))))))
- (defun perl-font-lock-syntactic-face-function (state)
- (cond
- ((and (nth 3 state)
- (eq ?e (cdr-safe (get-text-property (nth 8 state) 'syntax-table)))
-
-
-
-
-
-
-
- (let* ((parse-sexp-lookup-properties nil)
- (char (char-after (nth 8 state)))
- (paired (assq char perl-quote-like-pairs)))
- (with-syntax-table (perl-quote-syntax-table char)
- (save-excursion
- (if (not paired)
- (parse-partial-sexp (point) (point-max)
- nil nil state 'syntax-table)
- (condition-case nil
- (progn
- (goto-char (1+ (nth 8 state)))
- (up-list 1))
- (scan-error (goto-char (point-max)))))
- (put-text-property (nth 8 state) (point)
- 'jit-lock-defer-multiline t)
- (looking-at "[ \t]*\\sw*e")))))
- nil)
- (t (funcall (default-value 'font-lock-syntactic-face-function) state))))
- (defcustom perl-indent-level 4
- "*Indentation of Perl statements with respect to containing block."
- :type 'integer
- :group 'perl)
- (defcustom perl-continued-statement-offset 4
- "*Extra indent for lines not starting new statements."
- :type 'integer
- :group 'perl)
- (defcustom perl-continued-brace-offset -4
- "*Extra indent for substatements that start with open-braces.
- This is in addition to `perl-continued-statement-offset'."
- :type 'integer
- :group 'perl)
- (defcustom perl-brace-offset 0
- "*Extra indentation for braces, compared with other text in same context."
- :type 'integer
- :group 'perl)
- (defcustom perl-brace-imaginary-offset 0
- "*Imagined indentation of an open brace that actually follows a statement."
- :type 'integer
- :group 'perl)
- (defcustom perl-label-offset -2
- "*Offset of Perl label lines relative to usual indentation."
- :type 'integer
- :group 'perl)
- (defcustom perl-indent-continued-arguments nil
- "*If non-nil offset of argument lines relative to usual indentation.
- If nil, continued arguments are aligned with the first argument."
- :type '(choice integer (const nil))
- :group 'perl)
- (defcustom perl-tab-always-indent tab-always-indent
- "Non-nil means TAB in Perl mode always indents the current line.
- Otherwise it inserts a tab character if you type it past the first
- nonwhite character on the line."
- :type 'boolean
- :group 'perl)
- (defcustom perl-tab-to-comment nil
- "*Non-nil means TAB moves to eol or makes a comment in some cases.
- For lines which don't need indenting, TAB either indents an
- existing comment, moves to end-of-line, or if at end-of-line already,
- create a new comment."
- :type 'boolean
- :group 'perl)
- (defcustom perl-nochange ";?#\\|\f\\|\\s(\\|\\(\\w\\|\\s_\\)+:[^:]"
- "*Lines starting with this regular expression are not auto-indented."
- :type 'regexp
- :group 'perl)
- (defvar perl-outline-regexp
- (concat (mapconcat 'cadr perl-imenu-generic-expression "\\|")
- "\\|^=cut\\>"))
- (defun perl-outline-level ()
- (cond
- ((looking-at "package\\s-") 0)
- ((looking-at "sub\\s-") 1)
- ((looking-at "=head[0-9]") (- (char-before (match-end 0)) ?0))
- ((looking-at "=cut") 1)
- (t 3)))
- (defvar perl-mode-hook nil
- "Normal hook to run when entering Perl mode.")
- (define-derived-mode perl-mode prog-mode "Perl"
- "Major mode for editing Perl code.
- Expression and list commands understand all Perl brackets.
- Tab indents for Perl code.
- Comments are delimited with # ... \\n.
- Paragraphs are separated by blank lines only.
- Delete converts tabs to spaces as it moves back.
- \\{perl-mode-map}
- Variables controlling indentation style:
- `perl-tab-always-indent'
- Non-nil means TAB in Perl mode should always indent the current line,
- regardless of where in the line point is when the TAB command is used.
- `perl-tab-to-comment'
- Non-nil means that for lines which don't need indenting, TAB will
- either delete an empty comment, indent an existing comment, move
- to end-of-line, or if at end-of-line already, create a new comment.
- `perl-nochange'
- Lines starting with this regular expression are not auto-indented.
- `perl-indent-level'
- Indentation of Perl statements within surrounding block.
- The surrounding block's indentation is the indentation
- of the line on which the open-brace appears.
- `perl-continued-statement-offset'
- Extra indentation given to a substatement, such as the
- then-clause of an if or body of a while.
- `perl-continued-brace-offset'
- Extra indentation given to a brace that starts a substatement.
- This is in addition to `perl-continued-statement-offset'.
- `perl-brace-offset'
- Extra indentation for line if it starts with an open brace.
- `perl-brace-imaginary-offset'
- An open brace following other text is treated as if it were
- this far to the right of the start of its line.
- `perl-label-offset'
- Extra indentation for line that is a label.
- `perl-indent-continued-arguments'
- Offset of argument lines relative to usual indentation.
- Various indentation styles: K&R BSD BLK GNU LW
- perl-indent-level 5 8 0 2 4
- perl-continued-statement-offset 5 8 4 2 4
- perl-continued-brace-offset 0 0 0 0 -4
- perl-brace-offset -5 -8 0 0 0
- perl-brace-imaginary-offset 0 0 4 0 0
- perl-label-offset -5 -8 -2 -2 -2
- Turning on Perl mode runs the normal hook `perl-mode-hook'."
- :abbrev-table perl-mode-abbrev-table
- (set (make-local-variable 'paragraph-start) (concat "$\\|" page-delimiter))
- (set (make-local-variable 'paragraph-separate) paragraph-start)
- (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
- (set (make-local-variable 'indent-line-function) #'perl-indent-line)
- (set (make-local-variable 'comment-start) "# ")
- (set (make-local-variable 'comment-end) "")
- (set (make-local-variable 'comment-start-skip) "\\(^\\|\\s-\\);?#+ *")
- (set (make-local-variable 'comment-indent-function) #'perl-comment-indent)
- (set (make-local-variable 'parse-sexp-ignore-comments) t)
-
- (setq font-lock-defaults '((perl-font-lock-keywords
- perl-font-lock-keywords-1
- perl-font-lock-keywords-2)
- nil nil ((?\_ . "w")) nil
- (font-lock-syntactic-face-function
- . perl-font-lock-syntactic-face-function)))
- (set (make-local-variable 'syntax-propertize-function)
- #'perl-syntax-propertize-function)
- (add-hook 'syntax-propertize-extend-region-functions
- #'syntax-propertize-multiline 'append 'local)
-
- (set (make-local-variable 'imenu-generic-expression)
- perl-imenu-generic-expression)
- (setq imenu-case-fold-search nil)
-
- (set (make-local-variable 'outline-regexp) perl-outline-regexp)
- (set (make-local-variable 'outline-level) 'perl-outline-level))
- (defun perl-comment-indent ()
- (if (and (bolp) (not (eolp)))
- 0
- comment-column))
- (defalias 'electric-perl-terminator 'perl-electric-terminator)
- (defun perl-electric-terminator (arg)
- "Insert character and maybe adjust indentation.
- If at end-of-line, and not in a comment or a quote, correct the indentation."
- (interactive "P")
- (let ((insertpos (point)))
- (and (not arg)
- (eolp)
- (save-excursion
- (beginning-of-line)
- (and (not
- (and comment-start-skip
- (re-search-forward comment-start-skip insertpos t)) )
- (or (/= last-command-event ?:)
-
- (looking-at "\\s-*\\(\\w\\|\\s_\\)+$"))
- (let ((pps (parse-partial-sexp
- (perl-beginning-of-function) insertpos)))
- (not (or (nth 3 pps) (nth 4 pps) (nth 5 pps))))))
- (progn
- (insert-char last-command-event 1)
- (perl-indent-line)
- (delete-char -1))))
- (self-insert-command (prefix-numeric-value arg)))
- (defun perl-indent-command (&optional arg)
- "Indent Perl code in the active region or current line.
- In Transient Mark mode, when the region is active, reindent the region.
- Otherwise, with a prefix argument, reindent the current line
- unconditionally.
- Otherwise, if `perl-tab-always-indent' is nil and point is not in
- the indentation area at the beginning of the line, insert a tab.
- Otherwise, indent the current line. If point was within the
- indentation area, it is moved to the end of the indentation area.
- If the line was already indented properly and point was not
- within the indentation area, and if `perl-tab-to-comment' is
- non-nil (the default), then do the first possible action from the
- following list:
- 1) delete an empty comment
- 2) move forward to start of comment, indenting if necessary
- 3) move forward to end of line
- 4) create an empty comment
- 5) move backward to start of comment, indenting if necessary."
- (interactive "P")
- (cond ((use-region-p)
- (indent-region (region-beginning) (region-end)))
- (arg
- (perl-indent-line "\f"))
- ((and (not perl-tab-always-indent)
- (> (current-column) (current-indentation)))
- (insert-tab))
- (t
- (let* ((oldpnt (point))
- (lsexp (progn (beginning-of-line) (point)))
- (bof (perl-beginning-of-function))
- (delta (progn
- (goto-char oldpnt)
- (perl-indent-line "\f\\|;?#" bof))))
- (and perl-tab-to-comment
- (= oldpnt (point))
- (if (listp delta)
- (setq lsexp (or (nth 2 delta) bof))
- (= delta 0))
- (let ((eol (progn (end-of-line) (point)))
- state)
- (cond ((= (char-after bof) ?=)
- (if (= oldpnt eol)
- (message "In a format statement")))
- ((progn (setq state (parse-partial-sexp lsexp eol))
- (nth 3 state))
- (if (= oldpnt eol)
- (message "In a string which starts with a %c."
- (nth 3 state))))
- ((not (nth 4 state))
- (if (= oldpnt eol)
- (indent-for-comment)))
- ((progn (beginning-of-line)
- (and comment-start-skip
- (re-search-forward
- comment-start-skip eol 'move)))
- (if (eolp)
- (progn
- (goto-char (match-beginning 0))
- (skip-chars-backward " \t")
- (delete-region (point) eol))
- (if (or (< oldpnt (point)) (= oldpnt eol))
- (indent-for-comment)
- (end-of-line))))
- ((/= oldpnt eol)
- (end-of-line))
- (t
- (message "Use backslash to quote # characters.")
- (ding t)))))))))
- (defun perl-indent-line (&optional nochange parse-start)
- "Indent current line as Perl code.
- Return the amount the indentation
- changed by, or (parse-state) if line starts in a quoted string."
- (let ((case-fold-search nil)
- (pos (- (point-max) (point)))
- (bof (or parse-start (save-excursion (perl-beginning-of-function))))
- beg indent shift-amt)
- (beginning-of-line)
- (setq beg (point))
- (setq shift-amt
- (cond ((eq (char-after bof) ?=) 0)
- ((listp (setq indent (perl-calculate-indent bof))) indent)
- ((eq 'noindent indent) indent)
- ((looking-at (or nochange perl-nochange)) 0)
- (t
- (skip-chars-forward " \t\f")
- (setq indent (perl-indent-new-calculate nil indent bof))
- (- indent (current-column)))))
- (skip-chars-forward " \t\f")
- (if (and (numberp shift-amt) (/= 0 shift-amt))
- (progn (delete-region beg (point))
- (indent-to indent)))
-
-
- (if (> (- (point-max) pos) (point))
- (goto-char (- (point-max) pos)))
- shift-amt))
- (defun perl-continuation-line-p (limit)
- "Move to end of previous line and return non-nil if continued."
-
-
- (perl-backward-to-noncomment)
-
-
- (while (or (eq (preceding-char) ?\,)
- (and (eq (preceding-char) ?:)
- (memq (char-syntax (char-after (- (point) 2)))
- '(?w ?_))))
- (if (eq (preceding-char) ?\,)
- (perl-backward-to-start-of-continued-exp limit)
- (beginning-of-line))
- (perl-backward-to-noncomment))
-
- (not (memq (preceding-char) '(?\
- (defun perl-hanging-paren-p ()
- "Non-nil if we are right after a hanging parenthesis-like char."
- (and (looking-at "[ \t]*$")
- (save-excursion
- (skip-syntax-backward " (") (not (bolp)))))
- (defun perl-indent-new-calculate (&optional virtual default parse-start)
- (or
- (and virtual (save-excursion (skip-chars-backward " \t") (bolp))
- (current-column))
- (and (looking-at "\\(\\w\\|\\s_\\)+:[^:]")
- (max 1 (+ (or default (perl-calculate-indent parse-start))
- perl-label-offset)))
- (and (= (char-syntax (following-char)) ?\))
- (save-excursion
- (forward-char 1)
- (forward-sexp -1)
- (perl-indent-new-calculate
-
-
- 'virtual nil (save-excursion (perl-beginning-of-function)))))
- (and (and (= (following-char) ?{)
- (save-excursion (forward-char) (perl-hanging-paren-p)))
- (+ (or default (perl-calculate-indent parse-start))
- perl-brace-offset))
- (or default (perl-calculate-indent parse-start))))
- (defun perl-calculate-indent (&optional parse-start)
- "Return appropriate indentation for current line as Perl code.
- In usual case returns an integer: the column to indent to.
- Returns (parse-state) if line starts inside a string.
- Optional argument PARSE-START should be the position of `beginning-of-defun'."
- (save-excursion
- (let ((indent-point (point))
- (case-fold-search nil)
- (colon-line-end 0)
- state containing-sexp)
- (if parse-start
- (goto-char parse-start)
- (perl-beginning-of-function))
-
-
-
- (while (and (looking-at "{")
- (save-excursion
- (beginning-of-line)
- (looking-at "\\s-+sub\\>"))
- (> indent-point (save-excursion
- (condition-case nil
- (forward-sexp 1)
- (scan-error nil))
- (point))))
- (perl-beginning-of-function))
- (while (< (point) indent-point)
- (setq state (parse-partial-sexp (point) indent-point 0))
-
-
-
-
- (setq containing-sexp (nth 1 state)))
- (cond ((nth 3 state) 'noindent)
- ((null containing-sexp)
- (skip-chars-forward " \t\f")
- (if (= (following-char) ?{)
- 0
-
- (perl-backward-to-noncomment)
- (if (or (bobp)
- (memq (preceding-char) '(?\
- 0 perl-continued-statement-offset)))
- ((/= (char-after containing-sexp) ?{)
-
-
- (goto-char (1+ containing-sexp))
- (if (perl-hanging-paren-p)
-
-
-
-
-
- (progn
- (skip-syntax-backward "(")
- (condition-case nil
- (while (save-excursion
- (skip-syntax-backward " ") (not (bolp)))
- (forward-sexp -1))
- (scan-error nil))
- (+ (current-column) perl-indent-level))
- (if perl-indent-continued-arguments
- (+ perl-indent-continued-arguments (current-indentation))
- (skip-chars-forward " \t")
- (current-column))))
- (t
-
- (if (perl-continuation-line-p containing-sexp)
-
-
-
- (progn
- (perl-backward-to-start-of-continued-exp containing-sexp)
- (+ (if (save-excursion
- (perl-continuation-line-p containing-sexp))
-
-
- 0 perl-continued-statement-offset)
- (current-column)
- (if (save-excursion (goto-char indent-point)
- (looking-at "[ \t]*{"))
- perl-continued-brace-offset 0)))
-
-
- (goto-char containing-sexp)
- (or
-
-
- (save-excursion
- (forward-char 1)
-
- (while (progn
- (skip-chars-forward " \t\f\n")
- (cond ((looking-at ";?#")
- (forward-line 1) t)
- ((looking-at "\\(\\w\\|\\s_\\)+:[^:]")
- (setq colon-line-end (line-end-position))
- (search-forward ":")))))
-
-
- (and (< (point) indent-point)
- (if (> colon-line-end (point))
- (- (current-indentation) perl-label-offset)
- (current-column))))
-
-
-
-
-
-
-
- (+ (if (and (bolp) (zerop perl-indent-level))
- (+ perl-brace-offset perl-continued-statement-offset)
- perl-indent-level)
-
-
-
- (progn (skip-chars-backward " \t")
- (if (bolp) 0 perl-brace-imaginary-offset))
-
-
-
- (progn
- (if (eq (preceding-char) ?\))
- (forward-sexp -1))
-
- (current-indentation))))))))))
- (defun perl-backward-to-noncomment ()
- "Move point backward to after the first non-white-space, skipping comments."
- (interactive)
- (forward-comment (- (point-max))))
- (defun perl-backward-to-start-of-continued-exp (lim)
- (if (= (preceding-char) ?\))
- (forward-sexp -1))
- (beginning-of-line)
- (if (<= (point) lim)
- (goto-char (1+ lim)))
- (skip-chars-forward " \t\f"))
- (defalias 'indent-perl-exp 'perl-indent-exp)
- (defun perl-indent-exp ()
- "Indent each line of the Perl grouping following point."
- (interactive)
- (let* ((case-fold-search nil)
- (oldpnt (point-marker))
- (bof-mark (save-excursion
- (end-of-line 2)
- (perl-beginning-of-function)
- (point-marker)))
- eol last-mark lsexp-mark delta)
- (if (= (char-after (marker-position bof-mark)) ?=)
- (message "Can't indent a format statement")
- (message "Indenting Perl expression...")
- (setq eol (line-end-position))
- (save-excursion
- (while (and (not (eobp)) (<= (point) eol))
- (parse-partial-sexp (point) (point-max) 0))
- (setq last-mark (point-marker)))
- (setq lsexp-mark bof-mark)
- (beginning-of-line)
- (while (< (point) (marker-position last-mark))
- (setq delta (perl-indent-line nil (marker-position bof-mark)))
- (if (numberp delta)
- (progn
- (if (eolp)
- (delete-horizontal-space))
- (setq lsexp-mark (point-marker))))
- (end-of-line)
- (setq eol (point))
- (if (nth 4 (parse-partial-sexp (marker-position lsexp-mark) eol))
- (progn
- (beginning-of-line)
- (if (or (not (looking-at "\\s-*;?#"))
- (listp delta)
- (and (/= 0 delta)
- (= (- (current-indentation) delta) comment-column)))
- (if (and comment-start-skip
- (re-search-forward comment-start-skip eol t))
- (indent-for-comment)))))
- (forward-line 1))
- (goto-char (marker-position oldpnt))
- (message "Indenting Perl expression...done"))))
- (defun perl-beginning-of-function (&optional arg)
- "Move backward to next beginning-of-function, or as far as possible.
- With argument, repeat that many times; negative args move forward.
- Returns new value of point in all cases."
- (interactive "p")
- (or arg (setq arg 1))
- (if (< arg 0) (forward-char 1))
- (and (/= arg 0)
- (re-search-backward
- "^\\s(\\|^\\s-*sub\\b[ \t\n]*\\_<[^{]+{\\|^\\s-*format\\b[^=]*=\\|^\\."
- nil 'move arg)
- (goto-char (1- (match-end 0))))
- (point))
- (defun perl-end-of-function (&optional arg)
- "Move forward to next end-of-function.
- The end of a function is found by moving forward from the beginning of one.
- With argument, repeat that many times; negative args move backward."
- (interactive "p")
- (or arg (setq arg 1))
- (let ((first t))
- (while (and (> arg 0) (< (point) (point-max)))
- (let ((pos (point)))
- (while (progn
- (if (and first
- (progn
- (forward-char 1)
- (perl-beginning-of-function 1)
- (not (bobp))))
- nil
- (or (bobp) (forward-char -1))
- (perl-beginning-of-function -1))
- (setq first nil)
- (forward-list 1)
- (skip-chars-forward " \t")
- (if (looking-at "[#\n]")
- (forward-line 1))
- (<= (point) pos))))
- (setq arg (1- arg)))
- (while (< arg 0)
- (let ((pos (point)))
- (perl-beginning-of-function 1)
- (forward-sexp 1)
- (forward-line 1)
- (if (>= (point) pos)
- (if (progn (perl-beginning-of-function 2) (not (bobp)))
- (progn
- (forward-list 1)
- (skip-chars-forward " \t")
- (if (looking-at "[#\n]")
- (forward-line 1)))
- (goto-char (point-min)))))
- (setq arg (1+ arg)))))
- (defalias 'mark-perl-function 'perl-mark-function)
- (defun perl-mark-function ()
- "Put mark at end of Perl function, point at beginning."
- (interactive)
- (push-mark (point))
- (perl-end-of-function)
- (push-mark (point))
- (perl-beginning-of-function)
- (backward-paragraph))
- (provide 'perl-mode)
|