From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: John J Foerch Newsgroups: gmane.emacs.devel Subject: Outline mode Date: Fri, 31 Aug 2007 12:30:41 -0400 Message-ID: <87odgnbr9q.fsf@earthlink.net> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1188577363 1426 80.91.229.12 (31 Aug 2007 16:22:43 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 31 Aug 2007 16:22:43 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Aug 31 18:22:41 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1IR9GX-0001yo-QP for ged-emacs-devel@m.gmane.org; Fri, 31 Aug 2007 18:22:38 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IR9GX-00059a-1Q for ged-emacs-devel@m.gmane.org; Fri, 31 Aug 2007 12:22:37 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IR9GT-00056a-1V for emacs-devel@gnu.org; Fri, 31 Aug 2007 12:22:33 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IR9GQ-000525-Gy for emacs-devel@gnu.org; Fri, 31 Aug 2007 12:22:32 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IR9GQ-00051v-8M for emacs-devel@gnu.org; Fri, 31 Aug 2007 12:22:30 -0400 Original-Received: from main.gmane.org ([80.91.229.2] helo=ciao.gmane.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1IR9GP-0000ui-LX for emacs-devel@gnu.org; Fri, 31 Aug 2007 12:22:30 -0400 Original-Received: from list by ciao.gmane.org with local (Exim 4.43) id 1IR9GI-0000Uy-S2 for emacs-devel@gnu.org; Fri, 31 Aug 2007 18:22:22 +0200 Original-Received: from dialup-4.158.60.148.dial1.chicago1.level3.net ([4.158.60.148]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 31 Aug 2007 18:22:22 +0200 Original-Received: from jjfoerch by dialup-4.158.60.148.dial1.chicago1.level3.net with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Fri, 31 Aug 2007 18:22:22 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 397 Original-X-Complaints-To: usenet@sea.gmane.org X-Gmane-NNTP-Posting-Host: dialup-4.158.60.148.dial1.chicago1.level3.net User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1.50 (gnu/linux) Cancel-Lock: sha1:xgWljJL9Sd2KvZSUdW/JlS553bo= X-Detected-Kernel: Linux 2.6, seldom 2.4 (older, 4) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:77497 Archived-At: --=-=-= Hello, Outline-mode has a problem that I would like to fix. To see the problem, hide an entry (C-c C-c) in an outline-mode buffer, and put point at the end of the heading with C-e. Point will then be located to the right of the ellipsis, and as far as emacs knows, point is on the last line of the hidden entry. Typing characters or hitting backspace, and many other commands will affect the last line of the entry. When an entry is collapsed in outline-mode, what actually gets marked invisible is everything from the newline of the heading to the character before the final newline of the entry. It would make more sense, if the newline of the heading were left visible, and the final newline of the entry were hidden. The ellipsis can be placed in the buffer by using the 'display property on the newline of the heading. The code attached to this email implement this behavior, and I hope you will try it out. However, there is a large problem with fixing outline-mode. The problem is that many of the modes that derive their behavior from outline-mode probably depend on the current way that entries are hidden. I am hoping that I can get advice from more experienced emacs developers on how to go about this project. I am also hoping to get help from the maintainers of as many of the derived modes as possible. Thank you, John Foerch aka RetroJ in #emacs --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=outline-patch.el Content-Transfer-Encoding: quoted-printable Content-Description: update for outline-mode ;new (defconst outline-ellipsis "...\n" "String to display in place of the newline character at the end of a heading whose text is hidden.") ;258 (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 (...). Commands:\\ \\[outline-next-visible-heading] outline-next-visible-heading move b= y visible headings \\[outline-previous-visible-heading] outline-previous-visible-heading \\[outline-forward-same-level] outline-forward-same-level similar = but skip subheadings \\[outline-backward-same-level] outline-backward-same-level \\[outline-up-heading] outline-up-heading move from subheading to he= ading \\[hide-body] make all text invisible (not headings). \\[show-all] make everything in buffer visible. \\[hide-sublevels] make only the first N levels of headers visible. The remaining commands are used when point is on a heading line. They apply to some of the body or subheadings of that heading. \\[hide-subtree] hide-subtree make body and subheadings invisible. \\[show-subtree] show-subtree make body and subheadings visible. \\[show-children] show-children make direct subheadings visible. No effect on body, or subheadings 2 or more levels down. With arg N, affects subheadings N levels down. \\[hide-entry] make immediately following body invisible. \\[show-entry] make it visible. \\[hide-leaves] make body under heading and under its subheadings invisi= ble. The subheadings remain visible. \\[show-branches] make all subheadings at all levels visible. 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." (make-local-variable 'line-move-ignore-invisible) (setq line-move-ignore-invisible t) ;; Cause use of ellipses for invisible text. (add-to-invisibility-spec '(outline)) (set (make-local-variable 'paragraph-start) (concat paragraph-start "\\|\\(?:" outline-regexp "\\)")) ;; Inhibit auto-filling of header lines. (set (make-local-variable 'auto-fill-inhibit-regexp) outline-regexp) (set (make-local-variable 'paragraph-separate) (concat paragraph-separate "\\|\\(?:" outline-regexp "\\)")) (set (make-local-variable 'font-lock-defaults) '(outline-font-lock-keywords t nil nil backward-paragraph)) (setq imenu-generic-expression (list (list nil (concat "^\\(?:" outline-regexp "\\).*$") 0))) (add-hook 'change-major-mode-hook 'show-all nil t)) ;322 (define-minor-mode outline-minor-mode "Toggle Outline minor mode. With arg, turn Outline minor mode on if arg is positive, off otherwise. See the command `outline-mode' for more information on this mode." nil " Outl" (list (cons [menu-bar] outline-minor-mode-menu-bar-map) (cons outline-minor-mode-prefix outline-mode-prefix-map)) :group 'outlines (if outline-minor-mode (progn ;; Turn off this mode if we change major modes. (add-hook 'change-major-mode-hook (lambda () (outline-minor-mode -1)) nil t) (set (make-local-variable 'line-move-ignore-invisible) t) (add-to-invisibility-spec '(outline))) (setq line-move-ignore-invisible nil) (remove-from-invisibility-spec '(outline)) ;; When turning off outline mode, get rid of any outline hiding. (show-all))) ;new (defun outline-do-ellipsis (where &optional remove) (if remove (remove-overlays where (1+ where) 'display outline-ellipsis) (let ((o (make-overlay where (1+ where) nil t nil))) (overlay-put o 'display outline-ellipsis)))) ;new (defun outline-end-of-entry () "Skip forward to the end of the entry. This may be the same as the start of the next heading, or possibly a line before, if `outline-blank-line' is non-null." (outline-next-heading) (and outline-blank-line (not (eobp)) (not (bobp)) (eq (char-before (1- (point))) ?\n) (forward-char -1))) ;614 (defun outline-move-subtree-down (&optional arg) "Move the currrent subtree down past ARG headlines of the same level." (interactive "p") (let ((movfunc (if (> arg 0) 'outline-get-next-sibling 'outline-get-last-sibling)) (ins-point (make-marker)) (cnt (abs arg)) beg end 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 (1+ (point))))) (outline-end-of-subtree)) (if (=3D (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 (=3D (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))) ;688 (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) (push-mark (point) nil t) (goto-char beg))) ;771 (defun hide-entry () "Hide the body directly following this heading." (interactive) (save-excursion (outline-back-to-heading) (outline-end-of-heading) (outline-do-ellipsis (point)) (outline-flag-region (1+ (point)) (progn (outline-end-of-entry) (point)= ) t)) ;; leave point in a visible spot. (when (outline-invisible-p) (outline-back-to-heading) (outline-end-of-heading))) ;779 (defun show-entry () "Show the body directly following this heading. Show the heading too, if it is currently invisible." (interactive) (save-excursion (outline-back-to-heading t) (save-excursion (outline-end-of-heading) (outline-do-ellipsis (point) t)) (outline-flag-region (point) (progn (outline-end-of-entry) (point)) nil))) ;793 (defun hide-region-body (start end) "Hide all body lines in the region, but not headings." ;; 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)) (unless (outline-on-heading-p) (outline-next-heading)) (while (not (eobp)) (outline-end-of-heading) (outline-do-ellipsis (point)) (outline-flag-region (1+ (point)) (progn ;; to-do: implement outline-blank-line (outline-next-heading) (point)) t)))) ;; make sure we leave point in a visible spot (when (outline-invisible-p) (outline-back-to-heading) (outline-end-of-heading))) (run-hooks 'outline-view-change-hook)) ;814 (defun show-all () "Show all of the text in the buffer." (interactive) (outline-flag-region (point-min) (point-max) nil) (remove-overlays (point-min) (point-max) 'display outline-ellipsis)) ;824 (defun hide-leaves () "Hide the body after this heading and at deeper levels." (interactive) (save-excursion (outline-back-to-heading) ;; Turned off to fix bug reported by Otto Maddox on 22 Nov 2005. ;; (outline-end-of-heading) (hide-region-body (point) (progn (outline-end-of-subtree) (point))))) ;838 (defun outline-show-heading () "Show the current heading and move to its end." (outline-flag-region (- (point) (if (bobp) 0 (if (and outline-blank-line (eq (char-before (1- (point))) ?\n)) 1 0))) (progn (outline-end-of-heading) (1+ (point))) nil) (outline-do-ellipsis (point) (not (outline-invisible-p (1+ (point)))))) ;848 (defun hide-sublevels (levels) "Hide everything but the top LEVELS levels of headers, in whole buffer." (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)))) (if (< levels 1) (error "Must keep at least one level of headers")) (let (outline-view-change-hook) (save-excursion (goto-char (point-min)) ;; Skip the prelude, if any. (unless (outline-on-heading-p t) (outline-next-heading)) ;; First hide everything. (outline-flag-region (point) (point-max) t) ;; Then unhide the top level headers. (outline-map-region (lambda () (if (<=3D (funcall outline-level) levels) (outline-show-heading))) (point) (point-max)))) (run-hooks 'outline-view-change-hook)) ;880 (defun hide-other () "Hide everything except current body and parent and top-level headings." (interactive) (hide-sublevels 1) (let (outline-view-change-hook) (save-excursion (outline-back-to-heading t) (show-entry) (while (condition-case nil (progn (outline-up-heading 1 t) (not (bobp= ))) (error nil)) (outline-flag-region (1- (point)) (save-excursion (forward-line 1) (point)) nil)))) (run-hooks 'outline-view-change-hook)) ;895 (defun outline-toggle-children () "Show or hide the current subtree depending on its current state." (interactive) (save-excursion (outline-back-to-heading) (if (not (outline-invisible-p (1+ (line-end-position)))) (hide-subtree) (show-children) (show-entry)))) ;905 (defun outline-flag-subtree (flag) (save-excursion (outline-back-to-heading) (outline-end-of-heading) (outline-do-ellipsis (point) (not flag)) (outline-flag-region (1+ (point)) (progn (outline-end-of-subtree) (point)) flag))) ;913 (defun outline-end-of-subtree () (outline-back-to-heading) (let ((first t) (level (funcall outline-level))) (while (and (not (eobp)) (or first (> (funcall outline-level) level))) (setq first nil) (outline-next-heading)) (if (and (bolp) (not (eolp)) ;; We stopped at a nonempty line (the next heading). outline-blank-line (not (eobp)) (eq (char-before (1- (point))) ?\n)) (forward-char -1)))) --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --=-=-=--