all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* variable-pitch-mode misaligns org-mode heading tags
@ 2020-09-08 19:31 Protesilaos Stavrou
  2020-09-09  8:44 ` Bastien
  0 siblings, 1 reply; 14+ messages in thread
From: Protesilaos Stavrou @ 2020-09-08 19:31 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1177 bytes --]

1. Run 'emacs -Q'
2. Open a new Org file 'C-x C-f /tmp/test.org'
3. Insert the following contents:

* TODO this is a test                                                   :tag:
* TODO here is another test                                             :tag:

The tags should align to the right with the standard monospaced font.

4. Run 'M-x variable-pitch-mode'.
5. The tags are now misaligned.

Please see attached screenshots for the before and after states of the
'variable-pitch-mode' activation.

Running 'M-x describe-char' in the space between the heading's title and
the tag informs us that the space's face is the same as the heading's
(e.g. 'org-level-1').

I am also relaying the technical insight of Adam Spiers.  Please see
attached plain text document or visit the comment's URL:
https://gitlab.com/protesilaos/modus-themes/-/issues/85#note_407147422

Overview of my setup:

+ GNU Emacs 27.1 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.22,
  cairo version 1.17.3) of 2020-08-14

+ Org mode version 9.3 (release_9.3 @ /usr/share/emacs/27.1/lisp/org/)

* * *

This message was also posted on debbugs.gnu.org, bug#43272.

-- 
Protesilaos Stavrou
protesilaos.com

[-- Attachment #2: variable-pitch-mode-org-headings-misaligned-1.png --]
[-- Type: image/png, Size: 48799 bytes --]

[-- Attachment #3: variable-pitch-mode-org-headings-misaligned-2.png --]
[-- Type: image/png, Size: 49261 bytes --]

[-- Attachment #4: adam-spiers-align-org-tags.txt --]
[-- Type: text/plain, Size: 2266 bytes --]

I've investigated this and it's not nearly as easy as I had hoped.  It turns out that the right alignment supported by display properties can only align space, not text.  Something like this works as an experiment:

```lisp
(with-current-buffer "org/TODO.org"
  (put-text-property (region-beginning) (region-end)
                     'display '(space :align-to (- right 10))))
```

If a region of space characters is selected, the above will adjust the region's width so that its right hand side is 10 character widths in from the right margin.  However if the region contains text, it will make that text invisible.

This could be used to *left*-align the tags, but not *right*-align them, which doesn't really work because each heading's tags can be a different number of characters wide.

So to get our desired behaviour of adjusting the space in between the heading and the tags correctly in order to right-align the tags to [the right margin specified by `org-tags-column`](https://lists.gnu.org/archive/html/bug-gnu-emacs/2020-09/msg00728.html), we'd first have to calculate the display width of the (proportionally spaced) tags text, and then subtract that from the right margin.

In theory this width can be retrieved via `pos-visible-in-window-p` with the `PARTIALLY` argument set to `t`, but I haven't got that working yet, and even if I could, it would need to be done dynamically for each line and then the corresponding text property updated whenever that width changed (e.g. any of that line was edited, or when the window was scrolled to bring different headings into view).

However that raises questions about how well this would perform, since it would be creating quite a lot of work to do on each redisplay.  I suspect that the emacs gurus would say that support for right-alignment of variable pitch text would need to be added to emacs's internal display routines (the ones written in C, not Elisp).  But that's only a vague guess.  Hopefully I've underestimated what emacs can currently do here and there's an easier solution, but there's little chance of finding out either way without asking on the Org list, and then falling back to the `help-gnu-emacs` or `emacs-devel` list if it's even too difficult a question for any of the Org gurus.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-08 19:31 variable-pitch-mode misaligns org-mode heading tags Protesilaos Stavrou
@ 2020-09-09  8:44 ` Bastien
  2020-09-09 11:03   ` Eric S Fraga
  0 siblings, 1 reply; 14+ messages in thread
From: Bastien @ 2020-09-09  8:44 UTC (permalink / raw)
  To: Protesilaos Stavrou; +Cc: emacs-orgmode

Hi Protesilaos,

Protesilaos Stavrou <info@protesilaos.com> writes:

> 1. Run 'emacs -Q'
> 2. Open a new Org file 'C-x C-f /tmp/test.org'
> 3. Insert the following contents:
>
> * TODO this is a test                                                   :tag:
> * TODO here is another test                                             :tag:
>
> The tags should align to the right with the standard monospaced font.

Thanks for reporting this.  Actually yes, we should consider handling
variable-pitch-mode more pleasantly, with space-aligned tags and also
tables that still display with fixed-width.

Patch(es) welcome for 9.5!

Thanks,

-- 
 Bastien


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-09  8:44 ` Bastien
@ 2020-09-09 11:03   ` Eric S Fraga
  2020-09-09 14:39     ` Bastien
  0 siblings, 1 reply; 14+ messages in thread
