GNU bug report logs - #59141
28.1.90; Face :extend when all the line but trailing \n is invisible

Previous Next

Package: emacs;

Reported by: Ihor Radchenko <yantar92 <at> posteo.net>

Date: Wed, 9 Nov 2022 02:24:01 UTC

Severity: normal

Tags: fixed

Found in version 28.1.90

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


Message #68 received at 59141 <at> debbugs.gnu.org (full text, mbox):

From: Kévin Le Gouguec <kevin.legouguec <at> gmail.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 59141 <at> debbugs.gnu.org, yantar92 <at> posteo.net,
 Abdul-Lateef Haji-Ali <abdo.haji.ali <at> gmail.com>, juri <at> linkov.net
Subject: Re: bug#59141: 28.1.90; Face :extend when all the line but trailing
 \n is invisible
Date: Sat, 12 Nov 2022 12:18:49 +0100
Eli Zaretskii <eliz <at> gnu.org> writes:

> You are basically suggesting to hide the entire buffer text and
> instead display something else via display properties.  That's not
> what outline modes do.
>
> The solution to this problem is simple: don't use the :extend
> attribute for these faces.  That's all.  This attribute is not
> intended for what you want to achieve here.  A whole bunch of problems
> automatically gets resolved if you don't use :extend.

Can't speak to what :extend is intended for, but I think it's worth
noting that magit-section successfully combines overlays with :extend to
do exactly what outline.el does (a hierarchy of collapsable buffer
sections), without the problem under discussion.

If someone came up with a patch to allow outline.el to delimit and hide
sections using a logic closer to magit-section's[1] (via an opt-in
variable, to be set e.g. by major modes, so that users happy with the
status quo are not affected), would that patch be given any
consideration?

Asking because OT1H, it seems to me that this kind of change would be on
par with Juri's proposed outline-search-function in bug#53981, i.e. an
opt-in change to a core part of outline.el's design; OTOH the above
sounds quite final, so I don't want to waste anyone's time.


[1] Here are the relevant parts AFAIU, based on a cursory exploration.

Obviously nothing can be ported verbatim to outline.el: e.g. the eieio
idioms are not suited, neither are the parts that manipulate buffer
content directly (like magit-diff-wash-hunk deleting then re-inserting
the hunk heading).

Still, I'm hopeful we could teach outline.el the logic of where headings
end and content starts, and how to set overlays to hide the latter.

* magit-section.el:

(defclass magit-section ()
  ([…]
   (start    :initform nil :initarg :start)
   (content  :initform nil)
   (end      :initform nil)
   […]))

(defun magit-section-hide (section)
  "Hide the body of the current section."
  (interactive (list (magit-current-section)))
  (if (eq section magit-root-section)
      (user-error "Cannot hide root section")
    (oset section hidden t)
    (when-let ((beg (oref section content)))
      (let ((end (oref section end)))
        (when (< beg (point) end)
          (goto-char (oref section start)))
        (remove-overlays beg end 'invisible t)
        (let ((o (make-overlay beg end)))
          (overlay-put o 'evaporate t)
          (overlay-put o 'invisible t))))
    […]))

(defmacro magit-insert-section (&rest args)
  "Insert a section at point.
[…]"
  […]
                         :start (point-marker)
  […])

* magit-diff.el:

(defun magit-diff-wash-hunk ()
  (when (looking-at "^@\\{2,\\} \\(.+?\\) @\\{2,\\}\\(?: \\(.*\\)\\)?")
    (let* ((heading  (match-string 0))
           (ranges   (mapcar
                      (lambda (str)
                        (let ((range
                               (mapcar #'string-to-number
                                       (split-string (substring str 1) ","))))
                          ;; A single line is +1 rather than +1,1.
                          (if (length= range 1)
                              (nconc range (list 1))
                            range)))
                      (split-string (match-string 1))))
           (about    (match-string 2))
           (combined (length= ranges 3))
           (value    (cons about ranges)))
      (magit-delete-line)
      (magit-insert-section section (hunk value)
        (insert (propertize (concat heading "\n")
                            'font-lock-face 'magit-diff-hunk-heading))
        (magit-insert-heading)
        (while (not (or (eobp) (looking-at "^[^-+\s\\]")))
          (forward-line))
        (oset section end (point))
        (oset section washer #'magit-diff-paint-hunk)
        (oset section combined combined)
        […]))
    t))

JS-less, text/plain references:

https://raw.githubusercontent.com/magit/magit/master/lisp/magit-section.el
https://raw.githubusercontent.com/magit/magit/master/lisp/magit-diff.el




This bug report was last modified 1 year and 112 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.