gaynor@topaz.UUCP (05/01/87)
Hi... I finally discovered outline mode! This thrills you to no end, I'm sure. In preperation for making extensive use of it, though, I wrote a hook for outline-mode that associates with `outline' buffers their own outline-regexp and a human-readable description of that regexp. Also, it rebinds everything, and there are a couple of help functions. This doesn't do anything TOO fancy, like the recent fisheye-view message I read. I THINK I got all the bugs out, but if I missed any, please mail me and I'll apologize and post the diffs. Note that I am not the most experienced GNU Emacs Lisp programmer, and if you see things that could be done in a better way, or conventions not followed, or `foo's not `bar'ed, or whatnot, PLEASE mail me and I will post the diffs. Also, there are default default-outline-regexp and default-outline-description values that are set and used when these aren't set. These are kind of hard-coded in, and will require changes in several spots. The next thing to do is to write a function to easily modify the outline-regexp stuff. Hmm, come to think of it, I didn't write this with unwriteable buffers in mind. This shouldn't be a real big fix, I'll get the diffs out when I get a chance. The outline information is inserted into the buffer at the top (when necessary) and then narrowed away, so it will remain with the file when it's saved. It's not so hard to use. Find file (in a writeable buffer!), and go into outline-mode. The hook is autoloaded, no mess no fuss. If outline-regexp stuff needs to be inserted, this is when it's done. I would suggest putting this in your .emacs, setting the 2nd (and 3rd?) argument(s) of the autoload call appropriately: ====================================================================== (setq outline-mode-hook 'outline-mode-hook-function) (autoload 'outline-mode-hook-function "~/src/gnu-elisp/outline-mode-hook-function.el" "It makes a nice sandwhich. A nice sandwhich.") ====================================================================== Here is the hook, and associated functions: ====================================================================== (defun describe-outline-mode () "Describes this version of outline-mode." (interactive) ;; Don't `restart' the buffer if it's already there. (if (get-buffer "*Outline Description*") ;; Yes, it changes the current buffer to *Outline Description*. (switch-to-buffer "*Outline Description*") (progn (switch-to-buffer "*Outline Description*") ;; This is the text of the buffer. Remember to escape \s and "s! (insert (concat "outline-regexp info \\( \\)*\\*\\([0-9]+\\([---.][0-9]+\\)*\\*\\|\\**\\) 0 or more sequences of 4 blanks ` ' an asterisk `*' choose either of alternative 1 a digit-sequence (1 or more digits) 0 or more sequences of a period `.' or a hyphen `-' a digit-sequence an asterisk `*' alternative 2 0 or more asterisks `*' end choice finally, a blank ` ' *1* Help *1.1* C-c ? = describe-my-outline Select this buffer (`*Outline Commands*') if it exists, otherwise create it and fill it with this information. Note that it is initially in outline mode (with the defaults), hence all of the commands work. Use this buffer as a `proving grounds'. *1.2* C-c v = describe-outline-regexp-verbose This creates a help buffer containing the outline-regexp info (which is normally hidden from view). The values of the LOCAL variables outline-regexp and outline-description. *1.3* C-c r = describe-outline-regexp Display the value of the LOCAL variable outline-regexp in the mini-buffer. *1.4* outline-regexp info Here's how to supply the values for outline-regexp and outline-regexp-description. The first line of the file should contain `outline-regexp info', verbatim. The second line should contain the value for the outline-regexp. The third through n lines (optional) should be non-blank, containing a description (human readable) of outline-regexp. Then, a blank line ends this section. Now enter outline-mode, and this information will be processed and apparently disappear. Actually, it is 'narrowed away', to keep it out of sight. If you don't supply these values, default values are supplied. These defaults may be set, and are default-outline-regexp and default-outline-regexp-description. If not set, they will be assigned values by the hook. *1.5* More Information See the Info entry Outline Mode for a discussion of outline-mode, and the Info entry on Narrowing for a discussion of selective text display. See the Info entry on Regexps for a discussion of regular expressions. *2* Movement *2.1* C-c n = outline-next-visible-heading Move the point to the next visible heading. *2.2* C-c p = outline-previous-visible-heading Move the point to the previous visible heading. *2.3* C-c u = outline-up-previous-heading Move the point to the parent heading. *2.4* C-c f = outline-forward-same-level Move point to the next sibling heading. *2.5* C-c b = outline-backward-same-level Move point to the previous sibling heading. *3* Show *3.1* C-c s a = show-all Show everything in the outline. *3.2* C-c s s = show-subtree Show everything under under a heading. *3.3* C-c s b = show-branches Show all the sub-headings (ie branches) of a heading. *3.4* C-c s c = show-children Show the sub-headings (ie children's headings) of a heading. *3.5* C-c s . = show-entry Show the body of a heading. *4* Hide *4.1* C-c h a = hide-body (more apropos - hide-all-leaves) Hide all leaves, showing only the branches. *4.2* C-c h s = hide-subtree Hide everything underneath the subtree. *4.3* C-c h l = hide-leaves Hide the leaves under a subtree, leaving only the branches. *4.4* C-c h . = hide-entry Hide the leaf at the current node. ") (outline-mode) (set-buffer-modified-p nil)))) (defun describe-outline-regexp-terse () "Show the value of outline-regexp in the mini-buffer." (interactive) (message (concat "outline-regexp = `" outline-regexp "'"))) (defun describe-outline-regexp-verbose () "Show the values of outline-regexp and outline-regexp-description in their own buffer." (interactive) (with-output-to-temp-buffer "*Outline Regexp*" (princ (concat "outline-regexp = `" outline-regexp "'\n\nusage\n\n" outline-regexp-description)))) (defun outline-mode-hook-function () "An implementation of outline-mode that associates with each outline file its own outline-regexp and outline-regexp-description. It does some rebinding, and a couple of help functions are bound. I think the next thing I'll want to do is make a convenient way to change these values, rather than doing it lisply." ;; So that each buffer in outline mode may have it's own ;; outline-regexp and outline-regexp-description... (make-local-variable 'outline-regexp) (make-local-variable 'outline-regexp-description) ;; Now that proper variables exist locally, set their values. ;; Move the point to the end of the first line, kissing the old ;; point bye-bye. (goto-char (point-min)) (end-of-line) ;; If the buffer contains outline-regexp info (ie if the first line ;; equal to "outline-regexp info"), ... (if (equal (buffer-substring (point-min) (point)) "outline-regexp info") ;; ... then the values are there and must be extracted. (progn ;; First, get the value for outline-regexp by setting it to the ;; second line of the file (kissing the original mark bye-bye). (setq outline-regexp (buffer-substring (progn (forward-char 1) (point)) (progn (end-of-line) (point)))) ;; Second, get the value for outline-regexp-description to ;; everything from here on in + 1 to the next blank line. (setq outline-regexp-description (buffer-substring (1+ (point)) (progn (search-forward "\n\n") (1- (point)))))) ;; Otherwise, insert the default info and set the values. (progn (message "inserting default outline-regexp info...") (insert (concat "outline-regexp info\n" ;; If default-outline-regexp is bound, ... (if (boundp 'default-outline-regexp) ;; ... use it. (setq outline-regexp default-outline-regexp) ;; Otherwise, set it and use it. Ie a default default value. (setq default-outline-regexp (setq outline-regexp "\\( \\)*\\*\\([0-9]+\\([---.][0-9]+\\)*\\*\\|\\**\\) "))) ;; If default-outline-regexp-description is bound, ... (if (boundp 'default-outline-regexp-description) ;; ... use it. (setq outline-regexp-description default-outline-regexp-description) ;; Otherwise, set it and use it. Ie a default default value. (setq default-outline-regexp-description (setq outline-regexp-description (concat "0 or more sequences of 4 blanks ` '\n" "an asterisk `*'\n" "choose either\n" " alternative 1\n" " a digit-sequence (1 or more digits)\n" " 0 or more sequences of\n" " a period `.' or a hyphen `-'\n" " a digit-sequence\n" " an asterisk `*'\n" " alternative 2\n" " 0 or more asterisks `*'\n" "end choice\n" "finally, a blank ` '\n\n")))))))) ;; Now, narrow away (and hope it survives outline-mode) ;; everything up to point. (Hindsight - it does.) (narrow-to-region (point) (point-max)) ;; MY bindings. Every defined function is bound. Okay, so you may ;; frown at the 3-character sequences. They're mnemonic and fairly ;; consistant between hides and shows. Try them before you change ;; them. THEN change them! ;; "C-cs" is the prefix for all the show commands. (local-unset-key "\C-cs") (define-key outline-mode-map "\C-csa" 'show-all) (define-key outline-mode-map "\C-css" 'show-subtree) (define-key outline-mode-map "\C-csb" 'show-branches) (define-key outline-mode-map "\C-csc" 'show-children) (define-key outline-mode-map "\C-cs." 'show-entry) ;; "C-ch" is the prefix for all the hide commands. (local-unset-key "\C-ch") (define-key outline-mode-map "\C-cha" 'hide-body) (define-key outline-mode-map "\C-chs" 'hide-subtree) (define-key outline-mode-map "\C-chl" 'hide-leaves) (define-key outline-mode-map "\C-ch." 'hide-entry) ;; The motion commands are fine as two-key sequences. (define-key outline-mode-map "\C-cn" 'outline-next-visible-heading) (define-key outline-mode-map "\C-cp" 'outline-previous-visible-heading) (define-key outline-mode-map "\C-cu" 'outline-up-heading) (define-key outline-mode-map "\C-cf" 'outline-forward-same-level) (define-key outline-mode-map "\C-cb" 'outline-backward-same-level) ;; The help commands are also find as two key sequences. (define-key outline-mode-map "\C-c?" 'describe-outline-mode) (define-key outline-mode-map "\C-cr" 'describe-outline-regexp-terse) (define-key outline-mode-map "\C-ct" 'describe-outline-regexp-terse) (define-key outline-mode-map "\C-cv" 'describe-outline-regexp-verbose)) ====================================================================== /-------------------------------------------------\ | uucp: ...!topaz!gaynor ...!topaz!remus!gaynor | | ~~~~~~~~~~~~~~~~ | | arpa: gaynor@topaz silver@aim | \-------------------------------------------------/
gaynor@topaz.UUCP (05/01/87)
The ORIGINAL doesn't work, even! Yes, I'm embarressed <:^( . Here are the mods: line 10: It's not really an error, but it messes up paren matching. Remove the second sentence. line 135: I don't know how it happenned, but I lost a right-paren somewhow. The `insert' that inserts the buffer contents in `describe-outline-mode' needs to be closed, so append a right-paren to the line. I hate when things like this happen. Andy "Oh sure, I'll just take one last look before posting..." Gaynor /-------------------------------------------------\ | uucp: ...!topaz!gaynor ...!topaz!remus!gaynor | | ~~~~~~~~~~~~~~~~ | | arpa: gaynor@topaz silver@aim | \-------------------------------------------------/