mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Fix c-declaration-limits to return correct limits in all cases.
This function is the guts of c-indent-defun and c-mark-function. In particular, when c-defun-tactic is nil, return a correct value rather than always nil, and when it's 'go-outward, go through an intricate algorithm to determine the requisite narrowing before the "top-level" defuns go to work. * lisp/progmodes/cc-cmds.el (c-narrow-to-most-enclosing-decl-block): Enhance to take additional optional parameter LEVEL, saying how many enclosing levels of decl-block to narrow to. (c-declaration-limits): Introduce algorithm to determine narrowing. Use c-where-wrt-to-brace-block to determine whether to go back to BOD to determine lower bound.
This commit is contained in:
parent
0c94b84708
commit
dda2d6a311
1 changed files with 132 additions and 104 deletions
|
|
@ -1501,15 +1501,24 @@ No indentation or other \"electric\" behavior is performed."
|
|||
(setq n (1- n))))
|
||||
n)
|
||||
|
||||
(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive)
|
||||
(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive level)
|
||||
;; If we are inside a decl-block (in the sense of c-looking-at-decl-block),
|
||||
;; i.e. something like namespace{} or extern{}, narrow to the insides of
|
||||
;; that block (NOT including the enclosing braces) if INCLUSIVE is nil,
|
||||
;; otherwise include the braces. If the closing brace is missing,
|
||||
;; (point-max) is used instead.
|
||||
;; otherwise include the braces and the declaration which introduces them.
|
||||
;; If the closing brace is missing, (point-max) is used instead. LEVEL, if
|
||||
;; non-nil, says narrow to the LEVELth decl-block outward, default value
|
||||
;; being 1.
|
||||
(let ((paren-state (c-parse-state))
|
||||
encl-decl)
|
||||
(setq encl-decl (and paren-state (c-most-enclosing-decl-block paren-state)))
|
||||
(setq level (or level 1))
|
||||
(while (> level 0)
|
||||
(setq encl-decl (c-most-enclosing-decl-block paren-state))
|
||||
(if encl-decl
|
||||
(progn
|
||||
(while (> (c-pull-open-brace paren-state) encl-decl))
|
||||
(setq level (1- level)))
|
||||
(setq level 0)))
|
||||
(if encl-decl
|
||||
(save-excursion
|
||||
(narrow-to-region
|
||||
|
|
@ -1875,114 +1884,133 @@ with a brace block."
|
|||
;; This function might do hidden buffer changes.
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(when (eq c-defun-tactic 'go-outward)
|
||||
(c-narrow-to-most-enclosing-decl-block t) ; e.g. class, namespace
|
||||
(or (save-restriction
|
||||
(c-narrow-to-most-enclosing-decl-block nil)
|
||||
(let ((start (point))
|
||||
(paren-state (c-parse-state))
|
||||
lim pos end-pos encl-decl-block where)
|
||||
;; Narrow enclosing brace blocks out, as required by the values of
|
||||
;; `c-defun-tactic', `near', and the position of point.
|
||||
(when (eq c-defun-tactic 'go-outward)
|
||||
(let ((bounds
|
||||
(save-restriction
|
||||
(if (and (not (save-excursion (c-beginning-of-macro)))
|
||||
(save-restriction
|
||||
(c-narrow-to-most-enclosing-decl-block)
|
||||
(memq (c-where-wrt-brace-construct)
|
||||
'(at-function-end outwith-function)))
|
||||
(not near))
|
||||
(c-narrow-to-most-enclosing-decl-block nil 2)
|
||||
(c-narrow-to-most-enclosing-decl-block))
|
||||
(cons (point-min) (point-max)))))
|
||||
(narrow-to-region (car bounds) (cdr bounds))))
|
||||
(setq paren-state (c-parse-state))
|
||||
|
||||
;; Note: Some code duplication in `c-beginning-of-defun' and
|
||||
;; `c-end-of-defun'.
|
||||
(catch 'exit
|
||||
(let ((start (point))
|
||||
(paren-state (c-parse-state))
|
||||
lim pos end-pos)
|
||||
(unless (c-safe
|
||||
(goto-char (c-least-enclosing-brace paren-state))
|
||||
;; If we moved to the outermost enclosing paren
|
||||
;; then we can use c-safe-position to set the
|
||||
;; limit. Can't do that otherwise since the
|
||||
;; earlier paren pair on paren-state might very
|
||||
;; well be part of the declaration we should go
|
||||
;; to.
|
||||
(setq lim (c-safe-position (point) paren-state))
|
||||
t)
|
||||
;; At top level. Make sure we aren't inside a literal.
|
||||
(setq pos (c-literal-start
|
||||
(c-safe-position (point) paren-state)))
|
||||
(if pos (goto-char pos)))
|
||||
(or
|
||||
;; Note: Some code duplication in `c-beginning-of-defun' and
|
||||
;; `c-end-of-defun'.
|
||||
(catch 'exit
|
||||
(unless (c-safe
|
||||
(goto-char (c-least-enclosing-brace paren-state))
|
||||
;; If we moved to the outermost enclosing paren
|
||||
;; then we can use c-safe-position to set the
|
||||
;; limit. Can't do that otherwise since the
|
||||
;; earlier paren pair on paren-state might very
|
||||
;; well be part of the declaration we should go
|
||||
;; to.
|
||||
(setq lim (c-safe-position (point) paren-state))
|
||||
t)
|
||||
;; At top level. Make sure we aren't inside a literal.
|
||||
(setq pos (c-literal-start
|
||||
(c-safe-position (point) paren-state)))
|
||||
(if pos (goto-char pos)))
|
||||
|
||||
(when (c-beginning-of-macro)
|
||||
(throw 'exit
|
||||
(cons (point)
|
||||
(save-excursion
|
||||
(c-end-of-macro)
|
||||
(forward-line 1)
|
||||
(point)))))
|
||||
(when (c-beginning-of-macro)
|
||||
(throw 'exit
|
||||
(cons (point)
|
||||
(save-excursion
|
||||
(c-end-of-macro)
|
||||
(forward-line 1)
|
||||
(point)))))
|
||||
|
||||
(setq pos (point))
|
||||
(when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous)
|
||||
(= pos (point)))
|
||||
;; We moved back over the previous defun. Skip to the next
|
||||
;; one. Not using c-forward-syntactic-ws here since we
|
||||
;; should not skip a macro. We can also be directly after
|
||||
;; the block in a `c-opt-block-decls-with-vars-key'
|
||||
;; declaration, but then we won't move significantly far
|
||||
;; here.
|
||||
(goto-char pos)
|
||||
(c-forward-comments)
|
||||
(setq pos (point))
|
||||
(setq where (and (not (save-excursion (c-beginning-of-macro)))
|
||||
(c-where-wrt-brace-construct)))
|
||||
(when (and (not (eq where 'at-header))
|
||||
(or (and near
|
||||
(memq where
|
||||
'(at-function-end outwith-function)))
|
||||
(eq (car (c-beginning-of-decl-1 lim)) 'previous)
|
||||
(= pos (point))))
|
||||
;; We moved back over the previous defun. Skip to the next
|
||||
;; one. Not using c-forward-syntactic-ws here since we
|
||||
;; should not skip a macro. We can also be directly after
|
||||
;; the block in a `c-opt-block-decls-with-vars-key'
|
||||
;; declaration, but then we won't move significantly far
|
||||
;; here.
|
||||
(goto-char pos)
|
||||
(c-forward-comments)
|
||||
|
||||
(when (and near (c-beginning-of-macro))
|
||||
(throw 'exit
|
||||
(cons (point)
|
||||
(save-excursion
|
||||
(c-end-of-macro)
|
||||
(forward-line 1)
|
||||
(point))))))
|
||||
(when (and near (c-beginning-of-macro))
|
||||
(throw 'exit
|
||||
(cons (point)
|
||||
(save-excursion
|
||||
(c-end-of-macro)
|
||||
(forward-line 1)
|
||||
(point))))))
|
||||
|
||||
(if (eobp) (throw 'exit nil))
|
||||
(if (eobp) (throw 'exit nil))
|
||||
|
||||
;; Check if `c-beginning-of-decl-1' put us after the block in a
|
||||
;; declaration that doesn't end there. We're searching back and
|
||||
;; forth over the block here, which can be expensive.
|
||||
(setq pos (point))
|
||||
(if (and c-opt-block-decls-with-vars-key
|
||||
(progn
|
||||
(c-backward-syntactic-ws)
|
||||
(eq (char-before) ?}))
|
||||
(eq (car (c-beginning-of-decl-1))
|
||||
'previous)
|
||||
(save-excursion
|
||||
(c-end-of-decl-1)
|
||||
(and (> (point) pos)
|
||||
(setq end-pos (point)))))
|
||||
nil
|
||||
(goto-char pos))
|
||||
;; Check if `c-beginning-of-decl-1' put us after the block in a
|
||||
;; declaration that doesn't end there. We're searching back and
|
||||
;; forth over the block here, which can be expensive.
|
||||
(setq pos (point))
|
||||
(if (and c-opt-block-decls-with-vars-key
|
||||
(progn
|
||||
(c-backward-syntactic-ws)
|
||||
(eq (char-before) ?}))
|
||||
(eq (car (c-beginning-of-decl-1))
|
||||
'previous)
|
||||
(save-excursion
|
||||
(c-end-of-decl-1)
|
||||
(and (> (point) pos)
|
||||
(setq end-pos (point)))))
|
||||
nil
|
||||
(goto-char pos))
|
||||
|
||||
(if (and (not near) (> (point) start))
|
||||
nil
|
||||
(if (and (not near) (> (point) start))
|
||||
nil
|
||||
|
||||
;; Try to be line oriented; position the limits at the
|
||||
;; closest preceding boi, and after the next newline, that
|
||||
;; isn't inside a comment, but if we hit a neighboring
|
||||
;; declaration then we instead use the exact declaration
|
||||
;; limit in that direction.
|
||||
(cons (progn
|
||||
(setq pos (point))
|
||||
(while (and (/= (point) (c-point 'boi))
|
||||
(c-backward-single-comment)))
|
||||
(if (/= (point) (c-point 'boi))
|
||||
pos
|
||||
(point)))
|
||||
(progn
|
||||
(if end-pos
|
||||
(goto-char end-pos)
|
||||
(c-end-of-decl-1))
|
||||
(setq pos (point))
|
||||
(while (and (not (bolp))
|
||||
(not (looking-at "\\s *$"))
|
||||
(c-forward-single-comment)))
|
||||
(cond ((bolp)
|
||||
(point))
|
||||
((looking-at "\\s *$")
|
||||
(forward-line 1)
|
||||
(point))
|
||||
(t
|
||||
pos))))))))
|
||||
(and (not near)
|
||||
(goto-char (point-min))
|
||||
(c-forward-decl-or-cast-1 -1 nil nil)
|
||||
(eq (char-after) ?\{)
|
||||
(cons (point-min) (point-max))))))))
|
||||
;; Try to be line oriented; position the limits at the
|
||||
;; closest preceding boi, and after the next newline, that
|
||||
;; isn't inside a comment, but if we hit a neighboring
|
||||
;; declaration then we instead use the exact declaration
|
||||
;; limit in that direction.
|
||||
(cons (progn
|
||||
(setq pos (point))
|
||||
(while (and (/= (point) (c-point 'boi))
|
||||
(c-backward-single-comment)))
|
||||
(if (/= (point) (c-point 'boi))
|
||||
pos
|
||||
(point)))
|
||||
(progn
|
||||
(if end-pos
|
||||
(goto-char end-pos)
|
||||
(c-end-of-decl-1))
|
||||
(setq pos (point))
|
||||
(while (and (not (bolp))
|
||||
(not (looking-at "\\s *$"))
|
||||
(c-forward-single-comment)))
|
||||
(cond ((bolp)
|
||||
(point))
|
||||
((looking-at "\\s *$")
|
||||
(forward-line 1)
|
||||
(point))
|
||||
(t
|
||||
pos))))))
|
||||
(and (not near)
|
||||
(goto-char (point-min))
|
||||
(c-forward-decl-or-cast-1 -1 nil nil)
|
||||
(eq (char-after) ?\{)
|
||||
(cons (point-min) (point-max))))))))
|
||||
|
||||
(defun c-mark-function ()
|
||||
"Put mark at end of the current top-level declaration or macro, point at beginning.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue