aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2016-09-01 18:06:22 +0000
committerAlan Mackenzie2016-09-01 18:12:43 +0000
commitdda2d6a311fd2a7096176e240e4e81b423eaa8e2 (patch)
tree6c7f43e3058c8642f8c51a9ef1ad5d0f95207a75
parent0c94b847082bf915137c4270b8009ad599681ccf (diff)
downloademacs-dda2d6a311fd2a7096176e240e4e81b423eaa8e2.tar.gz
emacs-dda2d6a311fd2a7096176e240e4e81b423eaa8e2.zip
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.
-rw-r--r--lisp/progmodes/cc-cmds.el252
1 files changed, 140 insertions, 112 deletions
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index f0ad2942457..cdca67c698d 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1501,15 +1501,24 @@ No indentation or other \"electric\" behavior is performed."
1501 (setq n (1- n)))) 1501 (setq n (1- n))))
1502 n) 1502 n)
1503 1503
1504(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive) 1504(defun c-narrow-to-most-enclosing-decl-block (&optional inclusive level)
1505 ;; If we are inside a decl-block (in the sense of c-looking-at-decl-block), 1505 ;; If we are inside a decl-block (in the sense of c-looking-at-decl-block),
1506 ;; i.e. something like namespace{} or extern{}, narrow to the insides of 1506 ;; i.e. something like namespace{} or extern{}, narrow to the insides of
1507 ;; that block (NOT including the enclosing braces) if INCLUSIVE is nil, 1507 ;; that block (NOT including the enclosing braces) if INCLUSIVE is nil,
1508 ;; otherwise include the braces. If the closing brace is missing, 1508 ;; otherwise include the braces and the declaration which introduces them.
1509 ;; (point-max) is used instead. 1509 ;; If the closing brace is missing, (point-max) is used instead. LEVEL, if
1510 ;; non-nil, says narrow to the LEVELth decl-block outward, default value
1511 ;; being 1.
1510 (let ((paren-state (c-parse-state)) 1512 (let ((paren-state (c-parse-state))
1511 encl-decl) 1513 encl-decl)
1512 (setq encl-decl (and paren-state (c-most-enclosing-decl-block paren-state))) 1514 (setq level (or level 1))
1515 (while (> level 0)
1516 (setq encl-decl (c-most-enclosing-decl-block paren-state))
1517 (if encl-decl
1518 (progn
1519 (while (> (c-pull-open-brace paren-state) encl-decl))
1520 (setq level (1- level)))
1521 (setq level 0)))
1513 (if encl-decl 1522 (if encl-decl
1514 (save-excursion 1523 (save-excursion
1515 (narrow-to-region 1524 (narrow-to-region
@@ -1875,114 +1884,133 @@ with a brace block."
1875 ;; This function might do hidden buffer changes. 1884 ;; This function might do hidden buffer changes.
1876 (save-excursion 1885 (save-excursion
1877 (save-restriction 1886 (save-restriction
1878 (when (eq c-defun-tactic 'go-outward) 1887 (let ((start (point))
1879 (c-narrow-to-most-enclosing-decl-block t) ; e.g. class, namespace 1888 (paren-state (c-parse-state))
1880 (or (save-restriction 1889 lim pos end-pos encl-decl-block where)
1881 (c-narrow-to-most-enclosing-decl-block nil) 1890 ;; Narrow enclosing brace blocks out, as required by the values of
1882 1891 ;; `c-defun-tactic', `near', and the position of point.
1883 ;; Note: Some code duplication in `c-beginning-of-defun' and 1892 (when (eq c-defun-tactic 'go-outward)
1884 ;; `c-end-of-defun'. 1893 (let ((bounds
1885 (catch 'exit 1894 (save-restriction
1886 (let ((start (point)) 1895 (if (and (not (save-excursion (c-beginning-of-macro)))
1887 (paren-state (c-parse-state)) 1896 (save-restriction
1888 lim pos end-pos) 1897 (c-narrow-to-most-enclosing-decl-block)
1889 (unless (c-safe 1898 (memq (c-where-wrt-brace-construct)
1890 (goto-char (c-least-enclosing-brace paren-state)) 1899 '(at-function-end outwith-function)))
1891 ;; If we moved to the outermost enclosing paren 1900 (not near))
1892 ;; then we can use c-safe-position to set the 1901 (c-narrow-to-most-enclosing-decl-block nil 2)
1893 ;; limit. Can't do that otherwise since the 1902 (c-narrow-to-most-enclosing-decl-block))
1894 ;; earlier paren pair on paren-state might very 1903 (cons (point-min) (point-max)))))
1895 ;; well be part of the declaration we should go 1904 (narrow-to-region (car bounds) (cdr bounds))))
1896 ;; to. 1905 (setq paren-state (c-parse-state))
1897 (setq lim (c-safe-position (point) paren-state)) 1906
1898 t) 1907 (or
1899 ;; At top level. Make sure we aren't inside a literal. 1908 ;; Note: Some code duplication in `c-beginning-of-defun' and
1900 (setq pos (c-literal-start 1909 ;; `c-end-of-defun'.
1901 (c-safe-position (point) paren-state))) 1910 (catch 'exit
1902 (if pos (goto-char pos))) 1911 (unless (c-safe
1903 1912 (goto-char (c-least-enclosing-brace paren-state))
1904 (when (c-beginning-of-macro) 1913 ;; If we moved to the outermost enclosing paren
1905 (throw 'exit 1914 ;; then we can use c-safe-position to set the
1906 (cons (point) 1915 ;; limit. Can't do that otherwise since the
1907 (save-excursion 1916 ;; earlier paren pair on paren-state might very
1908 (c-end-of-macro) 1917 ;; well be part of the declaration we should go
1909 (forward-line 1) 1918 ;; to.
1910 (point))))) 1919 (setq lim (c-safe-position (point) paren-state))
1911 1920 t)
1912 (setq pos (point)) 1921 ;; At top level. Make sure we aren't inside a literal.
1913 (when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous) 1922 (setq pos (c-literal-start
1914 (= pos (point))) 1923 (c-safe-position (point) paren-state)))
1915 ;; We moved back over the previous defun. Skip to the next 1924 (if pos (goto-char pos)))
1916 ;; one. Not using c-forward-syntactic-ws here since we 1925
1917 ;; should not skip a macro. We can also be directly after 1926 (when (c-beginning-of-macro)
1918 ;; the block in a `c-opt-block-decls-with-vars-key' 1927 (throw 'exit
1919 ;; declaration, but then we won't move significantly far 1928 (cons (point)
1920 ;; here. 1929 (save-excursion
1921 (goto-char pos) 1930 (c-end-of-macro)
1922 (c-forward-comments) 1931 (forward-line 1)
1923 1932 (point)))))
1924 (when (and near (c-beginning-of-macro)) 1933
1925 (throw 'exit 1934 (setq pos (point))
1926 (cons (point) 1935 (setq where (and (not (save-excursion (c-beginning-of-macro)))
1927 (save-excursion 1936 (c-where-wrt-brace-construct)))
1928 (c-end-of-macro) 1937 (when (and (not (eq where 'at-header))
1929 (forward-line 1) 1938 (or (and near
1930 (point)))))) 1939 (memq where
1931 1940 '(at-function-end outwith-function)))
1932 (if (eobp) (throw 'exit nil)) 1941 (eq (car (c-beginning-of-decl-1 lim)) 'previous)
1933 1942 (= pos (point))))
1934 ;; Check if `c-beginning-of-decl-1' put us after the block in a 1943 ;; We moved back over the previous defun. Skip to the next
1935 ;; declaration that doesn't end there. We're searching back and 1944 ;; one. Not using c-forward-syntactic-ws here since we
1936 ;; forth over the block here, which can be expensive. 1945 ;; should not skip a macro. We can also be directly after
1937 (setq pos (point)) 1946 ;; the block in a `c-opt-block-decls-with-vars-key'
1938 (if (and c-opt-block-decls-with-vars-key 1947 ;; declaration, but then we won't move significantly far
1939 (progn 1948 ;; here.
1940 (c-backward-syntactic-ws) 1949 (goto-char pos)
1941 (eq (char-before) ?})) 1950 (c-forward-comments)
1942 (eq (car (c-beginning-of-decl-1)) 1951
1943 'previous) 1952 (when (and near (c-beginning-of-macro))
1944 (save-excursion 1953 (throw 'exit
1945 (c-end-of-decl-1) 1954 (cons (point)
1946 (and (> (point) pos) 1955 (save-excursion
1947 (setq end-pos (point))))) 1956 (c-end-of-macro)
1948 nil 1957 (forward-line 1)
1949 (goto-char pos)) 1958 (point))))))
1950 1959
1951 (if (and (not near) (> (point) start)) 1960 (if (eobp) (throw 'exit nil))
1952 nil 1961
1953 1962 ;; Check if `c-beginning-of-decl-1' put us after the block in a
1954 ;; Try to be line oriented; position the limits at the 1963 ;; declaration that doesn't end there. We're searching back and
1955 ;; closest preceding boi, and after the next newline, that 1964 ;; forth over the block here, which can be expensive.
1956 ;; isn't inside a comment, but if we hit a neighboring 1965 (setq pos (point))
1957 ;; declaration then we instead use the exact declaration 1966 (if (and c-opt-block-decls-with-vars-key
1958 ;; limit in that direction. 1967 (progn
1959 (cons (progn 1968 (c-backward-syntactic-ws)
1960 (setq pos (point)) 1969 (eq (char-before) ?}))
1961 (while (and (/= (point) (c-point 'boi)) 1970 (eq (car (c-beginning-of-decl-1))
1962 (c-backward-single-comment))) 1971 'previous)
1963 (if (/= (point) (c-point 'boi)) 1972 (save-excursion
1964 pos 1973 (c-end-of-decl-1)
1965 (point))) 1974 (and (> (point) pos)
1966 (progn 1975 (setq end-pos (point)))))
1967 (if end-pos 1976 nil
1968 (goto-char end-pos) 1977 (goto-char pos))
1969 (c-end-of-decl-1)) 1978
1970 (setq pos (point)) 1979 (if (and (not near) (> (point) start))
1971 (while (and (not (bolp)) 1980 nil
1972 (not (looking-at "\\s *$")) 1981
1973 (c-forward-single-comment))) 1982 ;; Try to be line oriented; position the limits at the
1974 (cond ((bolp) 1983 ;; closest preceding boi, and after the next newline, that
1975 (point)) 1984 ;; isn't inside a comment, but if we hit a neighboring
1976 ((looking-at "\\s *$") 1985 ;; declaration then we instead use the exact declaration
1977 (forward-line 1) 1986 ;; limit in that direction.
1978 (point)) 1987 (cons (progn
1979 (t 1988 (setq pos (point))
1980 pos)))))))) 1989 (while (and (/= (point) (c-point 'boi))
1981 (and (not near) 1990 (c-backward-single-comment)))
1982 (goto-char (point-min)) 1991 (if (/= (point) (c-point 'boi))
1983 (c-forward-decl-or-cast-1 -1 nil nil) 1992 pos
1984 (eq (char-after) ?\{) 1993 (point)))
1985 (cons (point-min) (point-max)))))))) 1994 (progn
1995 (if end-pos
1996 (goto-char end-pos)
1997 (c-end-of-decl-1))
1998 (setq pos (point))
1999 (while (and (not (bolp))
2000 (not (looking-at "\\s *$"))
2001 (c-forward-single-comment)))
2002 (cond ((bolp)
2003 (point))
2004 ((looking-at "\\s *$")
2005 (forward-line 1)
2006 (point))
2007 (t
2008 pos))))))
2009 (and (not near)
2010 (goto-char (point-min))
2011 (c-forward-decl-or-cast-1 -1 nil nil)
2012 (eq (char-after) ?\{)
2013 (cons (point-min) (point-max))))))))
1986 2014
1987(defun c-mark-function () 2015(defun c-mark-function ()
1988 "Put mark at end of the current top-level declaration or macro, point at beginning. 2016 "Put mark at end of the current top-level declaration or macro, point at beginning.