bard@THEORY.LCS.MIT.EDU (06/14/89)
I write heavily-indented outlines that look like this: * Wombats ** From Hell ** From the Moons of Neptune *** Highly Insulated *** Methane-breathing ** From Australia *** Reported in science fiction stories *** Real and so I wrote a few commands for inserting the heading points more automatically: e.g., c-c c-c gives you another heading point at the current depth, c-c c-e gives you one further in, and so on. -- Bard the emacs gargoyle ------------------------ cut here ------------------------ ;; out-indent.el -- indented outline-mode ;; Copyright (C) Bard Bloom, June 1989 ;; bard@theory.lcs.mit.edu ;; This file is not yet part of GNU Emacs. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY. No author or distributor ;; accepts responsibility to anyone for the consequences of using it ;; or for whether it serves any particular purpose or works at all, ;; unless he says so in writing. Refer to the GNU Emacs General Public ;; License for full details. ;; Everyone is granted permission to copy, modify and redistribute ;; GNU Emacs, but only under the conditions described in the ;; GNU Emacs General Public License. A copy of this license is ;; supposed to have been given to you along with GNU Emacs so you ;; can know your rights and responsibilities. It should be in a ;; file named COPYING. Among other things, the copyright notice ;; and this notice must be preserved on all copies. ;; WHAT THIS DOES: ;; This lets you write outlines which are textually as well as logically ;; indented. It is best suited to writing outlines and things like that, ;; which is one of my major uses of outline-mode. ;; ;; For example, you can write: ;; ;; * Heading ;; ** Subheading-1 ;; ** Subheading-2 ;; *** Sub-subheading ;; ** Subheading-3 ;; ;; OK. You could do this before, too, but you had to put in all those ;; spaces and stars by hand. Now you can put them in by emacs commands, ;; and it even gets the spaces right. ;; ;; ;; Here's what you do. ;; Have your outline-mode-hook call set-outline-levels ;; (or use the one I have provided). ;; The outline-levels is a list of the headings you want. ;; It is actually an association-list, with elements of the form: ;; (level outline-string) ;; For example, ;; ((1 "*") ;; (2 " **") ;; (3 " ***") ;; (1 ">")) ;; This will use 1-3 stars for depth 1-3 points; it will recognize a ">" ;; but not insert it. (Note: outline-regexp is built automatically from ;; this alist; you shouldn't set it yourself. The things are ;; regexp-quoted, so don't worry about using *'s.) ;; ;; ;; The commands for making new outline points: ;; c-c c-c: start a new outline point on the next line, ;; which is (by default) at the same level as this one. ;; If you're at a **, this will make a new **. ;; c-u c-c c-c means make a top-level heading. ;; c-u c-u c-c c-c means make a second-level heading. ;; numeric argument makes a heading of that level. ;; c-c c-d: Start a heading which is one (or ARG) levels further out. ;; Go from "**" to "*" ;; c-c c-e: Start a heading which is one (or ARG) levels deeper. ;; Go from "**" to "***" ;; ;; This works quite well with Martin Neitzel's gin-mode, a gadget which guesses ;; the proper indentation for the current line. The variable ;; gin-left-hang-indent-re should have have something like ;; \\*+\\s + ;; (with double-backslashes for use with strings) ;; so that each point fills in a block nicely. ;; ;; I do not consider this perfected yet. Comments and improvements ;; to bard@theory.lcs.mit.edu. (provide 'out-indent) (defun set-outline-levels (level-list) "Sets outline-levels. The argument LEVEL-LIST should be a list looking like: ( (1 \"*\") (2 \" **\") (3 \" ***\")) The numbers tell what level the outline entry is at. The string is the string which will start entries at that level: things at level two (here) will start with a space and two stars." (setq outline-levels level-list) (setq outline-level-regexp (regexp-quote "*")) (dolist (i outline-levels) (setq outline-level-regexp (concat outline-level-regexp "\\|" (regexp-quote (cadr i)))))) (set-outline-levels '((1 "*") (2 " **") (3 " ***") (4 " ****") (5 " *****") (6 " ******") (7 " *******"))) (defun outline-new-heading (arg) "Start a new outline point on the next line. Default level is the same as the last one. numeric ARG sets the level of the heading. c-u means level one, c-u c-u means level two." (interactive "P") (outline-maybe-newline) (let ((depth (cond ((null arg) (outline-previous-depth)) ((equal arg '(4)) 1) ((equal arg '(16)) 2) ((integerp arg) arg) (t (error "huh?"))))) (insert (cadr (assq depth outline-levels)) " "))) (defun outline-previous-depth () (catch 'outline-depth-found (save-excursion (while (not (bobp)) (previous-line 1) (beginning-of-line 1) (when (looking-at outline-level-regexp) (dolist (l outline-levels) (when (looking-at (regexp-quote (cadr l))) (throw 'outline-depth-found (car l))))) )) ;; At this point, we're lost -- assume depth 1. (throw 'outline-depth-found 1) )) (define-key outline-mode-map "\C-c\C-c" 'outline-new-heading) (define-key outline-mode-map "\C-c\C-d" 'outline-new-outer-heading) (define-key outline-mode-map "\C-c\C-e" 'outline-new-inner-heading) (defun outline-new-outer-heading (arg) "Start a new outline point on the next line, ARG levels farther out." (interactive "p") (outline-maybe-newline) (insert (cadr (assq (- (outline-previous-depth) arg) outline-levels)) " ")) (defun outline-new-inner-heading (arg) "Start a new outline point on the next line, ARG levels deeper." (interactive "p") (outline-maybe-newline) (insert (cadr (assq (+ (outline-previous-depth) arg) outline-levels)) " ")) (defun outline-maybe-newline () (let ((shouldnt-newline (save-excursion (beginning-of-line 1) (looking-at "^[ \t]*$")))) (cond (shouldnt-newline (delete-region (save-excursion (beginning-of-line 1) (point)) (save-excursion (end-of-line 1) (point)))) (t (newline)))))