# HG changeset patch # User Richard M. Stallman # Date 887699088 0 # Node ID a0748eef9a76f41abd43046495b92ff4546dbc78 # Parent 8ec2d600e66d5eab8f834a8106899d61f4e83b03 (c-beginning-of-statement) (c-end-of-statement): Do not move by sentence in strings. (c-beginning-of-statement): Major rewrite. (c-beginning-of-defun, c-indent-defun): Use (c-point 'bod) instead of beginning-of-defun directly. (c-beginning-of-defun, c-end-of-defun): New commands. (c-beginning-of-statement): When moving forward by sentences, because we're either inside or at the start of a comment, be sure to limit movement to only within the extent of the comment. (c-electric-colon): Don't insert newlines before or after scope operators, regardless of the value of c-hanging-colons. (c-electric-brace): namespace-open and namespace-close braces can hang. (c-comment-line-break-function): When breaking a line-oriented comment, copy the comment leader from the previous line instead of hardcoding it to "// ". This ensures that whitespace between the slashes and the text is preserved. (c-electric-pound, c-electric-brace) (c-electric-slash, c-electric-star, c-electric-semi&comma) (c-electric-colon, c-electric-lt-gt, c-scope-operator) (c-electric-backspace, c-electric-delete) (c-indent-command, c-indent-exp, c-indent-defun) (c-backslash-region, c-fill-paragraph): Add "*" to interactive spec. (c-fill-paragraph): regexp-quote the fill-prefix when search forward for the end of line oriented comments. (c-backslash-region): Do not preserve the zmacs region (XEmacs). diff -r 8ec2d600e66d -r a0748eef9a76 lisp/progmodes/cc-cmds.el --- a/lisp/progmodes/cc-cmds.el Tue Feb 17 07:02:18 1998 +0000 +++ b/lisp/progmodes/cc-cmds.el Tue Feb 17 07:04:48 1998 +0000 @@ -1,6 +1,6 @@ ;;; cc-cmds.el --- user level commands for CC Mode -;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc. +;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc. ;; Authors: 1992-1997 Barry A. Warsaw ;; 1987 Dave Detlefs and Stewart Clamen @@ -102,7 +102,7 @@ `c-backspace-function' is called. See also \\[c-electric-delete]." - (interactive "P") + (interactive "*P") (if (or (not c-hungry-delete-key) arg (c-in-literal)) @@ -122,13 +122,14 @@ exist, as in older Emacsen), then this function behaves identical to \\[c-electric-backspace]. -If `delete-key-deletes-forward' is non-nil, then deletion occurs in -the forward direction. So if `c-hungry-delete-key' is non-nil, as -evidenced by the \"/h\" or \"/ah\" string on the mode line, then all -following whitespace is consumed. If however an ARG is supplied, or -`c-hungry-delete-key' is nil, or point is inside a literal then the -function in the variable `c-delete-function' is called." - (interactive "P") +If `delete-key-deletes-forward' is non-nil and is supported in your +Emacs, then deletion occurs in the forward direction. So if +`c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or +\"/ah\" string on the mode line, then all following whitespace is +consumed. If however an ARG is supplied, or `c-hungry-delete-key' is +nil, or point is inside a literal then the function in the variable +`c-delete-function' is called." + (interactive "*P") (if (and (boundp 'delete-key-deletes-forward) delete-key-deletes-forward) (if (or (not c-hungry-delete-key) @@ -148,7 +149,7 @@ Inserts a `#' character specially depending on the variable `c-electric-pound-behavior'. If a numeric ARG is supplied, or if point is inside a literal, nothing special happens." - (interactive "P") + (interactive "*P") (if (or (c-in-literal) arg (not (memq 'alignleft c-electric-pound-behavior))) @@ -174,7 +175,7 @@ Also, the line is re-indented unless a numeric ARG is supplied, there are non-whitespace characters present on the line after the brace, or the brace is inserted inside a literal." - (interactive "P") + (interactive "*P") (let* ((c-state-cache (c-parse-state)) (safepos (c-safe-position (point) c-state-cache)) (literal (c-in-literal safepos))) @@ -185,11 +186,19 @@ ; (not c-auto-newline) (not (looking-at "[ \t]*$"))) (self-insert-command (prefix-numeric-value arg)) - (let* ((syms '(class-open class-close defun-open defun-close - inline-open inline-close brace-list-open brace-list-close - brace-list-intro brace-list-entry block-open block-close - substatement-open statement-case-open - extern-lang-open extern-lang-close)) + (let* ((syms + ;; This is the list of brace syntactic symbols that can + ;; hang. If any new ones are added to c-offsets-alist, + ;; they should be added here as well. + '(class-open class-close defun-open defun-close + inline-open inline-close + brace-list-open brace-list-close + brace-list-intro brace-list-entry + block-open block-close + substatement-open statement-case-open + extern-lang-open extern-lang-close + namespace-open namespace-close + )) ;; we want to inhibit blinking the paren since this will ;; be most disruptive. we'll blink it ourselves later on (old-blink-paren blink-paren-function) @@ -366,7 +375,7 @@ If numeric ARG is supplied or point is inside a literal, indentation is inhibited." - (interactive "P") + (interactive "*P") (let* ((ch (char-before)) (indentp (and (not arg) (eq last-command-char ?/) @@ -387,7 +396,7 @@ construct, and we are on a comment-only-line, indent line as comment. If numeric ARG is supplied or point is inside a literal, indentation is inhibited." - (interactive "P") + (interactive "*P") (self-insert-command (prefix-numeric-value arg)) ;; if we are in a literal, or if arg is given do not re-indent the ;; current line, unless this star introduces a comment-only line. @@ -416,7 +425,7 @@ When semicolon is inserted, the line is re-indented unless a numeric arg is supplied, point is inside a literal, or there are non-whitespace characters on the line following the semicolon." - (interactive "P") + (interactive "*P") (let* ((lim (c-most-enclosing-brace (c-parse-state))) (literal (c-in-literal lim)) (here (point)) @@ -479,10 +488,10 @@ This function cleans up double colon scope operators based on the value of `c-cleanup-list'." - (interactive "P") + (interactive "*P") (let* ((bod (c-point 'bod)) (literal (c-in-literal bod)) - syntax newlines + syntax newlines is-scope-op ;; shut this up (c-echo-syntactic-information-p nil)) (if (or literal @@ -502,7 +511,9 @@ (eq (char-before) ?:)) (not (c-in-literal)) (not (eq (char-after (- (point) 2)) ?:))) - (delete-region (point) (1- here))) + (progn + (delete-region (point) (1- here)) + (setq is-scope-op t))) (goto-char (- (point-max) pos))) ;; lets do some special stuff with the colon character (setq syntax (c-guess-basic-syntax) @@ -526,6 +537,7 @@ ;; non-hung colons. However, we don't unhang them because that ;; would be a cleanup (and anti-social). (if (and (memq 'before newlines) + (not is-scope-op) (save-excursion (skip-chars-backward ": \t") (not (bolp)))) @@ -535,7 +547,8 @@ (c-indent-line) (goto-char (- (point-max) pos)))) ;; does a newline go after the colon? - (if (memq 'after (cdr-safe newlines)) + (if (and (memq 'after (cdr-safe newlines)) + (not is-scope-op)) (progn (newline) (c-indent-line))) @@ -550,7 +563,7 @@ The line will also not be re-indented if a numeric argument is supplied, or point is inside a literal." - (interactive "P") + (interactive "*P") (let ((indentp (and (not arg) (eq (char-before) last-command-char) (not (c-in-literal)))) @@ -590,16 +603,67 @@ (defun c-scope-operator () "Insert a double colon scope operator at point. No indentation or other \"electric\" behavior is performed." - (interactive) + (interactive "*") (insert "::")) +(defun c-beginning-of-defun (&optional arg) + "Move backward to the beginning of a defun. +With argument, do it that many times. Negative arg -N +means move forward to Nth following beginning of defun. +Returns t unless search stops due to beginning or end of buffer. + +Unlike the built-in `beginning-of-defun' this tries to be smarter +about finding the char with open-parenthesis syntax that starts the +defun." + (interactive "p") + (if (< arg 0) + (c-end-of-defun (- arg)) + (while (> arg 0) + (let ((state (nreverse (c-parse-state))) + prevbod bod) + (while (and state (not bod)) + (setq bod (car state) + state (cdr state)) + (if (consp bod) + (setq prevbod (car bod) + bod nil))) + (cond + (bod (goto-char bod)) + (prevbod (goto-char prevbod)) + (t (goto-char (c-point 'bod))))) + (setq arg (1- arg)))) + (c-keep-region-active)) + +(defun c-end-of-defun (&optional arg) + "Move forward to next end of defun. With argument, do it that many times. +Negative argument -N means move back to Nth preceding end of defun. + +An end of a defun occurs right after the close-parenthesis that matches +the open-parenthesis that starts a defun; see `beginning-of-defun'." + (interactive "p") + (if (< arg 0) + (c-beginning-of-defun (- arg)) + (while (> arg 0) + ;; skip down into the next defun-block + (while (and (c-safe (down-list 1) t) + (not (eq (char-before) ?{))) + (forward-char -1) + (forward-sexp)) + (c-beginning-of-defun 1) + (forward-sexp 1) + (setq arg (1- arg))) + (forward-line 1)) + (c-keep-region-active)) + (defun c-beginning-of-statement (&optional count lim sentence-flag) "Go to the beginning of the innermost C statement. With prefix arg, go back N - 1 statements. If already at the -beginning of a statement then go to the beginning of the preceding -one. If within a string or comment, or next to a comment (only -whitespace between), move by sentences instead of statements. +beginning of a statement then go to the beginning of the closest +preceding one, moving into nested blocks if necessary (use +\\[backward-sexp] to skip over a block). If within a comment, or next +to a comment (only whitespace between), move by sentences instead of +statements. When called from a program, this function takes 3 optional args: the repetition count, a buffer position limit which is the farthest back @@ -607,45 +671,167 @@ comment." (interactive (list (prefix-numeric-value current-prefix-arg) nil t)) - (let ((here (point)) - (count (or count 1)) - (lim (or lim (c-point 'bod))) - state) - (save-excursion - (goto-char lim) - (setq state (parse-partial-sexp (point) here nil nil))) - (if (and sentence-flag - (or (nth 3 state) - (nth 4 state) - ;; skipping forward into a comment? - (and (> 0 count) - (save-excursion - (skip-chars-forward " \t\n") - (or (eobp) - (looking-at comment-start-skip)))) - (and (< 0 count) - (save-excursion - (skip-chars-backward " \t\n") - (goto-char (- (point) 2)) - (looking-at "\\*/"))))) - (forward-sentence (- count)) - (while (> count 0) - (c-beginning-of-statement-1 lim) - (setq count (1- count))) - (while (< count 0) - (c-end-of-statement-1) - (setq count (1+ count)))) + (let* ((count (or count 1)) + here + (range (c-collect-line-comments (c-literal-limits lim)))) + (while (and (/= count 0) + (or (not lim) (> (point) lim))) + (setq here (point)) + (if (and (not range) sentence-flag) + (save-excursion + ;; Find the comment next to point if we're not in one. + (if (> count 0) + ;; Finding a comment backwards is a bit cumbersome + ;; because `forward-comment' regards every newline as + ;; a comment when searching backwards (Emacs 19.34). + (while (and (progn (skip-chars-backward " \t") + (setq range (point)) + (setq range (if (forward-comment -1) + (cons (point) range) + nil))) + (= (char-after) ?\n))) + (skip-chars-forward " \t\n") + (setq range (point)) + (setq range (if (forward-comment 1) + (cons range (point)) + nil))) + (setq range (c-collect-line-comments range)))) + (if (and (< count 0) (= here (point-max))) + ;; Special case because eob might be in a literal. + (setq range nil)) + (if range + (if (and sentence-flag + (/= (char-syntax (char-after (car range))) ?\")) + (progn + ;; move by sentence, but not past the limit of the literal + (save-restriction + (narrow-to-region (save-excursion + (goto-char (car range)) + (looking-at comment-start-skip) + (goto-char (match-end 0)) + (point)) + (save-excursion + (goto-char (cdr range)) + (if (save-excursion + (goto-char (car range)) + (looking-at "/\\*")) + (backward-char 2)) + (skip-chars-backward " \t\n") + (point))) + (c-safe (forward-sentence (if (> count 0) -1 1)))) + ;; See if we should escape the literal. + (if (> count 0) + (if (< (point) here) + (setq count (1- count)) + (goto-char (car range)) + (setq range nil)) + (if (> (point) here) + (setq count (1+ count)) + (goto-char (cdr range)) + (setq range nil)))) + (goto-char (if (> count 0) (car range) (cdr range))) + (setq range nil)) + ;; Below we do approximately the same as + ;; c-beginning-of-statement-1 and c-end-of-statement-1 and + ;; perhaps they should be changed, but that'd likely break a + ;; lot in cc-engine. + (goto-char here) + ;; Move out of any enclosing non-`{ }' parens. + (let ((last (point))) + (while (and (c-safe (progn (up-list 1) t)) + (/= (char-before) ?\})) + (setq last (point))) + (goto-char last)) + (if (> count 0) + (if (condition-case nil + ;; Stop before `{' and after `;', `{', `}' and + ;; `};' when not followed by `}', but on the other + ;; side of the syntactic ws. Also stop before + ;; `}', but only to catch comments. Move by sexps + ;; and move into `{ }', but not into any other + ;; other type of paren. + (catch 'done + (let (last) + (while t + (setq last (point)) + (if (and (looking-at "[{}]") + (/= here last)) + (throw 'done (= (char-after) ?{))) + (c-backward-syntactic-ws) + (cond ((bobp) ; Must handle bob specially. + (if (= here last) + (if (= last (point-min)) + (throw 'done t) + (goto-char last) + (throw 'done nil)) + (goto-char last) + (throw 'done t))) + ((progn (backward-char) + (looking-at "[;{}]")) + (if (or (= here last) + (= (char-after last) ?})) + (if (and (= (char-before) ?}) + (= (char-after) ?\;)) + (backward-char)) + (goto-char last) + (throw 'done t))) + ((or (= (char-syntax (char-after)) ?\)) + (= (char-syntax (char-after)) ?\")) + (forward-char) + (backward-sexp)) + )))) + (error + (goto-char (point-min)) + t)) + (setq count (1- count))) + (if (condition-case nil + ;; Stop before `{' and `}' and after `;', `}' and + ;; `};'. Also stop after `{', but only to catch + ;; comments. Move by sexps and move into `{ }', but + ;; not into any other other type of paren. + (catch 'done + (let (last) + (while t + (setq last (point)) + (c-forward-syntactic-ws) + (cond ((= (char-after) ?{) + (if (= here last) + (progn (forward-char) + (throw 'done nil)) + (goto-char last) + (throw 'done t))) + ((and (= (char-after) ?}) + (/= here last)) + (goto-char last) + (throw 'done t)) + ((looking-at ";\\|};?") + (goto-char (match-end 0)) + (throw 'done t)) + ((or (= (char-syntax (char-after)) ?\() + (= (char-syntax (char-after)) ?\")) + (forward-sexp)) + (t + (forward-char)) + )))) + (error + (goto-char (point-max)) + t)) + (setq count (1+ count))))) + ;; If we haven't moved we're near a buffer limit. + (when (= (point) here) + (goto-char (if (> count 0) (point-min) (point-max))) + (setq count 0))) ;; its possible we've been left up-buf of lim - (goto-char (max (point) lim)) - ) + (if lim (goto-char (max (point) lim)))) (c-keep-region-active)) (defun c-end-of-statement (&optional count lim sentence-flag) "Go to the end of the innermost C statement. - -With prefix arg, go forward N - 1 statements. Move forward to end of -the next statement if already at end. If within a string or comment, -move by sentences instead of statements. +With prefix arg, go forward N - 1 statements. Move forward to the end +of the next statement if already at end, and move into nested blocks +\(use \\[forward-sexp] to skip over a block). If within a comment, or +next to a comment (only whitespace between), move by sentences instead +of statements. When called from a program, this function takes 3 optional args: the repetition count, a buffer position limit which is the farthest back @@ -778,7 +964,7 @@ "\\)[ \t]+")) (string-equal (match-string 1) "//")) ;; line style - (setq leader "// ")) + (setq leader (match-string 0))) (goto-char here) (delete-region (progn (skip-chars-backward " \t") (point)) (progn (skip-chars-forward " \t") (point))) @@ -909,7 +1095,7 @@ just inserts a tab character, or the equivalent number of spaces, depending on the variable `indent-tabs-mode'." - (interactive "P") + (interactive "*P") (let ((bod (c-point 'bod))) (if whole-exp ;; If arg, always indent this line as C @@ -952,7 +1138,7 @@ (defun c-indent-exp (&optional shutup-p) "Indent each line in balanced expression following point. Optional SHUTUP-P if non-nil, inhibits message printing and error checking." - (interactive "P") + (interactive "*P") (let ((here (point)) end progress-p) (unwind-protect @@ -999,13 +1185,11 @@ (defun c-indent-defun () "Re-indents the current top-level function def, struct or class declaration." - (interactive) + (interactive "*") (let ((here (point-marker)) (c-echo-syntactic-information-p nil) (brace (c-least-enclosing-brace (c-parse-state)))) - (if brace - (goto-char brace) - (beginning-of-defun)) + (goto-char (or brace (c-point 'bod))) ;; if we're sitting at b-o-b, it might be because there was no ;; least enclosing brace and we were sitting on the defun's open ;; brace. @@ -1205,7 +1389,7 @@ You can put the region around an entire macro definition and use this command to conveniently insert and align the necessary backslashes." - (interactive "r\nP") + (interactive "*r\nP") (save-excursion (goto-char from) (let ((column c-backslash-column) @@ -1240,8 +1424,7 @@ (c-append-backslash column) (c-delete-backslash)) (forward-line 1)) - (move-marker endmark nil))) - (c-keep-region-active)) + (move-marker endmark nil)))) (defun c-append-backslash (column) (end-of-line) @@ -1269,7 +1452,7 @@ preserving the comment indentation or line-starting decorations. Optional prefix ARG means justify paragraph as well." - (interactive "P") + (interactive "*P") (let* (comment-start-place (first-line ;; Check for obvious entry to comment. @@ -1308,7 +1491,8 @@ (narrow-to-region (c-point 'bol) (save-excursion (forward-line 1) - (while (looking-at fill-prefix) + (while + (looking-at (regexp-quote fill-prefix)) (forward-line 1)) (point))) (fill-paragraph arg)