Mercurial > emacs
annotate lisp/textmodes/page-ext.el @ 5020:94de08fd8a7c
(Fnext_single_property_change): Fix missing \n\.
| author | Richard M. Stallman <rms@gnu.org> |
|---|---|
| date | Mon, 15 Nov 1993 06:41:45 +0000 |
| parents | 507f64624555 |
| children | 47afb35f4968 |
| rev | line source |
|---|---|
|
659
505130d1ddf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
235
diff
changeset
|
1 ;;; page-ext.el --- page handling commands |
| 235 | 2 |
| 845 | 3 ;;; Copyright (C) 1990 Free Software Foundation |
| 4 | |
|
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
5 ;; Author: Robert J. Chassell <bob@gnu.ai.mit.edu> |
| 235 | 6 |
|
664
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
7 ;; This file is part of GNU Emacs. |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
8 |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
9 ;; GNU Emacs is free software; you can redistribute it and/or modify |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
10 ;; it under the terms of the GNU General Public License as published by |
|
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
11 ;; the Free Software Foundation; either version 2, or (at your option) |
|
664
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
12 ;; any later version. |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
13 |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
14 ;; GNU Emacs is distributed in the hope that it will be useful, |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
17 ;; GNU General Public License for more details. |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
18 |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
19 ;; You should have received a copy of the GNU General Public License |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
20 ;; along with GNU Emacs; see the file COPYING. If not, write to |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
21 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
|
9b0e666dfdf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
659
diff
changeset
|
22 |
|
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
23 ;;; Commentary: |
|
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
24 |
|
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
25 ;;; You may use these commands to handle an address list or other |
|
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
26 ;;; small data base. |
|
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
27 |
|
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
28 ;;; Change Log: |
|
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
29 |
| 235 | 30 ;;; Change Log ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 31 ;;; | |
| 32 ;;; Version 0.043 | |
| 33 ;;; 24 May 1990 - When the cursor is at the end of the pages directory | |
| 34 ;;; buffer (which is empty), a `C-c C-c' (pages-directory-goto) | |
| 35 ;;; command now takes you to the end of the buffer. | |
| 36 ;;; | |
| 37 ;;; Version 0.042 | |
| 38 ;;; 16 May 1990 - Since people often handle address and other files | |
| 39 ;;; differently, variable `pages-directory-for-addresses-narrowing-p' | |
| 40 ;;; now specifies whether `pages-directory-goto' should narrow | |
| 41 ;;; addresses buffer to entry to which it goes. | |
| 42 ;;; `pages-directory-buffer-narrowing-p' continues to control | |
| 43 ;;; narrowing of pages buffer. | |
| 44 ;;; | |
| 45 ;;; `add-new-page' documentation string now explains | |
| 46 ;;; that the value of the inserted page-delimiter is a `^L'. | |
| 47 ;;; | |
| 48 ;;; `pages-directory-previous-regexp' definition reworded. | |
| 49 ;;; | |
| 50 ;;; Removed unneeded defvar for `pages-directory-buffer'. | |
| 51 ;;; | |
| 52 ;;; Version 0.041 | |
| 53 ;;; 14 May 1990 - `pages-last-search' bound to nil initially. | |
| 54 ;;; Remove unnecessary lines from `search-pages' definition. | |
| 55 ;;; | |
| 56 ;;; Version 0.04 | |
| 57 ;;; 18 Mar 1990 - `pages-directory' creates a directory for only the | |
| 58 ;;; accessible portion of the buffer; it does not automatically widen | |
| 59 ;;; the buffer. | |
| 60 ;;; | |
| 61 ;;; However, `pages-directory-for-addresses' does widen the addresses' | |
| 62 ;;; buffer before constructing the addresses' directory. | |
| 63 ;;; | |
| 64 ;;; Version 0.032 | |
| 65 ;;; 20 Feb 1990 - `pages-directory-for-addresses' no longer copies | |
| 66 ;;; first line of addresses directory to kill-ring | |
| 67 ;;; | |
| 68 ;;; Remove `(kill-all-local-variables)' line from | |
| 69 ;;; `pages-directory-address-mode' so Emacs will not be told to forget | |
| 70 ;;; the name of the file containing the addresses! | |
| 71 ;;; | |
| 72 ;;; Version 0.031 | |
| 73 ;;; 15 Feb 1990 - `pages-directory-goto' no longer erroneously selects | |
| 74 ;;; the entry on the following line when the cursor is at the end of | |
| 75 ;;; the line, but selects the entry on which the cursor rests. | |
| 76 ;;; | |
| 77 ;;; `pages-directory-address-mode' now sets local variables and enables | |
| 78 ;;; `describe-mode' to describe Addresses Directory mode. | |
| 79 ;;; | |
|
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
1770
diff
changeset
|
80 ;;; `pages-directory-for-addresses' now sets the buffer-modified flag |
| 235 | 81 ;;; for the Addresses Directory to nil. |
| 82 ;;; | |
| 83 ;;; The documentation string for both `pages-directory-mode' and | |
| 84 ;;; `pages-directory-address-mode' now provide a lookup for the | |
| 85 ;;; `pages-directory-goto' keybinding. | |
| 86 ;;; | |
| 87 ;;; Version 0.03 | |
| 88 ;;; 10 Feb 1990 - Incorporated a specialized extension of the | |
| 89 ;;; `pages-directory' command called `pages-directory-for-addresses' | |
| 90 ;;; and bound it to ctl-x-ctl-p-map "d" for integration with other | |
| 91 ;;; page functions. This function finds a file, creates a directory | |
| 92 ;;; for it using the `pages-directory' command, and displays the | |
| 93 ;;; directory. It is primarily for lists of addresses and the like. | |
| 94 ;;; | |
| 95 ;;; The difference between this and the `pages-directory' command is | |
| 96 ;;; that the `pages-directory-for-addresses' command presumes a | |
| 97 ;;; default addresses file (although you may optionally specify a file | |
| 98 ;;; name) and it switches you to the directory for the file, but the | |
| 99 ;;; `pages-directory' command creates a directory for the current | |
| 100 ;;; buffer, and pops to the directory in another window. | |
| 101 ;;; | |
| 102 ;;; `pages-directory' now places the cursor over the header line of | |
| 103 ;;; the page in which point was located in the pages buffer. | |
| 104 ;;; | |
| 105 ;;; New `set-page-delimiter' command sets the buffer local value of | |
| 106 ;;; the page-delimiter variable. With prefix arg, resets function to | |
| 107 ;;; original value. (Quicker to use than `edit-options'.) | |
| 108 ;;; | |
| 109 ;;; Version 0.02 | |
| 110 ;;; 9 Feb 1990 - `pages-directory' now displays the | |
| 111 ;;; first line that contains a non-blank character that follows the | |
| 112 ;;; `page-delimiter'; this may be the rest of the line that contains | |
| 113 ;;; the `page-delimiter' or a line following. (In most instances, the | |
| 114 ;;; line containing a non-blank character is a line of text.) | |
| 115 ;;; Modification includes changes to `pages-copy-header-and-position'. | |
| 116 ;;; | |
| 117 ;;; Each directory created by `pages-directory' now possesses a name | |
| 118 ;;; derived on the name of the pages buffer. Consequently, you may | |
| 119 ;;; create several different directories, one for each pages buffer. | |
| 120 ;;; | |
| 121 ;;; `sort-pages-in-region' no longers requires the text to start on | |
| 122 ;;; the line immediately following the line containing the | |
| 123 ;;; page-delimiter. | |
| 124 ;;; | |
| 125 ;;; `pages-directory-goto' no longer narrows to the page | |
| 126 ;;; automatically. Instead, if you wish it to narrow to the page, set | |
| 127 ;;; variable pages-directory-buffer-narrowing-p to a non-nil value. | |
| 128 ;;; Default is nil; this is an experiment to see whether it is useful | |
| 129 ;;; to see the surrounding context. | |
| 130 ;;; | |
| 131 ;;; Version 0.011 | |
| 132 ;;; 2 Feb 1990 - `add-new-page': removed extraneous space. | |
| 133 ;;; | |
| 134 ;;; Version 0.01 | |
| 135 ;;; 28 Jan 1990 - Initial definitions. | |
| 136 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
| 137 | |
|
807
4f28bd14272c
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
664
diff
changeset
|
138 ;;; Code: |
| 235 | 139 |
| 140 ;;;; Summary | |
| 141 | |
| 142 ; The current page commands are: | |
| 143 | |
| 144 ; forward-page C-x ] | |
| 145 ; backward-page C-x [ | |
| 146 ; narrow-to-page C-x p | |
| 147 ; count-lines-page C-x l | |
| 148 ; mark-page C-x C-p (change this to C-x C-p C-m) | |
| 149 ; sort-pages not bound | |
| 150 ; what-page not bound | |
| 151 | |
| 152 ; The new page handling commands all use `C-x C-p' as a prefix. This | |
| 153 ; means that the key binding for `mark-page' must be changed. | |
| 154 ; Otherwise, no other changes are made to the current commands or | |
| 155 ; their bindings. | |
| 156 | |
| 157 ; New page handling commands: | |
| 158 | |
| 159 ; next-page C-x C-p C-n | |
| 160 ; previous-page C-x C-p C-p | |
| 161 ; search-pages C-x C-p C-s | |
| 162 ; add-new-page C-x C-p C-a | |
| 163 ; sort-pages-buffer C-x C-p s | |
| 164 ; set-page-delimiter C-x C-p C-l | |
| 165 ; pages-directory C-x C-p C-d | |
| 166 ; pages-directory-for-addresses C-x C-p d | |
| 167 ; goto-page C-c C-c | |
| 168 | |
| 169 | |
| 170 ;;;; Using the page commands | |
| 171 ; | |
| 172 ; The page commands are helpful in several different contexts. For | |
| 173 ; example, programmers often divide source files into sections using the | |
| 174 ; `page-delimiter'; you can use the `pages-directory' command to list | |
| 175 ; the sections. | |
| 176 | |
| 177 ; You may change the buffer local value of the `page-delimiter' with | |
| 178 ; the `set-page-delimiter' command. This command is bound to `C-x C-p | |
| 179 ; C-l' The command prompts you for a new value for the page-delimiter. | |
| 180 ; Called with a prefix-arg, the command resets the value of the | |
| 181 ; page-delimiter to its original value. | |
| 182 | |
| 183 | |
| 184 ;;;; Handling an address list or small data base | |
| 185 | |
| 186 ; You may use the page commands to handle an address list or other | |
| 187 ; small data base. Put each address or entry on its own page. The | |
| 188 ; first line of text in each page is a `header line' and is listed by | |
| 189 ; the `pages-directory' or `pages-directory-for-addresses' command. | |
| 190 | |
| 191 ; Specifically: | |
| 192 ; | |
| 193 ; 1. Begin each entry with a `page-delimiter' (which is, by default, | |
| 194 ; `^L' at the beginning of the line). | |
| 195 ; | |
| 196 ; 2. The first line of text in each entry is the `heading line'; it | |
| 197 ; will appear in the pages-directory-buffer which is constructed | |
| 198 ; using the `C-x C-p C-d' (pages-directory) command or the `C-x | |
| 199 ; C-p d' (pages-directory-for-addresses) command. | |
| 200 ; | |
| 201 ; The heading line may be on the same line as the page-delimiter | |
| 202 ; or it may follow after. It is the first non-blank line on the | |
| 203 ; page. Conventionally, the heading line is placed on the line | |
| 204 ; immediately following the line containing page-delimiter. | |
| 205 ; | |
| 206 ; 3. Follow the heading line with the body of the entry. The body | |
| 207 ; extends up to the next `page-delimiter'. The body may be of any | |
| 208 ; length. It is conventional to place a blank line after the last | |
| 209 ; line of the body. | |
| 210 | |
| 211 ; For example, a file might look like this: | |
| 212 ; | |
| 213 ; FSF | |
| 214 ; Free Software Foundation | |
| 215 ; 675 Massachusetts Avenue | |
| 216 ; Cambridge, MA 02139 USA | |
| 217 ; (617) 876-3296 | |
| 218 ; gnu@prep.ai.mit.edu | |
| 219 ; | |
| 220 ; | |
| 221 ; House Subcommittee on Intellectual Property, | |
| 222 ; U.S. House of Representatives, | |
| 223 ; Washington, DC 20515 | |
| 224 ; | |
| 225 ; Congressional committee concerned with permitting or preventing | |
|
3591
507f64624555
Apply typo patches from Paul Eggert.
Jim Blandy <jimb@redhat.com>
parents:
1770
diff
changeset
|
226 ; monopolistic restrictions on the use of software technology |
| 235 | 227 ; |
| 228 ; | |
| 229 ; George Lakoff | |
| 230 ; ``Women, Fire, and Dangerous Things: | |
| 231 ; What Categories Reveal about the Mind'' | |
| 232 ; 1987, Univ. of Chicago Press | |
| 233 ; | |
| 234 ; About philosophy, Whorfian effects, and linguistics. | |
| 235 ; | |
| 236 ; | |
| 237 ; OBI (On line text collection.) | |
| 238 ; Open Book Initiative | |
| 239 ; c/o Software Tool & Die | |
| 240 ; 1330 Beacon St, Brookline, MA 02146 USA | |
| 241 ; (617) 739-0202 | |
| 242 ; obi@world.std.com | |
| 243 | |
| 244 ; In this example, the heading lines are: | |
| 245 ; | |
| 246 ; FSF | |
| 247 ; House Subcommittee on Intellectual Property | |
| 248 ; George Lakoff | |
| 249 ; OBI (On line text collection.) | |
| 250 | |
| 251 ; The `C-x C-p s' (sort-pages-buffer) command sorts the entries in the | |
| 252 ; buffer alphabetically. | |
| 253 | |
| 254 ; You may use any of the page commands, including the `next-page', | |
| 255 ; `previous-page', `add-new-page', `mark-page', and `search-pages' | |
| 256 ; commands. | |
| 257 | |
| 258 ; You may use either the `C-x C-p d' (pages-directory-for-addresses) | |
| 259 ; or the `C-x C-p C-d' (pages-directory) command to construct and | |
| 260 ; dislay a directory of all the heading lines. | |
| 261 | |
| 262 ; In the directory, you may position the cursor over a heading line | |
| 263 ; and type `C-c C-c' to go to the entry to which it refers in the | |
| 264 ; pages buffer. | |
| 265 | |
| 266 ; When used in conjunction with the `pages-directory-for-addresses' | |
| 267 ; command, the `C-c C-c' (pages-directory-goto) command narrows to the | |
| 268 ; entry to which it goes. But, when used in conjunction with the | |
| 269 ; `pages-directory' command, the `C-c C-c' (pages-directory-goto) | |
| 270 ; command does not narrow to the entry, but widens the buffer so you | |
| 271 ; can see the context surrounding the entry. | |
| 272 | |
| 273 ; If you wish, you may create several different directories, | |
| 274 ; one for each different buffer. | |
| 275 | |
| 276 ;; `pages-directory-for-addresses' in detail | |
| 277 | |
| 278 ; The `pages-directory-for-addresses' assumes a default addresses | |
| 279 ; file. You do not need to specify the addresses file but merely type | |
| 280 ; `C-x C-p d' from any buffer. The command finds the file, constructs | |
| 281 ; a directory for it, and switches you to the directory. If you call | |
| 282 ; the command with a prefix arg, `C-u C-x C-p d', it prompts you for a | |
| 283 ; file name. | |
| 284 | |
| 285 ;; `pages-directory' in detail | |
| 286 | |
| 287 ; Call the `pages-directory' from the buffer for which you want a | |
| 288 ; directory created; it creates a directory for the buffer and pops | |
| 289 ; you to the directory. | |
| 290 | |
| 291 ; The `pages-directory' command has several options: | |
| 292 | |
| 293 ; Called with a prefix arg, `C-u C-x C-p C-d', the `pages-directory' | |
| 294 ; prompts you for a regular expression and only lists only those | |
| 295 ; header lines that are part of pages that contain matches to the | |
| 296 ; regexp. In the example above, `C-u C-x C-p C-d 617 RET' would | |
| 297 ; match the telephone area code of the first and fourth entries, so | |
| 298 ; only the header lines of those two entries would appear in the | |
| 299 ; pages-directory-buffer. | |
| 300 ; | |
| 301 ; Called with a numeric argument, the `pages-directory' command | |
| 302 ; lists the number of lines in each page. This is helpful when you | |
| 303 ; are printing hardcopy. | |
| 304 | |
| 305 ; Called with a negative numeric argument, the `pages-directory' | |
| 306 ; command lists the lengths of pages whose contents match a regexp. | |
| 307 | |
| 308 | |
| 309 ;;;; Key bindings for page handling functions | |
| 310 | |
| 311 (global-unset-key "\C-x\C-p") | |
| 312 | |
| 313 (defvar ctl-x-ctl-p-map (make-sparse-keymap) | |
| 314 "Keymap for subcommands of C-x C-p, which are for page handling.") | |
| 315 | |
| 316 (define-key ctl-x-map "\C-p" 'ctl-x-ctl-p-prefix) | |
| 317 (fset 'ctl-x-ctl-p-prefix ctl-x-ctl-p-map) | |
| 318 | |
| 319 (define-key ctl-x-ctl-p-map "\C-n" 'next-page) | |
| 320 (define-key ctl-x-ctl-p-map "\C-p" 'previous-page) | |
| 321 (define-key ctl-x-ctl-p-map "\C-a" 'add-new-page) | |
| 322 (define-key ctl-x-ctl-p-map "\C-m" 'mark-page) | |
| 323 (define-key ctl-x-ctl-p-map "\C-s" 'search-pages) | |
| 324 (define-key ctl-x-ctl-p-map "s" 'sort-pages-buffer) | |
| 325 (define-key ctl-x-ctl-p-map "\C-l" 'set-page-delimiter) | |
| 326 (define-key ctl-x-ctl-p-map "\C-d" 'pages-directory) | |
| 327 (define-key ctl-x-ctl-p-map "d" 'pages-directory-for-addresses) | |
| 328 | |
| 329 | |
| 330 ;;;; Page movement function definitions | |
| 331 | |
| 332 (defun next-page (&optional count) | |
| 333 "Move to the next page bounded by the `page-delimiter' variable. | |
| 334 With arg (prefix if interactive), move that many pages." | |
| 335 (interactive "p") | |
| 336 (or count (setq count 1)) | |
| 337 (widen) | |
| 338 ;; Cannot use forward-page because of problems at page boundaries. | |
| 339 (while (and (> count 0) (not (eobp))) | |
| 340 (if (re-search-forward page-delimiter nil t) | |
| 341 nil | |
| 342 (goto-char (point-max))) | |
| 343 (setq count (1- count))) | |
|
1770
29bcc2c88773
* page-ext.el (next-page): Correctly handle negative page count.
Jim Blandy <jimb@redhat.com>
parents:
845
diff
changeset
|
344 ;; If COUNT is negative, we want to go back -COUNT + 1 page boundaries. |
|
29bcc2c88773
* page-ext.el (next-page): Correctly handle negative page count.
Jim Blandy <jimb@redhat.com>
parents:
845
diff
changeset
|
345 ;; The first page boundary we reach is the top of the current page, |
|
29bcc2c88773
* page-ext.el (next-page): Correctly handle negative page count.
Jim Blandy <jimb@redhat.com>
parents:
845
diff
changeset
|
346 ;; which doesn't count. |
|
29bcc2c88773
* page-ext.el (next-page): Correctly handle negative page count.
Jim Blandy <jimb@redhat.com>
parents:
845
diff
changeset
|
347 (while (and (< count 1) (not (bobp))) |
| 235 | 348 (if (re-search-backward page-delimiter nil t) |
| 349 (goto-char (match-beginning 0)) | |
| 350 (goto-char (point-min))) | |
| 351 (setq count (1+ count))) | |
| 352 (narrow-to-page) | |
| 353 (goto-char (point-min)) | |
| 354 (recenter 0)) | |
| 355 | |
| 356 (defun previous-page (&optional count) | |
| 357 "Move to the previous page bounded by the `page-delimiter' variable. | |
| 358 With arg (prefix if interactive), move that many pages." | |
| 359 (interactive "p") | |
| 360 (or count (setq count 1)) | |
| 361 (next-page (- count))) | |
| 362 | |
| 363 | |
| 364 ;;;; Adding and searching pages | |
| 365 | |
| 366 (defun add-new-page (header-line) | |
| 367 "Insert new page at point; prompt for header line. | |
| 368 Page begins with a `^L' as the page-delimiter. | |
| 369 Point is left in the body of page." | |
| 370 (interactive "sHeader line: ") | |
| 371 (widen) | |
| 372 (insert (format "\n\n%s\n\n" header-line)) | |
| 373 ;; don't renarrow; stay unnarrowed to see context | |
| 374 (forward-line -1)) | |
| 375 | |
| 376 (defvar pages-last-search nil | |
| 377 "Value of last regexp searched for. Initially, nil.") | |
| 378 | |
| 379 (defun search-pages (regexp) | |
| 380 "Search for REGEXP, starting from point, and narrow to page it is in." | |
| 381 (interactive (list | |
| 382 (read-string | |
| 383 (format "Search for `%s' (end with RET): " | |
| 384 (or pages-last-search "regexp"))))) | |
| 385 (if (equal regexp "") | |
| 386 (setq regexp pages-last-search) | |
| 387 (setq pages-last-search regexp)) | |
| 388 (widen) | |
| 389 (re-search-forward regexp) | |
| 390 (narrow-to-page)) | |
| 391 | |
| 392 | |
| 393 ;;;; Sorting pages | |
| 394 | |
| 395 (autoload 'sort-subr "sort" "Primary function for sorting." t nil) | |
| 396 | |
| 397 (defun sort-pages-in-region (reverse beg end) | |
| 398 "Sort pages in region alphabetically. Prefix arg means reverse order. | |
| 399 | |
| 400 Called from a program, there are three arguments: | |
| 401 REVERSE (non-nil means reverse order), BEG and END (region to sort)." | |
| 402 | |
| 403 ;;; This sort function handles ends of pages differently than | |
| 404 ;;; `sort-pages' and works better with lists of addresses and similar | |
| 405 ;;; files. | |
| 406 | |
| 407 (interactive "P\nr") | |
| 408 (save-restriction | |
| 409 (narrow-to-region beg end) | |
| 410 (goto-char (point-min)) | |
| 411 ;;; `sort-subr' takes three arguments | |
| 412 (sort-subr reverse | |
| 413 | |
| 414 ;; NEXTRECFUN is called with point at the end of the | |
| 415 ;; previous record. It moves point to the start of the | |
| 416 ;; next record. | |
| 417 (function (lambda () | |
| 418 (re-search-forward page-delimiter nil t) | |
| 419 (skip-chars-forward " \t\n") | |
| 420 )) | |
| 421 | |
| 422 ;; ENDRECFUN is is called with point within the record. | |
| 423 ;; It should move point to the end of the record. | |
| 424 (function (lambda () | |
| 425 (if (re-search-forward | |
| 426 page-delimiter | |
| 427 nil | |
| 428 t) | |
| 429 (goto-char (match-beginning 0)) | |
| 430 (goto-char (point-max)))))))) | |
| 431 | |
| 432 (defun sort-pages-buffer (&optional reverse) | |
| 433 "Sort pages alphabetically in buffer. Prefix arg means reverse order. | |
| 434 \(Non-nil arg if not interactive.\)" | |
| 435 | |
| 436 (interactive "P") | |
| 437 (or reverse (setq reverse nil)) | |
| 438 (widen) | |
| 439 (let ((beginning (point-min)) | |
| 440 (end (point-max))) | |
| 441 (sort-pages-in-region reverse beginning end))) | |
| 442 | |
| 443 | |
| 444 ;;;; Pages directory ancillary definitions | |
| 445 | |
| 446 (defvar pages-directory-buffer-narrowing-p nil | |
| 447 "*If non-nil, `pages-directory-goto' narrows pages buffer to entry.") | |
| 448 | |
| 449 (defvar pages-directory-previous-regexp nil | |
| 450 "Value of previous regexp used by `pages-directory'. | |
| 451 \(This regular expression may be used to select only those pages that | |
| 452 contain matches to the regexp.\)") | |
| 453 | |
| 454 (defvar pages-buffer nil | |
| 455 "The buffer for which the pages-directory function creates the directory.") | |
| 456 | |
| 457 (defvar pages-directory-prefix "*Directory for:" | |
| 458 "Prefix of name of temporary buffer for pages-directory.") | |
| 459 | |
| 460 (defvar pages-pos-list nil | |
| 461 "List containing the positions of the pages in the pages-buffer.") | |
| 462 | |
| 463 (defvar pages-directory-map nil | |
| 464 "Keymap for the pages-directory-buffer.") | |
| 465 | |
| 466 (if pages-directory-map | |
| 467 () | |
| 468 (setq pages-directory-map (make-sparse-keymap)) | |
| 469 (define-key pages-directory-map "\C-c\C-c" | |
| 470 'pages-directory-goto)) | |
| 471 | |
| 472 (defun set-page-delimiter (regexp reset-p) | |
| 473 "Set buffer local value of page-delimiter to REGEXP. | |
| 474 Called interactively with a prefix argument, reset `page-delimiter' to | |
| 475 its original value. | |
| 476 | |
| 477 In a program, non-nil second arg causes first arg to be ignored and | |
| 478 resets the page-delimiter to the original value." | |
| 479 | |
| 480 (interactive | |
| 481 (if current-prefix-arg | |
| 482 (list original-page-delimiter nil) | |
| 483 (list (read-string "Set page-delimiter to regexp: " page-delimiter) | |
| 484 nil))) | |
| 485 (make-local-variable 'original-page-delimiter) | |
| 486 (make-local-variable 'page-delimiter) | |
| 487 (setq original-page-delimiter | |
| 488 (or original-page-delimiter page-delimiter)) | |
| 489 (if (not reset-p) | |
| 490 (setq page-delimiter regexp) | |
| 491 (setq page-delimiter original-page-delimiter)) | |
| 492 (if (interactive-p) | |
| 493 (message "The value of `page-delimiter' is now: %s" page-delimiter))) | |
| 494 | |
| 495 | |
| 496 ;;;; Pages directory main definitions | |
| 497 | |
| 498 (defun pages-directory | |
| 499 (pages-list-all-headers-p count-lines-p &optional regexp) | |
| 500 "Display a directory of the page headers in a temporary buffer. | |
| 501 A header is the first non-blank line after the page-delimiter. | |
| 502 \\[pages-directory-mode] | |
| 503 You may move point to one of the lines in the temporary buffer, | |
| 504 then use \\<pages-directory-goto> to go to the same line in the pages buffer. | |
| 505 | |
| 506 In interactive use: | |
| 507 | |
| 508 1. With no prefix arg, display all headers. | |
| 509 | |
| 510 2. With prefix arg, display the headers of only those pages that | |
| 511 contain matches to a regular expression for which you are | |
| 512 prompted. | |
| 513 | |
| 514 3. With numeric prefix arg, for every page, print the number of | |
| 515 lines within each page. | |
| 516 | |
| 517 4. With negative numeric prefix arg, for only those pages that | |
| 518 match a regular expression, print the number of lines within | |
| 519 each page. | |
| 520 | |
| 521 When called from a program, non-nil first arg means list all headers; | |
| 522 non-nil second arg means print numbers of lines in each page; if first | |
| 523 arg is nil, optional third arg is regular expression. | |
| 524 | |
| 525 If the buffer is narrowed, the `pages-directory' command creates a | |
| 526 directory for only the accessible portion of the buffer." | |
| 527 | |
| 528 (interactive | |
| 529 (cond ((not current-prefix-arg) | |
| 530 (list t nil nil)) | |
| 531 ((listp current-prefix-arg) | |
| 532 (list nil | |
| 533 nil | |
| 534 (read-string | |
| 535 (format "Select according to `%s' (end with RET): " | |
| 536 (or pages-directory-previous-regexp "regexp"))))) | |
| 537 ((> (prefix-numeric-value current-prefix-arg) 0) | |
| 538 (list t t nil)) | |
| 539 ((< (prefix-numeric-value current-prefix-arg) 0) | |
| 540 (list nil | |
| 541 t | |
| 542 (read-string | |
| 543 (format "Select according to `%s' (end with RET): " | |
| 544 (or pages-directory-previous-regexp "regexp"))))))) | |
| 545 | |
| 546 (if (equal regexp "") | |
| 547 (setq regexp pages-directory-previous-regexp) | |
| 548 (setq pages-directory-previous-regexp regexp)) | |
| 549 | |
| 550 (if (interactive-p) | |
| 551 (message "Creating directory for: %s " | |
| 552 (buffer-name))) | |
| 553 | |
| 554 (let ((buffer (current-buffer)) | |
| 555 (pages-directory-buffer | |
| 556 (concat pages-directory-prefix " " (buffer-name) " ")) | |
| 557 (linenum 1) | |
| 558 (pages-buffer-original-position (point)) | |
| 559 (pages-buffer-original-page 0)) | |
| 560 | |
| 561 ;; `with-output-to-temp-buffer' binds the value of the variable | |
| 562 ;; `standard-output' to the buffer named as its first argument, | |
| 563 ;; but does not switch to that buffer. | |
| 564 (with-output-to-temp-buffer pages-directory-buffer | |
| 565 (save-excursion | |
| 566 (set-buffer standard-output) | |
| 567 (pages-directory-mode) | |
| 568 (insert | |
| 569 "==== Pages Directory: use `C-c C-c' to go to page under cursor. ====" ?\n) | |
| 570 (setq pages-buffer buffer) | |
| 571 (setq pages-pos-list nil)) | |
| 572 | |
| 573 (if pages-list-all-headers-p | |
| 574 | |
| 575 ;; 1. If no prefix argument, list all headers | |
| 576 (save-excursion | |
| 577 (goto-char (point-min)) | |
| 578 | |
| 579 ;; (a) Point is at beginning of buffer; but the first | |
| 580 ;; page may not begin with a page-delimiter | |
| 581 (save-restriction | |
| 582 ;; If page delimiter is at beginning of buffer, skip it | |
| 583 (if (and (save-excursion | |
| 584 (re-search-forward page-delimiter nil t)) | |
| 585 (= 1 (match-beginning 0))) | |
| 586 (goto-char (match-end 0))) | |
| 587 (narrow-to-page) | |
| 588 (pages-copy-header-and-position count-lines-p)) | |
| 589 | |
| 590 ;; (b) Search within pages buffer for next page-delimiter | |
| 591 (while (re-search-forward page-delimiter nil t) | |
| 592 (pages-copy-header-and-position count-lines-p))) | |
| 593 | |
| 594 ;; 2. Else list headers whose pages match regexp. | |
| 595 (save-excursion | |
| 596 ;; REMOVED save-restriction AND widen FROM HERE | |
| 597 (goto-char (point-min)) | |
| 598 | |
| 599 ;; (a) Handle first page | |
| 600 (save-restriction | |
| 601 (narrow-to-page) | |
| 602 ;; search for selection regexp | |
| 603 (if (save-excursion (re-search-forward regexp nil t)) | |
| 604 (pages-copy-header-and-position count-lines-p))) | |
| 605 | |
| 606 ;; (b) Search for next page-delimiter | |
| 607 (while (re-search-forward page-delimiter nil t) | |
| 608 (save-restriction | |
| 609 (narrow-to-page) | |
| 610 ;; search for selection regexp | |
| 611 (if (save-excursion (re-search-forward regexp nil t)) | |
| 612 (pages-copy-header-and-position count-lines-p) | |
| 613 ))))) | |
| 614 | |
| 615 (set-buffer standard-output) | |
| 616 ;; Put positions in increasing order to go with buffer. | |
| 617 (setq pages-pos-list (nreverse pages-pos-list)) | |
| 618 (if (interactive-p) | |
| 619 (message "%d matching lines in: %s" | |
| 620 (length pages-pos-list) (buffer-name buffer)))) | |
| 621 (pop-to-buffer pages-directory-buffer) | |
| 622 (sit-for 0) ; otherwise forward-line fails if N > window height. | |
| 623 (forward-line (if (= 0 pages-buffer-original-page) | |
| 624 1 | |
| 625 pages-buffer-original-page)))) | |
| 626 | |
| 627 (defun pages-copy-header-and-position (count-lines-p) | |
| 628 "Copy page header and its position to the Pages Directory. | |
| 629 Only arg non-nil, count lines in page and insert before header. | |
| 630 Used by `pages-directory' function." | |
| 631 | |
| 632 (let (position line-count) | |
| 633 | |
| 634 (if count-lines-p | |
| 635 (save-excursion | |
| 636 (save-restriction | |
| 637 (narrow-to-page) | |
| 638 (setq line-count (count-lines (point-min) (point-max)))))) | |
| 639 | |
| 640 ;; Keep track of page for later cursor positioning | |
| 641 (if (<= (point) pages-buffer-original-position) | |
| 642 (setq pages-buffer-original-page | |
| 643 (1+ pages-buffer-original-page))) | |
| 644 | |
| 645 (save-excursion | |
| 646 ;; go to first non-blank char after the page-delimiter | |
| 647 (skip-chars-forward " \t\n") | |
| 648 ;; set the marker here; this the place to which the | |
| 649 ;; `pages-directory-goto' command will go | |
| 650 (setq position (make-marker)) | |
| 651 (set-marker position (point)) | |
| 652 (let ((start (point)) | |
| 653 (end (save-excursion (end-of-line) (point)))) | |
| 654 ;; change to directory buffer | |
| 655 (set-buffer standard-output) | |
| 656 ;; record page position | |
| 657 (setq pages-pos-list (cons position pages-pos-list)) | |
| 658 ;; insert page header | |
| 659 (insert-buffer-substring buffer start end)) | |
| 660 | |
| 661 (if count-lines-p | |
| 662 (save-excursion | |
| 663 (beginning-of-line) | |
| 664 (insert (format "%3d: " line-count)))) | |
| 665 | |
| 666 (terpri)) | |
| 667 (forward-line 1))) | |
| 668 | |
| 669 (defun pages-directory-mode () | |
| 670 "Mode for handling the pages-directory buffer. | |
| 671 | |
| 672 Move point to one of the lines in this buffer, then use \\[pages-directory-goto] to go | |
| 673 to the same line in the pages buffer." | |
| 674 | |
| 675 (kill-all-local-variables) | |
| 676 (use-local-map pages-directory-map) | |
| 677 (setq major-mode 'pages-directory-mode) | |
| 678 (setq mode-name "Pages-Directory") | |
| 679 (make-local-variable 'pages-buffer) | |
| 680 (make-local-variable 'pages-pos-list) | |
| 681 (make-local-variable 'pages-directory-buffer-narrowing-p)) | |
| 682 | |
| 683 (defun pages-directory-goto () | |
| 684 "Go to the corresponding line in the pages buffer." | |
| 685 | |
| 686 ;;; This function is mostly a copy of `occur-mode-goto-occurrence' | |
| 687 | |
| 688 (interactive) | |
| 689 (if (or (not pages-buffer) | |
| 690 (not (buffer-name pages-buffer))) | |
| 691 (progn | |
| 692 (setq pages-buffer nil | |
| 693 pages-pos-list nil) | |
| 694 (error "Buffer in which pages were found is deleted."))) | |
| 695 (beginning-of-line) | |
| 696 (let* ((pages-number (1- (count-lines (point-min) (point)))) | |
| 697 (pos (nth pages-number pages-pos-list)) | |
| 698 (end-of-directory-p (eobp)) | |
| 699 (narrowing-p pages-directory-buffer-narrowing-p)) | |
| 700 (pop-to-buffer pages-buffer) | |
| 701 (widen) | |
| 702 (if end-of-directory-p | |
| 703 (goto-char (point-max)) | |
| 704 (goto-char (marker-position pos))) | |
| 705 (if narrowing-p (narrow-to-page)))) | |
| 706 | |
| 707 | |
| 708 ;;;; The `pages-directory-for-addresses' function and ancillary code | |
| 709 | |
| 710 (defvar pages-addresses-file-name "~/addresses" | |
| 711 "*Standard name for file of addresses. Entries separated by `page-delimiter'. | |
| 712 Used by `pages-directory-for-addresses' function.") | |
| 713 | |
| 714 (defvar pages-directory-for-addresses-narrowing-p t | |
| 715 "*If non-nil, `pages-directory-goto' narrows addresses buffer to entry.") | |
| 716 | |
| 717 (defun pages-directory-for-addresses (&optional filename) | |
| 718 "Find addresses file and display its directory. | |
| 719 By default, create and display directory of `pages-addresses-file-name'. | |
| 720 Optional argument is FILENAME. In interactive use, with prefix | |
| 721 argument, prompt for file name and provide completion. | |
| 722 | |
| 723 Move point to one of the lines in the displayed directory, | |
| 724 then use C-c C-c to go to the same line in the addresses buffer." | |
| 725 | |
| 726 (interactive | |
| 727 (list (if current-prefix-arg | |
| 728 (read-file-name "Filename: " pages-addresses-file-name)))) | |
| 729 | |
| 730 (if (interactive-p) | |
| 731 (message "Creating directory for: %s " | |
| 732 (or filename pages-addresses-file-name))) | |
| 733 (if (file-exists-p (or filename pages-addresses-file-name)) | |
| 734 (progn | |
| 735 (set-buffer | |
| 736 (find-file-noselect | |
| 737 (expand-file-name | |
| 738 (or filename pages-addresses-file-name)))) | |
| 739 (widen) | |
| 740 (pages-directory t nil nil) | |
| 741 (pages-directory-address-mode) | |
| 742 (setq pages-directory-buffer-narrowing-p | |
| 743 pages-directory-for-addresses-narrowing-p) | |
| 744 (delete-other-windows) | |
| 745 (save-excursion | |
| 746 (goto-char (point-min)) | |
| 747 (delete-region (point) (save-excursion (end-of-line) (point))) | |
| 748 (insert | |
| 749 "=== Address List Directory: use `C-c C-c' to go to page under cursor. ===") | |
| 750 (set-buffer-modified-p nil) | |
| 751 )) | |
| 752 (error "No addresses file found!"))) | |
| 753 | |
| 754 (defun pages-directory-address-mode () | |
| 755 "Mode for handling the Addresses Directory buffer. | |
| 756 | |
| 757 Move point to one of the lines in this buffer, then use C-c C-c to go | |
| 758 to the same line in the pages buffer." | |
| 759 | |
| 760 (use-local-map pages-directory-map) | |
| 761 (setq major-mode 'pages-directory-address-mode) | |
| 762 (setq mode-name "Addresses Directory") | |
| 763 (make-local-variable 'pages-buffer) | |
| 764 (make-local-variable 'pages-pos-list) | |
| 765 (make-local-variable 'pages-directory-buffer-narrowing-p)) | |
| 766 | |
|
659
505130d1ddf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
235
diff
changeset
|
767 ;;; page-ext.el ends here |
|
505130d1ddf8
*** empty log message ***
Eric S. Raymond <esr@snark.thyrsus.com>
parents:
235
diff
changeset
|
768 |