From: Eric S Fraga @ 2020-09-09 11:03 UTC (permalink / raw)
  To: Bastien; +Cc: Protesilaos Stavrou, emacs-orgmode

On Wednesday,  9 Sep 2020 at 10:44, Bastien wrote:
> Thanks for reporting this.  Actually yes, we should consider handling
> variable-pitch-mode more pleasantly, with space-aligned tags and also
> tables that still display with fixed-width.

Also support for org-indent-mode: having the text align nicely with the
heading (as it does with monospace typefaces) would be more visually
pleasing.

But I have a feeling that the calculations required for this and the
above may be significant and arguably not worth it?  Org, especially
with respect to (large) tables, is already quite slow unfortunately.

Just my 2¢.

-- 
: Eric S Fraga via Emacs 28.0.50, Org release_9.3.7-725-g7bc18e


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-09 11:03   ` Eric S Fraga
@ 2020-09-09 14:39     ` Bastien
  2020-09-15 17:41       ` Jeff Filipovits
  0 siblings, 1 reply; 14+ messages in thread
From: Bastien @ 2020-09-09 14:39 UTC (permalink / raw)
  To: Eric S Fraga; +Cc: Protesilaos Stavrou, emacs-orgmode

Hi Eric,

Eric S Fraga <e.fraga@ucl.ac.uk> writes:

> Also support for org-indent-mode: having the text align nicely with the
> heading (as it does with monospace typefaces) would be more visually
> pleasing.
>
> But I have a feeling that the calculations required for this and the
> above may be significant and arguably not worth it?  

Indeed.

> Org, especially
> with respect to (large) tables, is already quite slow unfortunately.

Fortunately, the reasons why tables might be slow are distinct from
the reasons why org-indent might be slow.  

But yes, space-based alignment is a welcome improvement as long as it
does not make Org slower.

-- 
 Bastien


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-09 14:39     ` Bastien
@ 2020-09-15 17:41       ` Jeff Filipovits
  2020-09-16 16:21         ` Adam Spiers
  0 siblings, 1 reply; 14+ messages in thread
From: Jeff Filipovits @ 2020-09-15 17:41 UTC (permalink / raw)
  To: emacs-orgmode; +Cc: Protesilaos Stavrou, Eric S Fraga

Following the call for help to fix bugs, and with building guilt, 
I’ve taken a stab at fixing aligning tags when using a 
variable-pitch font. I haven’t tested this much because I do not 
know if it is misguided, but it seems to work.

Seems the only way to do it is to use the ‘display text property 
and expand a single space between the headline and tags. Here is a 
drop-in replacement of org--align-tags-here which ensures there is 
one space between the tags and headline, and then expands that 
space by setting a text property.

I’ve removed the point-preserving code because it does not seem to 
be needed using this method. This would also allow removing 
org-fix-tags-on-the-fly from org-self-insert-command since there 
is only a single space between the headline and the tags and it is 
adjusted automatically. 

If this looks promising I can throw some more time at it. If not, 
I will happily abandon it. 

