Changeset 4166 for trunk/lisp/allout.el
- Timestamp:
- 09/18/06 20:48:14 (2 years ago)
- Files:
-
- trunk/lisp/allout.el (modified) (110 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lisp/allout.el
r4148 r4166 848 848 "Length of current buffers' `allout-plain-bullets-string'.") 849 849 (make-variable-buffer-local 'allout-bullets-string-len) 850 ;;;_ = allout-depth-specific-regexp 851 (defvar allout-depth-specific-regexp "" 852 "*Regular expression to match a heading line prefix for a particular depth. 853 854 This expression is used to search for depth-specific topic 855 headers at depth 2 and greater. Use `allout-depth-one-regexp' 856 for to seek topics at depth one. 857 858 This var is set according to the user configuration vars by 859 `set-allout-regexp'. It is prepared with format strings for two 860 decimal numbers, which should each be one less than the depth of the 861 topic prefix to be matched.") 862 (make-variable-buffer-local 'allout-depth-specific-regexp) 863 ;;;_ = allout-depth-one-regexp 864 (defvar allout-depth-one-regexp "" 865 "*Regular expression to match a heading line prefix for depth one. 866 867 This var is set according to the user configuration vars by 868 `set-allout-regexp'. It is prepared with format strings for two 869 decimal numbers, which should each be one less than the depth of the 870 topic prefix to be matched.") 871 (make-variable-buffer-local 'allout-depth-one-regexp) 850 872 ;;;_ = allout-line-boundary-regexp 851 873 (defvar allout-line-boundary-regexp () 852 874 "`allout-regexp' with outline style beginning-of-line anchor. 853 875 854 This is properly set when `allout-regexp' is produced by 855 `set-allout-regexp', so that (match-beginning 2) and (match-end 856 2) delimit the prefix.") 876 This is properly set by `set-allout-regexp'.") 857 877 (make-variable-buffer-local 'allout-line-boundary-regexp) 858 878 ;;;_ = allout-bob-regexp 859 879 (defvar allout-bob-regexp () 860 "Like `allout-line-boundary-regexp', for headers at beginning of buffer. 861 \(match-beginning 2) and \(match-end 2) delimit the prefix.") 880 "Like `allout-line-boundary-regexp', for headers at beginning of buffer.") 862 881 (make-variable-buffer-local 'allout-bob-regexp) 863 882 ;;;_ = allout-header-subtraction … … 870 889 (make-variable-buffer-local 'allout-plain-bullets-string-len) 871 890 872 891 ;;;_ = allout-doublecheck-at-and-shallower 892 (defconst allout-doublecheck-at-and-shallower 3 893 "Verify apparent topics of this depth and shallower as being non-aberrant. 894 895 Verified with `allout-aberrant-container-p'. This check's usefulness is 896 limited to shallow prospects, because the determination of aberrance 897 depends on the mistaken item being followed by a legitimate item of 898 excessively greater depth.") 873 899 ;;;_ X allout-reset-header-lead (header-lead) 874 900 (defun allout-reset-header-lead (header-lead) … … 962 988 963 989 Works with respect to `allout-plain-bullets-string' and 964 `allout-distinctive-bullets-string'." 990 `allout-distinctive-bullets-string'. 991 992 Also refresh various data structures that hinge on the regexp." 965 993 966 994 (interactive) … … 997 1025 (setq allout-plain-bullets-string-len (length allout-plain-bullets-string)) 998 1026 (setq allout-header-subtraction (1- (length allout-header-prefix))) 999 ;; Produce the new allout-regexp: 1000 (setq allout-regexp (concat "\\(" 1001 (regexp-quote allout-header-prefix) 1002 "[ \t]*[" 1003 allout-bullets-string 1004 "]\\)\\|" 1005 (regexp-quote allout-primary-bullet) 1006 "+\\|\^l")) 1007 (setq allout-line-boundary-regexp 1008 (concat "\\(\n\\)\\(" allout-regexp "\\)")) 1009 (setq allout-bob-regexp 1010 (concat "\\(\\`\\)\\(" allout-regexp "\\)")) 1011 ) 1027 1028 (let (new-part old-part) 1029 (setq new-part (concat "\\(" 1030 (regexp-quote allout-header-prefix) 1031 "[ \t]*" 1032 ;; already regexp-quoted in a custom way: 1033 "[" allout-bullets-string "]" 1034 "\\)") 1035 old-part (concat "\\(" 1036 (regexp-quote allout-primary-bullet) 1037 "\\|" 1038 (regexp-quote allout-header-prefix) 1039 "\\)" 1040 "+" 1041 " ?[^" allout-primary-bullet "]") 1042 allout-regexp (concat new-part 1043 "\\|" 1044 old-part 1045 "\\|\^l") 1046 1047 allout-line-boundary-regexp (concat "\n" new-part 1048 "\\|" 1049 "\n" old-part) 1050 1051 allout-bob-regexp (concat "\\`" new-part 1052 "\\|" 1053 "\\`" old-part)) 1054 1055 (setq allout-depth-specific-regexp 1056 (concat "\\(^\\|\\`\\)" 1057 "\\(" 1058 1059 ;; new-style spacers-then-bullet string: 1060 "\\(" 1061 (allout-format-quote (regexp-quote allout-header-prefix)) 1062 " \\{%s\\}" 1063 "[" (allout-format-quote allout-bullets-string) "]" 1064 "\\)" 1065 1066 ;; old-style all-bullets string, if primary not multi-char: 1067 (if (< 0 allout-header-subtraction) 1068 "" 1069 (concat "\\|\\(" 1070 (allout-format-quote 1071 (regexp-quote allout-primary-bullet)) 1072 (allout-format-quote 1073 (regexp-quote allout-primary-bullet)) 1074 (allout-format-quote 1075 (regexp-quote allout-primary-bullet)) 1076 "\\{%s\\}" 1077 ;; disqualify greater depths: 1078 "[^" 1079 (allout-format-quote allout-primary-bullet) 1080 "]\\)" 1081 )) 1082 "\\)" 1083 )) 1084 (setq allout-depth-one-regexp 1085 (concat "\\(^\\|\\`\\)" 1086 "\\(" 1087 1088 "\\(" 1089 (regexp-quote allout-header-prefix) 1090 ;; disqualify any bullet char following any amount of 1091 ;; intervening whitespace: 1092 " *" 1093 (concat "[^ " allout-bullets-string "]") 1094 "\\)" 1095 (if (< 0 allout-header-subtraction) 1096 ;; Need not support anything like the old 1097 ;; bullet style if the prefix is multi-char. 1098 "" 1099 (concat "\\|" 1100 (regexp-quote allout-primary-bullet) 1101 ;; disqualify deeper primary-bullet sequences: 1102 "[^" allout-primary-bullet "]")) 1103 "\\)" 1104 )))) 1012 1105 ;;;_ : Key bindings 1013 1106 ;;;_ = allout-mode-map … … 1143 1236 (error "Pair's name, %S, must be a symbol, not %s" 1144 1237 name (type-of name))) 1145 (setq prior-value (condition-case err1238 (setq prior-value (condition-case nil 1146 1239 (symbol-value name) 1147 1240 (void-variable nil))) … … 1793 1886 (remove-hook 'pre-command-hook 'allout-pre-command-business t) 1794 1887 (remove-hook 'post-command-hook 'allout-post-command-business t) 1795 (when (featurep 'xemacs) 1796 (remove-hook 'before-change-functions 'allout-before-change-handler t)) 1888 (remove-hook 'before-change-functions 'allout-before-change-handler t) 1797 1889 (remove-hook 'isearch-mode-end-hook 'allout-isearch-end-handler t) 1798 1890 (remove-hook write-file-hook-var-name 'allout-write-file-hook-handler t) … … 1814 1906 (allout-overlay-preparations) ; Doesn't hurt to redo this. 1815 1907 1816 (allout-infer-header-lead )1908 (allout-infer-header-lead-and-primary-bullet) 1817 1909 (allout-infer-body-reindent) 1818 1910 … … 1855 1947 (add-hook 'pre-command-hook 'allout-pre-command-business nil t) 1856 1948 (add-hook 'post-command-hook 'allout-post-command-business nil t) 1857 (when (featurep 'xemacs) 1858 (add-hook 'before-change-functions 'allout-before-change-handler 1859 nil t)) 1949 (add-hook 'before-change-functions 'allout-before-change-handler 1950 nil t) 1860 1951 (add-hook 'isearch-mode-end-hook 'allout-isearch-end-handler nil t) 1861 1952 (add-hook write-file-hook-var-name 'allout-write-file-hook-handler … … 2001 2092 This before-change handler is used only where modification-hooks 2002 2093 overlay property is not supported." 2094 2095 (if (and (allout-mode-p) undo-in-progress (allout-hidden-p)) 2096 (allout-show-to-offshoot)) 2097 2003 2098 ;; allout-overlay-interior-modification-handler on an overlay handles 2004 2099 ;; this in other emacs, via `allout-exposure-category's 'modification-hooks. 2005 2100 (when (and (featurep 'xemacs) (allout-mode-p)) 2006 2101 ;; process all of the pending overlays: 2007 (dolist (overlay (overlays-in beg end)) 2008 (if (eq (overlay-get ol 'invisible) 'allout) 2009 (allout-overlay-interior-modification-handler 2010 overlay nil beg end nil))))) 2102 (save-excursion 2103 (got-char beg) 2104 (let ((overlay (allout-get-invisibility-overlay))) 2105 (allout-overlay-interior-modification-handler 2106 overlay nil beg end nil))))) 2011 2107 ;;;_ > allout-isearch-end-handler (&optional overlay) 2012 2108 (defun allout-isearch-end-handler (&optional overlay) … … 2036 2132 "Buffer point of the end of the last topic prefix encountered.") 2037 2133 (make-variable-buffer-local 'allout-recent-prefix-end) 2134 ;;;_ = allout-recent-depth 2135 (defvar allout-recent-depth 0 2136 "Depth of the last topic prefix encountered.") 2137 (make-variable-buffer-local 'allout-recent-depth) 2038 2138 ;;;_ = allout-recent-end-of-subtree 2039 2139 (defvar allout-recent-end-of-subtree 0 2040 2140 "Buffer point last returned by `allout-end-of-current-subtree'.") 2041 2141 (make-variable-buffer-local 'allout-recent-end-of-subtree) 2042 ;;;_ > allout-prefix-data ( beg end)2043 (def macro allout-prefix-data (beg end)2044 "Register allout-prefix state data - BEGINNING and END of prefix.2142 ;;;_ > allout-prefix-data () 2143 (defsubst allout-prefix-data () 2144 "Register allout-prefix state data. 2045 2145 2046 2146 For reference by `allout-recent' funcs. Returns BEGINNING." 2047 `(setq allout-recent-prefix-end ,end 2048 allout-recent-prefix-beginning ,beg)) 2147 (setq allout-recent-prefix-end (or (match-end 1) (match-end 2)) 2148 allout-recent-prefix-beginning (or (match-beginning 1) 2149 (match-beginning 2)) 2150 allout-recent-depth (max 1 (- allout-recent-prefix-end 2151 allout-recent-prefix-beginning 2152 allout-header-subtraction))) 2153 allout-recent-prefix-beginning) 2154 ;;;_ > nullify-allout-prefix-data () 2155 (defsubst nullify-allout-prefix-data () 2156 "Mark allout prefix data as being uninformative." 2157 (setq allout-recent-prefix-end (point) 2158 allout-recent-prefix-beginning (point) 2159 allout-recent-depth 0) 2160 allout-recent-prefix-beginning) 2049 2161 ;;;_ > allout-recent-depth () 2050 (def macroallout-recent-depth ()2162 (defsubst allout-recent-depth () 2051 2163 "Return depth of last heading encountered by an outline maneuvering function. 2052 2164 … … 2056 2168 to return the current depth." 2057 2169 2058 '(max 1 (- allout-recent-prefix-end 2059 allout-recent-prefix-beginning 2060 allout-header-subtraction))) 2170 allout-recent-depth) 2061 2171 ;;;_ > allout-recent-prefix () 2062 (def macroallout-recent-prefix ()2172 (defsubst allout-recent-prefix () 2063 2173 "Like `allout-recent-depth', but returns text of last encountered prefix. 2064 2174 … … 2066 2176 headings set the variables `allout-recent-prefix-beginning' and 2067 2177 `allout-recent-prefix-end' if successful. This function uses those settings 2068 to return the current depth."2069 '(buffer-substringallout-recent-prefix-beginning2070 allout-recent-prefix-end))2178 to return the current prefix." 2179 (buffer-substring-no-properties allout-recent-prefix-beginning 2180 allout-recent-prefix-end)) 2071 2181 ;;;_ > allout-recent-bullet () 2072 2182 (defmacro allout-recent-bullet () … … 2077 2187 `allout-recent-prefix-end' if successful. This function uses those settings 2078 2188 to return the current depth of the most recently matched topic." 2079 '(buffer-substring (1- allout-recent-prefix-end)2080 allout-recent-prefix-end))2189 '(buffer-substring-no-properties (1- allout-recent-prefix-end) 2190 allout-recent-prefix-end)) 2081 2191 2082 2192 ;;;_ #4 Navigation … … 2092 2202 (allout-beginning-of-current-line) 2093 2203 (and (looking-at allout-regexp) 2094 (allout-prefix-data (match-beginning 0) (match-end 0))))) 2204 (not (allout-aberrant-container-p)) 2205 (allout-prefix-data)))) 2095 2206 ;;;_ > allout-on-heading-p () 2096 2207 (defalias 'allout-on-heading-p 'allout-on-current-heading-p) … … 2102 2213 (looking-at allout-regexp)) 2103 2214 (= (point)(save-excursion (allout-end-of-prefix)(point))))) 2215 ;;;_ > allout-aberrant-container-p () 2216 (defun allout-aberrant-container-p () 2217 "True if topic, or next sibling with children, contains them discontinuously. 2218 2219 Discontinuous means an immediate offspring that is nested more 2220 than one level deeper than the topic. 2221 2222 If topic has no offspring, then the next sibling with offspring will 2223 determine whether or not this one is determined to be aberrant. 2224 2225 If true, then the allout-recent-* settings are calibrated on the 2226 offspring that qaulifies it as aberrant, ie with depth that 2227 exceeds the topic by more than one." 2228 2229 ;; This is most clearly understood when considering standard-prefix-leader 2230 ;; low-level topics, which can all too easily match text not intended as 2231 ;; headers. For example, any line with a leading '.' or '*' and lacking a 2232 ;; following bullet qualifies without this protection. (A sequence of 2233 ;; them can occur naturally, eg a typical textual bullet list.) We 2234 ;; disqualify such low-level sequences when they are followed by a 2235 ;; discontinuously contained child, inferring that the sequences are not 2236 ;; actually connected with their prospective context. 2237 2238 (let ((depth (allout-depth)) 2239 (start-point (point)) 2240 done aberrant) 2241 (save-excursion 2242 (while (and (not done) 2243 (re-search-forward allout-line-boundary-regexp nil 0)) 2244 (allout-prefix-data) 2245 (goto-char allout-recent-prefix-beginning) 2246 (cond 2247 ;; sibling - continue: 2248 ((eq allout-recent-depth depth)) 2249 ;; first offspring is excessive - aberrant: 2250 ((> allout-recent-depth (1+ depth)) 2251 (setq done t aberrant t)) 2252 ;; next non-sibling is lower-depth - not aberrant: 2253 (t (setq done t))))) 2254 (if aberrant 2255 aberrant 2256 (goto-char start-point) 2257 ;; recalibrate allout-recent-* 2258 (allout-depth) 2259 nil))) 2104 2260 ;;;_ : Location attributes 2105 2261 ;;;_ > allout-depth () … … 2114 2270 (if (and (allout-goto-prefix) 2115 2271 (not (< start-point (point)))) 2116 (allout-recent-depth)2272 allout-recent-depth 2117 2273 (progn 2118 ;; Oops, no prefix, zero prefix data:2119 ( allout-prefix-data (point)(point))2274 ;; Oops, no prefix, nullify it: 2275 (nullify-allout-prefix-data) 2120 2276 ;; ... and return 0: 2121 2277 0))))) … … 2150 2306 (save-excursion 2151 2307 (allout-back-to-current-heading) 2152 (buffer-substring (- allout-recent-prefix-end 1)2153 allout-recent-prefix-end))2308 (buffer-substring-no-properties (- allout-recent-prefix-end 1) 2309 allout-recent-prefix-end)) 2154 2310 ;; Quick and dirty provision, ostensibly for missing bullet: 2155 ( 'args-out-of-range nil))2311 (args-out-of-range nil)) 2156 2312 ) 2157 2313 ;;;_ > allout-get-prefix-bullet (prefix) … … 2161 2317 ;; oughtn't be called then, so forget about it... 2162 2318 (if (string-match allout-regexp prefix) 2163 (substring prefix (1- (match-end 0)) (match-end 0))))2319 (substring prefix (1- (match-end 2)) (match-end 2)))) 2164 2320 ;;;_ > allout-sibling-index (&optional depth) 2165 2321 (defun allout-sibling-index (&optional depth) … … 2175 2331 ((or (not depth) (= depth (allout-depth))) 2176 2332 (let ((index 1)) 2177 (while (allout-previous-sibling (allout-recent-depth)nil)2333 (while (allout-previous-sibling allout-recent-depth nil) 2178 2334 (setq index (1+ index))) 2179 2335 index)) 2180 ((< depth (allout-recent-depth))2336 ((< depth allout-recent-depth) 2181 2337 (allout-ascend-to-depth depth) 2182 2338 (allout-sibling-index)) … … 2230 2386 (not (equal last-command this-command))) 2231 2387 (move-beginning-of-line 1) 2232 (let ((beginning-of-body (save-excursion 2233 (allout-beginning-of-current-entry) 2234 (point)))) 2388 (allout-depth) 2389 (let ((beginning-of-body 2390 (save-excursion 2391 (while (and (<= allout-recent-depth 2392 allout-doublecheck-at-and-shallower) 2393 (allout-aberrant-container-p) 2394 (allout-previous-visible-heading 1))) 2395 (allout-beginning-of-current-entry) 2396 (point)))) 2235 2397 (cond ((= (current-column) 0) 2236 ( allout-beginning-of-current-entry))2398 (goto-char beginning-of-body)) 2237 2399 ((< (point) beginning-of-body) 2238 2400 (allout-beginning-of-current-line)) … … 2242 2404 (if (< (point) beginning-of-body) 2243 2405 ;; we were on the headline after its start: 2244 ( allout-beginning-of-current-entry)))))))2406 (goto-char beginning-of-body))))))) 2245 2407 ;;;_ > allout-end-of-line () 2246 2408 (defun allout-end-of-line () … … 2262 2424 (allout-back-to-current-heading) 2263 2425 (allout-show-current-entry) 2426 (allout-show-children) 2264 2427 (allout-end-of-entry)) 2265 2428 ((>= (point) end-of-entry) … … 2271 2434 "Move to the heading for the topic \(possibly invisible) after this one. 2272 2435 2273 Returns the location of the heading, or nil if none found." 2274 2275 (if (and (bobp) (not (eobp)) (looking-at allout-regexp)) 2436 Returns the location of the heading, or nil if none found. 2437 2438 We skip anomolous low-level topics, a la `allout-aberrant-container-p'." 2439 (if (looking-at allout-regexp) 2276 2440 (forward-char 1)) 2277 2441 2278 (if (re-search-forward allout-line-boundary-regexp nil 0) 2279 (allout-prefix-data ; Got valid location state - set vars: 2280 (goto-char (or (match-beginning 2) 2281 allout-recent-prefix-beginning)) 2282 (or (match-end 2) allout-recent-prefix-end)))) 2442 (when (re-search-forward allout-line-boundary-regexp nil 0) 2443 (allout-prefix-data) 2444 (and (<= allout-recent-depth allout-doublecheck-at-and-shallower) 2445 ;; this will set allout-recent-* on the first non-aberrant topic, 2446 ;; whether it's the current one or one that disqualifies it: 2447 (allout-aberrant-container-p)) 2448 (goto-char allout-recent-prefix-beginning))) 2283 2449 ;;;_ > allout-this-or-next-heading 2284 2450 (defun allout-this-or-next-heading () … … 2286 2452 ;; A throwaway non-macro that is defined after allout-next-heading 2287 2453 ;; and usable by allout-mode. 2288 (if (not (allout-goto-prefix )) (allout-next-heading)))2454 (if (not (allout-goto-prefix-doublechecked)) (allout-next-heading))) 2289 2455 ;;;_ > allout-previous-heading () 2290 (def macroallout-previous-heading ()2456 (defun allout-previous-heading () 2291 2457 "Move to the prior \(possibly invisible) heading line. 2292 2458 2293 Return the location of the beginning of the heading, or nil if not found." 2294 2295 '(if (bobp) 2296 nil 2297 (allout-goto-prefix) 2298 (if 2299 ;; searches are unbounded and return nil if failed: 2300 (or (re-search-backward allout-line-boundary-regexp nil 0) 2301 (looking-at allout-bob-regexp)) 2302 (progn ; Got valid location state - set vars: 2303 (allout-prefix-data 2304 (goto-char (or (match-beginning 2) 2305 allout-recent-prefix-beginning)) 2306 (or (match-end 2) allout-recent-prefix-end)))))) 2459 Return the location of the beginning of the heading, or nil if not found. 2460 2461 We skip anomolous low-level topics, a la `allout-aberrant-container-p'." 2462 2463 (if (bobp) 2464 nil 2465 ;; allout-goto-prefix-doublechecked calls us, so we can't use it here. 2466 (let ((start-point (point))) 2467 (allout-goto-prefix) 2468 (when (or (re-search-backward allout-line-boundary-regexp nil 0) 2469 (looking-at allout-bob-regexp)) 2470 (goto-char (allout-prefix-data)) 2471 (if (and (<= allout-recent-depth allout-doublecheck-at-and-shallower) 2472 (allout-aberrant-container-p)) 2473 (or (allout-previous-heading) 2474 (and (goto-char start-point) 2475 ;; recalibrate allout-recent-*: 2476 (allout-depth) 2477 nil)) 2478 (point)))))) 2307 2479 ;;;_ > allout-get-invisibility-overlay () 2308 2480 (defun allout-get-invisibility-overlay () … … 2312 2484 (while (and overlays (not got)) 2313 2485 (if (equal (overlay-get (car overlays) 'invisible) 'allout) 2314 (setq got (car overlays)))) 2486 (setq got (car overlays)) 2487 (pop overlays))) 2315 2488 got)) 2316 2489 ;;;_ > allout-back-to-visible-text () … … 2325 2498 ;;; nested lists of the locations of topics within a subtree. 2326 2499 ;;; 2327 ;;; Use of charts enables efficient navigation of subtrees, by 2328 ;;; requiring only a single regexp-search based traversal, to scope 2329 ;;; out the subtopic locations. The chart then serves as the basis 2330 ;;; for assessment or adjustment of the subtree, without redundant 2331 ;;; traversal of the structure. 2500 ;;; Charts enable efficient subtree navigation by providing a reusable basis 2501 ;;; for elaborate, compound assessment and adjustment of a subtree. 2332 2502 2333 2503 ;;;_ > allout-chart-subtree (&optional levels visible orig-depth prev-depth) … … 2349 2519 for their elaborate manipulations. 2350 2520 2351 T opics are entered in the chart so the last one is at the car.2352 The entry for each topic consists of an integer indicating the point 2353 a t the beginning of the topic. Charts for offspring consists of a2354 list containing, recursively, the charts for the respective subtopics. 2355 The chart for a topics' offspring precedes the entry for the topic 2356 itself.2521 The chart entries for the topics are in reverse order, so the 2522 last topic is listed first. The entry for each topic consists of 2523 an integer indicating the point at the beginning of the topic 2524 prefix. Charts for offspring consists of a list containing, 2525 recursively, the charts for the respective subtopics. The chart 2526 for a topics' offspring precedes the entry for the topic itself. 2357 2527 2358 2528 The other function parameters are for internal recursion, and should … … 2381 2551 (while (and (not (eobp)) 2382 2552 ; Still within original topic? 2383 (< orig-depth (setq curr-depth (allout-recent-depth)))2553 (< orig-depth (setq curr-depth allout-recent-depth)) 2384 2554 (cond ((= prev-depth curr-depth) 2385 2555 ;; Register this one and move on: 2386 (setq chart (cons (point)chart))2556 (setq chart (cons allout-recent-prefix-beginning chart)) 2387 2557 (if (and levels (<= levels 1)) 2388 2558 ;; At depth limit - skip sublevels: … … 2391 2561 ;; next heading at lesser depth: 2392 2562 (while (and (<= curr-depth 2393 (allout-recent-depth))2563 allout-recent-depth) 2394 2564 (if visible 2395 2565 (allout-next-visible-heading 1) … … 2438 2608 for an explanation of charts." 2439 2609 (save-excursion 2440 ( if (allout-goto-prefix)2441 (let ((chart (list (point))))2442 (while (allout-next-sibling)2443 (setq chart (cons (point) chart)))2444 (if chart (setq chart (nreverse chart)))))))2610 (when (allout-goto-prefix-doublechecked) 2611 (let ((chart (list (point)))) 2612 (while (allout-next-sibling) 2613 (setq chart (cons (point) chart))) 2614 (if chart (setq chart (nreverse chart))))))) 2445 2615 ;;;_ > allout-chart-to-reveal (chart depth) 2446 2616 (defun allout-chart-to-reveal (chart depth) … … 2515 2685 (forward-char 1) 2516 2686 (if (looking-at allout-regexp) 2517 (setq done (allout-prefix-data (match-beginning 0) 2518 (match-end 0))) 2687 (setq done (allout-prefix-data)) 2519 2688 (forward-char -1))) 2520 2689 (if (bobp) 2521 2690 (cond ((looking-at allout-regexp) 2522 (allout-prefix-data (match-beginning 0)(match-end 0)))2691 (allout-prefix-data)) 2523 2692 ((allout-next-heading)) 2524 2693 (done)) 2525 2694 done))) 2695 ;;;_ > allout-goto-prefix-doublechecked () 2696 (defun allout-goto-prefix-doublechecked () 2697 "Put point at beginning of immediately containing outline topic. 2698 2699 Like `allout-goto-prefix', but shallow topics \(according to `allout-doublecheck-at-and-shallower') are checked and disqualified for child containment discontinuity, according to `allout-aberrant-container-p'." 2700 (allout-goto-prefix) 2701 (if (and (<= allout-recent-depth allout-doublecheck-at-and-shallower) 2702 (allout-aberrant-container-p)) 2703 (allout-previous-heading) 2704 (point))) 2705 2526 2706 ;;;_ > allout-end-of-prefix () 2527 2707 (defun allout-end-of-prefix (&optional ignore-decorations) … … 2531 2711 otherwise skip white space between bullet and ensuing text." 2532 2712 2533 (if (not (allout-goto-prefix ))2713 (if (not (allout-goto-prefix-doublechecked)) 2534 2714 nil 2535 (let ((match-data (match-data))) 2536 (goto-char (match-end 0)) 2537 (if ignore-decorations 2538 t 2539 (while (looking-at "[0-9]") (forward-char 1)) 2540 (if (and (not (eolp)) (looking-at "\\s-")) (forward-char 1))) 2541 (store-match-data match-data)) 2715 (goto-char allout-recent-prefix-end) 2716 (if ignore-decorations 2717 t 2718 (while (looking-at "[0-9]") (forward-char 1)) 2719 (if (and (not (eolp)) (looking-at "\\s-")) (forward-char 1))) 2542 2720 ;; Reestablish where we are: 2543 2721 (allout-current-depth))) … … 2546 2724 "Return position of current \(visible) topic's bullet." 2547 2725 2548 (if (not (allout-current-depth))2726 (if (not (allout-current-depth)) 2549 2727 nil 2550 (1- (match-end 0))))2728 (1- allout-recent-prefix-end))) 2551 2729 ;;;_ > allout-back-to-current-heading () 2552 2730 (defun allout-back-to-current-heading () … … 2563 2741 (allout-beginning-of-current-line) 2564 2742 (if (not (looking-at allout-regexp)) 2565 (re-search-backward (concat 2566 "^\\(" allout-regexp "\\)") 2743 (re-search-backward allout-regexp 2567 2744 nil 'move))) 2568 (allout-prefix-data (match-beginning 1) 2569 (match-end 1))))) 2745 (allout-prefix-data)))) 2570 2746 (if (interactive-p) 2571 2747 (allout-end-of-prefix) … … 2579 2755 Returns that character position." 2580 2756 2581 (if (re-search-forward allout-line-boundary-regexp nil 'move) 2582 (prog1 (goto-char (match-beginning 0)) 2583 (allout-prefix-data (match-beginning 2)(match-end 2))))) 2757 (if (allout-next-heading) 2758 (goto-char (1- allout-recent-prefix-beginning)))) 2584 2759 ;;;_ > allout-end-of-subtree (&optional current include-trailing-blank) 2585 2760 (defun allout-end-of-subtree (&optional current include-trailing-blank) … … 2597 2772 (if current 2598 2773 (allout-back-to-current-heading) 2599 (allout-goto-prefix ))2600 (let ((level (allout-recent-depth)))2774 (allout-goto-prefix-doublechecked)) 2775 (let ((level allout-recent-depth)) 2601 2776 (allout-next-heading) 2602 2777 (while (and (not (eobp)) 2603 (> (allout-recent-depth)level))2778 (> allout-recent-depth level)) 2604 2779 (allout-next-heading)) 2605 2780 (if (eobp) … … 2630 2805 (let ((start-point (point))) 2631 2806 (move-beginning-of-line 1) 2807 (if (< 0 (allout-current-depth)) 2808 (goto-char allout-recent-prefix-end) 2809 (goto-char (point-min))) 2632 2810 (allout-end-of-prefix) 2633 2811 (if (and (interactive-p) … … 2677 2855 "Ascend to depth DEPTH, returning depth if successful, nil if not." 2678 2856 (if (and (> depth 0)(<= depth (allout-depth))) 2679 (let ((last-good (point))) 2680 (while (and (< depth (allout-depth)) 2681 (setq last-good (point)) 2682 (allout-beginning-of-level) 2683 (allout-previous-heading))) 2684 (if (= (allout-recent-depth) depth) 2685 (progn (goto-char allout-recent-prefix-beginning) 2686 depth) 2687 (goto-char last-good) 2688 nil)) 2689 (if (interactive-p) (allout-end-of-prefix)))) 2857 (let (last-ascended) 2858 (while (and (< depth allout-recent-depth) 2859 (setq last-ascended (allout-ascend)))) 2860 (goto-char allout-recent-prefix-beginning) 2861 (if (interactive-p) (allout-end-of-prefix)) 2862 (and last-ascended allout-recent-depth)))) 2690 2863 ;;;_ > allout-ascend () 2691 2864 (defun allout-ascend () … … 2693 2866 (prog1 2694 2867 (if (allout-beginning-of-level) 2695 (allout-previous-heading))2868 (allout-previous-heading)) 2696 2869 (if (interactive-p) (allout-end-of-prefix)))) 2697 2870 ;;;_ > allout-descend-to-depth (depth) … … 2704 2877 (while 2705 2878 (and (> (allout-depth) 0) 2706 (not (= depth (allout-recent-depth))) ; ... not there yet2879 (not (= depth allout-recent-depth)) ; ... not there yet 2707 2880 (allout-next-heading) ; ... go further 2708 (< start-depth (allout-recent-depth)))) ; ... still in topic2881 (< start-depth allout-recent-depth))) ; ... still in topic 2709 2882 (if (and (> (allout-depth) 0) 2710 (= (allout-recent-depth)depth))2883 (= allout-recent-depth depth)) 2711 2884 depth 2712 2885 (goto-char start-point) 2713 2886 nil)) 2714 2887 ) 2715 ;;;_ > allout-up-current-level (arg &optional dont-complain) 2716 (defun allout-up-current-level (arg &optional dont-complain) 2717 "Move out ARG levels from current visible topic. 2718 2719 Positions on heading line of containing topic. Error if unable to 2720 ascend that far, or nil if unable to ascend but optional arg 2721 DONT-COMPLAIN is non-nil." 2888 ;;;_ > allout-up-current-level (arg) 2889 (defun allout-up-current-level (arg) 2890 "Move out ARG levels from current visible topic." 2722 2891 (interactive "p") 2723 (allout-back-to-current-heading) 2724 (let ((present-level (allout-recent-depth)) 2725 (last-good (point)) 2726 failed) 2727 ;; Loop for iterating arg: 2728 (while (and (> (allout-recent-depth) 1) 2729 (> arg 0) 2730 (not (bobp)) 2731 (not failed)) 2732 (setq last-good (point)) 2733 ;; Loop for going back over current or greater depth: 2734 (while (and (not (< (allout-recent-depth) present-level)) 2735 (or (allout-previous-visible-heading 1) 2736 (not (setq failed present-level))))) 2737 (setq present-level (allout-current-depth)) 2738 (setq arg (- arg 1))) 2739 (if (or failed 2740 (> arg 0)) 2741 (progn (goto-char last-good) 2742 (if (interactive-p) (allout-end-of-prefix)) 2743 (if (not dont-complain) 2744 (error "Can't ascend past outermost level") 2745 (if (interactive-p) (allout-end-of-prefix)) 2746 nil)) 2892 (let ((start-point (point))) 2893 (allout-back-to-current-heading) 2894 (if (not (allout-ascend)) 2895 (progn (goto-char start-point) 2896 (error "Can't ascend past outermost level")) 2747 2897 (if (interactive-p) (allout-end-of-prefix)) 2748 2898 allout-recent-prefix-beginning))) … … 2757 2907 Go backward if optional arg BACKWARD is non-nil. 2758 2908 2759 Return depthif successful, nil otherwise."2760 2761 (if ( and backward (bobp))2909 Return the start point of the new topic if successful, nil otherwise." 2910 2911 (if (if backward (bobp) (eobp)) 2762 2912 nil 2763 (let (( start-depth (or depth (allout-depth)))2913 (let ((target-depth (or depth (allout-depth))) 2764 2914 (start-point (point)) 2915 (count 0) 2916 leaping 2765 2917 last-depth) 2766 (while (and (not (if backward (bobp) (eobp))) 2767 (if backward (allout-previous-heading) 2768 (allout-next-heading)) 2769 (> (setq last-depth (allout-recent-depth)) start-depth))) 2770 (if (and (not (eobp)) 2771 (and (> (or last-depth (allout-depth)) 0) 2772 (= (allout-recent-depth) start-depth))) 2773 allout-recent-prefix-beginning 2774 (goto-char start-point) 2775 (if depth (allout-depth) start-depth) 2776 nil)))) 2918 (while (and 2919 ;; done too few single steps to resort to the leap routine: 2920 (not leaping) 2921 ;; not at limit: 2922 (not (if backward (bobp) (eobp))) 2923 ;; still traversable: 2924 (if backward (allout-previous-heading) (allout-next-heading)) 2925 ;; we're below the target depth 2926 (> (setq last-depth allout-recent-depth) target-depth)) 2927 (setq count (1+ count)) 2928 (if (> count 7) ; lists are commonly 7 +- 2, right?-) 2929 (setq leaping t))) 2930 (cond (leaping 2931 (or (allout-next-sibling-leap target-depth backward) 2932 (progn 2933 (goto-char start-point) 2934 (if depth (allout-depth) target-depth) 2935 nil))) 2936 ((and (not (eobp)) 2937 (and (> (or last-depth (allout-depth)) 0) 2938 (= allout-recent-depth target-depth))) 2939 allout-recent-prefix-beginning) 2940 (t 2941 (goto-char start-point) 2942 (if depth (allout-depth) target-depth) 2943 nil))))) 2944 ;;;_ > allout-next-sibling-leap (&optional depth backward) 2945 (defun allout-next-sibling-leap (&optional depth backward) 2946 "Like `allout-next-sibling', but by direct search for topic at depth. 2947 2948 Traverse at optional DEPTH, or current depth if none specified. 2949 2950 Go backward if optional arg BACKWARD is non-nil. 2951 2952 Return the start point of the new topic if successful, nil otherwise. 2953 2954 Costs more than regular `allout-next-sibling' for short traversals: 2955 2956 - we have to check the prior \(next, if travelling backwards) 2957 item to confirm connectivity with the prior topic, and 2958 - if confirmed, we have to reestablish the allout-recent-* settings with 2959 some extra navigation 2960 - if confirmation fails, we have to do more work to recover 2961 2962 It is an increasingly big win when there are many intervening 2963 offspring before the next sibling, however, so 2964 `allout-next-sibling' resorts to this if it finds itself in that 2965 situation." 2966 2967 (if (if backward (bobp) (eobp)) 2968 nil 2969 (let* ((start-point (point)) 2970 (target-depth (or depth (allout-depth))) 2971 (search-whitespace-regexp nil) 2972 (depth-biased (- target-depth 2)) 2973 (expression (if (<= target-depth 1) 2974 allout-depth-one-regexp 2975 (format allout-depth-specific-regexp 2976 depth-biased depth-biased))) 2977 found 2978 done) 2979 (while (not done) 2980 (setq found (if backward 2981 (re-search-backward expression nil 'to-limit) 2982 (forward-char 1) 2983 (re-search-forward expression nil 'to-limit))) 2984 (if (and found (allout-aberrant-container-p)) 2985 (setq found nil)) 2986 (setq done (or found (if backward (bobp) (eobp))))) 2987 (if (not found) 2988 (progn (goto-char start-point) 2989 nil) 2990 ;; rationale: if any intervening items were at a lower depth, we 2991 ;; would now be on the first offspring at the target depth - ie, 2992 ;; the preceeding item (per the search direction) must be at a 2993 ;; lesser depth. that's all we need to check. 2994 (if backward (allout-next-heading) (allout-previous-heading)) 2995 (if (< allout-recent-depth target-depth) 2996 ;; return to start and reestablish allout-recent-*: 2997 (progn 2998 (goto-char start-point) 2999 (allout-depth) 3000 nil) 3001 (goto-char found) 3002 ;; locate cursor and set allout-recent-*: 3003 (allout-goto-prefix)))))) 2777 3004 ;;;_ > allout-previous-sibling (&optional depth backward) 2778 3005 (defun allout-previous-sibling (&optional depth backward) … … 2808 3035 (let ((depth (allout-depth))) 2809 3036 (while (allout-previous-sibling depth nil)) 2810 (prog1 (allout-recent-depth)3037 (prog1 allout-recent-depth 2811 3038 (if (interactive-p) (allout-end-of-prefix))))) 2812 3039 ;;;_ > allout-next-visible-heading (arg) … … 2822 3049 prev got) 2823 3050 2824 (while (> arg 0) ; limit condition 2825 (while (and (not (if backward (bobp)(eobp))) ; boundary condition 2826 ;; Move, skipping over all those concealed lines: 2827 (prog1 (condition-case nil (or (line-move step) t) 2828 (error nil)) 2829 (allout-beginning-of-current-line)) 2830 (not (setq got (looking-at allout-regexp))))) 3051 (while (> arg 0) 3052 (while (and 3053 ;; Boundary condition: 3054 (not (if backward (bobp)(eobp))) 3055 ;; Move, skipping over all concealed lines in one fell swoop: 3056 (prog1 (condition-case nil (or (line-move step) t) 3057 (error nil)) 3058 (allout-beginning-of-current-line)) 3059 ;; Deal with apparent header line: 3060 (if (not (looking-at allout-regexp)) 3061
