aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/textmodes
diff options
context:
space:
mode:
authorStefan Monnier2003-03-13 18:15:07 +0000
committerStefan Monnier2003-03-13 18:15:07 +0000
commit21a3d3e7c97da660fd5c45b9d0d2c5a969b2e3b7 (patch)
tree9de02d72b366996402a5e0fb77af33565fc3b0d1 /lisp/textmodes
parentdf380962210bb5f655f9ad80b38e88a8254b6b61 (diff)
downloademacs-21a3d3e7c97da660fd5c45b9d0d2c5a969b2e3b7.tar.gz
emacs-21a3d3e7c97da660fd5c45b9d0d2c5a969b2e3b7.zip
(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.
Diffstat (limited to 'lisp/textmodes')
-rw-r--r--lisp/textmodes/outline.el226
1 files changed, 152 insertions, 74 deletions
diff --git a/lisp/textmodes/outline.el b/lisp/textmodes/outline.el
index ffb9c3bd881..fe8f747cb99 100644
--- a/lisp/textmodes/outline.el
+++ b/lisp/textmodes/outline.el
@@ -80,9 +80,12 @@ in the file it applies to."
80 (define-key map "\C-k" 'show-branches) 80 (define-key map "\C-k" 'show-branches)
81 (define-key map "\C-q" 'hide-sublevels) 81 (define-key map "\C-q" 'hide-sublevels)
82 (define-key map "\C-o" 'hide-other) 82 (define-key map "\C-o" 'hide-other)
83 (define-key map "\C-^" 'outline-promote) 83 (define-key map "\C-^" 'outline-move-subtree-up)
84 (define-key map "\C-v" 'outline-demote) 84 (define-key map "\C-v" 'outline-move-subtree-down)
85 ;; Where to bind toggle and insert-heading ? 85 (define-key map [(control ?<)] 'outline-promote)
86 (define-key map [(control ?>)] 'outline-demote)
87 (define-key map "\C-m" 'outline-insert-heading)
88 ;; Where to bind outline-cycle ?
86 map)) 89 map))
87 90
88(defvar outline-mode-menu-bar-map 91(defvar outline-mode-menu-bar-map
@@ -108,9 +111,19 @@ in the file it applies to."
108 (define-key map [headings] 111 (define-key map [headings]
109 (cons "Headings" (make-sparse-keymap "Headings"))) 112 (cons "Headings" (make-sparse-keymap "Headings")))
110 113
114 (define-key map [headings demote-subtree]
115 '(menu-item "Demote subtree" outline-demote))
116 (define-key map [headings promote-subtree]
117 '(menu-item "Promote subtree" outline-promote))
118 (define-key map [headings move-subtree-down]
119 '(menu-item "Move subtree down" outline-move-subtree-down))
120 (define-key map [headings move-subtree-up]
121 '(menu-item "Move subtree up" outline-move-subtree-up))
111 (define-key map [headings copy] 122 (define-key map [headings copy]
112 '(menu-item "Copy to kill ring" outline-headers-as-kill 123 '(menu-item "Copy to kill ring" outline-headers-as-kill
113 :enable mark-active)) 124 :enable mark-active))
125 (define-key map [headings outline-insert-heading]
126 '("New heading" . outline-insert-heading))
114 (define-key map [headings outline-backward-same-level] 127 (define-key map [headings outline-backward-same-level]
115 '("Previous Same Level" . outline-backward-same-level)) 128 '("Previous Same Level" . outline-backward-same-level))
116 (define-key map [headings outline-forward-same-level] 129 (define-key map [headings outline-forward-same-level]
@@ -139,7 +152,7 @@ in the file it applies to."
139 (cons '(--- "---") (cdr x)))) 152 (cons '(--- "---") (cdr x))))
140 outline-mode-menu-bar-map)))))) 153 outline-mode-menu-bar-map))))))
141 map)) 154 map))
142 155
143 156
144(defvar outline-mode-map 157(defvar outline-mode-map
145 (let ((map (make-sparse-keymap))) 158 (let ((map (make-sparse-keymap)))
@@ -339,9 +352,9 @@ at the end of the buffer."
339 (re-search-backward (concat "^\\(?:" outline-regexp "\\)") 352 (re-search-backward (concat "^\\(?:" outline-regexp "\\)")
340 nil 'move)) 353 nil 'move))
341 354
342(defsubst outline-invisible-p () 355(defsubst outline-invisible-p (&optional pos)
343 "Non-nil if the character after point is invisible." 356 "Non-nil if the character after point is invisible."
344 (get-char-property (point) 'invisible)) 357 (get-char-property (or pos (point)) 'invisible))
345 358
346(defun outline-visible () 359(defun outline-visible ()
347 (not (outline-invisible-p))) 360 (not (outline-invisible-p)))
@@ -391,75 +404,144 @@ If INVISIBLE-OK is non-nil, an invisible heading line is ok too."
391 (run-hooks 'outline-insert-heading-hook))) 404 (run-hooks 'outline-insert-heading-hook)))
392 405
393(defun outline-promote (&optional children) 406(defun outline-promote (&optional children)
394 "Promote the current heading higher up the tree. 407 "Promote headings higher up the tree.
395If prefix argument CHILDREN is given, promote also all the children." 408If prefix argument CHILDREN is given, promote also all the children.
396 (interactive "P") 409If the region is active in `transient-mark-mode', promote all headings
397 (outline-back-to-heading) 410in the region."
398 (let* ((head (match-string 0)) 411 (interactive
399 (level (save-match-data (funcall outline-level))) 412 (list (if (and transient-mark-mode mark-active) 'region
400 (up-head (or (car (rassoc (1- level) outline-heading-alist)) 413 (outline-back-to-heading)
401 (save-excursion 414 (if current-prefix-arg nil 'subtree))))
402 (save-match-data 415 (cond
403 (outline-up-heading 1 t) 416 ((eq children 'region)
404 (match-string 0)))))) 417 (outline-map-region 'outline-promote (region-beginning) (region-end)))
405 418 (children
406 (unless (rassoc level outline-heading-alist) 419 (outline-map-region 'outline-promote
407 (push (cons head level) outline-heading-alist)) 420 (point)
408 421 (save-excursion (outline-get-next-sibling) (point))))
409 (replace-match up-head nil t) 422 (t
410 (when children 423 (outline-back-to-heading t)
411 (outline-map-tree 'outline-promote level)))) 424 (let* ((head (match-string 0))
425 (level (save-match-data (funcall outline-level)))
426 (up-head (or (car (rassoc (1- level) outline-heading-alist))
427 (save-excursion
428 (save-match-data
429 (outline-up-heading 1 t)
430 (match-string 0))))))
431
432 (unless (rassoc level outline-heading-alist)
433 (push (cons head level) outline-heading-alist))
434
435 (replace-match up-head nil t)))))
412 436
413(defun outline-demote (&optional children) 437(defun outline-demote (&optional children)
414 "Demote the current heading lower down the tree. 438 "Demote headings lower down the tree.
415If prefix argument CHILDREN is given, demote also all the children." 439If prefix argument CHILDREN is given, demote also all the children.
416 (interactive "P") 440If the region is active in `transient-mark-mode', demote all headings
417 (outline-back-to-heading) 441in the region."
418 (let* ((head (match-string 0)) 442 (interactive
419 (level (save-match-data (funcall outline-level))) 443 (list (if (and transient-mark-mode mark-active) 'region
420 (down-head 444 (outline-back-to-heading)
421 (or (car (rassoc (1+ level) outline-heading-alist)) 445 (if current-prefix-arg nil 'subtree))))
422 (save-excursion 446 (cond
423 (save-match-data 447 ((eq children 'region)
424 (while (and (not (eobp)) 448 (outline-map-region 'outline-demote (region-beginning) (region-end)))
425 (progn 449 (children
426 (outline-next-heading) 450 (outline-map-region 'outline-demote
427 (<= (funcall outline-level) level)))) 451 (point)
428 (when (eobp) 452 (save-excursion (outline-get-next-sibling) (point))))
429 ;; Try again from the beginning of the buffer. 453 (t
430 (goto-char (point-min)) 454 (let* ((head (match-string 0))
455 (level (save-match-data (funcall outline-level)))
456 (down-head
457 (or (car (rassoc (1+ level) outline-heading-alist))
458 (save-excursion
459 (save-match-data
431 (while (and (not (eobp)) 460 (while (and (not (eobp))
432 (progn 461 (progn
433 (outline-next-heading) 462 (outline-next-heading)
434 (<= (funcall outline-level) level))))) 463 (<= (funcall outline-level) level))))
435 (unless (eobp) 464 (when (eobp)
436 (looking-at outline-regexp) 465 ;; Try again from the beginning of the buffer.
437 (match-string 0)))) 466 (goto-char (point-min))
438 (save-match-data 467 (while (and (not (eobp))
439 ;; Bummer!! There is no lower heading in the buffer. 468 (progn
440 ;; Let's try to invent one by repeating the first char. 469 (outline-next-heading)
441 (let ((new-head (concat (substring head 0 1) head))) 470 (<= (funcall outline-level) level)))))
442 (if (string-match (concat "\\`" outline-regexp) new-head) 471 (unless (eobp)
443 ;; Why bother checking that it is indeed of lower level ? 472 (looking-at outline-regexp)
444 new-head 473 (match-string 0))))
445 ;; Didn't work: keep it as is so it's still a heading. 474 (save-match-data
446 head)))))) 475 ;; Bummer!! There is no lower heading in the buffer.
476 ;; Let's try to invent one by repeating the first char.
477 (let ((new-head (concat (substring head 0 1) head)))
478 (if (string-match (concat "\\`" outline-regexp) new-head)
479 ;; Why bother checking that it is indeed lower level ?
480 new-head
481 ;; Didn't work: keep it as is so it's still a heading.
482 head))))))
447 483
448 (unless (rassoc level outline-heading-alist) 484 (unless (rassoc level outline-heading-alist)
449 (push (cons head level) outline-heading-alist)) 485 (push (cons head level) outline-heading-alist))
486 (replace-match down-head nil t)))))
450 487
451 (replace-match down-head nil t) 488(defun outline-map-region (fun beg end)
452 (when children 489 "Call FUN for every heading between BEG and END.
453 (outline-map-tree 'outline-demote level)))) 490When FUN is called, point is at the beginning of the heading and
454 491the match data is set appropriately."
455(defun outline-map-tree (fun level)
456 "Call FUN for every heading underneath the current one."
457 (save-excursion 492 (save-excursion
458 (while (and (progn 493 (setq end (copy-marker end))
459 (outline-next-heading) 494 (goto-char beg)
460 (> (funcall outline-level) level)) 495 (when (re-search-forward (concat "^\\(?:" outline-regexp "\\)") end t)
461 (not (eobp))) 496 (goto-char (match-beginning 0))
462 (funcall fun)))) 497 (funcall fun)
498 (while (and (progn
499 (outline-next-heading)
500 (< (point) end))
501 (not (eobp)))
502 (funcall fun)))))
503
504;; Vertical tree motion
505
506(defun outline-move-subtree-up (&optional arg)
507 "Move the currrent subtree up past ARG headlines of the same level."
508 (interactive "p")
509 (outline-move-subtree-down (- arg)))
510
511(defun outline-move-subtree-down (&optional arg)
512 "Move the currrent subtree down past ARG headlines of the same level."
513 (interactive "p")
514 (let ((re (concat "^" outline-regexp))
515 (movfunc (if (> arg 0) 'outline-get-next-sibling
516 'outline-get-last-sibling))
517 (ins-point (make-marker))
518 (cnt (abs arg))
519 beg end txt folded)
520 ;; Select the tree
521 (outline-back-to-heading)
522 (setq beg (point))
523 (save-match-data
524 (save-excursion (outline-end-of-heading)
525 (setq folded (outline-invisible-p)))
526 (outline-end-of-subtree))
527 (if (= (char-after) ?\n) (forward-char 1))
528 (setq end (point))
529 ;; Find insertion point, with error handling
530 (goto-char beg)
531 (while (> cnt 0)
532 (or (funcall movfunc)
533 (progn (goto-char beg)
534 (error "Cannot move past superior level")))
535 (setq cnt (1- cnt)))
536 (if (> arg 0)
537 ;; Moving forward - still need to move over subtree
538 (progn (outline-end-of-subtree)
539 (if (= (char-after) ?\n) (forward-char 1))))
540 (move-marker ins-point (point))
541 (insert (delete-and-extract-region beg end))
542 (goto-char ins-point)
543 (if folded (hide-subtree))
544 (move-marker ins-point nil)))
463 545
464(defun outline-end-of-heading () 546(defun outline-end-of-heading ()
465 (if (re-search-forward outline-heading-end-regexp nil 'move) 547 (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
484 (while (and (not (eobp)) 566 (while (and (not (eobp))
485 (re-search-forward (concat "^\\(?:" outline-regexp "\\)") 567 (re-search-forward (concat "^\\(?:" outline-regexp "\\)")
486 nil 'move) 568 nil 'move)
487 (save-excursion 569 (outline-invisible-p (match-beginning 0))))
488 (goto-char (match-beginning 0))
489 (outline-invisible-p))))
490 (setq arg (1- arg))) 570 (setq arg (1- arg)))
491 (beginning-of-line)) 571 (beginning-of-line))
492 572
@@ -534,7 +614,7 @@ If FLAG is nil then text is shown, while if FLAG is t the text is hidden."
534 ;; reveal do the rest, by simply doing: 614 ;; reveal do the rest, by simply doing:
535 ;; (remove-overlays (overlay-start o) (overlay-end o) 615 ;; (remove-overlays (overlay-start o) (overlay-end o)
536 ;; 'invisible 'outline) 616 ;; 'invisible 'outline)
537 ;; 617 ;;
538 ;; That works fine as long as everything is in sync, but if the 618 ;; That works fine as long as everything is in sync, but if the
539 ;; structure of the document is changed while revealing parts of it, 619 ;; structure of the document is changed while revealing parts of it,
540 ;; the resulting behavior can be ugly. I.e. we need to make 620 ;; 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."
681 "Show or hide the current subtree depending on its current state." 761 "Show or hide the current subtree depending on its current state."
682 (interactive) 762 (interactive)
683 (outline-back-to-heading) 763 (outline-back-to-heading)
684 (if (save-excursion 764 (if (not (outline-invisible-p (line-end-position)))
685 (end-of-line)
686 (not (outline-invisible-p)))
687 (hide-subtree) 765 (hide-subtree)
688 (show-children) 766 (show-children)
689 (show-entry))) 767 (show-entry)))
@@ -754,7 +832,7 @@ Default is enough to cause the following heading to appear."
754 (point)) 832 (point))
755 (progn (outline-end-of-heading) (point)) 833 (progn (outline-end-of-heading) (point))
756 nil))))))) 834 nil)))))))
757 (run-hooks 'outline-view-change-hook)) 835 (run-hooks 'outline-view-change-hook))
758 836
759 837
760 838
@@ -801,7 +879,7 @@ Stop at the first and last subheadings of a superior heading."
801 (while (and (> (funcall outline-level) level) 879 (while (and (> (funcall outline-level) level)
802 (not (eobp))) 880 (not (eobp)))
803 (outline-next-visible-heading 1)) 881 (outline-next-visible-heading 1))
804 (if (< (funcall outline-level) level) 882 (if (or (eobp) (< (funcall outline-level) level))
805 nil 883 nil
806 (point)))) 884 (point))))
807 885