diff options
| author | Stefan Monnier | 2002-09-13 18:44:29 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-09-13 18:44:29 +0000 |
| commit | d3627c478fb41199ccd53e927df613075a2b64c7 (patch) | |
| tree | 4d31f1a09088063f023ef1c42285f7633dd3ec3e | |
| parent | 595015bbf8225865b18db2efca387e90846599e9 (diff) | |
| download | emacs-d3627c478fb41199ccd53e927df613075a2b64c7.tar.gz emacs-d3627c478fb41199ccd53e927df613075a2b64c7.zip | |
(perl-mode-syntax-table): Mark $, % and @
such that backward-sexp correctly skips them.
(perl-font-lock-keywords-2): Use regexp-opt.
(perl-font-lock-syntactic-keywords)
(perl-font-lock-syntactic-face-function): Better handle PODs.
Handle package names with ' in them and ($$) in `sub' declarations.
Handle format staements. Handle regexp and quote-like ops.
(perl-empty-syntax-table): New var.
(perl-quote-syntax-table): New fun.
| -rw-r--r-- | lisp/progmodes/perl-mode.el | 273 |
1 files changed, 205 insertions, 68 deletions
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el index eba70b86f52..2b12f86e29b 100644 --- a/lisp/progmodes/perl-mode.el +++ b/lisp/progmodes/perl-mode.el | |||
| @@ -66,22 +66,23 @@ | |||
| 66 | ;; Known problems (these are all caused by limitations in the Emacs Lisp | 66 | ;; Known problems (these are all caused by limitations in the Emacs Lisp |
| 67 | ;; parsing routine (parse-partial-sexp), which was not designed for such | 67 | ;; parsing routine (parse-partial-sexp), which was not designed for such |
| 68 | ;; a rich language; writing a more suitable parser would be a big job): | 68 | ;; a rich language; writing a more suitable parser would be a big job): |
| 69 | ;; 1) Regular expression delimiters do not act as quotes, so special | ||
| 70 | ;; characters such as `'"#:;[](){} may need to be backslashed | ||
| 71 | ;; in regular expressions and in both parts of s/// and tr///. | ||
| 72 | ;; 2) The globbing syntax <pattern> is not recognized, so special | 69 | ;; 2) The globbing syntax <pattern> is not recognized, so special |
| 73 | ;; characters in the pattern string must be backslashed. | 70 | ;; characters in the pattern string must be backslashed. |
| 74 | ;; 3) The q, qq, and << quoting operators are not recognized; see below. | 71 | ;; 3) The << quoting operators are not recognized; see below. |
| 75 | ;; 5) To make '$' work correctly, $' is not recognized as a variable. | 72 | ;; 5) To make '$' work correctly, $' is not recognized as a variable. |
| 76 | ;; Use "$'" or $POSTMATCH instead. | 73 | ;; Use "$'" or $POSTMATCH instead. |
| 77 | ;; 7) When ' (quote) is used as a package name separator, perl-mode | ||
| 78 | ;; doesn't understand, and thinks it is seeing a quoted string. | ||
| 79 | ;; | 74 | ;; |
| 80 | ;; If you don't use font-lock, additional problems will appear: | 75 | ;; If you don't use font-lock, additional problems will appear: |
| 76 | ;; 1) Regular expression delimiters do not act as quotes, so special | ||
| 77 | ;; characters such as `'"#:;[](){} may need to be backslashed | ||
| 78 | ;; in regular expressions and in both parts of s/// and tr///. | ||
| 79 | ;; 4) The q and qq quoting operators are not recognized; see below. | ||
| 81 | ;; 5) To make variables such a $' and $#array work, perl-mode treats | 80 | ;; 5) To make variables such a $' and $#array work, perl-mode treats |
| 82 | ;; $ just like backslash, so '$' is not treated correctly. | 81 | ;; $ just like backslash, so '$' is not treated correctly. |
| 83 | ;; 6) Unfortunately, treating $ like \ makes ${var} be treated as an | 82 | ;; 6) Unfortunately, treating $ like \ makes ${var} be treated as an |
| 84 | ;; unmatched }. See below. | 83 | ;; unmatched }. See below. |
| 84 | ;; 7) When ' (quote) is used as a package name separator, perl-mode | ||
| 85 | ;; doesn't understand, and thinks it is seeing a quoted string. | ||
| 85 | 86 | ||
| 86 | ;; Here are some ugly tricks to bypass some of these problems: the perl | 87 | ;; Here are some ugly tricks to bypass some of these problems: the perl |
| 87 | ;; expression /`/ (that's a back-tick) usually evaluates harmlessly, | 88 | ;; expression /`/ (that's a back-tick) usually evaluates harmlessly, |
| @@ -91,6 +92,11 @@ | |||
| 91 | ;; | 92 | ;; |
| 92 | ;; /`/; $ugly = q?"'$?; /`/; | 93 | ;; /`/; $ugly = q?"'$?; /`/; |
| 93 | ;; | 94 | ;; |
| 95 | ;; The same trick can be used for problem 6 as in: | ||
| 96 | ;; /{/; while (<${glob_me}>) | ||
| 97 | ;; but a simpler solution is to add a space between the $ and the {: | ||
| 98 | ;; while (<$ {glob_me}>) | ||
| 99 | ;; | ||
| 94 | ;; Problem 7 is even worse, but this 'fix' does work :-( | 100 | ;; Problem 7 is even worse, but this 'fix' does work :-( |
| 95 | ;; $DB'stop#' | 101 | ;; $DB'stop#' |
| 96 | ;; [$DB'line#' | 102 | ;; [$DB'line#' |
| @@ -133,8 +139,9 @@ The expansion is entirely correct because it uses the C preprocessor." | |||
| 133 | (let ((st (make-syntax-table (standard-syntax-table)))) | 139 | (let ((st (make-syntax-table (standard-syntax-table)))) |
| 134 | (modify-syntax-entry ?\n ">" st) | 140 | (modify-syntax-entry ?\n ">" st) |
| 135 | (modify-syntax-entry ?# "<" st) | 141 | (modify-syntax-entry ?# "<" st) |
| 136 | (modify-syntax-entry ?$ "/" st) | 142 | (modify-syntax-entry ?$ "/ p" st) |
| 137 | (modify-syntax-entry ?% "." st) | 143 | (modify-syntax-entry ?% ". p" st) |
| 144 | (modify-syntax-entry ?@ ". p" st) | ||
| 138 | (modify-syntax-entry ?& "." st) | 145 | (modify-syntax-entry ?& "." st) |
| 139 | (modify-syntax-entry ?\' "\"" st) | 146 | (modify-syntax-entry ?\' "\"" st) |
| 140 | (modify-syntax-entry ?* "." st) | 147 | (modify-syntax-entry ?* "." st) |
| @@ -187,14 +194,11 @@ The expansion is entirely correct because it uses the C preprocessor." | |||
| 187 | (list | 194 | (list |
| 188 | ;; | 195 | ;; |
| 189 | ;; Fontify keywords, except those fontified otherwise. | 196 | ;; Fontify keywords, except those fontified otherwise. |
| 190 | ; (make-regexp '("if" "until" "while" "elsif" "else" "unless" "do" "dump" | 197 | (concat "\\<" |
| 191 | ; "for" "foreach" "exit" "die" | 198 | (regexp-opt '("if" "until" "while" "elsif" "else" "unless" |
| 192 | ; "BEGIN" "END" "return" "exec" "eval")) | 199 | "do" "dump" "for" "foreach" "exit" "die" |
| 193 | (concat "\\<\\(" | 200 | "BEGIN" "END" "return" "exec" "eval") t) |
| 194 | "BEGIN\\|END\\|d\\(ie\\|o\\|ump\\)\\|" | 201 | "\\>") |
| 195 | "e\\(ls\\(e\\|if\\)\\|val\\|x\\(ec\\|it\\)\\)\\|" | ||
| 196 | "for\\(\\|each\\)\\|if\\|return\\|un\\(less\\|til\\)\\|while" | ||
| 197 | "\\)\\>") | ||
| 198 | ;; | 202 | ;; |
| 199 | ;; Fontify local and my keywords as types. | 203 | ;; Fontify local and my keywords as types. |
| 200 | '("\\<\\(local\\|my\\)\\>" . font-lock-type-face) | 204 | '("\\<\\(local\\|my\\)\\>" . font-lock-type-face) |
| @@ -217,17 +221,149 @@ The expansion is entirely correct because it uses the C preprocessor." | |||
| 217 | (defvar perl-font-lock-keywords perl-font-lock-keywords-1 | 221 | (defvar perl-font-lock-keywords perl-font-lock-keywords-1 |
| 218 | "Default expressions to highlight in Perl mode.") | 222 | "Default expressions to highlight in Perl mode.") |
| 219 | 223 | ||
| 224 | (defvar perl-quote-like-pairs | ||
| 225 | '((?\( . ?\)) (?\[ . ?\]) (?\{ . ?\}) (?\< . ?\>))) | ||
| 226 | |||
| 227 | ;; FIXME: handle here-docs and regexps. | ||
| 228 | ;; <<EOF <<"EOF" <<'EOF' (no space) | ||
| 229 | ;; see `man perlop' | ||
| 230 | ;; ?...? | ||
| 231 | ;; /.../ | ||
| 232 | ;; m [...] | ||
| 233 | ;; m /.../ | ||
| 234 | ;; q /.../ = '...' | ||
| 235 | ;; qq /.../ = "..." | ||
| 236 | ;; qx /.../ = `...` | ||
| 237 | ;; qr /.../ = precompiled regexp =~=~ m/.../ | ||
| 238 | ;; qw /.../ | ||
| 239 | ;; s /.../.../ | ||
| 240 | ;; s <...> /.../ | ||
| 241 | ;; s '...'...' | ||
| 242 | ;; tr /.../.../ | ||
| 243 | ;; y /.../.../ | ||
| 244 | ;; | ||
| 245 | ;; <file*glob> | ||
| 220 | (defvar perl-font-lock-syntactic-keywords | 246 | (defvar perl-font-lock-syntactic-keywords |
| 221 | ;; Turn POD into b-style comments | 247 | ;; Turn POD into b-style comments |
| 222 | '(("^\\(=\\)\\(head1\\|pod\\)\\([ \t]\\|$\\)" (1 "< b")) | 248 | '(("^\\(=\\)\\sw" (1 "< b")) |
| 223 | ("^=cut[ \t]*\\(\n\\)" (1 "> b")) | 249 | ("^=cut[ \t]*\\(\n\\)" (1 "> b")) |
| 224 | ;; Catch ${ so that ${var} doesn't screw up indentation. | 250 | ;; Catch ${ so that ${var} doesn't screw up indentation. |
| 225 | ("\\(\\$\\)[{']" (1 ".")))) | 251 | ;; This also catches $' to handle 'foo$', although it should really |
| 252 | ;; check that it occurs inside a '..' string. | ||
| 253 | ("\\(\\$\\)[{']" (1 ".")) | ||
| 254 | ;; Handle funny names like $DB'stop. | ||
| 255 | ("\\$ ?{?^?[_a-zA-Z][_a-zA-Z0-9]*\\('\\)[_a-zA-Z]" (1 "_")) | ||
| 256 | ;; format statements | ||
| 257 | ("^[ \t]*format.*=[ \t]*\\(\n\\)" (1 '(7))) | ||
| 258 | ;; Funny things in sub arg specifications like `sub myfunc ($$)' | ||
| 259 | ("\\<sub\\s-+\\S-+\\s-*(\\([^)]+\\))" 1 '(1)) | ||
| 260 | ;; regexp and funny quotes | ||
| 261 | ("[;(=!~{][ \t\n]*\\(/\\)" (1 '(7))) | ||
| 262 | ("[;( =!~{\t\n]\\([msy]\\|q[qxrw]?\\|tr\\)\\>\\s-*\\([^])}> \n\t]\\)" | ||
| 263 | ;; Nasty cases: | ||
| 264 | ;; /foo/m $a->m $#m $m @m %m | ||
| 265 | ;; \s (appears often in regexps). | ||
| 266 | ;; -s file | ||
| 267 | (2 (if (assoc (char-after (match-beginning 2)) | ||
| 268 | perl-quote-like-pairs) | ||
| 269 | '(15) '(7)))))) | ||
| 270 | |||
| 271 | (defvar perl-empty-syntax-table | ||
| 272 | (let ((st (copy-syntax-table))) | ||
| 273 | ;; Make all chars be of punctuation syntax. | ||
| 274 | (dotimes (i 256) (aset st i '(1))) | ||
| 275 | (modify-syntax-entry ?\\ "\\" st) | ||
| 276 | st) | ||
| 277 | "Syntax table used internally for processing quote-like operators.") | ||
| 278 | |||
| 279 | (defun perl-quote-syntax-table (char) | ||
| 280 | (let ((close (cdr (assq char perl-quote-like-pairs))) | ||
| 281 | (st (copy-syntax-table perl-empty-syntax-table))) | ||
| 282 | (if (not close) | ||
| 283 | (modify-syntax-entry char "\"" st) | ||
| 284 | (modify-syntax-entry char "(" st) | ||
| 285 | (modify-syntax-entry close ")" st)) | ||
| 286 | st)) | ||
| 226 | 287 | ||
| 227 | (defun perl-font-lock-syntactic-face-function (state) | 288 | (defun perl-font-lock-syntactic-face-function (state) |
| 228 | (if (nth 3 state) | 289 | (let ((char (nth 3 state))) |
| 229 | font-lock-string-face | 290 | (cond |
| 230 | (if (nth 7 state) font-lock-doc-face font-lock-comment-face))) | 291 | ((not char) |
| 292 | ;; Comment or docstring. | ||
| 293 | (if (nth 7 state) font-lock-doc-face font-lock-comment-face)) | ||
| 294 | ((and (char-valid-p char) (eq (char-syntax (nth 3 state)) ?\")) | ||
| 295 | ;; Normal string. | ||
| 296 | font-lock-string-face) | ||
| 297 | ((eq (nth 3 state) ?\n) | ||
| 298 | ;; A `format' command. | ||
| 299 | (save-excursion | ||
| 300 | (when (and (re-search-forward "^\\s *\\.\\s *$" nil t) | ||
| 301 | (not (eobp))) | ||
| 302 | (put-text-property (point) (1+ (point)) 'syntax-table '(7))) | ||
| 303 | font-lock-string-face)) | ||
| 304 | (t | ||
| 305 | ;; This is regexp like quote thingy. | ||
| 306 | (setq char (char-after (nth 8 state))) | ||
| 307 | (save-excursion | ||
| 308 | (let ((twoargs (save-excursion | ||
| 309 | (goto-char (nth 8 state)) | ||
| 310 | (skip-syntax-backward " ") | ||
| 311 | (skip-syntax-backward "w") | ||
| 312 | (member (buffer-substring | ||
| 313 | (point) (progn (forward-word 1) (point))) | ||
| 314 | '("tr" "s" "y")))) | ||
| 315 | (close (cdr (assq char perl-quote-like-pairs))) | ||
| 316 | (pos (point)) | ||
| 317 | (st (perl-quote-syntax-table char))) | ||
| 318 | (if (not close) | ||
| 319 | ;; The closing char is the same as the opening char. | ||
| 320 | (with-syntax-table st | ||
| 321 | (parse-partial-sexp (point) (point-max) | ||
| 322 | nil nil state 'syntax-table) | ||
| 323 | (when twoargs | ||
| 324 | (parse-partial-sexp (point) (point-max) | ||
| 325 | nil nil state 'syntax-table))) | ||
| 326 | ;; The open/close chars are matched like () [] {} and <>. | ||
| 327 | (let ((parse-sexp-lookup-properties nil)) | ||
| 328 | (ignore-errors | ||
| 329 | (with-syntax-table st | ||
| 330 | (goto-char (nth 8 state)) (forward-sexp 1)) | ||
| 331 | (when twoargs | ||
| 332 | (save-excursion | ||
| 333 | ;; Skip whitespace and make sure that font-lock will | ||
| 334 | ;; refontify the second part in the proper context. | ||
| 335 | (put-text-property | ||
| 336 | (point) (progn (forward-comment (point-max)) (point)) | ||
| 337 | 'font-lock-multiline t) | ||
| 338 | ;; | ||
| 339 | (unless | ||
| 340 | (save-excursion | ||
| 341 | (let* ((char2 (char-after)) | ||
| 342 | (st2 (perl-quote-syntax-table char2))) | ||
| 343 | (with-syntax-table st2 (forward-sexp 1)) | ||
| 344 | (put-text-property pos (line-end-position) | ||
| 345 | 'jit-lock-defer-multiline t) | ||
| 346 | (looking-at "\\s-*\\sw*e"))) | ||
| 347 | (put-text-property (point) (1+ (point)) | ||
| 348 | 'syntax-table | ||
| 349 | (if (assoc (char-after) | ||
| 350 | perl-quote-like-pairs) | ||
| 351 | '(15) '(7))))))))) | ||
| 352 | ;; Erase any syntactic marks within the quoted text. | ||
| 353 | (put-text-property pos (1- (point)) 'syntax-table nil) | ||
| 354 | (when (eq (char-before (1- (point))) ?$) | ||
| 355 | (put-text-property (- (point) 2) (1- (point)) | ||
| 356 | 'syntax-table '(1))) | ||
| 357 | (put-text-property (1- (point)) (point) | ||
| 358 | 'syntax-table (if close '(15) '(7))) | ||
| 359 | font-lock-string-face)))))) | ||
| 360 | ;; (if (or twoargs (not (looking-at "\\s-*\\sw*e"))) | ||
| 361 | ;; font-lock-string-face | ||
| 362 | ;; (font-lock-fontify-syntactically-region | ||
| 363 | ;; ;; FIXME: `end' is accessed via dyn-scoping. | ||
| 364 | ;; pos (min end (1- (point))) nil '(nil)) | ||
| 365 | ;; nil))))))) | ||
| 366 | |||
| 231 | 367 | ||
| 232 | (defcustom perl-indent-level 4 | 368 | (defcustom perl-indent-level 4 |
| 233 | "*Indentation of Perl statements with respect to containing block." | 369 | "*Indentation of Perl statements with respect to containing block." |
| @@ -536,7 +672,8 @@ changed by, or (parse-state) if line starts in a quoted string." | |||
| 536 | (defun perl-calculate-indent (&optional parse-start) | 672 | (defun perl-calculate-indent (&optional parse-start) |
| 537 | "Return appropriate indentation for current line as Perl code. | 673 | "Return appropriate indentation for current line as Perl code. |
| 538 | In usual case returns an integer: the column to indent to. | 674 | In usual case returns an integer: the column to indent to. |
| 539 | Returns (parse-state) if line starts inside a string." | 675 | Returns (parse-state) if line starts inside a string. |
| 676 | Optional argument PARSE-START should be the position of `beginning-of-defun'." | ||
| 540 | (save-excursion | 677 | (save-excursion |
| 541 | (beginning-of-line) | 678 | (beginning-of-line) |
| 542 | (let ((indent-point (point)) | 679 | (let ((indent-point (point)) |
| @@ -557,16 +694,16 @@ Returns (parse-state) if line starts inside a string." | |||
| 557 | (perl-beginning-of-function)) | 694 | (perl-beginning-of-function)) |
| 558 | (while (< (point) indent-point) ;repeat until right sexp | 695 | (while (< (point) indent-point) ;repeat until right sexp |
| 559 | (setq state (parse-partial-sexp (point) indent-point 0)) | 696 | (setq state (parse-partial-sexp (point) indent-point 0)) |
| 560 | ; state = (depth_in_parens innermost_containing_list last_complete_sexp | 697 | ;; state = (depth_in_parens innermost_containing_list |
| 561 | ; string_terminator_or_nil inside_commentp following_quotep | 698 | ;; last_complete_sexp string_terminator_or_nil inside_commentp |
| 562 | ; minimum_paren-depth_this_scan) | 699 | ;; following_quotep minimum_paren-depth_this_scan) |
| 563 | ; Parsing stops if depth in parentheses becomes equal to third arg. | 700 | ;; Parsing stops if depth in parentheses becomes equal to third arg. |
| 564 | (setq containing-sexp (nth 1 state))) | 701 | (setq containing-sexp (nth 1 state))) |
| 565 | (cond ((nth 3 state) state) ; In a quoted string? | 702 | (cond ((nth 3 state) state) ; In a quoted string? |
| 566 | ((null containing-sexp) ; Line is at top level. | 703 | ((null containing-sexp) ; Line is at top level. |
| 567 | (skip-chars-forward " \t\f") | 704 | (skip-chars-forward " \t\f") |
| 568 | (if (= (following-char) ?{) | 705 | (if (= (following-char) ?{) |
| 569 | 0 ; move to beginning of line if it starts a function body | 706 | 0 ; move to beginning of line if it starts a function body |
| 570 | ;; indent a little if this is a continuation line | 707 | ;; indent a little if this is a continuation line |
| 571 | (perl-backward-to-noncomment) | 708 | (perl-backward-to-noncomment) |
| 572 | (if (or (bobp) | 709 | (if (or (bobp) |
| @@ -609,50 +746,50 @@ Returns (parse-state) if line starts inside a string." | |||
| 609 | ;; Is line first statement after an open-brace? | 746 | ;; Is line first statement after an open-brace? |
| 610 | ;; If no, find that first statement and indent like it. | 747 | ;; If no, find that first statement and indent like it. |
| 611 | (save-excursion | 748 | (save-excursion |
| 612 | (forward-char 1) | 749 | (forward-char 1) |
| 613 | ;; Skip over comments and labels following openbrace. | 750 | ;; Skip over comments and labels following openbrace. |
| 614 | (while (progn | 751 | (while (progn |
| 615 | (skip-chars-forward " \t\f\n") | 752 | (skip-chars-forward " \t\f\n") |
| 616 | (cond ((looking-at ";?#") | 753 | (cond ((looking-at ";?#") |
| 617 | (forward-line 1) t) | 754 | (forward-line 1) t) |
| 618 | ((looking-at "\\(\\w\\|\\s_\\)+:") | 755 | ((looking-at "\\(\\w\\|\\s_\\)+:") |
| 619 | (save-excursion | 756 | (save-excursion |
| 620 | (end-of-line) | 757 | (end-of-line) |
| 621 | (setq colon-line-end (point))) | 758 | (setq colon-line-end (point))) |
| 622 | (search-forward ":"))))) | 759 | (search-forward ":"))))) |
| 623 | ;; The first following code counts | 760 | ;; The first following code counts |
| 624 | ;; if it is before the line we want to indent. | 761 | ;; if it is before the line we want to indent. |
| 625 | (and (< (point) indent-point) | 762 | (and (< (point) indent-point) |
| 626 | (if (> colon-line-end (point)) | 763 | (if (> colon-line-end (point)) |
| 627 | (- (current-indentation) perl-label-offset) | 764 | (- (current-indentation) perl-label-offset) |
| 628 | (current-column)))) | 765 | (current-column)))) |
| 629 | ;; If no previous statement, | 766 | ;; If no previous statement, |
| 630 | ;; indent it relative to line brace is on. | 767 | ;; indent it relative to line brace is on. |
| 631 | ;; For open paren in column zero, don't let statement | 768 | ;; For open paren in column zero, don't let statement |
| 632 | ;; start there too. If perl-indent-level is zero, | 769 | ;; start there too. If perl-indent-level is zero, |
| 633 | ;; use perl-brace-offset + perl-continued-statement-offset | 770 | ;; use perl-brace-offset + perl-continued-statement-offset |
| 634 | ;; For open-braces not the first thing in a line, | 771 | ;; For open-braces not the first thing in a line, |
| 635 | ;; add in perl-brace-imaginary-offset. | 772 | ;; add in perl-brace-imaginary-offset. |
| 636 | (+ (if (and (bolp) (zerop perl-indent-level)) | 773 | (+ (if (and (bolp) (zerop perl-indent-level)) |
| 637 | (+ perl-brace-offset perl-continued-statement-offset) | 774 | (+ perl-brace-offset perl-continued-statement-offset) |
| 638 | perl-indent-level) | 775 | perl-indent-level) |
| 639 | ;; Move back over whitespace before the openbrace. | 776 | ;; Move back over whitespace before the openbrace. |
| 640 | ;; If openbrace is not first nonwhite thing on the line, | 777 | ;; If openbrace is not first nonwhite thing on the line, |
| 641 | ;; add the perl-brace-imaginary-offset. | 778 | ;; add the perl-brace-imaginary-offset. |
| 642 | (progn (skip-chars-backward " \t") | 779 | (progn (skip-chars-backward " \t") |
| 643 | (if (bolp) 0 perl-brace-imaginary-offset)) | 780 | (if (bolp) 0 perl-brace-imaginary-offset)) |
| 644 | ;; If the openbrace is preceded by a parenthesized exp, | 781 | ;; If the openbrace is preceded by a parenthesized exp, |
| 645 | ;; move to the beginning of that; | 782 | ;; move to the beginning of that; |
| 646 | ;; possibly a different line | 783 | ;; possibly a different line |
| 647 | (progn | 784 | (progn |
| 648 | (if (eq (preceding-char) ?\)) | 785 | (if (eq (preceding-char) ?\)) |
| 649 | (forward-sexp -1)) | 786 | (forward-sexp -1)) |
| 650 | ;; Get initial indentation of the line we are on. | 787 | ;; Get initial indentation of the line we are on. |
| 651 | (current-indentation)))))))))) | 788 | (current-indentation)))))))))) |
| 652 | 789 | ||
| 653 | (defun perl-backward-to-noncomment () | 790 | (defun perl-backward-to-noncomment () |
| 654 | "Move point backward to after the first non-white-space, skipping comments." | 791 | "Move point backward to after the first non-white-space, skipping comments." |
| 655 | (interactive) ;why?? -stef | 792 | (interactive) |
| 656 | (forward-comment (- (point-max)))) | 793 | (forward-comment (- (point-max)))) |
| 657 | 794 | ||
| 658 | (defun perl-backward-to-start-of-continued-exp (lim) | 795 | (defun perl-backward-to-start-of-continued-exp (lim) |