1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-02-07 08:00:48 -08:00

(outline-mode-menu-bar-map): Add entries.

(outline-mode-prefix-map): Match new bindings to those of allout.
(outline-map-region): New fun.
(outline-map-tree): Remove.
(outline-promote, outline-demote): Apply to region if active.
Change the default to apply to the subtree.
(outline-move-subtree-up, outline-move-subtree-down): New funs.
(outline-invisible-p): Add optional `pos' argument.
(outline-next-visible-heading, outline-toggle-children): Use it.
(outline-get-next-sibling): Don't call outline-level at eob.
This commit is contained in:
Stefan Monnier 2003-03-13 18:15:07 +00:00
parent df38096221
commit 21a3d3e7c9

View file

@ -80,9 +80,12 @@ in the file it applies to."
(define-key map "\C-k" 'show-branches)
(define-key map "\C-q" 'hide-sublevels)
(define-key map "\C-o" 'hide-other)
(define-key map "\C-^" 'outline-promote)
(define-key map "\C-v" 'outline-demote)
;; Where to bind toggle and insert-heading ?
(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)
;; Where to bind outline-cycle ?
map))
(defvar outline-mode-menu-bar-map
@ -108,9 +111,19 @@ in the file it applies to."
(define-key map [headings]
(cons "Headings" (make-sparse-keymap "Headings")))
(define-key map [headings demote-subtree]
'(menu-item "Demote subtree" outline-demote))
(define-key map [headings promote-subtree]
'(menu-item "Promote subtree" outline-promote))
(define-key map [headings move-subtree-down]
'(menu-item "Move subtree down" outline-move-subtree-down))
(define-key map [headings move-subtree-up]
'(menu-item "Move subtree up" outline-move-subtree-up))
(define-key map [headings copy]
'(menu-item "Copy to kill ring" outline-headers-as-kill
:enable mark-active))
(define-key map [headings outline-insert-heading]
'("New heading" . outline-insert-heading))
(define-key map [headings outline-backward-same-level]
'("Previous Same Level" . outline-backward-same-level))
(define-key map [headings outline-forward-same-level]
@ -139,7 +152,7 @@ in the file it applies to."
(cons '(--- "---") (cdr x))))
outline-mode-menu-bar-map))))))
map))
(defvar outline-mode-map
(let ((map (make-sparse-keymap)))
@ -339,9 +352,9 @@ at the end of the buffer."
(re-search-backward (concat "^\\(?:" outline-regexp "\\)")
nil 'move))
(defsubst outline-invisible-p ()
(defsubst outline-invisible-p (&optional pos)
"Non-nil if the character after point is invisible."
(get-char-property (point) 'invisible))
(get-char-property (or pos (point)) 'invisible))
(defun outline-visible ()
(not (outline-invisible-p)))
@ -391,75 +404,144 @@ If INVISIBLE-OK is non-nil, an invisible heading line is ok too."
(run-hooks 'outline-insert-heading-hook)))
(defun outline-promote (&optional children)
"Promote the current heading higher up the tree.
If prefix argument CHILDREN is given, promote also all the children."
(interactive "P")
(outline-back-to-heading)
(let* ((head (match-string 0))
(level (save-match-data (funcall outline-level)))
(up-head (or (car (rassoc (1- level) outline-heading-alist))
(save-excursion
(save-match-data
(outline-up-heading 1 t)
(match-string 0))))))
(unless (rassoc level outline-heading-alist)
(push (cons head level) outline-heading-alist))
(replace-match up-head nil t)
(when children
(outline-map-tree 'outline-promote level))))
"Promote headings higher up the tree.
If prefix argument CHILDREN is given, promote also all the children.
If the region is active in `transient-mark-mode', promote all headings
in the region."
(interactive
(list (if (and transient-mark-mode mark-active) 'region
(outline-back-to-heading)
(if current-prefix-arg nil 'subtree))))
(cond
((eq children 'region)
(outline-map-region 'outline-promote (region-beginning) (region-end)))
(children
(outline-map-region 'outline-promote
(point)
(save-excursion (outline-get-next-sibling) (point))))
(t
(outline-back-to-heading t)
(let* ((head (match-string 0))
(level (save-match-data (funcall outline-level)))
(up-head (or (car (rassoc (1- level) outline-heading-alist))
(save-excursion
(save-match-data
(outline-up-heading 1 t)
(match-string 0))))))
(unless (rassoc level outline-heading-alist)
(push (cons head level) outline-heading-alist))
(replace-match up-head nil t)))))
(defun outline-demote (&optional children)
"Demote the current heading lower down the tree.
If prefix argument CHILDREN is given, demote also all the children."
(interactive "P")
(outline-back-to-heading)
(let* ((head (match-string 0))
(level (save-match-data (funcall outline-level)))
(down-head
(or (car (rassoc (1+ level) outline-heading-alist))
(save-excursion
(save-match-data
(while (and (not (eobp))
(progn
(outline-next-heading)
(<= (funcall outline-level) level))))
(when (eobp)
;; Try again from the beginning of the buffer.
(goto-char (point-min))
"Demote headings lower down the tree.
If prefix argument CHILDREN is given, demote also all the children.
If the region is active in `transient-mark-mode', demote all headings
in the region."
(interactive
(list (if (and transient-mark-mode mark-active) 'region
(outline-back-to-heading)
(if current-prefix-arg nil 'subtree))))
(cond
((eq children 'region)
(outline-map-region 'outline-demote (region-beginning) (region-end)))
(children
(outline-map-region 'outline-demote
(point)
(save-excursion (outline-get-next-sibling) (point))))
(t
(let* ((head (match-string 0))
(level (save-match-data (funcall outline-level)))
(down-head
(or (car (rassoc (1+ level) outline-heading-alist))
(save-excursion
(save-match-data
(while (and (not (eobp))
(progn
(outline-next-heading)
(<= (funcall outline-level) level)))))
(unless (eobp)
(looking-at outline-regexp)
(match-string 0))))
(save-match-data
;; Bummer!! There is no lower heading in the buffer.
;; Let's try to invent one by repeating the first char.
(let ((new-head (concat (substring head 0 1) head)))
(if (string-match (concat "\\`" outline-regexp) new-head)
;; Why bother checking that it is indeed of lower level ?
new-head
;; Didn't work: keep it as is so it's still a heading.
head))))))
(<= (funcall outline-level) level))))
(when (eobp)
;; Try again from the beginning of the buffer.
(goto-char (point-min))
(while (and (not (eobp))
(progn
(outline-next-heading)
(<= (funcall outline-level) level)))))
(unless (eobp)
(looking-at outline-regexp)
(match-string 0))))
(save-match-data
;; Bummer!! There is no lower heading in the buffer.
;; Let's try to invent one by repeating the first char.
(let ((new-head (concat (substring head 0 1) head)))
(if (string-match (concat "\\`" outline-regexp) new-head)
;; Why bother checking that it is indeed lower level ?
new-head
;; Didn't work: keep it as is so it's still a heading.
head))))))
(unless (rassoc level outline-heading-alist)
(push (cons head level) outline-heading-alist))
(replace-match down-head nil t)))))
(replace-match down-head nil t)
(when children
(outline-map-tree 'outline-demote level))))
(defun outline-map-tree (fun level)
"Call FUN for every heading underneath the current one."
(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
(while (and (progn
(outline-next-heading)
(> (funcall outline-level) level))
(not (eobp)))
(funcall fun))))
(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)
"Move the currrent subtree up past ARG headlines of the same level."
(interactive "p")
(outline-move-subtree-down (- arg)))
(defun outline-move-subtree-down (&optional arg)
"Move the currrent subtree down past ARG headlines of the same level."
(interactive "p")
(let ((re (concat "^" outline-regexp))
(movfunc (if (> arg 0) 'outline-get-next-sibling
'outline-get-last-sibling))
(ins-point (make-marker))
(cnt (abs arg))
beg end txt folded)
;; Select the tree
(outline-back-to-heading)
(setq beg (point))
(save-match-data
(save-excursion (outline-end-of-heading)
(setq folded (outline-invisible-p)))
(outline-end-of-subtree))
(if (= (char-after) ?\n) (forward-char 1))
(setq end (point))
;; Find insertion point, with error handling
(goto-char beg)
(while (> cnt 0)
(or (funcall movfunc)
(progn (goto-char beg)
(error "Cannot move past superior level")))
(setq cnt (1- cnt)))
(if (> arg 0)
;; Moving forward - still need to move over subtree
(progn (outline-end-of-subtree)
(if (= (char-after) ?\n) (forward-char 1))))
(move-marker ins-point (point))
(insert (delete-and-extract-region beg end))
(goto-char ins-point)
(if folded (hide-subtree))
(move-marker ins-point nil)))
(defun outline-end-of-heading ()
(if (re-search-forward outline-heading-end-regexp nil 'move)
@ -484,9 +566,7 @@ A heading line is one that starts with a `*' (or that
(while (and (not (eobp))
(re-search-forward (concat "^\\(?:" outline-regexp "\\)")
nil 'move)
(save-excursion
(goto-char (match-beginning 0))
(outline-invisible-p))))
(outline-invisible-p (match-beginning 0))))
(setq arg (1- arg)))
(beginning-of-line))
@ -534,7 +614,7 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
;; 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
@ -681,9 +761,7 @@ Show the heading too, if it is currently invisible."
"Show or hide the current subtree depending on its current state."
(interactive)
(outline-back-to-heading)
(if (save-excursion
(end-of-line)
(not (outline-invisible-p)))
(if (not (outline-invisible-p (line-end-position)))
(hide-subtree)
(show-children)
(show-entry)))
@ -754,7 +832,7 @@ Default is enough to cause the following heading to appear."
(point))
(progn (outline-end-of-heading) (point))
nil)))))))
(run-hooks 'outline-view-change-hook))
(run-hooks 'outline-view-change-hook))
@ -801,7 +879,7 @@ Stop at the first and last subheadings of a superior heading."
(while (and (> (funcall outline-level) level)
(not (eobp)))
(outline-next-visible-heading 1))
(if (< (funcall outline-level) level)
(if (or (eobp) (< (funcall outline-level) level))
nil
(point))))