khal icon indicating copy to clipboard operation
khal copied to clipboard

line wrapping

Open mirabilos opened this issue 4 months ago • 3 comments

Three-part suggestion.

One, add --width to khal list.

Two, add a configurable continuation indent to the wrapping (textwrap does have subsequent_indent, but the indent should not be highlighted, so you’ll probably wish to do it manually in color_wrap).

Three, make things actually line up. Right now, I have:

Today, 12.08.2025
↔ Urlaub $name
⇥ testgt2 mit einem sehr langen Namen lorem ipsum dolor und so weiter und so fort et cetera etm…
↔ Urlaub $othername
 testgttermin mit einem sehr langen Namen lorem ipsum dolor und so weiter und so fort et cetera etm…
Tomorrow, 13.08.2025
↔ Urlaub $othername
17:00:00-18:00:00 Testtermin mit einem sehr langen Namen lorem ipsum dolor und so weiter und so fort et cetera etm…

I’d suggest adding before nōn-range whole-day events and before nōn-whole-day events, so they line up, plus continuation indent:

Today, 12.08.2025
↔ Urlaub $name
⇥ testgt2 mit einem sehr langen Namen lorem ipsum dolor und so weiter
  und so fort et cetera etm…
↔ Urlaub $othername
• testgttermin mit einem sehr langen Namen lorem ipsum dolor und so
  weiter und so fort et cetera etm…
Tomorrow, 13.08.2025
↔ Urlaub $othername
• 17:00:00-18:00:00 Testtermin mit einem sehr langen Namen lorem ipsum
  dolor und so weiter und so fort et cetera etm…

For the ASCII case, of course equivalent, just wider indent.

In this case, you might not even need the continuation indent configurable, but OTOH since people can change the formatting, you may wish to keep it so.

mirabilos avatar Aug 12 '25 15:08 mirabilos

PoC (definitely not PR-worthy, inlines Unicode):

--- khalendar/event.py~	2025-08-12 17:35:27.202768626 +0200
+++ khalendar/event.py	2025-08-12 17:38:21.466616269 +0200
@@ -706,6 +706,13 @@
             else:
                 attributes['start-end-time-style'] = ''
 
+        attributes['start-end-time-style-indented'] = attributes['start-end-time-style']
+        if allday:
+            if not attributes['start-end-time-style-indented']:
+                attributes['start-end-time-style-indented'] = '‣'
+        else:
+                attributes['start-end-time-style-indented'] = '• ' + attributes['start-end-time-style-indented']
+
         if allday:
             attributes['end-necessary'] = ''
             attributes['end-necessary-long'] = ''

Turns out that using ‣ ipv • for whole-day events (closer to the range symbols) to differentiate looks better.

(And, yes, next I’ll fix my date/time formats.)

mirabilos avatar Aug 12 '25 15:08 mirabilos

PoC for the line wrapping (I didn’t add the option because I don’t have the time to learn about click right now, but if you like my PoCs I can probably make a PR with better versions):

--- cli.py~	2025-08-12 17:48:28.758595369 +0200
+++ cli.py	2025-08-12 17:49:56.490521171 +0200
@@ -189,6 +189,7 @@
             daterange=daterange,
             once=once,
             notstarted=notstarted,
+            width=79,
             conf=ctx.obj['conf'],
             env={"calendars": ctx.obj['conf']['calendars']},
             json=json
--- utils.py~	2025-08-12 17:49:58.562519425 +0200
+++ utils.py	2025-08-12 17:51:07.614461014 +0200
@@ -100,6 +100,8 @@
             lines[num] += RESET
             if (num + 1) < len(lines):
                 lines[num + 1] = sgr + lines[num + 1]
+        if (num + 1) < len(lines):
+            lines[num + 1] = '  ' + lines[num + 1]
     return lines
 
 

I did quickly look into not counting the colour escapes (relatively easy, as they all go from ESC to m in khal), but then we also need wcwidth(3), and while there are Python3 libraries that implement-ish a wcwidth-like function, they don’t use the same width data as the system libc (and therefore screen and xterm) does, and as such are unsuitable, so I decided to leave the colour escapes in while wrapping to overestimate the per-line character count so the occasional fullwidth character won’t make it fail.

To solve this properly, we’ll need to call out to libc, which is going to be iffy. Reimplementing the width calculation means updating it all the time, and then it’ll be out of sync if locale data gets updated anyway, so I’d advice against doing so.

mirabilos avatar Aug 12 '25 15:08 mirabilos

I guess one alternative would be to output to JSON and then format that myself.

mirabilos avatar Aug 12 '25 16:08 mirabilos