(defun org--align-tags-here (to-col)
  "Align tags on the current headline to TO-COL.
Assume point is on a headline.  Preserve point when aligning
tags."
  (save-excursion 
    (when (org-match-line org-tag-line-re)
      (let* ((tags-start (match-beginning 1))
	     (blank-start (progn (goto-char tags-start)
				 (skip-chars-backward " \t")
				 (point))))
	;; If there is more than one space between the headline 
           and tags,
	;; delete the extra spaces.  Might be better to
        ;; make the delete region one space smaller rather than 
        inserting
        ;; a new space?
	(when (> tags-start (1+ blank-start))
	  (delete-region blank-start tags-start)
	  (goto-char blank-start)
	  (insert " "))
	;; Don't set the text property unless it is needed.
	;; Not sure this check is efficient.  Probably not 
           necessary.
	(unless (equal (get-text-property blank-start 'display)
		       `(space . (:align-to ,to-col)))
	  (put-text-property blank-start (1+ blank-start)
			     'display `(space . (:align-to 
			     ,to-col))))))))




Bastien <bzg@gnu.org> writes:

> Hi Eric,
>
> Eric S Fraga <e.fraga@ucl.ac.uk> writes:
>
>> Also support for org-indent-mode: having the text align nicely 
>> with the
>> heading (as it does with monospace typefaces) would be more 
>> visually
>> pleasing.
>>
>> But I have a feeling that the calculations required for this 
>> and the
>> above may be significant and arguably not worth it?  
>
> Indeed.
>
>> Org, especially
>> with respect to (large) tables, is already quite slow 
>> unfortunately.
>
> Fortunately, the reasons why tables might be slow are distinct 
> from
> the reasons why org-indent might be slow.  
>
> But yes, space-based alignment is a welcome improvement as long 
> as it
> does not make Org slower.


-- 
Jeff Filipovits
Spears & Filipovits, LLC
1126 Ponce de Leon Avenue
Atlanta, GA 30306
678.237.9302 (direct)
jrfilipovits@gmail.com

All emails confidential to the fullest extent of the law.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-15 17:41       ` Jeff Filipovits
@ 2020-09-16 16:21         ` Adam Spiers
  2020-09-16 19:03           ` Jeff Filipovits
  2021-04-27 19:41           ` Bastien
  0 siblings, 2 replies; 14+ messages in thread
From: Adam Spiers @ 2020-09-16 16:21 UTC (permalink / raw)
  To: Jeff Filipovits; +Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga

Hi Jeff,

Firstly thanks a lot for looking into this! 

On Tue, Sep 15, 2020 at 01:41:04PM -0400, Jeff Filipovits wrote:
>Following the call for help to fix bugs, and with building guilt, I’ve 
>taken a stab at fixing aligning tags when using a variable-pitch font. 
>I haven’t tested this much because I do not know if it is misguided, 
>but it seems to work. 
>
>Seems the only way to do it is to use the ‘display text property and 
>expand a single space between the headline and tags. Here is a drop-in 
>replacement of org--align-tags-here which ensures there is one space 
>between the tags and headline, and then expands that space by setting 
>a text property. 

Yes, this is the same conclusion I reached a little while ago: 

    https://gitlab.com/protesilaos/modus-themes/-/issues/85#note_407147422

However as mentioned there, AFAICS this approach only manages to 
*left*-align the tags, not *right*-align them.  When there are several 
tags, this can be problematic as the colon-delimited list of tags will 
either spill over the buffer's right margin, or avoid that by 
requiring an alignment column which is further to the left and ends up 
interfering with the main text of the buffer.  Given that the 
colon-delimited lists have variable numbers of characters, I think 
it's clear that right alignment is the only decent space-efficient 
layout.

BTW I tried your code and for some reason it didn't insert any space for 
me, but I didn't look into that yet. 

>I’ve removed the point-preserving code because it does not seem to be 
>needed using this method. This would also allow removing 
>org-fix-tags-on-the-fly from org-self-insert-command since there is 
>only a single space between the headline and the tags and it is 
>adjusted automatically. 

Makes sense. 

>If this looks promising I can throw some more time at it. If not, I 
>will happily abandon it. 

I think it's promising for sure.  But I think there is still a 
remaining problem regarding how to implement the right alignment of 
the colon-delimited list of tags.  If this list uses a fixed-width 
font then it is relatively easy, because then the value to provide to 
:align-to can be calculated as `org-tags-column' minus the column 
width of the tag list.  And indeed this seems to be how the original 
version of `org--align-tags-here' achieves right alignment: 

            (new (max (if (>= to-col 0) to-col
                        (- (abs to-col) (string-width (match-string 1))))

But the whole point of this exercise is to support variable-width 
fonts.  In this case, the correct position for the end of the single 
space is most likely not even a multiple of the fixed column width, so 
it would probably need to be measured in pixels rather than columns. 
And in order to calculate it, it is first necessary to calculate the 
exact width in pixels of the colon-delimited list of tags. 

As I mentioned in the comment linked above, I searched for a way of 
calculating the pixel width of the tag list, and the best I could find 
was `pos-visible-in-window-p' which has some issues which I mentioned 
there.  If you have thoughts on whether I'm right about those, and if 
so how to solve them, I'd love to hear! 

Cheers,
Adam


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-16 16:21         ` Adam Spiers
@ 2020-09-16 19:03           ` Jeff Filipovits
  2020-09-16 21:14             ` Samuel Wales
  2020-09-16 22:55             ` Adam Spiers
  2021-04-27 19:41           ` Bastien
  1 sibling, 2 replies; 14+ messages in thread
From: Jeff Filipovits @ 2020-09-16 19:03 UTC (permalink / raw)
  To: Adam Spiers; +Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga


Adam,

Thanks. You are right of course and I realized the right-align 
issue right after I sent my email. 

Adam Spiers <orgmode@adamspiers.org> writes:

> But the whole point of this exercise is to support 
> variable-width
> fonts.  In this case, the correct position for the end of the 
> single
> space is most likely not even a multiple of the fixed column 
> width, so
> it would probably need to be measured in pixels rather than
> columns. And in order to calculate it, it is first necessary to
> calculate the exact width in pixels of the colon-delimited list 
> of
> tags. As I mentioned in the comment linked above, I searched for 
> a way
> of calculating the pixel width of the tag list, and the best I 
> could
> find was `pos-visible-in-window-p' which has some issues which I
> mentioned there.  If you have thoughts on whether I'm right 
> about
> those, and if so how to solve them, I'd love to hear! Cheers,
> Adam

It looks like (window-text-pixel-size) could be used to calculate 
the pixel length of the tags list? I am having trouble deciphering 
the manual 
(https://www.gnu.org/software/emacs/manual/html_node/elisp/Pixel-Specification.html#Pixel-Specification) 
for pixel specification for spaces, though. The right alignment 
specification for some reason sends the tags to the next line, as 
do most other solutions that I would expect to align the text to 
the right side of the window. 

I can experiment more in a couple days, but in the meantime maybe 
someone smarter than me give some hints on how to use the pixel 
specification properties. 

> BTW I tried your code and for some reason it didn't insert any 
> space
> for me, but I didn't look into that yet.

The way it’s written it would only reduce the gap between the 
headline and tags to a space, and it assumes there are multiple 
spaces there already. If there’s no space between the two, I don’t 
think it’ll insert one. Probably not the best way as it was thrown 
together to test the text property fix. 

I accepted long ago that the solution to using a variable pitch 
font for org headings was that the tags would not be aligned to 
the right and never looked back, so maybe this is not worth the 
price of fixing it if it is messy. And diving down to calculating 
the pixel width of text seems like it’s getting pretty messy. 

-- 
Jeff Filipovits
Spears & Filipovits, LLC
1126 Ponce de Leon Avenue
Atlanta, GA 30306
678.237.9302 (direct)
jrfilipovits@gmail.com

All emails confidential to the fullest extent of the law.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-16 19:03           ` Jeff Filipovits
@ 2020-09-16 21:14             ` Samuel Wales
  2020-09-16 22:55             ` Adam Spiers
  1 sibling, 0 replies; 14+ messages in thread
From: Samuel Wales @ 2020-09-16 21:14 UTC (permalink / raw)
  To: Jeff Filipovits; +Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga

can emacs supply tools that would be useful?

On 9/16/20, Jeff Filipovits <jrfilipovits@gmail.com> wrote:
>
> Adam,
>
> Thanks. You are right of course and I realized the right-align
> issue right after I sent my email.
>
> Adam Spiers <orgmode@adamspiers.org> writes:
>
>> But the whole point of this exercise is to support
>> variable-width
>> fonts.  In this case, the correct position for the end of the
>> single
>> space is most likely not even a multiple of the fixed column
>> width, so
>> it would probably need to be measured in pixels rather than
>> columns. And in order to calculate it, it is first necessary to
>> calculate the exact width in pixels of the colon-delimited list
>> of
>> tags. As I mentioned in the comment linked above, I searched for
>> a way
>> of calculating the pixel width of the tag list, and the best I
>> could
>> find was `pos-visible-in-window-p' which has some issues which I
>> mentioned there.  If you have thoughts on whether I'm right
>> about
>> those, and if so how to solve them, I'd love to hear! Cheers,
>> Adam
>
> It looks like (window-text-pixel-size) could be used to calculate
> the pixel length of the tags list? I am having trouble deciphering
> the manual
> (https://www.gnu.org/software/emacs/manual/html_node/elisp/Pixel-Specification.html#Pixel-Specification)
>
> for pixel specification for spaces, though. The right alignment
> specification for some reason sends the tags to the next line, as
> do most other solutions that I would expect to align the text to
> the right side of the window.
>
> I can experiment more in a couple days, but in the meantime maybe
> someone smarter than me give some hints on how to use the pixel
> specification properties.
>
>> BTW I tried your code and for some reason it didn't insert any
>> space
>> for me, but I didn't look into that yet.
>
> The way it’s written it would only reduce the gap between the
> headline and tags to a space, and it assumes there are multiple
> spaces there already. If there’s no space between the two, I don’t
> think it’ll insert one. Probably not the best way as it was thrown
> together to test the text property fix.
>
> I accepted long ago that the solution to using a variable pitch
> font for org headings was that the tags would not be aligned to
> the right and never looked back, so maybe this is not worth the
> price of fixing it if it is messy. And diving down to calculating
> the pixel width of text seems like it’s getting pretty messy.
>
> --
> Jeff Filipovits
> Spears & Filipovits, LLC
> 1126 Ponce de Leon Avenue
> Atlanta, GA 30306
> 678.237.9302 (direct)
> jrfilipovits@gmail.com
>
> All emails confidential to the fullest extent of the law.
>
>


-- 
The Kafka Pandemic

Please learn what misopathy is.
https://thekafkapandemic.blogspot.com/2013/10/why-some-diseases-are-wronged.html


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-16 19:03           ` Jeff Filipovits
  2020-09-16 21:14             ` Samuel Wales
@ 2020-09-16 22:55             ` Adam Spiers
  2020-09-17  0:18               ` Adam Spiers
  2020-09-17  2:03               ` Jeff Filipovits
  1 sibling, 2 replies; 14+ messages in thread
From: Adam Spiers @ 2020-09-16 22:55 UTC (permalink / raw)
  To: Jeff Filipovits; +Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga

[-- Attachment #1: Type: text/plain, Size: 3326 bytes --]

On Wed, Sep 16, 2020 at 03:03:02PM -0400, Jeff Filipovits wrote: 
>It looks like (window-text-pixel-size) could be used to calculate the 
>pixel length of the tags list? 

Ahah!  This indeed did the trick!  I have no idea how I missed this 
handy function previously when I was scouring the manual... 

>I am having trouble deciphering the 
>manual (https://www.gnu.org/software/emacs/manual/html_node/elisp/Pixel-Specification.html#Pixel-Specification) 
>for pixel specification for spaces, though. The right alignment 
>specification for some reason sends the tags to the next line, as do 
>most other solutions that I would expect to align the text to the 
>right side of the window. 
>
>I can experiment more in a couple days, but in the meantime maybe 
>someone smarter than me give some hints on how to use the pixel 
>specification properties. 

I've actually managed it get it working now!  See the attached patch. 
However unfortunately it is not ready to be merged yet.  Firstly, it 
breaks `test-org/tag-align'.  Secondly, since this changes the method 
of alignment from simply using raw spaces to using a single space with 
a display text property, when the file is saved and reloaded, it just 
displays a single space and the alignment is lost.  Another unfortunate 
side-effect is that if the file is simultaneously displayed in a graphical 
window and a text window via the same emacs server (e.g. via emacsclient -t), 
then one of the two windows will have incorrect alignment. 

So I think the correct fix will be to keep the original number of 
spaces, but use a display text property to redisplay those spaces as a 
single space with the given width.  I'm guessing that the display text 
property will be ignored on text-only (tty) windows, fixing both 
problems in one go. 

So I'll take another stab at this soon, if Bastien or some other Org 
guru can confirm I'm on the right track. 

>>BTW I tried your code and for some reason it didn't insert any space 
>>for me, but I didn't look into that yet. 
>
>The way it’s written it would only reduce the gap between the headline 
>and tags to a space, and it assumes there are multiple spaces there 
>already. If there’s no space between the two, I don’t think it’ll 
>insert one. Probably not the best way as it was thrown together to 
>test the text property fix. 

I figured out that it wasn't working because my `org-tags-column' is a 
negative value in order to align flush-right, and your code didn't 
support that. 

>I accepted long ago that the solution to using a variable pitch font 
>for org headings was that the tags would not be aligned to the right 
>and never looked back, so maybe this is not worth the price of fixing 
>it if it is messy. And diving down to calculating the pixel width of 
>text seems like it’s getting pretty messy. 

Actually I think it ended up fairly clean.  Huge thanks to you for 
giving me the hint I needed!  I just adapted your code a bit.  I've 
marked you as a co-author in the commit message.  For now your 
contribution probably still falls into the category of "Tiny changes": 

     https://orgmode.org/worg/org-contribute.html#org9fbb342

However you might want to preemptively sign the copyright assignment 
papers: 

     https://orgmode.org/worg/org-contribute.html#copyrighted-contributors

[-- Attachment #2: 0001-org.el-Align-tags-using-specified-space-display-prop.patch --]
[-- Type: text/x-patch, Size: 4927 bytes --]

From 7655c32847d7abd9da7603b1a1a314b7d1b87ba5 Mon Sep 17 00:00:00 2001
From: Adam Spiers <orgmode@adamspiers.org>
Date: Wed, 16 Sep 2020 23:12:04 +0100
Subject: [PATCH] [WIP] org.el: Align tags using specified space display property
To: emacs-orgmode@gnu.org

Previously tags on heading lines were aligned using spaces, which
assumed a fixed width font.  However variable pitch fonts are becoming
increasingly popular, so ensure there is always a single space in
between the heading text and the (colon-delimited) list of tags, and
then if necessary use a display text property to specify the exact
width required by that space to align it in accordance with the value
of `org-tags-column' which the user has chosen:

  https://www.gnu.org/software/emacs/manual/html_node/elisp/Pixel-Specification.html#Pixel-Specification

If the value is positive, align flush-left; if negative, align
flush-right; and if zero, just leave a normal width space.

See the following links for the discussion threads leading to this
patch:

- https://lists.gnu.org/archive/html/emacs-orgmode/2020-09/msg00415.html
- https://gitlab.com/protesilaos/modus-themes/-/issues/85

Signed-off-by: Adam Spiers <orgmode@adamspiers.org>
Co-authored-by: Jeff Filipovits <jrfilipovits@gmail.com>
---
 lisp/org.el | 68 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 29 deletions(-)

diff --git a/lisp/org.el b/lisp/org.el
index 053635c85..e800eb642 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -11831,35 +11831,45 @@ (defun org-toggle-tag (tag &optional onoff)
       res)))
 
 (defun org--align-tags-here (to-col)
-  "Align tags on the current headline to TO-COL.
-Assume point is on a headline.  Preserve point when aligning
-tags."
-  (when (org-match-line org-tag-line-re)
-    (let* ((tags-start (match-beginning 1))
-	   (blank-start (save-excursion
-			  (goto-char tags-start)
-			  (skip-chars-backward " \t")
-			  (point)))
-	   (new (max (if (>= to-col 0) to-col
-		       (- (abs to-col) (string-width (match-string 1))))
-		     ;; Introduce at least one space after the heading
-		     ;; or the stars.
-		     (save-excursion
-		       (goto-char blank-start)
-		       (1+ (current-column)))))
-	   (current
-	    (save-excursion (goto-char tags-start) (current-column)))
-	   (origin (point-marker))
-	   (column (current-column))
-	   (in-blank? (and (> origin blank-start) (<= origin tags-start))))
-      (when (/= new current)
-	(delete-region blank-start tags-start)
-	(goto-char blank-start)
-	(let ((indent-tabs-mode nil)) (indent-to new))
-	;; Try to move back to original position.  If point was in the
-	;; blanks before the tags, ORIGIN marker is of no use because
-	;; it now points to BLANK-START.  Use COLUMN instead.
-	(if in-blank? (org-move-to-column column) (goto-char origin))))))
+  "Align tags on the current headline to TO-COL.  Since TO-COL is
+derived from `org-tags-column', a negative value is interpreted as
+alignment flush-right, a positive value as flush-left, and 0 means
+insert a single space in between the headline and the tags.
+
+Assume point is on a headline.  Preserve point when aligning tags."
+  (save-excursion
+    (when (org-match-line org-tag-line-re)
+      (let* ((tags-start (match-beginning 1))
+             (tags-end (match-end 1))
+             (tags-pixel-width
+              (car (window-text-pixel-size (selected-window)
+                                           tags-start tags-end)))
+             (blank-start (progn
+                            (goto-char tags-start)
+                            (skip-chars-backward " \t")
+                            (point))))
+        ;; If there is more than one space between the headline and
+        ;; tags, delete the extra spaces.  Might be better to make the
+        ;; delete region one space smaller rather than inserting a new
+        ;; space?
+        (when (> tags-start (1+ blank-start))
+          (delete-region blank-start tags-start)
+          (goto-char blank-start)
+          (insert " "))
+        (if (= to-col 0)
+            ;; Just leave one normal space width
+            (remove-text-properties blank-start (1+ blank-start) '(display nil))
+          (let ((align-expr
+                 (if (> to-col 0)
+                     ;; Left-align positive values
+                     to-col
+                   ;; Right-align negative values by subtracting the
+                   ;; width of the tags.  Conveniently, the pixel
+                   ;; specification allows us to mix units,
+                   ;; subtracting a pixel width from a column number.
+                   `(- ,(- to-col) (,tags-pixel-width)))))
+            (put-text-property blank-start (1+ blank-start)
+                               'display `(space . (:align-to ,align-expr)))))))))
 
 (defun org-set-tags-command (&optional arg)
   "Set the tags for the current visible entry.
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-16 22:55             ` Adam Spiers
@ 2020-09-17  0:18               ` Adam Spiers
  2020-09-17  2:03               ` Jeff Filipovits
  1 sibling, 0 replies; 14+ messages in thread
From: Adam Spiers @ 2020-09-17  0:18 UTC (permalink / raw)
  To: Jeff Filipovits; +Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga

On Wed, Sep 16, 2020 at 11:55:53PM +0100, Adam Spiers wrote: 
>I've actually managed it get it working now!  See the attached patch. 
>However unfortunately it is not ready to be merged yet.  Firstly, it 
>breaks `test-org/tag-align'.  Secondly, since this changes the method 
>of alignment from simply using raw spaces to using a single space with 
>a display text property, when the file is saved and reloaded, it just 
>displays a single space and the alignment is lost.  Another 
>unfortunate side-effect is that if the file is simultaneously 
>displayed in a graphical window and a text window via the same emacs 
>server (e.g. via emacsclient -t), then one of the two windows will 
>have incorrect alignment. 
>
>So I think the correct fix will be to keep the original number of 
>spaces, but use a display text property to redisplay those spaces as a 
>single space with the given width.  I'm guessing that the display text 
>property will be ignored on text-only (tty) windows, fixing both 
>problems in one go. 
>
>So I'll take another stab at this soon, if Bastien or some other Org 
>guru can confirm I'm on the right track. 

Hrm, no this isn't good enough.  For graphical windows we still need 
to set the display text properties to align all tags when the buffer 
initially loads.  AFAICS there's currently no code to trigger this, so 
it would need to be added, and for large files this might actually 
cause problems with file loading time unless it was done in the 
background (a bit like fontification can be done). 

Advice on how to handle this best is very welcome. 


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-16 22:55             ` Adam Spiers
  2020-09-17  0:18               ` Adam Spiers
@ 2020-09-17  2:03               ` Jeff Filipovits
  2020-09-17 15:36                 ` Jeff Filipovits
  2020-09-18 12:49                 ` Ihor Radchenko
  1 sibling, 2 replies; 14+ messages in thread
From: Jeff Filipovits @ 2020-09-17  2:03 UTC (permalink / raw)
  To: Adam Spiers; +Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga

Adam Spiers <orgmode@adamspiers.org> writes:

> Hrm, no this isn't good enough.  For graphical windows we still 
> need
> to set the display text properties to align all tags when the 
> buffer
> initially loads.  AFAICS there's currently no code to trigger 
> this, so
> it would need to be added, and for large files this might 
> actually
> cause problems with file loading time unless it was done in the
> background (a bit like fontification can be done).

Initial test had some problems on my end. I have a couple 
ideas. Will try to write something tomorrow. Hopefully someone 
will chime in otherwise.


The upside of this is that it enabled me do to some hacking so now 
I can use a variable pitch font in the mu4e headers view and keep 
the columns aligned, which makes mu4e much prettier. 


-- 
Jeff Filipovits
Spears & Filipovits, LLC
1126 Ponce de Leon Avenue
Atlanta, GA 30306
678.237.9302 (direct)
jeff@civil-rights.law

All emails confidential to the fullest extent of the law.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-17  2:03               ` Jeff Filipovits
@ 2020-09-17 15:36                 ` Jeff Filipovits
  2020-09-18 12:49                 ` Ihor Radchenko
  1 sibling, 0 replies; 14+ messages in thread
From: Jeff Filipovits @ 2020-09-17 15:36 UTC (permalink / raw)
  To: Adam Spiers; +Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga


> Adam Spiers <orgmode@adamspiers.org> writes:
>
> Hrm, no this isn't good enough.  For graphical windows we still 
> need
> to set the display text properties to align all tags when the 
> buffer
> initially loads.  AFAICS there's currently no code to trigger 
> this,
> so it would need to be added, and for large files this might 
> actually
> cause problems with file loading time unless it was done in the
> background (a bit like fontification can be done).

A few issues I found:

1. If the headline text exceeds the org-tags-column, the tags are 
moved so there is no space between the headline and the tag. This 
is only aesthetic, since in reality there is still a space 
there. Not sure this needs to be fixed. 

2. If you try to insert a space at the end of the headline, it 
will be gobbled automatically because org-self-insert-command 
calls org–align-tags-here. With this method of aligning tags I 
don’t think org-self-insert-command needs to make this call, 
because the display text property updates automatically on 
redisplay. So the solution may be take that call out, but I don’t 
know if that will break anything. Otherwise, maybe the code 
ensuring there is one space is not really necessary. 

3. Org-indent-mode creates a problem. Not sure why yet, or whether 
it’s org-indent-mode or some setting I have associated with it, 
but tags of child nodes don’t align properly. 



Jeff Filipovits
Spears & Filipovits, LLC
1126 Ponce de Leon Avenue
Atlanta, GA 30306
678.237.9302 (direct)
jeff@civil-rights.law

All emails confidential to the fullest extent of the law.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-17  2:03               ` Jeff Filipovits
  2020-09-17 15:36                 ` Jeff Filipovits
@ 2020-09-18 12:49                 ` Ihor Radchenko
  1 sibling, 0 replies; 14+ messages in thread
From: Ihor Radchenko @ 2020-09-18 12:49 UTC (permalink / raw)
  To: Jeff Filipovits, Adam Spiers
  Cc: Protesilaos Stavrou, emacs-orgmode, Eric S Fraga

I somehow missed this thread.

I have a (mostly) working code achieving the same thing in my personal
config. The code is below. Hope it can give you some more ideas.

I am using font-lock for tag alignment.

(add-hook 'org-mode-hook (lambda () (font-lock-add-keywords 'org-mode '(yant/org-align-tags) t)) 100)
(add-hook 'org-mode-hook (lambda () (add-to-list 'font-lock-extra-managed-props 'org-tag-aligned)))

(defun yant/org-align-tags (limit &optional force)
    "Align all the tags in org buffer."
    (save-match-data
      (when (eq major-mode 'org-mode)
	(while (re-search-forward "^\\*+ \\(.+?\\)\\([ \t]+\\)\\(:\\(?:[^ \n]+:\\)+\\)$" limit t)
	  (when (and (match-string 2)
		     (or force
			 (not (get-text-property (match-beginning 2) 'org-tag-aligned))))
	    (with-silent-modifications
              (put-text-property (match-beginning 2) (match-end 2) 'org-tag-aligned t)
	      (put-text-property (if (>= 2 (- (match-end 2) (match-beginning 2)))
				     (match-beginning 2)
				   ;; multiple whitespaces may mean that we are in process of typing
				   (1+ (match-beginning 2)))
				 (match-end 2)
				 'display
				 `(space . (:align-to (- right
							 (,(+ 3 ;; no idea, but otherwise it is sometimes not enough
							      (string-display-pixel-width org-ellipsis)
							      (string-display-pixel-width (or (match-string 3)
											      ""))))))))))))))

(defun string-display-pixel-width (string &optional mode)
  "Calculate pixel width of STRING.
Optional MODE specifies major mode used for display."
  (with-temp-buffer
    (with-silent-modifications
      (setf (buffer-string) string))
    (when (fboundp mode)
      (funcall mode)
      (font-lock-fontify-buffer))
    (if (get-buffer-window (current-buffer))
	(car (window-text-pixel-size nil (line-beginning-position) (point)))
      (set-window-buffer nil (current-buffer))
      (car (window-text-pixel-size nil (line-beginning-position) (point))))))


Jeff Filipovits <jrfilipovits@gmail.com> writes:

> Adam Spiers <orgmode@adamspiers.org> writes:
>
>> Hrm, no this isn't good enough.  For graphical windows we still 
>> need
>> to set the display text properties to align all tags when the 
>> buffer
>> initially loads.  AFAICS there's currently no code to trigger 
>> this, so
>> it would need to be added, and for large files this might 
>> actually
>> cause problems with file loading time unless it was done in the
>> background (a bit like fontification can be done).
>
>
>
> The upside of this is that it enabled me do to some hacking so now 
> I can use a variable pitch font in the mu4e headers view and keep 
> the columns aligned, which makes mu4e much prettier. 
>
>
> -- 
> Jeff Filipovits
> Spears & Filipovits, LLC
> 1126 Ponce de Leon Avenue
> Atlanta, GA 30306
> 678.237.9302 (direct)
> jeff@civil-rights.law
>
> All emails confidential to the fullest extent of the law.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: variable-pitch-mode misaligns org-mode heading tags
  2020-09-16 16:21         ` Adam Spiers
  2020-09-16 19:03           ` Jeff Filipovits
@ 2021-04-27 19:41           ` Bastien
  1 sibling, 0 replies; 14+ messages in thread
From: Bastien @ 2021-04-27 19:41 UTC (permalink / raw)
  To: Adam Spiers
  Cc: Jeff Filipovits, Protesilaos Stavrou, emacs-orgmode, Eric S Fraga

I would welcome a clean solution for tags alignment.

Ideally, one could switch from the current (manual) alignment, which
tries to align to a fixed column, while allowing to switch to a more
visually consistent alignement in variable-pitch-mode.

But this need to be done *without* slowing done big Org files, which
is probably a challenge.


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-04-27 19:43 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-09-08 19:31 variable-pitch-mode misaligns org-mode heading tags Protesilaos Stavrou
2020-09-09  8:44 ` Bastien
2020-09-09 11:03   ` Eric S Fraga
2020-09-09 14:39     ` Bastien
2020-09-15 17:41       ` Jeff Filipovits
2020-09-16 16:21         ` Adam Spiers
2020-09-16 19:03           ` Jeff Filipovits
2020-09-16 21:14             ` Samuel Wales
2020-09-16 22:55             ` Adam Spiers
2020-09-17  0:18               ` Adam Spiers
2020-09-17  2:03               ` Jeff Filipovits
2020-09-17 15:36                 ` Jeff Filipovits
2020-09-18 12:49                 ` Ihor Radchenko
2021-04-27 19:41           ` Bastien

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.