2020-10-20 23:00:52 +00:00
|
|
|
|
;;; outline.el --- outline mode commands for Emacs -*- lexical-binding: t; -*-
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2022-07-03 15:35:53 +00:00
|
|
|
|
;; Copyright (C) 1986-2022 Free Software Foundation, Inc.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2019-05-25 20:43:06 +00:00
|
|
|
|
;; Maintainer: emacs-devel@gnu.org
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Keywords: outlines
|
|
|
|
|
|
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
2008-05-06 08:06:51 +00:00
|
|
|
|
;; GNU Emacs is free software: you can redistribute it and/or modify
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
2008-05-06 08:06:51 +00:00
|
|
|
|
;; the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
;; (at your option) any later version.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
2017-09-13 22:52:52 +00:00
|
|
|
|
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; This package is a major mode for editing outline-format documents.
|
|
|
|
|
;; An outline can be `abstracted' to show headers at any given level,
|
|
|
|
|
;; with all stuff below hidden. See the Emacs manual for details.
|
|
|
|
|
|
|
|
|
|
;;; Todo:
|
|
|
|
|
|
|
|
|
|
;; - subtree-terminators
|
|
|
|
|
;; - better handle comments before function bodies (i.e. heading)
|
|
|
|
|
;; - don't bother hiding whitespace
|
|
|
|
|
|
|
|
|
|
;;; Code:
|
|
|
|
|
|
2021-11-02 12:29:32 +00:00
|
|
|
|
(eval-when-compile (require 'cl-lib))
|
2022-07-28 12:37:59 +00:00
|
|
|
|
(require 'icons)
|
2021-11-02 12:29:32 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(defgroup outlines nil
|
2005-07-04 02:56:16 +00:00
|
|
|
|
"Support for hierarchical outlining."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
:prefix "outline-"
|
2016-10-08 13:37:42 +00:00
|
|
|
|
:group 'text)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2013-02-20 13:05:24 +00:00
|
|
|
|
(defvar outline-regexp "[*\^L]+"
|
2006-03-06 04:49:42 +00:00
|
|
|
|
"Regular expression to match the beginning of a heading.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
Any line whose beginning matches this regexp is considered to start a heading.
|
|
|
|
|
Note that Outline mode only checks this regexp at the start of a line,
|
|
|
|
|
so the regexp need not (and usually does not) start with `^'.
|
|
|
|
|
The recommended way to set this is with a Local Variables: list
|
2013-02-20 13:05:24 +00:00
|
|
|
|
in the file it applies to. See also `outline-heading-end-regexp'.")
|
2011-03-04 08:40:00 +00:00
|
|
|
|
;;;###autoload(put 'outline-regexp 'safe-local-variable 'stringp)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2013-02-20 13:05:24 +00:00
|
|
|
|
(defvar outline-heading-end-regexp "\n"
|
2006-03-06 04:49:42 +00:00
|
|
|
|
"Regular expression to match the end of a heading line.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
You can assume that point is at the beginning of a heading when this
|
|
|
|
|
regexp is searched for. The heading ends at the end of the match.
|
|
|
|
|
The recommended way to set this is with a `Local Variables:' list
|
2013-02-20 13:05:24 +00:00
|
|
|
|
in the file it applies to.")
|
2011-03-04 08:40:00 +00:00
|
|
|
|
;;;###autoload(put 'outline-heading-end-regexp 'safe-local-variable 'stringp)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defvar outline-mode-prefix-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map "@" 'outline-mark-subtree)
|
|
|
|
|
(define-key map "\C-n" 'outline-next-visible-heading)
|
|
|
|
|
(define-key map "\C-p" 'outline-previous-visible-heading)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map "\C-i" 'outline-show-children)
|
|
|
|
|
(define-key map "\C-s" 'outline-show-subtree)
|
|
|
|
|
(define-key map "\C-d" 'outline-hide-subtree)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map "\C-u" 'outline-up-heading)
|
|
|
|
|
(define-key map "\C-f" 'outline-forward-same-level)
|
|
|
|
|
(define-key map "\C-b" 'outline-backward-same-level)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map "\C-t" 'outline-hide-body)
|
|
|
|
|
(define-key map "\C-a" 'outline-show-all)
|
|
|
|
|
(define-key map "\C-c" 'outline-hide-entry)
|
|
|
|
|
(define-key map "\C-e" 'outline-show-entry)
|
|
|
|
|
(define-key map "\C-l" 'outline-hide-leaves)
|
|
|
|
|
(define-key map "\C-k" 'outline-show-branches)
|
|
|
|
|
(define-key map "\C-q" 'outline-hide-sublevels)
|
|
|
|
|
(define-key map "\C-o" 'outline-hide-other)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map "\C-^" 'outline-move-subtree-up)
|
|
|
|
|
(define-key map "\C-v" 'outline-move-subtree-down)
|
|
|
|
|
(define-key map [(control ?<)] 'outline-promote)
|
|
|
|
|
(define-key map [(control ?>)] 'outline-demote)
|
|
|
|
|
(define-key map "\C-m" 'outline-insert-heading)
|
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
(defvar outline-mode-menu-bar-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map [hide] (cons "Hide" (make-sparse-keymap "Hide")))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [hide outline-hide-other]
|
|
|
|
|
'(menu-item "Hide Other" outline-hide-other
|
2008-04-04 22:45:01 +00:00
|
|
|
|
:help "Hide everything except current body and parent and top-level headings"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [hide outline-hide-sublevels]
|
|
|
|
|
'(menu-item "Hide Sublevels" outline-hide-sublevels
|
2008-04-04 22:45:01 +00:00
|
|
|
|
:help "Hide everything but the top LEVELS levels of headers, in whole buffer"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [hide outline-hide-subtree]
|
|
|
|
|
'(menu-item "Hide Subtree" outline-hide-subtree
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Hide everything after this heading at deeper levels"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [hide outline-hide-entry]
|
|
|
|
|
'(menu-item "Hide Entry" outline-hide-entry
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Hide the body directly following this heading"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [hide outline-hide-body]
|
|
|
|
|
'(menu-item "Hide Body" outline-hide-body
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Hide all body lines in buffer, leaving all headings visible"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [hide outline-hide-leaves]
|
|
|
|
|
'(menu-item "Hide Leaves" outline-hide-leaves
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Hide the body after this heading and at deeper levels"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [show] (cons "Show" (make-sparse-keymap "Show")))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [show outline-show-subtree]
|
|
|
|
|
'(menu-item "Show Subtree" outline-show-subtree
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Show everything after this heading at deeper levels"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [show outline-show-children]
|
|
|
|
|
'(menu-item "Show Children" outline-show-children
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Show all direct subheadings of this heading"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [show outline-show-branches]
|
|
|
|
|
'(menu-item "Show Branches" outline-show-branches
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Show all subheadings of this heading, but not their bodies"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [show outline-show-entry]
|
|
|
|
|
'(menu-item "Show Entry" outline-show-entry
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Show the body directly following this heading"))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-key map [show outline-show-all]
|
|
|
|
|
'(menu-item "Show All" outline-show-all
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Show all of the text in the buffer"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings]
|
|
|
|
|
(cons "Headings" (make-sparse-keymap "Headings")))
|
|
|
|
|
(define-key map [headings demote-subtree]
|
2011-09-18 20:43:20 +00:00
|
|
|
|
'(menu-item "Demote Subtree" outline-demote
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Demote headings lower down the tree"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings promote-subtree]
|
2011-09-18 20:43:20 +00:00
|
|
|
|
'(menu-item "Promote Subtree" outline-promote
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Promote headings higher up the tree"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings move-subtree-down]
|
2011-09-18 20:43:20 +00:00
|
|
|
|
'(menu-item "Move Subtree Down" outline-move-subtree-down
|
2011-11-15 17:37:37 +00:00
|
|
|
|
:help "Move the current subtree down past arg headlines of the same level"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings move-subtree-up]
|
2011-09-18 20:43:20 +00:00
|
|
|
|
'(menu-item "Move Subtree Up" outline-move-subtree-up
|
2011-11-15 17:37:37 +00:00
|
|
|
|
:help "Move the current subtree up past arg headlines of the same level"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings copy]
|
2011-09-18 20:43:20 +00:00
|
|
|
|
'(menu-item "Copy to Kill Ring" outline-headers-as-kill
|
2008-04-04 22:45:01 +00:00
|
|
|
|
:enable mark-active
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Save the visible outline headers in region at the start of the kill ring"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings outline-insert-heading]
|
2011-09-18 20:43:20 +00:00
|
|
|
|
'(menu-item "New Heading" outline-insert-heading
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Insert a new heading at same depth at point"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings outline-backward-same-level]
|
2008-04-04 22:45:01 +00:00
|
|
|
|
'(menu-item "Previous Same Level" outline-backward-same-level
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Move backward to the arg'th subheading at same level as this one."))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings outline-forward-same-level]
|
2008-04-04 22:45:01 +00:00
|
|
|
|
'(menu-item "Next Same Level" outline-forward-same-level
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Move forward to the arg'th subheading at same level as this one"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings outline-previous-visible-heading]
|
2008-04-04 22:45:01 +00:00
|
|
|
|
'(menu-item "Previous" outline-previous-visible-heading
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Move to the previous heading line"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings outline-next-visible-heading]
|
2008-04-04 22:45:01 +00:00
|
|
|
|
'(menu-item "Next" outline-next-visible-heading
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Move to the next visible heading line"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(define-key map [headings outline-up-heading]
|
2008-04-04 22:45:01 +00:00
|
|
|
|
'(menu-item "Up" outline-up-heading
|
2008-04-09 06:15:13 +00:00
|
|
|
|
:help "Move to the visible heading line of which the present line is a subheading"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
(defvar outline-minor-mode-menu-bar-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map [outline]
|
|
|
|
|
(cons "Outline"
|
|
|
|
|
(nconc (make-sparse-keymap "Outline")
|
|
|
|
|
;; Remove extra separator
|
|
|
|
|
(cdr
|
|
|
|
|
;; Flatten the major mode's menus into a single menu.
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(apply #'append
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(mapcar (lambda (x)
|
|
|
|
|
(if (consp x)
|
|
|
|
|
;; Add a separator between each
|
|
|
|
|
;; part of the unified menu.
|
|
|
|
|
(cons '(--- "---") (cdr x))))
|
|
|
|
|
outline-mode-menu-bar-map))))))
|
|
|
|
|
map))
|
2003-07-28 21:50:05 +00:00
|
|
|
|
|
2021-09-23 16:14:56 +00:00
|
|
|
|
(defcustom outline-minor-mode-cycle-filter nil
|
2022-04-16 07:56:01 +00:00
|
|
|
|
"Control where on a heading the visibility-cycling commands are bound to keys.
|
|
|
|
|
This option controls, in Outline minor mode, where on a heading typing
|
|
|
|
|
the key sequences bound to visibility-cycling commands like `outline-cycle'
|
|
|
|
|
and `outline-cycle-buffer' will invoke those commands. By default, you can
|
2022-07-03 15:35:53 +00:00
|
|
|
|
invoke these commands by typing \\`TAB' and \\`S-TAB' anywhere on a heading line,
|
2022-04-16 07:56:01 +00:00
|
|
|
|
but customizing this option can make those bindings be in effect only at
|
|
|
|
|
specific positions on the heading, like only at the line's beginning or
|
|
|
|
|
line's end. This allows these keys to be bound to their usual commands,
|
|
|
|
|
as determined by the major mode, elsewhere on the heading lines.
|
|
|
|
|
This option is only in effect when `outline-minor-mode-cycle' is non-nil."
|
2021-09-23 16:14:56 +00:00
|
|
|
|
:type '(choice (const :tag "Everywhere" nil)
|
|
|
|
|
(const :tag "At line beginning" bolp)
|
|
|
|
|
(const :tag "Not at line beginning"
|
|
|
|
|
(lambda () (not (bolp))))
|
|
|
|
|
(const :tag "At line end" eolp)
|
2022-04-16 07:56:01 +00:00
|
|
|
|
(function :tag "Custom filter function"))
|
2021-09-23 16:14:56 +00:00
|
|
|
|
:version "28.1")
|
|
|
|
|
|
2022-01-10 18:20:09 +00:00
|
|
|
|
(defvar outline-minor-mode-cycle)
|
2021-09-23 16:14:56 +00:00
|
|
|
|
(defun outline-minor-mode-cycle--bind (map key binding &optional filter)
|
|
|
|
|
(define-key map key
|
|
|
|
|
`(menu-item
|
|
|
|
|
"" ,binding
|
|
|
|
|
;; Filter out specific positions on the heading.
|
|
|
|
|
:filter
|
|
|
|
|
,(or filter
|
|
|
|
|
(lambda (cmd)
|
2022-01-10 18:20:09 +00:00
|
|
|
|
(when (and outline-minor-mode-cycle
|
2022-01-11 08:56:54 +00:00
|
|
|
|
(outline-on-heading-p t)
|
2022-01-10 18:20:09 +00:00
|
|
|
|
(or (not (functionp outline-minor-mode-cycle-filter))
|
|
|
|
|
(funcall outline-minor-mode-cycle-filter)))
|
2021-09-23 16:14:56 +00:00
|
|
|
|
cmd))))))
|
|
|
|
|
|
|
|
|
|
(defvar outline-minor-mode-cycle-map
|
2021-03-03 19:12:13 +00:00
|
|
|
|
(let ((map (make-sparse-keymap)))
|
2021-09-23 16:14:56 +00:00
|
|
|
|
(outline-minor-mode-cycle--bind map (kbd "TAB") #'outline-cycle)
|
|
|
|
|
(outline-minor-mode-cycle--bind map (kbd "<backtab>") #'outline-cycle-buffer)
|
2021-03-03 19:12:13 +00:00
|
|
|
|
map)
|
2021-09-23 16:14:56 +00:00
|
|
|
|
"Keymap used by `outline-minor-mode-cycle'.")
|
2021-03-03 19:12:13 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(defvar outline-mode-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map "\C-c" outline-mode-prefix-map)
|
|
|
|
|
(define-key map [menu-bar] outline-mode-menu-bar-map)
|
2021-09-23 16:14:56 +00:00
|
|
|
|
;; Only takes effect if point is on a heading.
|
|
|
|
|
(define-key map (kbd "TAB")
|
|
|
|
|
`(menu-item "" outline-cycle
|
|
|
|
|
:filter ,(lambda (cmd)
|
|
|
|
|
(when (outline-on-heading-p) cmd))))
|
|
|
|
|
(define-key map (kbd "<backtab>") #'outline-cycle-buffer)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
(defvar outline-font-lock-keywords
|
2015-01-30 08:24:33 +00:00
|
|
|
|
'(
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Highlight headings according to the level.
|
2021-11-24 18:46:53 +00:00
|
|
|
|
(eval . (list (concat "^\\(?:" outline-regexp "\\).*")
|
2021-03-07 18:52:39 +00:00
|
|
|
|
0 '(if outline-minor-mode
|
2022-01-10 18:20:09 +00:00
|
|
|
|
(if outline-minor-mode-highlight
|
|
|
|
|
(list 'face (outline-font-lock-face)))
|
2021-03-03 19:12:13 +00:00
|
|
|
|
(outline-font-lock-face))
|
2021-03-13 21:33:14 +00:00
|
|
|
|
(when outline-minor-mode
|
|
|
|
|
(pcase outline-minor-mode-highlight
|
|
|
|
|
('override t)
|
|
|
|
|
('append 'append)))
|
2021-03-11 18:30:15 +00:00
|
|
|
|
t)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Additional expressions to highlight in Outline mode.")
|
|
|
|
|
|
2005-05-27 11:51:14 +00:00
|
|
|
|
(defface outline-1
|
|
|
|
|
'((t :inherit font-lock-function-name-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 1.")
|
2005-05-27 11:51:14 +00:00
|
|
|
|
|
|
|
|
|
(defface outline-2
|
|
|
|
|
'((t :inherit font-lock-variable-name-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 2.")
|
2005-05-27 11:51:14 +00:00
|
|
|
|
|
|
|
|
|
(defface outline-3
|
|
|
|
|
'((t :inherit font-lock-keyword-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 3.")
|
2005-05-27 11:51:14 +00:00
|
|
|
|
|
|
|
|
|
(defface outline-4
|
2007-09-10 18:21:58 +00:00
|
|
|
|
'((t :inherit font-lock-comment-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 4.")
|
2005-05-27 11:51:14 +00:00
|
|
|
|
|
|
|
|
|
(defface outline-5
|
2007-09-10 18:21:58 +00:00
|
|
|
|
'((t :inherit font-lock-type-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 5.")
|
2005-05-27 11:51:14 +00:00
|
|
|
|
|
|
|
|
|
(defface outline-6
|
|
|
|
|
'((t :inherit font-lock-constant-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 6.")
|
2005-05-27 11:51:14 +00:00
|
|
|
|
|
|
|
|
|
(defface outline-7
|
2007-09-10 18:21:58 +00:00
|
|
|
|
'((t :inherit font-lock-builtin-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 7.")
|
2005-05-27 11:51:14 +00:00
|
|
|
|
|
|
|
|
|
(defface outline-8
|
|
|
|
|
'((t :inherit font-lock-string-face))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
"Level 8.")
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defvar outline-font-lock-faces
|
|
|
|
|
[outline-1 outline-2 outline-3 outline-4
|
|
|
|
|
outline-5 outline-6 outline-7 outline-8])
|
2021-10-31 22:13:52 +00:00
|
|
|
|
|
2022-07-28 12:37:59 +00:00
|
|
|
|
(defcustom outline-minor-mode-use-buttons '(derived-mode . special-mode)
|
|
|
|
|
"Whether to display clickable buttons on the headings.
|
|
|
|
|
The value should be a `buffer-match-p' condition, or nil to
|
|
|
|
|
disable in all buffers and t to enable in all buffers.
|
|
|
|
|
|
2022-07-22 07:58:59 +00:00
|
|
|
|
These buttons can be used to hide and show the body under the heading.
|
2021-11-06 18:54:16 +00:00
|
|
|
|
Note that this feature is not meant to be used in editing
|
2022-07-28 12:37:59 +00:00
|
|
|
|
buffers (yet) -- that will be amended in a future version."
|
2021-10-31 22:13:52 +00:00
|
|
|
|
:type 'boolean
|
2021-12-15 17:17:48 +00:00
|
|
|
|
:safe #'booleanp
|
2021-10-31 22:13:52 +00:00
|
|
|
|
:version "29.1")
|
|
|
|
|
|
2022-07-28 12:37:59 +00:00
|
|
|
|
(define-icon outline-open button
|
|
|
|
|
'((emoji "▶️")
|
|
|
|
|
(symbol " ▶ ")
|
|
|
|
|
(text " open "))
|
|
|
|
|
"Icon used for buttons for opening a section in outline buffers."
|
|
|
|
|
:version "29.1"
|
|
|
|
|
:help-echo "Open this section")
|
|
|
|
|
|
|
|
|
|
(define-icon outline-close button
|
|
|
|
|
'((emoji "🔽")
|
|
|
|
|
(symbol " ▼ ")
|
|
|
|
|
(text " close "))
|
|
|
|
|
"Icon used for buttons for closing a section in outline buffers."
|
|
|
|
|
:version "29.1"
|
|
|
|
|
:help-echo "Close this section")
|
2021-10-31 22:13:52 +00:00
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
|
|
|
|
|
(defvar outline-level #'outline-level
|
|
|
|
|
"Function of no args to compute a header's nesting level in an outline.
|
|
|
|
|
It can assume point is at the beginning of a header line and that the match
|
|
|
|
|
data reflects the `outline-regexp'.")
|
|
|
|
|
;;;###autoload(put 'outline-level 'risky-local-variable t)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-font-lock-face ()
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Return one of `outline-font-lock-faces' for current level."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (match-beginning 0))
|
|
|
|
|
(looking-at outline-regexp)
|
2015-01-30 08:24:33 +00:00
|
|
|
|
(aref outline-font-lock-faces
|
|
|
|
|
(% (1- (funcall outline-level))
|
|
|
|
|
(length outline-font-lock-faces)))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defvar outline-view-change-hook nil
|
|
|
|
|
"Normal hook to be run after outline visibility changes.")
|
|
|
|
|
|
2003-07-28 21:50:05 +00:00
|
|
|
|
(defvar outline-mode-hook nil
|
2012-04-09 13:05:48 +00:00
|
|
|
|
"This hook is run when outline mode starts.")
|
2003-07-28 21:50:05 +00:00
|
|
|
|
|
2022-02-22 13:51:47 +00:00
|
|
|
|
(defcustom outline-blank-line nil
|
|
|
|
|
"Non-nil means to leave an unhidden blank line before headings."
|
|
|
|
|
:type 'boolean
|
|
|
|
|
:safe #'booleanp
|
|
|
|
|
:version "22.1")
|
2004-05-01 03:44:30 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;;;###autoload
|
|
|
|
|
(define-derived-mode outline-mode text-mode "Outline"
|
|
|
|
|
"Set major mode for editing outlines with selective display.
|
|
|
|
|
Headings are lines which start with asterisks: one for major headings,
|
|
|
|
|
two for subheadings, etc. Lines not starting with asterisks are body lines.
|
|
|
|
|
|
|
|
|
|
Body text or subheadings under a heading can be made temporarily
|
|
|
|
|
invisible, or visible again. Invisible lines are attached to the end
|
|
|
|
|
of the heading, so they move with it, if the line is killed and yanked
|
|
|
|
|
back. A heading with text hidden under it is marked with an ellipsis (...).
|
|
|
|
|
|
2015-01-30 08:24:33 +00:00
|
|
|
|
\\{outline-mode-map}
|
2015-01-28 09:32:12 +00:00
|
|
|
|
The commands `outline-hide-subtree', `outline-show-subtree',
|
|
|
|
|
`outline-show-children', `outline-hide-entry',
|
|
|
|
|
`outline-show-entry', `outline-hide-leaves', and `outline-show-branches'
|
2015-01-30 08:24:33 +00:00
|
|
|
|
are used when point is on a heading line.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
The variable `outline-regexp' can be changed to control what is a heading.
|
|
|
|
|
A line is a heading if `outline-regexp' matches something at the
|
|
|
|
|
beginning of the line. The longer the match, the deeper the level.
|
|
|
|
|
|
|
|
|
|
Turning on outline mode calls the value of `text-mode-hook' and then of
|
|
|
|
|
`outline-mode-hook', if they are non-nil."
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(setq-local line-move-ignore-invisible t)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Cause use of ellipses for invisible text.
|
|
|
|
|
(add-to-invisibility-spec '(outline . t))
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(setq-local paragraph-start
|
|
|
|
|
(concat paragraph-start "\\|\\(?:" outline-regexp "\\)"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Inhibit auto-filling of header lines.
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(setq-local auto-fill-inhibit-regexp outline-regexp)
|
|
|
|
|
(setq-local paragraph-separate
|
|
|
|
|
(concat paragraph-separate "\\|\\(?:" outline-regexp "\\)"))
|
|
|
|
|
(setq-local font-lock-defaults
|
|
|
|
|
'(outline-font-lock-keywords t nil nil backward-paragraph))
|
|
|
|
|
(setq-local imenu-generic-expression
|
|
|
|
|
(list (list nil (concat "^\\(?:" outline-regexp "\\).*$") 0)))
|
2022-01-16 18:13:21 +00:00
|
|
|
|
(add-hook 'change-major-mode-hook #'outline-show-all nil t)
|
|
|
|
|
(add-hook 'hack-local-variables-hook #'outline-apply-default-state nil t))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2020-08-08 11:52:46 +00:00
|
|
|
|
(defvar outline-minor-mode-map)
|
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(defcustom outline-minor-mode-prefix "\C-c@"
|
2008-12-03 05:48:14 +00:00
|
|
|
|
"Prefix key to use for Outline commands in Outline minor mode.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
The value of this variable is checked as part of loading Outline mode.
|
|
|
|
|
After that, changing the prefix key requires manipulating keymaps."
|
2020-08-08 11:56:05 +00:00
|
|
|
|
:type 'key-sequence
|
2020-08-08 15:35:34 +00:00
|
|
|
|
:initialize 'custom-initialize-default
|
2020-08-08 11:52:46 +00:00
|
|
|
|
:set (lambda (sym val)
|
|
|
|
|
(define-key outline-minor-mode-map outline-minor-mode-prefix nil)
|
|
|
|
|
(define-key outline-minor-mode-map val outline-mode-prefix-map)
|
|
|
|
|
(set-default sym val)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2021-03-07 18:52:39 +00:00
|
|
|
|
(defcustom outline-minor-mode-cycle nil
|
2022-04-16 07:56:01 +00:00
|
|
|
|
"Enable visibility-cycling commands on headings in `outline-minor-mode'.
|
2022-07-03 15:35:53 +00:00
|
|
|
|
If enabled, typing \\`TAB' on a heading line cycles the visibility
|
2022-04-16 07:56:01 +00:00
|
|
|
|
state of that heading's body between `hide all', `headings only'
|
2022-07-03 15:35:53 +00:00
|
|
|
|
and `show all' (`outline-cycle'), and typing \\`S-TAB' on a heading
|
2022-04-16 07:56:01 +00:00
|
|
|
|
line likewise cycles the visibility state of the whole buffer
|
|
|
|
|
\(`outline-cycle-buffer').
|
|
|
|
|
Typing these keys anywhere outside heading lines invokes their default
|
|
|
|
|
bindings, per the current major mode."
|
2021-03-07 18:52:39 +00:00
|
|
|
|
:type 'boolean
|
2021-12-15 17:17:48 +00:00
|
|
|
|
:safe #'booleanp
|
2021-03-07 18:52:39 +00:00
|
|
|
|
:version "28.1")
|
2021-03-03 19:12:13 +00:00
|
|
|
|
|
2021-03-07 18:52:39 +00:00
|
|
|
|
(defcustom outline-minor-mode-highlight nil
|
2022-04-16 07:56:01 +00:00
|
|
|
|
"Whether to highlight headings in `outline-minor-mode' using font-lock keywords.
|
|
|
|
|
This option controles whether `outline-minor-mode' will use its font-lock
|
|
|
|
|
keywords to highlight headings, which could potentially conflict with
|
|
|
|
|
font-lock faces defined by the major mode. Thus, a non-nil value will
|
|
|
|
|
work well only when there's no such conflict.
|
|
|
|
|
If the value is t, use outline faces only if there are no major mode's
|
|
|
|
|
font-lock faces on headings. When `override', completely overwrite major
|
|
|
|
|
mode's font-lock faces with outline faces. When `append', try to append
|
|
|
|
|
outline font-lock faces to those of major mode."
|
|
|
|
|
:type '(choice (const :tag "Do not use outline font-lock highlighting" nil)
|
|
|
|
|
(const :tag "Overwrite major mode font-lock faces" override)
|
|
|
|
|
(const :tag "Append outline font-lock faces to major mode's"
|
|
|
|
|
append)
|
|
|
|
|
(const :tag "Highlight with outline font-lock faces only if major mode doesn't" t))
|
2021-12-15 17:17:48 +00:00
|
|
|
|
:safe #'symbolp
|
2021-03-07 18:52:39 +00:00
|
|
|
|
:version "28.1")
|
2021-03-03 19:12:13 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-minor-mode-highlight-buffer ()
|
|
|
|
|
;; Fallback to overlays when font-lock is unsupported.
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(let ((regexp (concat "^\\(?:" outline-regexp "\\).*$")))
|
|
|
|
|
(while (re-search-forward regexp nil t)
|
|
|
|
|
(let ((overlay (make-overlay (match-beginning 0)
|
|
|
|
|
(match-end 0))))
|
|
|
|
|
(overlay-put overlay 'outline-overlay t)
|
2021-03-07 18:52:39 +00:00
|
|
|
|
(when (or (eq outline-minor-mode-highlight 'override)
|
|
|
|
|
(and (eq outline-minor-mode-highlight t)
|
2021-03-13 21:33:14 +00:00
|
|
|
|
(goto-char (match-beginning 0))
|
2021-03-07 18:52:39 +00:00
|
|
|
|
(not (get-text-property (point) 'face))))
|
2021-03-03 19:12:13 +00:00
|
|
|
|
(overlay-put overlay 'face (outline-font-lock-face)))
|
2022-07-29 11:20:06 +00:00
|
|
|
|
(when (outline--use-buttons-p)
|
2022-01-10 18:20:09 +00:00
|
|
|
|
(outline--insert-open-button)))
|
2021-03-03 19:12:13 +00:00
|
|
|
|
(goto-char (match-end 0))))))
|
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;;;###autoload
|
|
|
|
|
(define-minor-mode outline-minor-mode
|
|
|
|
|
"Toggle Outline minor mode.
|
Fix minor mode docstrings for the new meaning of a nil ARG.
* abbrev.el (abbrev-mode):
* allout.el (allout-mode):
* autoinsert.el (auto-insert-mode):
* autoarg.el (autoarg-mode, autoarg-kp-mode):
* autorevert.el (auto-revert-mode, auto-revert-tail-mode)
(global-auto-revert-mode):
* battery.el (display-battery-mode):
* composite.el (global-auto-composition-mode)
(auto-composition-mode):
* delsel.el (delete-selection-mode):
* desktop.el (desktop-save-mode):
* dired-x.el (dired-omit-mode):
* dirtrack.el (dirtrack-mode):
* doc-view.el (doc-view-minor-mode):
* double.el (double-mode):
* electric.el (electric-indent-mode, electric-pair-mode):
* emacs-lock.el (emacs-lock-mode):
* epa-hook.el (auto-encryption-mode):
* follow.el (follow-mode):
* font-core.el (font-lock-mode):
* frame.el (auto-raise-mode, auto-lower-mode, blink-cursor-mode):
* help.el (temp-buffer-resize-mode):
* hilit-chg.el (highlight-changes-mode)
(highlight-changes-visible-mode):
* hi-lock.el (hi-lock-mode):
* hl-line.el (hl-line-mode, global-hl-line-mode):
* icomplete.el (icomplete-mode):
* ido.el (ido-everywhere):
* image-file.el (auto-image-file-mode):
* image-mode.el (image-minor-mode):
* iswitchb.el (iswitchb-mode):
* jka-cmpr-hook.el (auto-compression-mode):
* linum.el (linum-mode):
* longlines.el (longlines-mode):
* master.el (master-mode):
* mb-depth.el (minibuffer-depth-indicate-mode):
* menu-bar.el (menu-bar-mode):
* minibuf-eldef.el (minibuffer-electric-default-mode):
* mouse-sel.el (mouse-sel-mode):
* msb.el (msb-mode):
* mwheel.el (mouse-wheel-mode):
* outline.el (outline-minor-mode):
* paren.el (show-paren-mode):
* recentf.el (recentf-mode):
* reveal.el (reveal-mode, global-reveal-mode):
* rfn-eshadow.el (file-name-shadow-mode):
* ruler-mode.el (ruler-mode):
* savehist.el (savehist-mode):
* scroll-all.el (scroll-all-mode):
* scroll-bar.el (scroll-bar-mode):
* server.el (server-mode):
* shell.el (shell-dirtrack-mode):
* simple.el (auto-fill-mode, transient-mark-mode)
(visual-line-mode, overwrite-mode, binary-overwrite-mode)
(line-number-mode, column-number-mode, size-indication-mode)
(auto-save-mode, normal-erase-is-backspace-mode, visible-mode):
* strokes.el (strokes-mode):
* time.el (display-time-mode):
* t-mouse.el (gpm-mouse-mode):
* tool-bar.el (tool-bar-mode):
* tooltip.el (tooltip-mode):
* type-break.el (type-break-mode-line-message-mode)
(type-break-query-mode):
* view.el (view-mode):
* whitespace.el (whitespace-mode, whitespace-newline-mode)
(global-whitespace-mode, global-whitespace-newline-mode):
* xt-mouse.el (xterm-mouse-mode): Doc fix.
* emacs-lisp/easy-mmode.el (define-globalized-minor-mode): Fix
autogenerated docstring.
2011-10-19 12:54:24 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
See the command `outline-mode' for more information on this mode."
|
2021-04-12 03:47:14 +00:00
|
|
|
|
:lighter " Outl"
|
2022-01-10 18:20:09 +00:00
|
|
|
|
:keymap (easy-mmode-define-keymap
|
|
|
|
|
`(([menu-bar] . ,outline-minor-mode-menu-bar-map)
|
|
|
|
|
(,outline-minor-mode-prefix . ,outline-mode-prefix-map))
|
|
|
|
|
:inherit outline-minor-mode-cycle-map)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(if outline-minor-mode
|
|
|
|
|
(progn
|
2022-01-10 18:20:09 +00:00
|
|
|
|
(when outline-minor-mode-highlight
|
2021-03-03 19:12:13 +00:00
|
|
|
|
(if (and global-font-lock-mode (font-lock-specified-p major-mode))
|
|
|
|
|
(progn
|
|
|
|
|
(font-lock-add-keywords nil outline-font-lock-keywords t)
|
|
|
|
|
(font-lock-flush))
|
|
|
|
|
(outline-minor-mode-highlight-buffer)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Turn off this mode if we change major modes.
|
|
|
|
|
(add-hook 'change-major-mode-hook
|
|
|
|
|
(lambda () (outline-minor-mode -1))
|
|
|
|
|
nil t)
|
2020-12-09 08:44:38 +00:00
|
|
|
|
(setq-local line-move-ignore-invisible t)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Cause use of ellipses for invisible text.
|
2022-01-16 18:13:21 +00:00
|
|
|
|
(add-to-invisibility-spec '(outline . t))
|
|
|
|
|
(outline-apply-default-state))
|
2022-01-10 18:20:09 +00:00
|
|
|
|
(when outline-minor-mode-highlight
|
2021-03-03 19:12:13 +00:00
|
|
|
|
(if font-lock-fontified
|
|
|
|
|
(font-lock-remove-keywords nil outline-font-lock-keywords))
|
|
|
|
|
(remove-overlays nil nil 'outline-overlay t)
|
|
|
|
|
(font-lock-flush))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(setq line-move-ignore-invisible nil)
|
|
|
|
|
;; Cause use of ellipses for invisible text.
|
|
|
|
|
(remove-from-invisibility-spec '(outline . t))
|
|
|
|
|
;; When turning off outline mode, get rid of any outline hiding.
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(outline-show-all)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2022-07-29 11:21:45 +00:00
|
|
|
|
(defun outline--use-buttons-p ()
|
|
|
|
|
(and outline-minor-mode
|
|
|
|
|
outline-minor-mode-use-buttons
|
|
|
|
|
(or (eq outline-minor-mode-use-buttons t)
|
|
|
|
|
(buffer-match-p outline-minor-mode-use-buttons
|
|
|
|
|
(current-buffer)))))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(defvar-local outline-heading-alist ()
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Alist associating a heading for every possible level.
|
|
|
|
|
Each entry is of the form (HEADING . LEVEL).
|
|
|
|
|
This alist is used two ways: to find the heading corresponding to
|
|
|
|
|
a given level and to find the level of a given heading.
|
|
|
|
|
If a mode or document needs several sets of outline headings (for example
|
|
|
|
|
numbered and unnumbered sections), list them set by set and sorted by level
|
|
|
|
|
within each set. For example in texinfo mode:
|
|
|
|
|
|
|
|
|
|
(setq outline-heading-alist
|
2015-09-02 01:21:42 +00:00
|
|
|
|
\\='((\"@chapter\" . 2) (\"@section\" . 3) (\"@subsection\" . 4)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(\"@subsubsection\" . 5)
|
|
|
|
|
(\"@unnumbered\" . 2) (\"@unnumberedsec\" . 3)
|
|
|
|
|
(\"@unnumberedsubsec\" . 4) (\"@unnumberedsubsubsec\" . 5)
|
|
|
|
|
(\"@appendix\" . 2) (\"@appendixsec\" . 3)...
|
|
|
|
|
(\"@appendixsubsec\" . 4) (\"@appendixsubsubsec\" . 5) ..))
|
|
|
|
|
|
|
|
|
|
Instead of sorting the entries in each set, you can also separate the
|
|
|
|
|
sets with nil.")
|
|
|
|
|
|
|
|
|
|
;; This used to count columns rather than characters, but that made ^L
|
|
|
|
|
;; appear to be at level 2 instead of 1. Columns would be better for
|
|
|
|
|
;; tab handling, but the default regexp doesn't use tabs, and anyone
|
|
|
|
|
;; who changes the regexp can also redefine the outline-level variable
|
|
|
|
|
;; as appropriate.
|
|
|
|
|
(defun outline-level ()
|
|
|
|
|
"Return the depth to which a statement is nested in the outline.
|
|
|
|
|
Point must be at the beginning of a header line.
|
|
|
|
|
This is actually either the level specified in `outline-heading-alist'
|
|
|
|
|
or else the number of characters matched by `outline-regexp'."
|
|
|
|
|
(or (cdr (assoc (match-string 0) outline-heading-alist))
|
|
|
|
|
(- (match-end 0) (match-beginning 0))))
|
|
|
|
|
|
|
|
|
|
(defun outline-next-preface ()
|
|
|
|
|
"Skip forward to just before the next heading line.
|
|
|
|
|
If there's no following heading line, stop before the newline
|
|
|
|
|
at the end of the buffer."
|
|
|
|
|
(if (re-search-forward (concat "\n\\(?:" outline-regexp "\\)")
|
|
|
|
|
nil 'move)
|
|
|
|
|
(goto-char (match-beginning 0)))
|
2004-05-01 03:44:30 +00:00
|
|
|
|
(if (and (bolp) (or outline-blank-line (eobp)) (not (bobp)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(forward-char -1)))
|
|
|
|
|
|
|
|
|
|
(defun outline-next-heading ()
|
|
|
|
|
"Move to the next (possibly invisible) heading line."
|
|
|
|
|
(interactive)
|
|
|
|
|
;; Make sure we don't match the heading we're at.
|
|
|
|
|
(if (and (bolp) (not (eobp))) (forward-char 1))
|
|
|
|
|
(if (re-search-forward (concat "^\\(?:" outline-regexp "\\)")
|
|
|
|
|
nil 'move)
|
|
|
|
|
(goto-char (match-beginning 0))))
|
|
|
|
|
|
|
|
|
|
(defun outline-previous-heading ()
|
|
|
|
|
"Move to the previous (possibly invisible) heading line."
|
|
|
|
|
(interactive)
|
|
|
|
|
(re-search-backward (concat "^\\(?:" outline-regexp "\\)")
|
|
|
|
|
nil 'move))
|
|
|
|
|
|
|
|
|
|
(defsubst outline-invisible-p (&optional pos)
|
2016-09-30 08:06:02 +00:00
|
|
|
|
"Non-nil if the character after POS has outline invisible property.
|
2015-01-28 10:55:47 +00:00
|
|
|
|
If POS is nil, use `point' instead."
|
2016-09-30 08:06:02 +00:00
|
|
|
|
(eq (get-char-property (or pos (point)) 'invisible) 'outline))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2020-10-19 08:45:14 +00:00
|
|
|
|
(define-error 'outline-before-first-heading "Before first heading")
|
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(defun outline-back-to-heading (&optional invisible-ok)
|
|
|
|
|
"Move to previous heading line, or beg of this line if it's a heading.
|
|
|
|
|
Only visible heading lines are considered, unless INVISIBLE-OK is non-nil."
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(or (outline-on-heading-p invisible-ok)
|
|
|
|
|
(let (found)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(while (not found)
|
|
|
|
|
(or (re-search-backward (concat "^\\(?:" outline-regexp "\\)")
|
|
|
|
|
nil t)
|
2020-10-19 08:45:14 +00:00
|
|
|
|
(signal 'outline-before-first-heading nil))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(setq found (and (or invisible-ok (not (outline-invisible-p)))
|
|
|
|
|
(point)))))
|
|
|
|
|
(goto-char found)
|
|
|
|
|
found)))
|
|
|
|
|
|
|
|
|
|
(defun outline-on-heading-p (&optional invisible-ok)
|
|
|
|
|
"Return t if point is on a (visible) heading line.
|
|
|
|
|
If INVISIBLE-OK is non-nil, an invisible heading line is ok too."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(and (bolp) (or invisible-ok (not (outline-invisible-p)))
|
|
|
|
|
(looking-at outline-regexp))))
|
|
|
|
|
|
|
|
|
|
(defun outline-insert-heading ()
|
|
|
|
|
"Insert a new heading at same depth at point."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((head (save-excursion
|
|
|
|
|
(condition-case nil
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(error (outline-next-heading)))
|
|
|
|
|
(if (eobp)
|
|
|
|
|
(or (caar outline-heading-alist) "")
|
|
|
|
|
(match-string 0)))))
|
|
|
|
|
(unless (or (string-match "[ \t]\\'" head)
|
2004-01-21 03:26:30 +00:00
|
|
|
|
(not (string-match (concat "\\`\\(?:" outline-regexp "\\)")
|
|
|
|
|
(concat head " "))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(setq head (concat head " ")))
|
|
|
|
|
(unless (bolp) (end-of-line) (newline))
|
|
|
|
|
(insert head)
|
|
|
|
|
(unless (eolp)
|
|
|
|
|
(save-excursion (newline-and-indent)))
|
|
|
|
|
(run-hooks 'outline-insert-heading-hook)))
|
|
|
|
|
|
2005-08-26 15:31:59 +00:00
|
|
|
|
(defun outline-invent-heading (head up)
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Create a heading by using heading HEAD as a template.
|
|
|
|
|
When UP is non-nil, the created heading will be one level above.
|
|
|
|
|
Otherwise, it will be one level below."
|
2005-08-26 15:31:59 +00:00
|
|
|
|
(save-match-data
|
|
|
|
|
;; Let's try to invent one by repeating or deleting the last char.
|
|
|
|
|
(let ((new-head (if up (substring head 0 -1)
|
|
|
|
|
(concat head (substring head -1)))))
|
|
|
|
|
(if (string-match (concat "\\`\\(?:" outline-regexp "\\)")
|
|
|
|
|
new-head)
|
|
|
|
|
;; Why bother checking that it is indeed higher/lower level ?
|
|
|
|
|
new-head
|
|
|
|
|
;; Didn't work, so ask what to do.
|
Top-level elisp files respect ‘text-quoting-style’
In top-level elisp files, use format-message in diagnostic formats,
so that they follow user preference as per ‘text-quoting-style’
rather than being hard-coded to quote `like this'.
* lisp/allout.el (allout-get-configvar-values):
* lisp/apropos.el (apropos-symbols-internal):
* lisp/dired-aux.el (dired-do-shell-command, dired-create-files)
(dired-do-create-files-regexp, dired-create-files-non-directory):
* lisp/dired-x.el (dired-do-run-mail):
* lisp/dired.el (dired-log, dired-dnd-handle-local-file):
* lisp/disp-table.el (standard-display-european):
* lisp/find-dired.el (find-dired):
* lisp/forms.el (forms-mode):
* lisp/ido.el (ido-buffer-internal):
* lisp/info.el (Info-index-next):
* lisp/outline.el (outline-invent-heading):
* lisp/printing.el (pr-ps-outfile-preprint, pr-i-ps-send):
* lisp/proced.el (proced-log):
* lisp/ps-print.el (ps-print-preprint, ps-get-size):
* lisp/recentf.el (recentf-open-files, recentf-save-list):
* lisp/savehist.el (savehist-save):
* lisp/server.el (server-ensure-safe-dir):
* lisp/ses.el (ses-rename-cell):
* lisp/simple.el (list-processes--refresh):
* lisp/startup.el (command-line):
* lisp/strokes.el (strokes-unset-last-stroke)
(strokes-execute-stroke):
Use format-message so that quotes are restyled.
* lisp/cus-edit.el (custom-raised-buttons, customize-browse):
Don’t quote ‘raised’.
* lisp/descr-text.el (describe-char):
* lisp/dirtrack.el (dirtrack-debug-message):
* lisp/hexl.el (hexl-insert-multibyte-char):
Apply substitute-command-keys to help string.
* lisp/wdired.el (wdired-do-renames, wdired-do-symlink-changes)
(wdired-do-perm-changes):
Let dired-log do the formatting.
2015-08-26 08:30:29 +00:00
|
|
|
|
(read-string (format-message "%s heading for `%s': "
|
|
|
|
|
(if up "Parent" "Demoted") head)
|
2005-08-26 15:31:59 +00:00
|
|
|
|
head nil nil t)))))
|
|
|
|
|
|
2007-01-27 18:47:55 +00:00
|
|
|
|
(defun outline-promote (&optional which)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Promote headings higher up the tree.
|
2015-01-28 10:55:47 +00:00
|
|
|
|
If `transient-mark-mode' is on, and mark is active, promote headings in
|
2007-01-27 18:47:55 +00:00
|
|
|
|
the region (from a Lisp program, pass `region' for WHICH). Otherwise:
|
|
|
|
|
without prefix argument, promote current heading and all headings in the
|
|
|
|
|
subtree (from a Lisp program, pass `subtree' for WHICH); with prefix
|
|
|
|
|
argument, promote just the current heading (from a Lisp program, pass
|
|
|
|
|
nil for WHICH, or do not pass any argument)."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(list (if (and transient-mark-mode mark-active) 'region
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(if current-prefix-arg nil 'subtree))))
|
|
|
|
|
(cond
|
2007-01-27 18:47:55 +00:00
|
|
|
|
((eq which 'region)
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(outline-map-region #'outline-promote (region-beginning) (region-end)))
|
2007-01-27 18:47:55 +00:00
|
|
|
|
(which
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(outline-map-region #'outline-promote
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(point)
|
|
|
|
|
(save-excursion (outline-get-next-sibling) (point))))
|
|
|
|
|
(t
|
|
|
|
|
(outline-back-to-heading t)
|
2005-08-26 11:52:08 +00:00
|
|
|
|
(let* ((head (match-string-no-properties 0))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(level (save-match-data (funcall outline-level)))
|
|
|
|
|
(up-head (or (outline-head-from-level (1- level) head)
|
2005-08-26 11:52:08 +00:00
|
|
|
|
;; Use the parent heading, if it is really
|
|
|
|
|
;; one level less.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(save-match-data
|
|
|
|
|
(outline-up-heading 1 t)
|
2005-08-26 11:52:08 +00:00
|
|
|
|
(and (= (1- level) (funcall outline-level))
|
|
|
|
|
(match-string-no-properties 0))))
|
2005-08-26 15:31:59 +00:00
|
|
|
|
;; Bummer!! There is no lower level heading.
|
|
|
|
|
(outline-invent-heading head 'up))))
|
2003-07-28 21:50:05 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(unless (rassoc level outline-heading-alist)
|
|
|
|
|
(push (cons head level) outline-heading-alist))
|
2003-07-28 21:50:05 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(replace-match up-head nil t)))))
|
|
|
|
|
|
2007-01-27 18:47:55 +00:00
|
|
|
|
(defun outline-demote (&optional which)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Demote headings lower down the tree.
|
2015-01-28 10:55:47 +00:00
|
|
|
|
If `transient-mark-mode' is on, and mark is active, demote headings in
|
2007-01-27 18:47:55 +00:00
|
|
|
|
the region (from a Lisp program, pass `region' for WHICH). Otherwise:
|
|
|
|
|
without prefix argument, demote current heading and all headings in the
|
|
|
|
|
subtree (from a Lisp program, pass `subtree' for WHICH); with prefix
|
|
|
|
|
argument, demote just the current heading (from a Lisp program, pass
|
|
|
|
|
nil for WHICH, or do not pass any argument)."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(interactive
|
|
|
|
|
(list (if (and transient-mark-mode mark-active) 'region
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(if current-prefix-arg nil 'subtree))))
|
|
|
|
|
(cond
|
2007-01-27 18:47:55 +00:00
|
|
|
|
((eq which 'region)
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(outline-map-region #'outline-demote (region-beginning) (region-end)))
|
2007-01-27 18:47:55 +00:00
|
|
|
|
(which
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(outline-map-region #'outline-demote
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(point)
|
|
|
|
|
(save-excursion (outline-get-next-sibling) (point))))
|
|
|
|
|
(t
|
2005-08-26 11:52:08 +00:00
|
|
|
|
(let* ((head (match-string-no-properties 0))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(level (save-match-data (funcall outline-level)))
|
|
|
|
|
(down-head
|
|
|
|
|
(or (outline-head-from-level (1+ level) head)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-match-data
|
|
|
|
|
(while (and (progn (outline-next-heading) (not (eobp)))
|
|
|
|
|
(<= (funcall outline-level) level)))
|
|
|
|
|
(when (eobp)
|
|
|
|
|
;; Try again from the beginning of the buffer.
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(while (and (progn (outline-next-heading) (not (eobp)))
|
|
|
|
|
(<= (funcall outline-level) level))))
|
|
|
|
|
(unless (eobp)
|
|
|
|
|
(looking-at outline-regexp)
|
2005-08-26 11:52:08 +00:00
|
|
|
|
(match-string-no-properties 0))))
|
2005-08-26 15:31:59 +00:00
|
|
|
|
;; Bummer!! There is no higher-level heading in the buffer.
|
|
|
|
|
(outline-invent-heading head nil))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2005-08-26 11:52:08 +00:00
|
|
|
|
(unless (rassoc level outline-heading-alist)
|
|
|
|
|
(push (cons head level) outline-heading-alist))
|
|
|
|
|
(replace-match down-head nil t)))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-head-from-level (level head &optional alist)
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Get new heading with level LEVEL, closest to HEAD, from ALIST.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
If there are no such entries, return nil.
|
|
|
|
|
ALIST defaults to `outline-heading-alist'.
|
|
|
|
|
Similar to (car (rassoc LEVEL ALIST)).
|
lisp/*.el: Fix typos and other trivial doc fixes
* lisp/allout-widgets.el (allout-widgets-auto-activation)
(allout-current-decorated-p):
* lisp/auth-source.el (auth-source-protocols):
* lisp/autorevert.el (auto-revert-set-timer):
* lisp/battery.el (battery-mode-line-limit):
* lisp/calc/calcalg3.el (math-map-binop):
* lisp/calendar/cal-dst.el (calendar-dst-find-startend):
* lisp/calendar/cal-mayan.el (calendar-mayan-long-count-to-absolute):
* lisp/calendar/calendar.el (calendar-date-echo-text)
(calendar-generate-month, calendar-string-spread)
(calendar-cursor-to-date, calendar-read, calendar-read-date)
(calendar-mark-visible-date, calendar-dayname-on-or-before):
* lisp/calendar/diary-lib.el (diary-ordinal-suffix):
* lisp/cedet/ede/autoconf-edit.el (autoconf-new-program)
(autoconf-find-last-macro, autoconf-parameter-strip):
* lisp/cedet/ede/config.el (ede-target-with-config-build):
* lisp/cedet/ede/linux.el (ede-linux--detect-architecture)
(ede-linux--get-architecture):
* lisp/cedet/semantic/complete.el (semantic-collector-calculate-cache)
(semantic-displayer-abstract, semantic-displayer-point-position):
* lisp/cedet/semantic/format.el (semantic-format-face-alist)
(semantic-format-tag-short-doc):
* lisp/cedet/semantic/fw.el (semantic-find-file-noselect):
* lisp/cedet/semantic/idle.el (semantic-idle-scheduler-work-idle-time)
(semantic-idle-breadcrumbs-display-function)
(semantic-idle-breadcrumbs-format-tag-list-function):
* lisp/cedet/semantic/lex.el (semantic-lex-map-types)
(define-lex, define-lex-block-type-analyzer):
* lisp/cedet/semantic/senator.el (senator-search-default-tag-filter):
* lisp/cedet/semantic/symref.el (semantic-symref-result)
(semantic-symref-hit-to-tag-via-db):
* lisp/cedet/semantic/symref.el (semantic-symref-tool-baseclass):
* lisp/cedet/semantic/tag.el (semantic-tag-new-variable)
(semantic-tag-new-include, semantic-tag-new-package)
(semantic-tag-set-faux, semantic-create-tag-proxy)
(semantic-tag-function-parent)
(semantic-tag-components-with-overlays):
* lisp/cedet/srecode/cpp.el (srecode-cpp-namespaces)
(srecode-semantic-handle-:c, srecode-semantic-apply-tag-to-dict):
* lisp/cedet/srecode/dictionary.el (srecode-create-dictionary)
(srecode-dictionary-add-entries, srecode-dictionary-lookup-name)
(srecode-create-dictionaries-from-tags):
* lisp/cmuscheme.el (scheme-compile-region):
* lisp/color.el (color-lab-to-lch):
* lisp/doc-view.el (doc-view-image-width)
(doc-view-set-up-single-converter):
* lisp/dynamic-setting.el (font-setting-change-default-font)
(dynamic-setting-handle-config-changed-event):
* lisp/elec-pair.el (electric-pair-text-pairs)
(electric-pair-skip-whitespace-function)
(electric-pair-string-bound-function):
* lisp/emacs-lisp/avl-tree.el (avl-tree--del-balance)
(avl-tree-member, avl-tree-mapcar, avl-tree-iter):
* lisp/emacs-lisp/bytecomp.el (byte-compile-generate-call-tree):
* lisp/emacs-lisp/checkdoc.el (checkdoc-autofix-flag)
(checkdoc-spellcheck-documentation-flag, checkdoc-ispell)
(checkdoc-ispell-current-buffer, checkdoc-ispell-interactive)
(checkdoc-ispell-message-interactive)
(checkdoc-ispell-message-text, checkdoc-ispell-start)
(checkdoc-ispell-continue, checkdoc-ispell-comments)
(checkdoc-ispell-defun):
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method):
* lisp/emacs-lisp/eieio-custom.el (eieio-read-customization-group):
* lisp/emacs-lisp/lisp.el (forward-sexp, up-list):
* lisp/emacs-lisp/package-x.el (package--archive-contents-from-file):
* lisp/emacs-lisp/package.el (package-desc)
(package--make-autoloads-and-stuff, package-hidden-regexps):
* lisp/emacs-lisp/tcover-ses.el (ses-exercise-startup):
* lisp/emacs-lisp/testcover.el (testcover-nohits)
(testcover-1value):
* lisp/epg.el (epg-receive-keys, epg-start-edit-key):
* lisp/erc/erc-backend.el (erc-server-processing-p)
(erc-split-line-length, erc-server-coding-system)
(erc-server-send, erc-message):
* lisp/erc/erc-button.el (erc-button-face, erc-button-alist)
(erc-browse-emacswiki):
* lisp/erc/erc-ezbounce.el (erc-ezbounce, erc-ezb-get-login):
* lisp/erc/erc-fill.el (erc-fill-variable-maximum-indentation):
* lisp/erc/erc-log.el (erc-current-logfile):
* lisp/erc/erc-match.el (erc-log-match-format)
(erc-text-matched-hook):
* lisp/erc/erc-netsplit.el (erc-netsplit, erc-netsplit-debug):
* lisp/erc/erc-networks.el (erc-server-alist)
(erc-networks-alist, erc-current-network):
* lisp/erc/erc-ring.el (erc-input-ring-index):
* lisp/erc/erc-speedbar.el (erc-speedbar)
(erc-speedbar-update-channel):
* lisp/erc/erc-stamp.el (erc-timestamp-only-if-changed-flag):
* lisp/erc/erc-track.el (erc-track-position-in-mode-line)
(erc-track-remove-from-mode-line, erc-modified-channels-update)
(erc-track-last-non-erc-buffer, erc-track-sort-by-importance)
(erc-track-get-active-buffer):
* lisp/erc/erc.el (erc-get-channel-user-list)
(erc-echo-notice-hook, erc-echo-notice-always-hook)
(erc-wash-quit-reason, erc-format-@nick):
* lisp/ffap.el (ffap-latex-mode):
* lisp/files.el (abort-if-file-too-large)
(dir-locals--get-sort-score, buffer-stale--default-function):
* lisp/filesets.el (filesets-tree-max-level, filesets-data)
(filesets-update-pre010505):
* lisp/gnus/gnus-agent.el (gnus-agent-flush-cache):
* lisp/gnus/gnus-art.el (gnus-article-encrypt-protocol)
(gnus-button-prefer-mid-or-mail):
* lisp/gnus/gnus-cus.el (gnus-group-parameters):
* lisp/gnus/gnus-demon.el (gnus-demon-handlers)
(gnus-demon-run-callback):
* lisp/gnus/gnus-dired.el (gnus-dired-print):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-buffer):
* lisp/gnus/gnus-range.el (gnus-range-normalize):
* lisp/gnus/gnus-spec.el (gnus-pad-form):
* lisp/gnus/gnus-srvr.el (gnus-server-agent, gnus-server-cloud)
(gnus-server-opened, gnus-server-closed, gnus-server-denied)
(gnus-server-offline):
* lisp/gnus/gnus-sum.el (gnus-refer-thread-use-nnir)
(gnus-refer-thread-limit-to-thread)
(gnus-summary-limit-include-thread, gnus-summary-refer-thread)
(gnus-summary-find-matching):
* lisp/gnus/gnus-util.el (gnus-rescale-image):
* lisp/gnus/gnus.el (gnus-summary-line-format, gnus-no-server):
* lisp/gnus/mail-source.el (mail-source-incoming-file-prefix):
* lisp/gnus/message.el (message-cite-reply-position)
(message-cite-style-outlook, message-cite-style-thunderbird)
(message-cite-style-gmail, message--send-mail-maybe-partially):
* lisp/gnus/mm-extern.el (mm-inline-external-body):
* lisp/gnus/mm-partial.el (mm-inline-partial):
* lisp/gnus/mml-sec.el (mml-secure-message-sign)
(mml-secure-message-sign-encrypt, mml-secure-message-encrypt):
* lisp/gnus/mml2015.el (mml2015-epg-key-image)
(mml2015-epg-key-image-to-string):
* lisp/gnus/nndiary.el (nndiary-reminders, nndiary-get-new-mail):
* lisp/gnus/nnheader.el (nnheader-directory-files-is-safe):
* lisp/gnus/nnir.el (nnir-search-history)
(nnir-imap-search-other, nnir-artlist-length)
(nnir-artlist-article, nnir-artitem-group, nnir-artitem-number)
(nnir-artitem-rsv, nnir-article-group, nnir-article-number)
(nnir-article-rsv, nnir-article-ids, nnir-categorize)
(nnir-retrieve-headers-override-function)
(nnir-imap-default-search-key, nnir-hyrex-additional-switches)
(gnus-group-make-nnir-group, nnir-run-namazu, nnir-read-parms)
(nnir-read-parm, nnir-read-server-parm, nnir-search-thread):
* lisp/gnus/nnmairix.el (nnmairix-default-group)
(nnmairix-propagate-marks):
* lisp/gnus/smime.el (smime-keys, smime-crl-check)
(smime-verify-buffer, smime-noverify-buffer):
* lisp/gnus/spam-report.el (spam-report-url-ping-mm-url):
* lisp/gnus/spam.el (spam-spamassassin-positive-spam-flag-header)
(spam-spamassassin-spam-status-header, spam-sa-learn-rebuild)
(spam-classifications, spam-check-stat, spam-spamassassin-score):
* lisp/help.el (describe-minor-mode-from-symbol):
* lisp/hippie-exp.el (hippie-expand-ignore-buffers):
* lisp/htmlfontify.el (hfy-optimizations, hfy-face-resolve-face)
(hfy-begin-span):
* lisp/ibuf-ext.el (ibuffer-update-saved-filters-format)
(ibuffer-saved-filters, ibuffer-old-saved-filters-warning)
(ibuffer-filtering-qualifiers, ibuffer-repair-saved-filters)
(eval, ibuffer-unary-operand, file-extension, directory):
* lisp/image-dired.el (image-dired-cmd-pngcrush-options):
* lisp/image-mode.el (image-toggle-display):
* lisp/international/ccl.el (ccl-compile-read-multibyte-character)
(ccl-compile-write-multibyte-character):
* lisp/international/kkc.el (kkc-save-init-file):
* lisp/international/latin1-disp.el (latin1-display):
* lisp/international/ogonek.el (ogonek-name-encoding-alist)
(ogonek-information, ogonek-lookup-encoding)
(ogonek-deprefixify-region):
* lisp/isearch.el (isearch-filter-predicate)
(isearch--momentary-message):
* lisp/jsonrpc.el (jsonrpc-connection-send)
(jsonrpc-process-connection, jsonrpc-shutdown)
(jsonrpc--async-request-1):
* lisp/language/tibet-util.el (tibetan-char-p):
* lisp/mail/feedmail.el (feedmail-queue-use-send-time-for-date)
(feedmail-last-chance-hook, feedmail-before-fcc-hook)
(feedmail-send-it-immediately-wrapper, feedmail-find-eoh):
* lisp/mail/hashcash.el (hashcash-generate-payment)
(hashcash-generate-payment-async, hashcash-insert-payment)
(hashcash-verify-payment):
* lisp/mail/rmail.el (rmail-movemail-variant-in-use)
(rmail-get-attr-value):
* lisp/mail/rmailmm.el (rmail-mime-prefer-html, rmail-mime):
* lisp/mail/rmailsum.el (rmail-summary-show-message):
* lisp/mail/supercite.el (sc-raw-mode-toggle):
* lisp/man.el (Man-start-calling):
* lisp/mh-e/mh-acros.el (mh-do-at-event-location)
(mh-iterate-on-messages-in-region, mh-iterate-on-range):
* lisp/mh-e/mh-alias.el (mh-alias-system-aliases)
(mh-alias-reload, mh-alias-ali)
(mh-alias-canonicalize-suggestion, mh-alias-add-alias-to-file)
(mh-alias-add-alias):
* lisp/mouse.el (mouse-save-then-kill):
* lisp/net/browse-url.el (browse-url-default-macosx-browser):
* lisp/net/eudc.el (eudc-set, eudc-variable-protocol-value)
(eudc-variable-server-value, eudc-update-variable)
(eudc-expand-inline):
* lisp/net/eudcb-bbdb.el (eudc-bbdb-format-record-as-result):
* lisp/net/eudcb-ldap.el (eudc-ldap-get-field-list):
* lisp/net/pop3.el (pop3-list):
* lisp/net/soap-client.el (soap-namespace-put)
(soap-xs-parse-sequence, soap-parse-envelope):
* lisp/net/soap-inspect.el (soap-inspect-xs-complex-type):
* lisp/nxml/rng-xsd.el (rng-xsd-date-to-days):
* lisp/org/ob-C.el (org-babel-prep-session:C)
(org-babel-load-session:C):
* lisp/org/ob-J.el (org-babel-execute:J):
* lisp/org/ob-asymptote.el (org-babel-prep-session:asymptote):
* lisp/org/ob-awk.el (org-babel-execute:awk):
* lisp/org/ob-core.el (org-babel-process-file-name):
* lisp/org/ob-ebnf.el (org-babel-execute:ebnf):
* lisp/org/ob-forth.el (org-babel-execute:forth):
* lisp/org/ob-fortran.el (org-babel-execute:fortran)
(org-babel-prep-session:fortran, org-babel-load-session:fortran):
* lisp/org/ob-groovy.el (org-babel-execute:groovy):
* lisp/org/ob-io.el (org-babel-execute:io):
* lisp/org/ob-js.el (org-babel-execute:js):
* lisp/org/ob-lilypond.el (org-babel-default-header-args:lilypond)
(org-babel-lilypond-compile-post-tangle)
(org-babel-lilypond-display-pdf-post-tangle)
(org-babel-lilypond-tangle)
(org-babel-lilypond-execute-tangled-ly)
(org-babel-lilypond-compile-lilyfile)
(org-babel-lilypond-check-for-compile-error)
(org-babel-lilypond-process-compile-error)
(org-babel-lilypond-mark-error-line)
(org-babel-lilypond-parse-error-line)
(org-babel-lilypond-attempt-to-open-pdf)
(org-babel-lilypond-attempt-to-play-midi)
(org-babel-lilypond-switch-extension)
(org-babel-lilypond-set-header-args):
* lisp/org/ob-lua.el (org-babel-prep-session:lua):
* lisp/org/ob-picolisp.el (org-babel-execute:picolisp):
* lisp/org/ob-processing.el (org-babel-prep-session:processing):
* lisp/org/ob-python.el (org-babel-prep-session:python):
* lisp/org/ob-scheme.el (org-babel-scheme-capture-current-message)
(org-babel-scheme-execute-with-geiser, org-babel-execute:scheme):
* lisp/org/ob-shen.el (org-babel-execute:shen):
* lisp/org/org-agenda.el (org-agenda-entry-types)
(org-agenda-move-date-from-past-immediately-to-today)
(org-agenda-time-grid, org-agenda-sorting-strategy)
(org-agenda-filter-by-category, org-agenda-forward-block):
* lisp/org/org-colview.el (org-columns--overlay-text):
* lisp/org/org-faces.el (org-verbatim, org-cycle-level-faces):
* lisp/org/org-indent.el (org-indent-set-line-properties):
* lisp/org/org-macs.el (org-get-limited-outline-regexp):
* lisp/org/org-mobile.el (org-mobile-files):
* lisp/org/org.el (org-use-fast-todo-selection)
(org-extend-today-until, org-use-property-inheritance)
(org-refresh-effort-properties, org-open-at-point-global)
(org-track-ordered-property-with-tag, org-shiftright):
* lisp/org/ox-html.el (org-html-checkbox-type):
* lisp/org/ox-man.el (org-man-source-highlight)
(org-man-verse-block):
* lisp/org/ox-publish.el (org-publish-sitemap-default):
* lisp/outline.el (outline-head-from-level):
* lisp/progmodes/dcl-mode.el (dcl-back-to-indentation-1)
(dcl-calc-command-indent, dcl-indent-to):
* lisp/progmodes/flymake.el (flymake-make-diagnostic)
(flymake--overlays, flymake-diagnostic-functions)
(flymake-diagnostic-types-alist, flymake--backend-state)
(flymake-is-running, flymake--collect, flymake-mode):
* lisp/progmodes/gdb-mi.el (gdb-threads-list, gdb, gdb-non-stop)
(gdb-buffers, gdb-gud-context-call, gdb-jsonify-buffer):
* lisp/progmodes/grep.el (grep-error-screen-columns):
* lisp/progmodes/gud.el (gud-prev-expr):
* lisp/progmodes/ps-mode.el (ps-mode, ps-mode-target-column)
(ps-run-goto-error):
* lisp/progmodes/python.el (python-eldoc-get-doc)
(python-eldoc-function-timeout-permanent, python-eldoc-function):
* lisp/shadowfile.el (shadow-make-group):
* lisp/speedbar.el (speedbar-obj-do-check):
* lisp/textmodes/flyspell.el (flyspell-auto-correct-previous-hook):
* lisp/textmodes/reftex-cite.el (reftex-bib-or-thebib):
* lisp/textmodes/reftex-index.el (reftex-index-goto-entry)
(reftex-index-kill, reftex-index-undo):
* lisp/textmodes/reftex-parse.el (reftex-context-substring):
* lisp/textmodes/reftex.el (reftex-TeX-master-file):
* lisp/textmodes/rst.el (rst-next-hdr, rst-toc)
(rst-uncomment-region, rst-font-lock-extend-region-internal):
* lisp/thumbs.el (thumbs-mode):
* lisp/vc/ediff-util.el (ediff-restore-diff):
* lisp/vc/pcvs-defs.el (cvs-cvsroot, cvs-force-dir-tag):
* lisp/vc/vc-hg.el (vc-hg--ignore-patterns-valid-p):
* lisp/wid-edit.el (widget-field-value-set, string):
* lisp/x-dnd.el (x-dnd-version-from-flags)
(x-dnd-more-than-3-from-flags): Assorted docfixes.
2019-09-20 22:27:53 +00:00
|
|
|
|
If there are several different entries with same new level, choose the
|
|
|
|
|
one with the smallest distance to the association of HEAD in the alist.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
This makes it possible for promotion to work in modes with several
|
lisp/*.el: Fix typos and other trivial doc fixes
* lisp/allout-widgets.el (allout-widgets-auto-activation)
(allout-current-decorated-p):
* lisp/auth-source.el (auth-source-protocols):
* lisp/autorevert.el (auto-revert-set-timer):
* lisp/battery.el (battery-mode-line-limit):
* lisp/calc/calcalg3.el (math-map-binop):
* lisp/calendar/cal-dst.el (calendar-dst-find-startend):
* lisp/calendar/cal-mayan.el (calendar-mayan-long-count-to-absolute):
* lisp/calendar/calendar.el (calendar-date-echo-text)
(calendar-generate-month, calendar-string-spread)
(calendar-cursor-to-date, calendar-read, calendar-read-date)
(calendar-mark-visible-date, calendar-dayname-on-or-before):
* lisp/calendar/diary-lib.el (diary-ordinal-suffix):
* lisp/cedet/ede/autoconf-edit.el (autoconf-new-program)
(autoconf-find-last-macro, autoconf-parameter-strip):
* lisp/cedet/ede/config.el (ede-target-with-config-build):
* lisp/cedet/ede/linux.el (ede-linux--detect-architecture)
(ede-linux--get-architecture):
* lisp/cedet/semantic/complete.el (semantic-collector-calculate-cache)
(semantic-displayer-abstract, semantic-displayer-point-position):
* lisp/cedet/semantic/format.el (semantic-format-face-alist)
(semantic-format-tag-short-doc):
* lisp/cedet/semantic/fw.el (semantic-find-file-noselect):
* lisp/cedet/semantic/idle.el (semantic-idle-scheduler-work-idle-time)
(semantic-idle-breadcrumbs-display-function)
(semantic-idle-breadcrumbs-format-tag-list-function):
* lisp/cedet/semantic/lex.el (semantic-lex-map-types)
(define-lex, define-lex-block-type-analyzer):
* lisp/cedet/semantic/senator.el (senator-search-default-tag-filter):
* lisp/cedet/semantic/symref.el (semantic-symref-result)
(semantic-symref-hit-to-tag-via-db):
* lisp/cedet/semantic/symref.el (semantic-symref-tool-baseclass):
* lisp/cedet/semantic/tag.el (semantic-tag-new-variable)
(semantic-tag-new-include, semantic-tag-new-package)
(semantic-tag-set-faux, semantic-create-tag-proxy)
(semantic-tag-function-parent)
(semantic-tag-components-with-overlays):
* lisp/cedet/srecode/cpp.el (srecode-cpp-namespaces)
(srecode-semantic-handle-:c, srecode-semantic-apply-tag-to-dict):
* lisp/cedet/srecode/dictionary.el (srecode-create-dictionary)
(srecode-dictionary-add-entries, srecode-dictionary-lookup-name)
(srecode-create-dictionaries-from-tags):
* lisp/cmuscheme.el (scheme-compile-region):
* lisp/color.el (color-lab-to-lch):
* lisp/doc-view.el (doc-view-image-width)
(doc-view-set-up-single-converter):
* lisp/dynamic-setting.el (font-setting-change-default-font)
(dynamic-setting-handle-config-changed-event):
* lisp/elec-pair.el (electric-pair-text-pairs)
(electric-pair-skip-whitespace-function)
(electric-pair-string-bound-function):
* lisp/emacs-lisp/avl-tree.el (avl-tree--del-balance)
(avl-tree-member, avl-tree-mapcar, avl-tree-iter):
* lisp/emacs-lisp/bytecomp.el (byte-compile-generate-call-tree):
* lisp/emacs-lisp/checkdoc.el (checkdoc-autofix-flag)
(checkdoc-spellcheck-documentation-flag, checkdoc-ispell)
(checkdoc-ispell-current-buffer, checkdoc-ispell-interactive)
(checkdoc-ispell-message-interactive)
(checkdoc-ispell-message-text, checkdoc-ispell-start)
(checkdoc-ispell-continue, checkdoc-ispell-comments)
(checkdoc-ispell-defun):
* lisp/emacs-lisp/cl-generic.el (cl--generic-search-method):
* lisp/emacs-lisp/eieio-custom.el (eieio-read-customization-group):
* lisp/emacs-lisp/lisp.el (forward-sexp, up-list):
* lisp/emacs-lisp/package-x.el (package--archive-contents-from-file):
* lisp/emacs-lisp/package.el (package-desc)
(package--make-autoloads-and-stuff, package-hidden-regexps):
* lisp/emacs-lisp/tcover-ses.el (ses-exercise-startup):
* lisp/emacs-lisp/testcover.el (testcover-nohits)
(testcover-1value):
* lisp/epg.el (epg-receive-keys, epg-start-edit-key):
* lisp/erc/erc-backend.el (erc-server-processing-p)
(erc-split-line-length, erc-server-coding-system)
(erc-server-send, erc-message):
* lisp/erc/erc-button.el (erc-button-face, erc-button-alist)
(erc-browse-emacswiki):
* lisp/erc/erc-ezbounce.el (erc-ezbounce, erc-ezb-get-login):
* lisp/erc/erc-fill.el (erc-fill-variable-maximum-indentation):
* lisp/erc/erc-log.el (erc-current-logfile):
* lisp/erc/erc-match.el (erc-log-match-format)
(erc-text-matched-hook):
* lisp/erc/erc-netsplit.el (erc-netsplit, erc-netsplit-debug):
* lisp/erc/erc-networks.el (erc-server-alist)
(erc-networks-alist, erc-current-network):
* lisp/erc/erc-ring.el (erc-input-ring-index):
* lisp/erc/erc-speedbar.el (erc-speedbar)
(erc-speedbar-update-channel):
* lisp/erc/erc-stamp.el (erc-timestamp-only-if-changed-flag):
* lisp/erc/erc-track.el (erc-track-position-in-mode-line)
(erc-track-remove-from-mode-line, erc-modified-channels-update)
(erc-track-last-non-erc-buffer, erc-track-sort-by-importance)
(erc-track-get-active-buffer):
* lisp/erc/erc.el (erc-get-channel-user-list)
(erc-echo-notice-hook, erc-echo-notice-always-hook)
(erc-wash-quit-reason, erc-format-@nick):
* lisp/ffap.el (ffap-latex-mode):
* lisp/files.el (abort-if-file-too-large)
(dir-locals--get-sort-score, buffer-stale--default-function):
* lisp/filesets.el (filesets-tree-max-level, filesets-data)
(filesets-update-pre010505):
* lisp/gnus/gnus-agent.el (gnus-agent-flush-cache):
* lisp/gnus/gnus-art.el (gnus-article-encrypt-protocol)
(gnus-button-prefer-mid-or-mail):
* lisp/gnus/gnus-cus.el (gnus-group-parameters):
* lisp/gnus/gnus-demon.el (gnus-demon-handlers)
(gnus-demon-run-callback):
* lisp/gnus/gnus-dired.el (gnus-dired-print):
* lisp/gnus/gnus-icalendar.el (gnus-icalendar-event-from-buffer):
* lisp/gnus/gnus-range.el (gnus-range-normalize):
* lisp/gnus/gnus-spec.el (gnus-pad-form):
* lisp/gnus/gnus-srvr.el (gnus-server-agent, gnus-server-cloud)
(gnus-server-opened, gnus-server-closed, gnus-server-denied)
(gnus-server-offline):
* lisp/gnus/gnus-sum.el (gnus-refer-thread-use-nnir)
(gnus-refer-thread-limit-to-thread)
(gnus-summary-limit-include-thread, gnus-summary-refer-thread)
(gnus-summary-find-matching):
* lisp/gnus/gnus-util.el (gnus-rescale-image):
* lisp/gnus/gnus.el (gnus-summary-line-format, gnus-no-server):
* lisp/gnus/mail-source.el (mail-source-incoming-file-prefix):
* lisp/gnus/message.el (message-cite-reply-position)
(message-cite-style-outlook, message-cite-style-thunderbird)
(message-cite-style-gmail, message--send-mail-maybe-partially):
* lisp/gnus/mm-extern.el (mm-inline-external-body):
* lisp/gnus/mm-partial.el (mm-inline-partial):
* lisp/gnus/mml-sec.el (mml-secure-message-sign)
(mml-secure-message-sign-encrypt, mml-secure-message-encrypt):
* lisp/gnus/mml2015.el (mml2015-epg-key-image)
(mml2015-epg-key-image-to-string):
* lisp/gnus/nndiary.el (nndiary-reminders, nndiary-get-new-mail):
* lisp/gnus/nnheader.el (nnheader-directory-files-is-safe):
* lisp/gnus/nnir.el (nnir-search-history)
(nnir-imap-search-other, nnir-artlist-length)
(nnir-artlist-article, nnir-artitem-group, nnir-artitem-number)
(nnir-artitem-rsv, nnir-article-group, nnir-article-number)
(nnir-article-rsv, nnir-article-ids, nnir-categorize)
(nnir-retrieve-headers-override-function)
(nnir-imap-default-search-key, nnir-hyrex-additional-switches)
(gnus-group-make-nnir-group, nnir-run-namazu, nnir-read-parms)
(nnir-read-parm, nnir-read-server-parm, nnir-search-thread):
* lisp/gnus/nnmairix.el (nnmairix-default-group)
(nnmairix-propagate-marks):
* lisp/gnus/smime.el (smime-keys, smime-crl-check)
(smime-verify-buffer, smime-noverify-buffer):
* lisp/gnus/spam-report.el (spam-report-url-ping-mm-url):
* lisp/gnus/spam.el (spam-spamassassin-positive-spam-flag-header)
(spam-spamassassin-spam-status-header, spam-sa-learn-rebuild)
(spam-classifications, spam-check-stat, spam-spamassassin-score):
* lisp/help.el (describe-minor-mode-from-symbol):
* lisp/hippie-exp.el (hippie-expand-ignore-buffers):
* lisp/htmlfontify.el (hfy-optimizations, hfy-face-resolve-face)
(hfy-begin-span):
* lisp/ibuf-ext.el (ibuffer-update-saved-filters-format)
(ibuffer-saved-filters, ibuffer-old-saved-filters-warning)
(ibuffer-filtering-qualifiers, ibuffer-repair-saved-filters)
(eval, ibuffer-unary-operand, file-extension, directory):
* lisp/image-dired.el (image-dired-cmd-pngcrush-options):
* lisp/image-mode.el (image-toggle-display):
* lisp/international/ccl.el (ccl-compile-read-multibyte-character)
(ccl-compile-write-multibyte-character):
* lisp/international/kkc.el (kkc-save-init-file):
* lisp/international/latin1-disp.el (latin1-display):
* lisp/international/ogonek.el (ogonek-name-encoding-alist)
(ogonek-information, ogonek-lookup-encoding)
(ogonek-deprefixify-region):
* lisp/isearch.el (isearch-filter-predicate)
(isearch--momentary-message):
* lisp/jsonrpc.el (jsonrpc-connection-send)
(jsonrpc-process-connection, jsonrpc-shutdown)
(jsonrpc--async-request-1):
* lisp/language/tibet-util.el (tibetan-char-p):
* lisp/mail/feedmail.el (feedmail-queue-use-send-time-for-date)
(feedmail-last-chance-hook, feedmail-before-fcc-hook)
(feedmail-send-it-immediately-wrapper, feedmail-find-eoh):
* lisp/mail/hashcash.el (hashcash-generate-payment)
(hashcash-generate-payment-async, hashcash-insert-payment)
(hashcash-verify-payment):
* lisp/mail/rmail.el (rmail-movemail-variant-in-use)
(rmail-get-attr-value):
* lisp/mail/rmailmm.el (rmail-mime-prefer-html, rmail-mime):
* lisp/mail/rmailsum.el (rmail-summary-show-message):
* lisp/mail/supercite.el (sc-raw-mode-toggle):
* lisp/man.el (Man-start-calling):
* lisp/mh-e/mh-acros.el (mh-do-at-event-location)
(mh-iterate-on-messages-in-region, mh-iterate-on-range):
* lisp/mh-e/mh-alias.el (mh-alias-system-aliases)
(mh-alias-reload, mh-alias-ali)
(mh-alias-canonicalize-suggestion, mh-alias-add-alias-to-file)
(mh-alias-add-alias):
* lisp/mouse.el (mouse-save-then-kill):
* lisp/net/browse-url.el (browse-url-default-macosx-browser):
* lisp/net/eudc.el (eudc-set, eudc-variable-protocol-value)
(eudc-variable-server-value, eudc-update-variable)
(eudc-expand-inline):
* lisp/net/eudcb-bbdb.el (eudc-bbdb-format-record-as-result):
* lisp/net/eudcb-ldap.el (eudc-ldap-get-field-list):
* lisp/net/pop3.el (pop3-list):
* lisp/net/soap-client.el (soap-namespace-put)
(soap-xs-parse-sequence, soap-parse-envelope):
* lisp/net/soap-inspect.el (soap-inspect-xs-complex-type):
* lisp/nxml/rng-xsd.el (rng-xsd-date-to-days):
* lisp/org/ob-C.el (org-babel-prep-session:C)
(org-babel-load-session:C):
* lisp/org/ob-J.el (org-babel-execute:J):
* lisp/org/ob-asymptote.el (org-babel-prep-session:asymptote):
* lisp/org/ob-awk.el (org-babel-execute:awk):
* lisp/org/ob-core.el (org-babel-process-file-name):
* lisp/org/ob-ebnf.el (org-babel-execute:ebnf):
* lisp/org/ob-forth.el (org-babel-execute:forth):
* lisp/org/ob-fortran.el (org-babel-execute:fortran)
(org-babel-prep-session:fortran, org-babel-load-session:fortran):
* lisp/org/ob-groovy.el (org-babel-execute:groovy):
* lisp/org/ob-io.el (org-babel-execute:io):
* lisp/org/ob-js.el (org-babel-execute:js):
* lisp/org/ob-lilypond.el (org-babel-default-header-args:lilypond)
(org-babel-lilypond-compile-post-tangle)
(org-babel-lilypond-display-pdf-post-tangle)
(org-babel-lilypond-tangle)
(org-babel-lilypond-execute-tangled-ly)
(org-babel-lilypond-compile-lilyfile)
(org-babel-lilypond-check-for-compile-error)
(org-babel-lilypond-process-compile-error)
(org-babel-lilypond-mark-error-line)
(org-babel-lilypond-parse-error-line)
(org-babel-lilypond-attempt-to-open-pdf)
(org-babel-lilypond-attempt-to-play-midi)
(org-babel-lilypond-switch-extension)
(org-babel-lilypond-set-header-args):
* lisp/org/ob-lua.el (org-babel-prep-session:lua):
* lisp/org/ob-picolisp.el (org-babel-execute:picolisp):
* lisp/org/ob-processing.el (org-babel-prep-session:processing):
* lisp/org/ob-python.el (org-babel-prep-session:python):
* lisp/org/ob-scheme.el (org-babel-scheme-capture-current-message)
(org-babel-scheme-execute-with-geiser, org-babel-execute:scheme):
* lisp/org/ob-shen.el (org-babel-execute:shen):
* lisp/org/org-agenda.el (org-agenda-entry-types)
(org-agenda-move-date-from-past-immediately-to-today)
(org-agenda-time-grid, org-agenda-sorting-strategy)
(org-agenda-filter-by-category, org-agenda-forward-block):
* lisp/org/org-colview.el (org-columns--overlay-text):
* lisp/org/org-faces.el (org-verbatim, org-cycle-level-faces):
* lisp/org/org-indent.el (org-indent-set-line-properties):
* lisp/org/org-macs.el (org-get-limited-outline-regexp):
* lisp/org/org-mobile.el (org-mobile-files):
* lisp/org/org.el (org-use-fast-todo-selection)
(org-extend-today-until, org-use-property-inheritance)
(org-refresh-effort-properties, org-open-at-point-global)
(org-track-ordered-property-with-tag, org-shiftright):
* lisp/org/ox-html.el (org-html-checkbox-type):
* lisp/org/ox-man.el (org-man-source-highlight)
(org-man-verse-block):
* lisp/org/ox-publish.el (org-publish-sitemap-default):
* lisp/outline.el (outline-head-from-level):
* lisp/progmodes/dcl-mode.el (dcl-back-to-indentation-1)
(dcl-calc-command-indent, dcl-indent-to):
* lisp/progmodes/flymake.el (flymake-make-diagnostic)
(flymake--overlays, flymake-diagnostic-functions)
(flymake-diagnostic-types-alist, flymake--backend-state)
(flymake-is-running, flymake--collect, flymake-mode):
* lisp/progmodes/gdb-mi.el (gdb-threads-list, gdb, gdb-non-stop)
(gdb-buffers, gdb-gud-context-call, gdb-jsonify-buffer):
* lisp/progmodes/grep.el (grep-error-screen-columns):
* lisp/progmodes/gud.el (gud-prev-expr):
* lisp/progmodes/ps-mode.el (ps-mode, ps-mode-target-column)
(ps-run-goto-error):
* lisp/progmodes/python.el (python-eldoc-get-doc)
(python-eldoc-function-timeout-permanent, python-eldoc-function):
* lisp/shadowfile.el (shadow-make-group):
* lisp/speedbar.el (speedbar-obj-do-check):
* lisp/textmodes/flyspell.el (flyspell-auto-correct-previous-hook):
* lisp/textmodes/reftex-cite.el (reftex-bib-or-thebib):
* lisp/textmodes/reftex-index.el (reftex-index-goto-entry)
(reftex-index-kill, reftex-index-undo):
* lisp/textmodes/reftex-parse.el (reftex-context-substring):
* lisp/textmodes/reftex.el (reftex-TeX-master-file):
* lisp/textmodes/rst.el (rst-next-hdr, rst-toc)
(rst-uncomment-region, rst-font-lock-extend-region-internal):
* lisp/thumbs.el (thumbs-mode):
* lisp/vc/ediff-util.el (ediff-restore-diff):
* lisp/vc/pcvs-defs.el (cvs-cvsroot, cvs-force-dir-tag):
* lisp/vc/vc-hg.el (vc-hg--ignore-patterns-valid-p):
* lisp/wid-edit.el (widget-field-value-set, string):
* lisp/x-dnd.el (x-dnd-version-from-flags)
(x-dnd-more-than-3-from-flags): Assorted docfixes.
2019-09-20 22:27:53 +00:00
|
|
|
|
independent sets of headings (numbered, unnumbered, appendix...)."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(unless alist (setq alist outline-heading-alist))
|
|
|
|
|
(let ((l (rassoc level alist))
|
|
|
|
|
ll h hl l2 l2l)
|
|
|
|
|
(cond
|
|
|
|
|
((null l) nil)
|
|
|
|
|
;; If there's no HEAD after L, any other entry for LEVEL after L
|
|
|
|
|
;; can't be much better than L.
|
|
|
|
|
((null (setq h (assoc head (setq ll (memq l alist))))) (car l))
|
|
|
|
|
;; If there's no other entry for LEVEL, just keep L.
|
|
|
|
|
((null (setq l2 (rassoc level (cdr ll)))) (car l))
|
|
|
|
|
;; Now we have L, L2, and H: see if L2 seems better than L.
|
|
|
|
|
;; If H is after L2, L2 is better.
|
|
|
|
|
((memq h (setq l2l (memq l2 (cdr ll))))
|
|
|
|
|
(outline-head-from-level level head l2l))
|
|
|
|
|
;; Now we have H between L and L2.
|
|
|
|
|
;; If there's a separator between L and H, prefer L2.
|
|
|
|
|
((memq h (memq nil ll))
|
|
|
|
|
(outline-head-from-level level head l2l))
|
|
|
|
|
;; If there's a separator between L2 and H, prefer L.
|
|
|
|
|
((memq l2 (memq nil (setq hl (memq h ll)))) (car l))
|
|
|
|
|
;; No separator between L and L2, check the distance.
|
|
|
|
|
((< (* 2 (length hl)) (+ (length ll) (length l2l)))
|
|
|
|
|
(outline-head-from-level level head l2l))
|
|
|
|
|
;; If all else fails, just keep L.
|
|
|
|
|
(t (car l)))))
|
|
|
|
|
|
|
|
|
|
(defun outline-map-region (fun beg end)
|
|
|
|
|
"Call FUN for every heading between BEG and END.
|
|
|
|
|
When FUN is called, point is at the beginning of the heading and
|
|
|
|
|
the match data is set appropriately."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(setq end (copy-marker end))
|
|
|
|
|
(goto-char beg)
|
|
|
|
|
(when (re-search-forward (concat "^\\(?:" outline-regexp "\\)") end t)
|
|
|
|
|
(goto-char (match-beginning 0))
|
|
|
|
|
(funcall fun)
|
|
|
|
|
(while (and (progn
|
|
|
|
|
(outline-next-heading)
|
|
|
|
|
(< (point) end))
|
|
|
|
|
(not (eobp)))
|
|
|
|
|
(funcall fun)))))
|
|
|
|
|
|
|
|
|
|
;; Vertical tree motion
|
|
|
|
|
|
|
|
|
|
(defun outline-move-subtree-up (&optional arg)
|
2011-11-15 17:37:37 +00:00
|
|
|
|
"Move the current subtree up past ARG headlines of the same level."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(interactive "p")
|
|
|
|
|
(outline-move-subtree-down (- arg)))
|
|
|
|
|
|
|
|
|
|
(defun outline-move-subtree-down (&optional arg)
|
2011-11-15 17:37:37 +00:00
|
|
|
|
"Move the current subtree down past ARG headlines of the same level."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(interactive "p")
|
2014-11-29 13:56:59 +00:00
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(let* ((movfunc (if (> arg 0) 'outline-get-next-sibling
|
|
|
|
|
'outline-get-last-sibling))
|
|
|
|
|
;; Find the end of the subtree to be moved as well as the point to
|
|
|
|
|
;; move it to, adding a newline if necessary, to ensure these points
|
|
|
|
|
;; are at bol on the line below the subtree.
|
|
|
|
|
(end-point-func (lambda ()
|
|
|
|
|
(outline-end-of-subtree)
|
|
|
|
|
(if (eq (char-after) ?\n) (forward-char 1)
|
|
|
|
|
(if (and (eobp) (not (bolp))) (insert "\n")))
|
|
|
|
|
(point)))
|
|
|
|
|
(beg (point))
|
|
|
|
|
(folded (save-match-data
|
|
|
|
|
(outline-end-of-heading)
|
|
|
|
|
(outline-invisible-p)))
|
|
|
|
|
(end (save-match-data
|
|
|
|
|
(funcall end-point-func)))
|
|
|
|
|
(ins-point (make-marker))
|
|
|
|
|
(cnt (abs arg)))
|
2014-11-27 10:03:58 +00:00
|
|
|
|
;; Find insertion point, with error handling.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(goto-char beg)
|
|
|
|
|
(while (> cnt 0)
|
|
|
|
|
(or (funcall movfunc)
|
|
|
|
|
(progn (goto-char beg)
|
2014-11-27 10:03:58 +00:00
|
|
|
|
(user-error "Cannot move past superior level")))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(setq cnt (1- cnt)))
|
|
|
|
|
(if (> arg 0)
|
2014-11-27 10:03:58 +00:00
|
|
|
|
;; Moving forward - still need to move over subtree.
|
2014-11-29 13:56:59 +00:00
|
|
|
|
(funcall end-point-func))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(move-marker ins-point (point))
|
|
|
|
|
(insert (delete-and-extract-region beg end))
|
|
|
|
|
(goto-char ins-point)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(if folded (outline-hide-subtree))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(move-marker ins-point nil)))
|
|
|
|
|
|
|
|
|
|
(defun outline-end-of-heading ()
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Move to one char before the next `outline-heading-end-regexp'."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(if (re-search-forward outline-heading-end-regexp nil 'move)
|
|
|
|
|
(forward-char -1)))
|
|
|
|
|
|
|
|
|
|
(defun outline-next-visible-heading (arg)
|
|
|
|
|
"Move to the next visible heading line.
|
2015-01-28 10:55:47 +00:00
|
|
|
|
With ARG, repeats or can move backward if negative.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
A heading line is one that starts with a `*' (or that
|
|
|
|
|
`outline-regexp' matches)."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(if (< arg 0)
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
(end-of-line))
|
2006-12-22 22:57:15 +00:00
|
|
|
|
(let (found-heading-p)
|
|
|
|
|
(while (and (not (bobp)) (< arg 0))
|
|
|
|
|
(while (and (not (bobp))
|
|
|
|
|
(setq found-heading-p
|
|
|
|
|
(re-search-backward
|
|
|
|
|
(concat "^\\(?:" outline-regexp "\\)")
|
|
|
|
|
nil 'move))
|
|
|
|
|
(outline-invisible-p)))
|
|
|
|
|
(setq arg (1+ arg)))
|
|
|
|
|
(while (and (not (eobp)) (> arg 0))
|
|
|
|
|
(while (and (not (eobp))
|
|
|
|
|
(setq found-heading-p
|
|
|
|
|
(re-search-forward
|
|
|
|
|
(concat "^\\(?:" outline-regexp "\\)")
|
|
|
|
|
nil 'move))
|
|
|
|
|
(outline-invisible-p (match-beginning 0))))
|
|
|
|
|
(setq arg (1- arg)))
|
|
|
|
|
(if found-heading-p (beginning-of-line))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-previous-visible-heading (arg)
|
|
|
|
|
"Move to the previous heading line.
|
2015-01-28 10:55:47 +00:00
|
|
|
|
With ARG, repeats or can move forward if negative.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
A heading line is one that starts with a `*' (or that
|
|
|
|
|
`outline-regexp' matches)."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(outline-next-visible-heading (- arg)))
|
|
|
|
|
|
|
|
|
|
(defun outline-mark-subtree ()
|
|
|
|
|
"Mark the current subtree in an outlined document.
|
|
|
|
|
This puts point at the start of the current subtree, and mark at the end."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((beg))
|
|
|
|
|
(if (outline-on-heading-p)
|
|
|
|
|
;; we are already looking at a heading
|
|
|
|
|
(beginning-of-line)
|
|
|
|
|
;; else go back to previous heading
|
|
|
|
|
(outline-previous-visible-heading 1))
|
|
|
|
|
(setq beg (point))
|
|
|
|
|
(outline-end-of-subtree)
|
2005-10-04 20:54:26 +00:00
|
|
|
|
(push-mark (point) nil t)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(goto-char beg)))
|
|
|
|
|
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(defvar outline-isearch-open-invisible-function
|
|
|
|
|
#'outline-isearch-open-invisible
|
2006-12-17 00:48:26 +00:00
|
|
|
|
"Function called if `isearch' finishes in an invisible overlay.
|
2020-10-20 23:00:52 +00:00
|
|
|
|
The function is called with the overlay as its only argument.")
|
2006-12-17 00:48:26 +00:00
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(put 'outline 'reveal-toggle-invisible #'outline-reveal-toggle-invisible)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(defun outline-flag-region (from to flag)
|
|
|
|
|
"Hide or show lines from FROM to TO, according to FLAG.
|
|
|
|
|
If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
|
|
|
|
|
(remove-overlays from to 'invisible 'outline)
|
|
|
|
|
(when flag
|
2007-09-08 03:09:31 +00:00
|
|
|
|
;; We use `front-advance' here because the invisible text begins at the
|
|
|
|
|
;; very end of the heading, before the newline, so text inserted at FROM
|
|
|
|
|
;; belongs to the heading rather than to the entry.
|
|
|
|
|
(let ((o (make-overlay from to nil 'front-advance)))
|
2012-03-21 18:21:24 +00:00
|
|
|
|
(overlay-put o 'evaporate t)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(overlay-put o 'invisible 'outline)
|
2006-12-17 00:48:26 +00:00
|
|
|
|
(overlay-put o 'isearch-open-invisible
|
|
|
|
|
(or outline-isearch-open-invisible-function
|
2020-10-20 23:00:52 +00:00
|
|
|
|
#'outline-isearch-open-invisible))))
|
2021-11-06 18:49:07 +00:00
|
|
|
|
(outline--fix-up-all-buttons from to)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Seems only used by lazy-lock. I.e. obsolete.
|
|
|
|
|
(run-hooks 'outline-view-change-hook))
|
|
|
|
|
|
|
|
|
|
(defun outline-reveal-toggle-invisible (o hidep)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (overlay-start o))
|
|
|
|
|
(if hidep
|
2015-01-28 09:32:12 +00:00
|
|
|
|
;; When hiding the area again, we could just clean it up and let
|
|
|
|
|
;; reveal do the rest, by simply doing:
|
|
|
|
|
;; (remove-overlays (overlay-start o) (overlay-end o)
|
|
|
|
|
;; 'invisible 'outline)
|
|
|
|
|
;;
|
|
|
|
|
;; That works fine as long as everything is in sync, but if the
|
|
|
|
|
;; structure of the document is changed while revealing parts of it,
|
|
|
|
|
;; the resulting behavior can be ugly. I.e. we need to make
|
|
|
|
|
;; sure that we hide exactly a subtree.
|
|
|
|
|
(progn
|
|
|
|
|
(let ((end (overlay-end o)))
|
|
|
|
|
(delete-overlay o)
|
|
|
|
|
(while (progn
|
|
|
|
|
(outline-hide-subtree)
|
|
|
|
|
(outline-next-visible-heading 1)
|
|
|
|
|
(and (not (eobp)) (< (point) end))))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
;; When revealing, we just need to reveal sublevels. If point is
|
|
|
|
|
;; inside one of the sublevels, reveal will call us again.
|
|
|
|
|
;; But we need to preserve the original overlay.
|
|
|
|
|
(let ((o1 (copy-overlay o)))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(overlay-put o 'invisible nil) ;Show (most of) the text.
|
|
|
|
|
(while (progn
|
|
|
|
|
(outline-show-entry)
|
|
|
|
|
(outline-show-children)
|
|
|
|
|
;; Normally just the above is needed.
|
|
|
|
|
;; But in odd cases, the above might fail to show anything.
|
|
|
|
|
;; To avoid an infinite loop, we have to make sure that
|
|
|
|
|
;; *something* gets shown.
|
|
|
|
|
(and (equal (overlay-start o) (overlay-start o1))
|
|
|
|
|
(< (point) (overlay-end o))
|
|
|
|
|
(= 0 (forward-line 1)))))
|
|
|
|
|
;; If still nothing was shown, just kill the damn thing.
|
|
|
|
|
(when (equal (overlay-start o) (overlay-start o1))
|
|
|
|
|
;; I've seen it happen at the end of buffer.
|
|
|
|
|
(delete-overlay o1))))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
;; Function to be set as an outline-isearch-open-invisible' property
|
|
|
|
|
;; to the overlay that makes the outline invisible (see
|
|
|
|
|
;; `outline-flag-region').
|
2011-04-19 13:44:55 +00:00
|
|
|
|
(defun outline-isearch-open-invisible (_overlay)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; We rely on the fact that isearch places point on the matched text.
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(outline-show-entry))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(defun outline-hide-entry ()
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Hide the body directly following this heading."
|
|
|
|
|
(interactive)
|
|
|
|
|
(save-excursion
|
2005-08-29 20:49:01 +00:00
|
|
|
|
(outline-back-to-heading)
|
2004-04-29 15:34:58 +00:00
|
|
|
|
(outline-end-of-heading)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(outline-flag-region (point) (progn (outline-next-preface) (point)) t)))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'hide-entry #'outline-hide-entry "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-show-entry ()
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Show the body directly following this heading.
|
|
|
|
|
Show the heading too, if it is currently invisible."
|
|
|
|
|
(interactive)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(outline-back-to-heading t)
|
|
|
|
|
(outline-flag-region (1- (point))
|
2015-02-07 17:54:07 +00:00
|
|
|
|
(progn
|
|
|
|
|
(outline-next-preface)
|
|
|
|
|
(if (= 1 (- (point-max) (point)))
|
|
|
|
|
(point-max)
|
|
|
|
|
(point)))
|
|
|
|
|
nil)))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'show-entry #'outline-show-entry "25.1")
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(defun outline-hide-body ()
|
2016-11-07 15:55:42 +00:00
|
|
|
|
"Hide all body lines in buffer, leaving all headings visible.
|
|
|
|
|
Note that this does not hide the lines preceding the first heading line."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(interactive)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(outline-hide-region-body (point-min) (point-max)))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'hide-body #'outline-hide-body "25.1")
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(defun outline-hide-region-body (start end)
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Hide all body lines between START and END, but not headings."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Nullify the hook to avoid repeated calls to `outline-flag-region'
|
|
|
|
|
;; wasting lots of time running `lazy-lock-fontify-after-outline'
|
|
|
|
|
;; and run the hook finally.
|
|
|
|
|
(let (outline-view-change-hook)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region start end)
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(if (outline-on-heading-p)
|
2004-11-06 12:10:38 +00:00
|
|
|
|
(outline-end-of-heading)
|
|
|
|
|
(outline-next-preface))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(while (not (eobp))
|
|
|
|
|
(outline-flag-region (point)
|
|
|
|
|
(progn (outline-next-preface) (point)) t)
|
|
|
|
|
(unless (eobp)
|
|
|
|
|
(forward-char (if (looking-at "\n\n") 2 1))
|
|
|
|
|
(outline-end-of-heading))))))
|
|
|
|
|
(run-hooks 'outline-view-change-hook))
|
|
|
|
|
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(define-obsolete-function-alias
|
2020-10-20 23:00:52 +00:00
|
|
|
|
'hide-region-body #'outline-hide-region-body "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-show-all ()
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Show all of the text in the buffer."
|
|
|
|
|
(interactive)
|
|
|
|
|
(outline-flag-region (point-min) (point-max) nil))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'show-all #'outline-show-all "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(defun outline-hide-subtree (&optional event)
|
|
|
|
|
"Hide everything after this heading at deeper levels.
|
|
|
|
|
If non-nil, EVENT should be a mouse event."
|
|
|
|
|
(interactive (list last-nonmenu-event))
|
2021-10-31 23:05:10 +00:00
|
|
|
|
(when (mouse-event-p event)
|
2021-10-31 22:24:46 +00:00
|
|
|
|
(mouse-set-point event))
|
2022-07-29 11:20:06 +00:00
|
|
|
|
(when (outline--use-buttons-p)
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(outline--insert-close-button))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(outline-flag-subtree t))
|
|
|
|
|
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(defun outline--make-button-overlay (type)
|
|
|
|
|
(let ((o (seq-find (lambda (o)
|
|
|
|
|
(overlay-get o 'outline-button))
|
|
|
|
|
(overlays-at (point)))))
|
|
|
|
|
(unless o
|
|
|
|
|
(setq o (make-overlay (point) (1+ (point))))
|
2021-11-02 02:50:36 +00:00
|
|
|
|
(overlay-put o 'follow-link 'mouse-face)
|
|
|
|
|
(overlay-put o 'mouse-face 'highlight)
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(overlay-put o 'outline-button t))
|
2022-07-28 12:37:59 +00:00
|
|
|
|
(let ((icon
|
|
|
|
|
(icon-elements (if (eq type 'close) 'outline-close 'outline-open)))
|
|
|
|
|
(inhibit-read-only t))
|
|
|
|
|
;; In editing buffers we use overlays only, but in other buffers
|
|
|
|
|
;; we use a mix of text properties, text and overlays to make
|
|
|
|
|
;; movement commands work more logically.
|
|
|
|
|
(when (derived-mode-p 'special-mode)
|
|
|
|
|
(put-text-property (point) (1+ (point)) 'face (plist-get icon 'face)))
|
|
|
|
|
(when-let ((image (plist-get icon 'image)))
|
|
|
|
|
(overlay-put o 'display image))
|
|
|
|
|
(overlay-put o 'display (plist-get icon 'string))
|
|
|
|
|
(overlay-put o 'face (plist-get icon 'face)))
|
2021-10-31 22:13:52 +00:00
|
|
|
|
o))
|
|
|
|
|
|
|
|
|
|
(defun outline--insert-open-button ()
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
2022-07-28 12:37:59 +00:00
|
|
|
|
(when (derived-mode-p 'special-mode)
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(insert " ")
|
|
|
|
|
(beginning-of-line)))
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(let ((o (outline--make-button-overlay 'open)))
|
|
|
|
|
(overlay-put o 'help-echo "Click to hide")
|
|
|
|
|
(overlay-put o 'keymap
|
|
|
|
|
(define-keymap
|
2021-11-16 07:18:30 +00:00
|
|
|
|
"RET" #'outline-hide-subtree
|
|
|
|
|
"<mouse-2>" #'outline-hide-subtree)))))
|
2021-10-31 22:13:52 +00:00
|
|
|
|
|
|
|
|
|
(defun outline--insert-close-button ()
|
|
|
|
|
(save-excursion
|
|
|
|
|
(beginning-of-line)
|
2022-07-28 12:37:59 +00:00
|
|
|
|
(when (derived-mode-p 'special-mode)
|
|
|
|
|
(let ((inhibit-read-only t))
|
|
|
|
|
(insert " ")
|
|
|
|
|
(beginning-of-line)))
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(let ((o (outline--make-button-overlay 'close)))
|
|
|
|
|
(overlay-put o 'help-echo "Click to show")
|
|
|
|
|
(overlay-put o 'keymap
|
|
|
|
|
(define-keymap
|
2021-11-16 07:18:30 +00:00
|
|
|
|
"RET" #'outline-show-subtree
|
|
|
|
|
"<mouse-2>" #'outline-show-subtree)))))
|
2021-10-31 22:13:52 +00:00
|
|
|
|
|
2021-11-06 18:49:07 +00:00
|
|
|
|
(defun outline--fix-up-all-buttons (&optional from to)
|
|
|
|
|
(when from
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char from)
|
|
|
|
|
(setq from (line-beginning-position))))
|
2022-07-29 11:20:06 +00:00
|
|
|
|
(when (outline--use-buttons-p)
|
2021-11-06 18:49:07 +00:00
|
|
|
|
(outline-map-region
|
|
|
|
|
(lambda ()
|
2021-11-15 06:38:07 +00:00
|
|
|
|
;; `outline--cycle-state' will fail if we're in a totally
|
|
|
|
|
;; collapsed buffer -- but in that case, we're not in a
|
|
|
|
|
;; `show-all' situation.
|
|
|
|
|
(if (eq (ignore-errors (outline--cycle-state)) 'show-all)
|
2021-11-06 18:49:07 +00:00
|
|
|
|
(outline--insert-open-button)
|
|
|
|
|
(outline--insert-close-button)))
|
|
|
|
|
(or from (point-min)) (or to (point-max)))))
|
2021-10-31 22:13:52 +00:00
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'hide-subtree #'outline-hide-subtree "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-hide-leaves ()
|
2006-01-19 17:51:38 +00:00
|
|
|
|
"Hide the body after this heading and at deeper levels."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(interactive)
|
|
|
|
|
(save-excursion
|
2005-08-29 20:49:01 +00:00
|
|
|
|
(outline-back-to-heading)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
;; Turned off to fix bug reported by Otto Maddox on 22 Nov 2005.
|
|
|
|
|
;; (outline-end-of-heading)
|
|
|
|
|
(outline-hide-region-body
|
|
|
|
|
(point)
|
|
|
|
|
(progn (outline-end-of-subtree) (point)))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'hide-leaves #'outline-hide-leaves "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(defun outline-show-subtree (&optional event)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Show everything after this heading at deeper levels."
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(interactive (list last-nonmenu-event))
|
2021-10-31 23:05:10 +00:00
|
|
|
|
(when (mouse-event-p event)
|
2021-10-31 22:24:46 +00:00
|
|
|
|
(mouse-set-point event))
|
2022-07-29 11:20:06 +00:00
|
|
|
|
(when (outline--use-buttons-p)
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(outline--insert-open-button))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(outline-flag-subtree nil))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'show-subtree #'outline-show-subtree "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(defun outline-show-heading ()
|
|
|
|
|
"Show the current heading and move to its end."
|
2004-05-01 03:44:30 +00:00
|
|
|
|
(outline-flag-region (- (point)
|
|
|
|
|
(if (bobp) 0
|
|
|
|
|
(if (and outline-blank-line
|
|
|
|
|
(eq (char-before (1- (point))) ?\n))
|
|
|
|
|
2 1)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(progn (outline-end-of-heading) (point))
|
|
|
|
|
nil))
|
|
|
|
|
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(defun outline-hide-sublevels (levels)
|
2016-11-07 15:55:42 +00:00
|
|
|
|
"Hide everything but the top LEVELS levels of headers, in whole buffer.
|
|
|
|
|
This also unhides the top heading-less body, if any.
|
|
|
|
|
|
|
|
|
|
Interactively, the prefix argument supplies the value of LEVELS.
|
|
|
|
|
When invoked without a prefix argument, LEVELS defaults to the level
|
|
|
|
|
of the current heading, or to 1 if the current line is not a heading."
|
2006-03-06 04:49:42 +00:00
|
|
|
|
(interactive (list
|
|
|
|
|
(cond
|
|
|
|
|
(current-prefix-arg (prefix-numeric-value current-prefix-arg))
|
|
|
|
|
((save-excursion (beginning-of-line)
|
|
|
|
|
(looking-at outline-regexp))
|
|
|
|
|
(funcall outline-level))
|
|
|
|
|
(t 1))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(if (< levels 1)
|
|
|
|
|
(error "Must keep at least one level of headers"))
|
2007-02-19 18:48:58 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(let* (outline-view-change-hook
|
|
|
|
|
(beg (progn
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
;; Skip the prelude, if any.
|
|
|
|
|
(unless (outline-on-heading-p t) (outline-next-heading))
|
|
|
|
|
(point)))
|
|
|
|
|
(end (progn
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
;; Keep empty last line, if available.
|
|
|
|
|
(if (bolp) (1- (point)) (point)))))
|
2009-04-15 23:32:23 +00:00
|
|
|
|
(if (< end beg)
|
|
|
|
|
(setq beg (prog1 end (setq end beg))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; First hide everything.
|
2007-02-19 18:48:58 +00:00
|
|
|
|
(outline-flag-region beg end t)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
;; Then unhide the top level headers.
|
|
|
|
|
(outline-map-region
|
|
|
|
|
(lambda ()
|
|
|
|
|
(if (<= (funcall outline-level) levels)
|
2010-03-20 19:04:44 +00:00
|
|
|
|
(outline-show-heading)))
|
|
|
|
|
beg end)
|
|
|
|
|
;; Finally unhide any trailing newline.
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
(if (and (bolp) (not (bobp)) (outline-invisible-p (1- (point))))
|
|
|
|
|
(outline-flag-region (1- (point)) (point) nil))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(run-hooks 'outline-view-change-hook))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'hide-sublevels #'outline-hide-sublevels "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-hide-other ()
|
2016-11-07 15:55:42 +00:00
|
|
|
|
"Hide everything except current body and parent and top-level headings.
|
|
|
|
|
This also unhides the top heading-less body, if any."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(interactive)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(outline-hide-sublevels 1)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(let (outline-view-change-hook)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(outline-back-to-heading t)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(outline-show-entry)
|
2004-10-16 15:33:59 +00:00
|
|
|
|
(while (condition-case nil (progn (outline-up-heading 1 t) (not (bobp)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(error nil))
|
|
|
|
|
(outline-flag-region (1- (point))
|
|
|
|
|
(save-excursion (forward-line 1) (point))
|
|
|
|
|
nil))))
|
|
|
|
|
(run-hooks 'outline-view-change-hook))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'hide-other #'outline-hide-other "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(defun outline-toggle-children ()
|
|
|
|
|
"Show or hide the current subtree depending on its current state."
|
|
|
|
|
(interactive)
|
2005-08-29 20:49:01 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(if (not (outline-invisible-p (line-end-position)))
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(outline-hide-subtree)
|
|
|
|
|
(outline-show-children)
|
|
|
|
|
(outline-show-entry))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-flag-subtree (flag)
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Assign FLAG to the current subtree."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(outline-end-of-heading)
|
|
|
|
|
(outline-flag-region (point)
|
|
|
|
|
(progn (outline-end-of-subtree) (point))
|
|
|
|
|
flag)))
|
|
|
|
|
|
|
|
|
|
(defun outline-end-of-subtree ()
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Move to the end of the current subtree."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(outline-back-to-heading)
|
2005-08-26 15:31:59 +00:00
|
|
|
|
(let ((first t)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(level (funcall outline-level)))
|
|
|
|
|
(while (and (not (eobp))
|
|
|
|
|
(or first (> (funcall outline-level) level)))
|
|
|
|
|
(setq first nil)
|
|
|
|
|
(outline-next-heading))
|
2006-12-04 00:31:04 +00:00
|
|
|
|
(if (and (bolp) (not (eolp)))
|
|
|
|
|
;; We stopped at a nonempty line (the next heading).
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(progn
|
|
|
|
|
;; Go to end of line before heading
|
2004-05-01 03:44:30 +00:00
|
|
|
|
(forward-char -1)
|
|
|
|
|
(if (and outline-blank-line (bolp))
|
|
|
|
|
;; leave blank line before heading
|
|
|
|
|
(forward-char -1))))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(defun outline-show-branches ()
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Show all subheadings of this heading, but not their bodies."
|
|
|
|
|
(interactive)
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(outline-show-children 1000))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'show-branches #'outline-show-branches "25.1")
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2015-01-28 09:32:12 +00:00
|
|
|
|
(defun outline-show-children (&optional level)
|
2003-05-30 23:30:10 +00:00
|
|
|
|
"Show all direct subheadings of this heading.
|
|
|
|
|
Prefix arg LEVEL is how many levels below the current level should be shown.
|
|
|
|
|
Default is enough to cause the following heading to appear."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq level
|
|
|
|
|
(if level (prefix-numeric-value level)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(let ((start-level (funcall outline-level)))
|
|
|
|
|
(outline-next-heading)
|
|
|
|
|
(if (eobp)
|
|
|
|
|
1
|
|
|
|
|
(max 1 (- (funcall outline-level) start-level)))))))
|
|
|
|
|
(let (outline-view-change-hook)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(setq level (+ level (funcall outline-level)))
|
|
|
|
|
(outline-map-region
|
|
|
|
|
(lambda ()
|
|
|
|
|
(if (<= (funcall outline-level) level)
|
|
|
|
|
(outline-show-heading)))
|
|
|
|
|
(point)
|
|
|
|
|
(progn (outline-end-of-subtree)
|
|
|
|
|
(if (eobp) (point-max) (1+ (point)))))))
|
|
|
|
|
(run-hooks 'outline-view-change-hook))
|
|
|
|
|
|
2020-10-20 23:00:52 +00:00
|
|
|
|
(define-obsolete-function-alias 'show-children #'outline-show-children "25.1")
|
2015-01-28 09:32:12 +00:00
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(defun outline-up-heading (arg &optional invisible-ok)
|
|
|
|
|
"Move to the visible heading line of which the present line is a subheading.
|
|
|
|
|
With argument, move up ARG levels.
|
|
|
|
|
If INVISIBLE-OK is non-nil, also consider invisible lines."
|
|
|
|
|
(interactive "p")
|
2004-04-29 15:34:58 +00:00
|
|
|
|
(and (eq this-command 'outline-up-heading)
|
|
|
|
|
(or (eq last-command 'outline-up-heading) (push-mark)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(outline-back-to-heading invisible-ok)
|
|
|
|
|
(let ((start-level (funcall outline-level)))
|
2008-01-21 19:48:56 +00:00
|
|
|
|
(when (<= start-level 1)
|
|
|
|
|
(error "Already at top level of the outline"))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(while (and (> start-level 1) (> arg 0) (not (bobp)))
|
|
|
|
|
(let ((level start-level))
|
|
|
|
|
(while (not (or (< level start-level) (bobp)))
|
|
|
|
|
(if invisible-ok
|
|
|
|
|
(outline-previous-heading)
|
|
|
|
|
(outline-previous-visible-heading 1))
|
|
|
|
|
(setq level (funcall outline-level)))
|
|
|
|
|
(setq start-level level))
|
|
|
|
|
(setq arg (- arg 1))))
|
|
|
|
|
(looking-at outline-regexp))
|
|
|
|
|
|
|
|
|
|
(defun outline-forward-same-level (arg)
|
|
|
|
|
"Move forward to the ARG'th subheading at same level as this one.
|
|
|
|
|
Stop at the first and last subheadings of a superior heading."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(while (> arg 0)
|
|
|
|
|
(let ((point-to-move-to (save-excursion
|
|
|
|
|
(outline-get-next-sibling))))
|
|
|
|
|
(if point-to-move-to
|
|
|
|
|
(progn
|
|
|
|
|
(goto-char point-to-move-to)
|
|
|
|
|
(setq arg (1- arg)))
|
|
|
|
|
(progn
|
|
|
|
|
(setq arg 0)
|
|
|
|
|
(error "No following same-level heading"))))))
|
|
|
|
|
|
|
|
|
|
(defun outline-get-next-sibling ()
|
2007-04-13 01:17:51 +00:00
|
|
|
|
"Move to next heading of the same level, and return point.
|
|
|
|
|
If there is no such heading, return nil."
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(let ((level (funcall outline-level)))
|
|
|
|
|
(outline-next-visible-heading 1)
|
|
|
|
|
(while (and (not (eobp)) (> (funcall outline-level) level))
|
|
|
|
|
(outline-next-visible-heading 1))
|
|
|
|
|
(if (or (eobp) (< (funcall outline-level) level))
|
|
|
|
|
nil
|
|
|
|
|
(point))))
|
|
|
|
|
|
|
|
|
|
(defun outline-backward-same-level (arg)
|
|
|
|
|
"Move backward to the ARG'th subheading at same level as this one.
|
|
|
|
|
Stop at the first and last subheadings of a superior heading."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(while (> arg 0)
|
|
|
|
|
(let ((point-to-move-to (save-excursion
|
|
|
|
|
(outline-get-last-sibling))))
|
|
|
|
|
(if point-to-move-to
|
|
|
|
|
(progn
|
|
|
|
|
(goto-char point-to-move-to)
|
|
|
|
|
(setq arg (1- arg)))
|
|
|
|
|
(progn
|
|
|
|
|
(setq arg 0)
|
|
|
|
|
(error "No previous same-level heading"))))))
|
|
|
|
|
|
|
|
|
|
(defun outline-get-last-sibling ()
|
2007-04-13 01:17:51 +00:00
|
|
|
|
"Move to previous heading of the same level, and return point.
|
|
|
|
|
If there is no such heading, return nil."
|
|
|
|
|
(let ((opoint (point))
|
|
|
|
|
(level (funcall outline-level)))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(outline-previous-visible-heading 1)
|
2007-04-13 01:17:51 +00:00
|
|
|
|
(when (and (/= (point) opoint) (outline-on-heading-p))
|
|
|
|
|
(while (and (> (funcall outline-level) level)
|
|
|
|
|
(not (bobp)))
|
|
|
|
|
(outline-previous-visible-heading 1))
|
|
|
|
|
(if (< (funcall outline-level) level)
|
|
|
|
|
nil
|
|
|
|
|
(point)))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
(defun outline-headers-as-kill (beg end)
|
2015-01-28 10:55:47 +00:00
|
|
|
|
"Save the visible outline headers between BEG and END to the kill ring.
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
|
|
|
|
Text shown between the headers isn't copied. Two newlines are
|
|
|
|
|
inserted between saved headers. Yanking the result may be a
|
|
|
|
|
convenient way to make a table of contents of the buffer."
|
|
|
|
|
(interactive "r")
|
|
|
|
|
(save-excursion
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region beg end)
|
|
|
|
|
(goto-char (point-min))
|
2018-01-22 11:19:00 +00:00
|
|
|
|
(let ((buffer (current-buffer)) start end)
|
|
|
|
|
(with-temp-buffer
|
|
|
|
|
(let ((temp-buffer (current-buffer)))
|
|
|
|
|
(with-current-buffer buffer
|
|
|
|
|
;; Boundary condition: starting on heading:
|
|
|
|
|
(when (outline-on-heading-p)
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(setq start (point)
|
|
|
|
|
end (progn (outline-end-of-heading) (point)))
|
|
|
|
|
(with-current-buffer temp-buffer
|
|
|
|
|
(insert-buffer-substring buffer start end)
|
|
|
|
|
(insert "\n\n")))
|
|
|
|
|
(while (outline-next-heading)
|
|
|
|
|
(unless (outline-invisible-p)
|
|
|
|
|
(setq start (point)
|
|
|
|
|
end (progn (outline-end-of-heading) (point)))
|
|
|
|
|
(with-current-buffer temp-buffer
|
|
|
|
|
(insert-buffer-substring buffer start end)
|
|
|
|
|
(insert "\n\n"))))))
|
|
|
|
|
(kill-new (buffer-string)))))))
|
2003-05-30 23:30:10 +00:00
|
|
|
|
|
2022-01-16 18:13:21 +00:00
|
|
|
|
(defcustom outline-default-state nil
|
|
|
|
|
"If non-nil, some headings are initially outlined.
|
|
|
|
|
|
2022-01-17 19:20:28 +00:00
|
|
|
|
Note that the default state is applied when Outline major and
|
|
|
|
|
minor modes are set or when the command
|
|
|
|
|
`outline-apply-default-state' is called interactively.
|
2022-01-16 18:13:21 +00:00
|
|
|
|
|
2022-01-17 19:20:28 +00:00
|
|
|
|
When nil, no default state is defined and
|
|
|
|
|
`outline-apply-default-state' is a no-op.
|
2022-01-16 18:13:21 +00:00
|
|
|
|
|
|
|
|
|
If equal to `outline-show-all', all text of buffer is shown.
|
|
|
|
|
|
2022-01-17 19:20:28 +00:00
|
|
|
|
If equal to `outline-show-only-headings', show only headings,
|
|
|
|
|
whatever their level is.
|
2022-01-16 18:13:21 +00:00
|
|
|
|
|
|
|
|
|
If equal to a number, show only headings up to and including the
|
|
|
|
|
corresponding level. See `outline-default-rules' to customize
|
2022-01-17 19:20:28 +00:00
|
|
|
|
visibility of the subtree at that level.
|
2022-01-16 18:13:21 +00:00
|
|
|
|
|
|
|
|
|
If equal to a lambda function or function name, this function is
|
2022-01-17 19:20:28 +00:00
|
|
|
|
expected to toggle headings visibility, and will be
|
|
|
|
|
called without arguments after the mode is enabled."
|
2022-01-16 18:13:21 +00:00
|
|
|
|
:version "29.1"
|
|
|
|
|
:type '(choice (const :tag "Disabled" nil)
|
|
|
|
|
(const :tag "Show all" outline-show-all)
|
|
|
|
|
(const :tag "Only headings" outline-show-only-headings)
|
|
|
|
|
(natnum :tag "Show headings up to level" :value 1)
|
|
|
|
|
(function :tag "Custom function")))
|
|
|
|
|
|
|
|
|
|
(defcustom outline-default-rules nil
|
|
|
|
|
"Determines visibility of subtree starting at `outline-default-state' level.
|
|
|
|
|
|
2022-01-17 19:20:28 +00:00
|
|
|
|
The rules apply if and only if `outline-default-state' is a
|
|
|
|
|
number.
|
|
|
|
|
|
2022-01-16 18:13:21 +00:00
|
|
|
|
When nil, the subtree is hidden unconditionally.
|
|
|
|
|
|
|
|
|
|
When equal to a list, each element should be one of the following:
|
|
|
|
|
|
|
|
|
|
- A cons cell with CAR `match-regexp' and CDR a regexp, the
|
|
|
|
|
subtree will be hidden when the outline heading match the
|
|
|
|
|
regexp.
|
|
|
|
|
|
|
|
|
|
- `subtree-has-long-lines' to only show the heading branches when
|
|
|
|
|
long lines are detected in its subtree (see
|
|
|
|
|
`outline-default-long-line' for the definition of long lines).
|
|
|
|
|
|
|
|
|
|
- `subtree-is-long' to only show the heading branches when its
|
|
|
|
|
subtree contains more than `outline-default-line-count' lines.
|
|
|
|
|
|
2022-01-17 19:20:28 +00:00
|
|
|
|
- A cons cell of the form (custom-function . FUNCTION) where
|
|
|
|
|
FUNCTION is a lambda function or function name which will be
|
|
|
|
|
called without arguments with point at the beginning of the
|
|
|
|
|
heading and the match data set appropriately, the function
|
|
|
|
|
being expected to toggle the heading visibility."
|
2022-01-16 18:13:21 +00:00
|
|
|
|
:version "29.1"
|
|
|
|
|
:type '(choice (const :tag "Hide subtree" nil)
|
|
|
|
|
(set :tag "Show subtree unless"
|
|
|
|
|
(cons :tag "Heading match regexp"
|
|
|
|
|
(const match-regexp) string)
|
|
|
|
|
(const :tag "Subtree has long lines"
|
|
|
|
|
subtree-has-long-lines)
|
|
|
|
|
(const :tag "Subtree is long"
|
|
|
|
|
subtree-is-long)
|
|
|
|
|
(cons :tag "Custom function"
|
|
|
|
|
(const custom-function) function))))
|
|
|
|
|
|
|
|
|
|
(defcustom outline-default-long-line 1000
|
|
|
|
|
"Minimal number of characters in a line for a heading to be outlined."
|
|
|
|
|
:version "29.1"
|
|
|
|
|
:type '(natnum :tag "Number of characters"))
|
|
|
|
|
|
|
|
|
|
(defcustom outline-default-line-count 50
|
|
|
|
|
"Minimal number of lines for a heading to be outlined."
|
|
|
|
|
:version "29.1"
|
|
|
|
|
:type '(natnum :tag "Number of lines"))
|
|
|
|
|
|
|
|
|
|
(defun outline-apply-default-state ()
|
|
|
|
|
"Apply the outline state defined by `outline-default-state'."
|
|
|
|
|
(interactive)
|
|
|
|
|
(cond
|
|
|
|
|
((integerp outline-default-state)
|
|
|
|
|
(outline--show-headings-up-to-level outline-default-state))
|
|
|
|
|
((functionp outline-default-state)
|
|
|
|
|
(funcall outline-default-state))))
|
|
|
|
|
|
|
|
|
|
(defun outline-show-only-headings ()
|
|
|
|
|
"Show only headings."
|
|
|
|
|
(interactive)
|
|
|
|
|
(outline-show-all)
|
|
|
|
|
(outline-hide-region-body (point-min) (point-max)))
|
|
|
|
|
|
|
|
|
|
(eval-when-compile (require 'so-long))
|
|
|
|
|
(autoload 'so-long-detected-long-line-p "so-long")
|
|
|
|
|
(defvar so-long-skip-leading-comments)
|
|
|
|
|
(defvar so-long-threshold)
|
|
|
|
|
(defvar so-long-max-lines)
|
|
|
|
|
|
|
|
|
|
(defun outline--show-headings-up-to-level (level)
|
|
|
|
|
"Show only headings up to a LEVEL level.
|
|
|
|
|
|
|
|
|
|
Like `outline-hide-sublevels' but, for each heading at level
|
|
|
|
|
LEVEL, decides of subtree visibility according to
|
|
|
|
|
`outline-default-rules'."
|
|
|
|
|
(if (not outline-default-rules)
|
|
|
|
|
(outline-hide-sublevels level)
|
|
|
|
|
(if (< level 1)
|
|
|
|
|
(error "Must keep at least one level of headers"))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(let* (outline-view-change-hook
|
|
|
|
|
(beg (progn
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
;; Skip the prelude, if any.
|
|
|
|
|
(unless (outline-on-heading-p t) (outline-next-heading))
|
|
|
|
|
(point)))
|
|
|
|
|
(end (progn
|
|
|
|
|
(goto-char (point-max))
|
|
|
|
|
;; Keep empty last line, if available.
|
|
|
|
|
(if (bolp) (1- (point)) (point))))
|
|
|
|
|
(heading-regexp
|
|
|
|
|
(cdr-safe
|
|
|
|
|
(assoc 'match-regexp outline-default-rules)))
|
|
|
|
|
(check-line-count
|
|
|
|
|
(memq 'subtree-is-long outline-default-rules))
|
|
|
|
|
(check-long-lines
|
|
|
|
|
(memq 'subtree-has-long-lines outline-default-rules))
|
|
|
|
|
(custom-function
|
|
|
|
|
(cdr-safe
|
|
|
|
|
(assoc 'custom-function outline-default-rules))))
|
|
|
|
|
(if (< end beg)
|
|
|
|
|
(setq beg (prog1 end (setq end beg))))
|
|
|
|
|
;; First hide everything.
|
|
|
|
|
(outline-hide-sublevels level)
|
|
|
|
|
;; Then unhide the top level headers.
|
|
|
|
|
(outline-map-region
|
|
|
|
|
(lambda ()
|
|
|
|
|
(let ((current-level (funcall outline-level)))
|
|
|
|
|
(when (< current-level level)
|
|
|
|
|
(outline-show-heading)
|
|
|
|
|
(outline-show-entry))
|
|
|
|
|
(when (= current-level level)
|
|
|
|
|
(cond
|
|
|
|
|
((and heading-regexp
|
|
|
|
|
(let ((beg (point))
|
|
|
|
|
(end (progn (outline-end-of-heading) (point))))
|
|
|
|
|
(string-match-p heading-regexp (buffer-substring beg end))))
|
|
|
|
|
;; hide entry when heading match regexp
|
|
|
|
|
(outline-hide-entry))
|
|
|
|
|
((and check-line-count
|
|
|
|
|
(save-excursion
|
|
|
|
|
(let ((beg (point))
|
|
|
|
|
(end (progn (outline-end-of-subtree) (point))))
|
|
|
|
|
(<= outline-default-line-count (count-lines beg end)))))
|
|
|
|
|
;; show only branches when line count of subtree >
|
|
|
|
|
;; threshold
|
|
|
|
|
(outline-show-branches))
|
|
|
|
|
((and check-long-lines
|
|
|
|
|
(save-excursion
|
|
|
|
|
(let ((beg (point))
|
|
|
|
|
(end (progn (outline-end-of-subtree) (point))))
|
|
|
|
|
(save-restriction
|
|
|
|
|
(narrow-to-region beg end)
|
|
|
|
|
(let ((so-long-skip-leading-comments nil)
|
|
|
|
|
(so-long-threshold outline-default-long-line)
|
|
|
|
|
(so-long-max-lines nil))
|
|
|
|
|
(so-long-detected-long-line-p))))))
|
|
|
|
|
;; show only branches when long lines are detected
|
|
|
|
|
;; in subtree
|
|
|
|
|
(outline-show-branches))
|
|
|
|
|
(custom-function
|
|
|
|
|
;; call custom function if defined
|
|
|
|
|
(funcall custom-function))
|
|
|
|
|
(t
|
|
|
|
|
;; if no previous clause succeeds, show subtree
|
|
|
|
|
(outline-show-subtree))))))
|
|
|
|
|
beg end)))
|
|
|
|
|
(run-hooks 'outline-view-change-hook)))
|
|
|
|
|
|
2020-10-13 03:14:21 +00:00
|
|
|
|
(defun outline--cycle-state ()
|
|
|
|
|
"Return the cycle state of current heading.
|
2022-04-22 14:17:22 +00:00
|
|
|
|
Return either `hide-all', `headings-only', or `show-all'."
|
2020-10-13 03:14:21 +00:00
|
|
|
|
(save-excursion
|
|
|
|
|
(let (start end ov-list heading-end)
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(setq start (point))
|
|
|
|
|
(outline-end-of-heading)
|
|
|
|
|
(setq heading-end (point))
|
|
|
|
|
(outline-end-of-subtree)
|
|
|
|
|
(setq end (point))
|
2020-11-24 05:08:59 +00:00
|
|
|
|
(setq ov-list
|
|
|
|
|
(seq-filter
|
|
|
|
|
(lambda (o)
|
|
|
|
|
(and (eq (overlay-get o 'invisible) 'outline)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (overlay-start o))
|
|
|
|
|
(outline-on-heading-p t))))
|
|
|
|
|
(overlays-in start end)))
|
|
|
|
|
(cond ((null ov-list) 'show-all)
|
|
|
|
|
((and (or (= end (point-max)
|
|
|
|
|
(1+ (overlay-end (car ov-list))))
|
|
|
|
|
(= (overlay-end (car ov-list)) end))
|
|
|
|
|
(= (overlay-start (car ov-list)) heading-end))
|
2020-10-13 03:14:21 +00:00
|
|
|
|
'hide-all)
|
|
|
|
|
(t 'headings-only)))))
|
|
|
|
|
|
|
|
|
|
(defun outline-has-subheading-p ()
|
|
|
|
|
"Return t if this heading has subheadings, nil otherwise."
|
|
|
|
|
(save-excursion
|
|
|
|
|
(outline-back-to-heading)
|
|
|
|
|
(< (save-excursion (outline-next-heading) (point))
|
|
|
|
|
(save-excursion (outline-end-of-subtree) (point)))))
|
|
|
|
|
|
|
|
|
|
(defun outline-cycle ()
|
2022-04-16 07:56:01 +00:00
|
|
|
|
"Cycle visibility state of the current heading line's body.
|
2020-10-13 03:14:21 +00:00
|
|
|
|
|
2022-04-16 07:56:01 +00:00
|
|
|
|
This cycles the visibility of the current heading line's subheadings
|
|
|
|
|
and body between `hide all', `headings only' and `show all'.
|
|
|
|
|
|
|
|
|
|
`Hide all' means hide all the subheadings and their bodies.
|
|
|
|
|
`Headings only' means show the subheadings, but not their bodies.
|
|
|
|
|
`Show all' means show all the subheadings and their bodies."
|
2020-10-13 03:14:21 +00:00
|
|
|
|
(interactive)
|
2020-10-19 08:45:14 +00:00
|
|
|
|
(condition-case nil
|
|
|
|
|
(pcase (outline--cycle-state)
|
|
|
|
|
('hide-all
|
|
|
|
|
(if (outline-has-subheading-p)
|
|
|
|
|
(progn (outline-show-children)
|
|
|
|
|
(message "Only headings"))
|
|
|
|
|
(outline-show-subtree)
|
|
|
|
|
(message "Show all")))
|
|
|
|
|
('headings-only
|
|
|
|
|
(outline-show-subtree)
|
|
|
|
|
(message "Show all"))
|
|
|
|
|
('show-all
|
|
|
|
|
(outline-hide-subtree)
|
|
|
|
|
(message "Hide all")))
|
|
|
|
|
(outline-before-first-heading nil)))
|
2020-10-13 03:14:21 +00:00
|
|
|
|
|
|
|
|
|
(defvar-local outline--cycle-buffer-state 'show-all
|
|
|
|
|
"Internal variable used for tracking buffer cycle state.")
|
|
|
|
|
|
|
|
|
|
(defun outline-cycle-buffer ()
|
2022-04-16 07:56:01 +00:00
|
|
|
|
"Cycle visibility state of the body lines of the whole buffer.
|
|
|
|
|
|
|
|
|
|
This cycles the visibility of all the subheadings and bodies of all
|
|
|
|
|
the heading lines in the buffer. It cycles them between `hide all',
|
|
|
|
|
`headings only' and `show all'.
|
|
|
|
|
|
|
|
|
|
`Hide all' means hide all the buffer's subheadings and their bodies.
|
|
|
|
|
`Headings only' means show all the subheadings, but not their bodies.
|
|
|
|
|
`Show all' means show all the buffer's subheadings and their bodies."
|
2020-10-13 03:14:21 +00:00
|
|
|
|
(interactive)
|
2020-11-24 05:08:59 +00:00
|
|
|
|
(let (has-top-level)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(while (not (or has-top-level (eobp)))
|
|
|
|
|
(when (outline-on-heading-p t)
|
|
|
|
|
(when (= (funcall outline-level) 1)
|
|
|
|
|
(setq has-top-level t)))
|
|
|
|
|
(outline-next-heading)))
|
|
|
|
|
(cond
|
|
|
|
|
((and (eq outline--cycle-buffer-state 'show-all)
|
|
|
|
|
has-top-level)
|
|
|
|
|
(outline-hide-sublevels 1)
|
|
|
|
|
(setq outline--cycle-buffer-state 'top-level)
|
|
|
|
|
(message "Top level headings"))
|
|
|
|
|
((or (eq outline--cycle-buffer-state 'show-all)
|
|
|
|
|
(eq outline--cycle-buffer-state 'top-level))
|
|
|
|
|
(outline-show-all)
|
|
|
|
|
(outline-hide-region-body (point-min) (point-max))
|
|
|
|
|
(setq outline--cycle-buffer-state 'all-heading)
|
|
|
|
|
(message "All headings"))
|
|
|
|
|
(t
|
|
|
|
|
(outline-show-all)
|
|
|
|
|
(setq outline--cycle-buffer-state 'show-all)
|
2021-10-31 22:13:52 +00:00
|
|
|
|
(message "Show all")))
|
2021-11-06 18:49:07 +00:00
|
|
|
|
(outline--fix-up-all-buttons)))
|
2020-10-13 03:14:21 +00:00
|
|
|
|
|
2021-04-21 20:17:27 +00:00
|
|
|
|
(defvar outline-navigation-repeat-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map (kbd "C-b") #'outline-backward-same-level)
|
|
|
|
|
(define-key map (kbd "b") #'outline-backward-same-level)
|
|
|
|
|
(define-key map (kbd "C-f") #'outline-forward-same-level)
|
|
|
|
|
(define-key map (kbd "f") #'outline-forward-same-level)
|
|
|
|
|
(define-key map (kbd "C-n") #'outline-next-visible-heading)
|
|
|
|
|
(define-key map (kbd "n") #'outline-next-visible-heading)
|
|
|
|
|
(define-key map (kbd "C-p") #'outline-previous-visible-heading)
|
|
|
|
|
(define-key map (kbd "p") #'outline-previous-visible-heading)
|
|
|
|
|
(define-key map (kbd "C-u") #'outline-up-heading)
|
|
|
|
|
(define-key map (kbd "u") #'outline-up-heading)
|
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
(dolist (command '(outline-backward-same-level
|
|
|
|
|
outline-forward-same-level
|
|
|
|
|
outline-next-visible-heading
|
|
|
|
|
outline-previous-visible-heading
|
|
|
|
|
outline-up-heading))
|
|
|
|
|
(put command 'repeat-map 'outline-navigation-repeat-map))
|
|
|
|
|
|
|
|
|
|
(defvar outline-editing-repeat-map
|
|
|
|
|
(let ((map (make-sparse-keymap)))
|
|
|
|
|
(define-key map (kbd "C-v") #'outline-move-subtree-down)
|
|
|
|
|
(define-key map (kbd "v") #'outline-move-subtree-down)
|
|
|
|
|
(define-key map (kbd "C-^") #'outline-move-subtree-up)
|
|
|
|
|
(define-key map (kbd "^") #'outline-move-subtree-up)
|
|
|
|
|
(define-key map (kbd "C->") #'outline-demote)
|
|
|
|
|
(define-key map (kbd ">") #'outline-demote)
|
|
|
|
|
(define-key map (kbd "C-<") #'outline-promote)
|
|
|
|
|
(define-key map (kbd "<") #'outline-promote)
|
|
|
|
|
map))
|
|
|
|
|
|
|
|
|
|
(dolist (command '(outline-move-subtree-down
|
|
|
|
|
outline-move-subtree-up
|
|
|
|
|
outline-demote
|
|
|
|
|
outline-promote))
|
|
|
|
|
(put command 'repeat-map 'outline-editing-repeat-map))
|
|
|
|
|
|
2003-05-30 23:30:10 +00:00
|
|
|
|
(provide 'outline)
|
|
|
|
|
(provide 'noutline)
|
|
|
|
|
|
|
|
|
|
;;; outline.el ends here
|