Commit graph

6795 commits

Author SHA1 Message Date
Daniel Eklöf
8b63869f57
render: minimum window size: 2 cols -> 1 col 2025-02-10 13:19:57 +01:00
Daniel Eklöf
eced7cf1d6
grid: reflow: don't special case the first cell in a multi-column character
Wrap *all* cell copying logic in a for-loop for the characters
width. This _should_, in theory, mean reflow of e.g. cursor
coordinates in the middle of a multi-column character works correctly.

Also fix reflow of cmd start/end integration.
2025-02-10 13:19:57 +01:00
Daniel Eklöf
6a181c9f72
grid: performance: check for non-NULL before comparing with terminator
This should be slightly faster in the normal(?) case (no styled
underlines or OSC-8).
2025-02-10 13:19:57 +01:00
Daniel Eklöf
3d66db63cc
grid: refactor reflow
We've been trying to performance optimize reflow by "chunking" cells;
try to gather as many as possible, and memcpy a chunk at once.

The problem is that a) this quickly becomes very complex, and b) is
very hard to get right for multi-column characters, especially when we
need to truncate long ones due to the window being too small.

Refactor, and once again walk and copy all cells one by one. This is
slower, but at least it's correct.
2025-02-10 13:19:50 +01:00
Daniel Eklöf
c63202ee0e
url-mode: regex: don't try to NULL-terminate an invalid vline 2025-02-10 13:09:07 +01:00
Daniel Eklöf
970d95c5a1
doc: foot.ini: fix 'hashes' regex example
It's A-F, not A-f
2025-02-10 13:08:33 +01:00
Daniel Eklöf
fce755aafe
forgejo: better names for templates 2025-02-10 12:58:35 +01:00
Daniel Eklöf
26acf41d13
grid: pull in misc.h when TIME_REFLOW is defined 2025-02-10 09:08:14 +01:00
Daniel Eklöf
98db965813
url-mode: terminate last virtual line before regex matching
If the last line doesn't have a hard linebreak, it was never NULL
terminated, causing regexec() to crash on an out-of-bounds access.
2025-02-10 08:54:42 +01:00
Johannes Altmanninger
4e5ad6e013
Fix URL detection regression on lines with NUL bytes
Commit 859b4c89 (url-mode: wip: more work on regex matching,
2025-01-30) regressed URL detection in weechat. Some of the URLs
still work but others don't. This is because regexec() stops at the
first NUL, thus skipping the rest of the line. weechat seems create
NUL cells between their UI widgets.

Work around this by replacing NUL with space. This is probably correct
because selecting and copying those cells also translates to space
(not sure where in the code).
2025-02-10 08:06:08 +01:00
Daniel Eklöf
325086291b
config: regex: fix invalid free
Zero-initialize the 'launch' spawn template before calling
value_to_spawn_template(). This is needed since
value_to_spawn_template() tries to free the old value before assigning
the new one.

Closes #1951
2025-02-10 07:43:52 +01:00
Daniel Eklöf
d84b0d4c6a
Merge branch 'text-width-protocol' 2025-02-06 14:03:33 +01:00
Daniel Eklöf
8d20b82721
changelog: text-sizing protocol 2025-02-06 14:02:38 +01:00
Daniel Eklöf
a3a404a257
render: resize: note why min_cols=7 2025-02-06 14:02:38 +01:00
Daniel Eklöf
d7e8f29ee2
grid: reflow: get number of spacers to insert from the old grid
When checking if we're breaking in the middle of a multi-column
character, we counted spacers starting from the break point. But,
the character may be wider than that. Use the fact that the spacers
cells encode how many *more* there are after them; when we get to the
first one, we know exactly how wide the character is.
2025-02-06 14:02:38 +01:00
Daniel Eklöf
9840204097
term: print-non-ascii: propagate existing forced-width
When appending to an existing composed character, "inherit" its forced
width, if set.

Also make sure to actually _use_ the forced width, if set, rather than
the calculated width.

This fixes an issue when appending zero-width codepoints to a
forced-width combining character.
2025-02-06 14:02:38 +01:00
Daniel Eklöf
0f93766614
osc: text-size: disable optimization
The optimization prevents the forced-width to be set on the new
combining character, causing issues when followed by more zero-width
codepoints.
2025-02-06 14:02:38 +01:00
Daniel Eklöf
ed35a238d6
doc: ctlseq: add OSC 66 (kitty text sizing) 2025-02-06 14:02:38 +01:00
Daniel Eklöf
3998f8570c
composed: codespell: infinitely 2025-02-06 07:46:00 +01:00
Daniel Eklöf
1260004330
osc: text-sizing: implement w=0, plus optimize single-codepoint cases
If there's a single codepoint in the text portion of the OSC sequence,
and its calculated width matches the forced width, print it directly
to the grid instead of emitting a combining character.

When w=0, we split up the text string "as we normally would". Since we
don't support any other text-sizing parameters, this means simply
printing each codepoint to the grid.
2025-02-06 07:45:58 +01:00
Daniel Eklöf
d3f692990e
term+vt: refactor: move "utf8" char processing to term_process_and_print_non_ascii()
This function "prints" any non-ascii character (i.e. any character
that ends up in the action_utf8_print() function in vt.c) to the
grid. This includes grapheme cluster processing etc.

action_utf8_print() now simply calls this function.

This allows us to re-use the same functionality from other
places (like the text-sizing protocol).
2025-02-06 07:45:20 +01:00
Daniel Eklöf
7a8d2b5e01
osc: wip: kitty text size protocol
This brings initial support for the new kitty text-sizing
protocol. Note hat only the width-parameter ('w') is supported. That
is, no font scaling, and no multi-line cells.

For now, only explicit widths are supported. That is, w=0 does not yet
work.

There are a couple of changes to the renderer, to handle e.g.

    OSC 66 ; w=6 ; foobar ST

There are two ways this can get rendered, depending on whether
grapheme shaping has been enabled. We either shape it, and get an
array of glyphs back that we render. Or, we rasterize each codepoint
ourselves, and render each resulting glyph.

The two cases ends up in two different renderer loops, that worked
somewhat different. In particular, the first case has probably never
been tested/used at all...

With this patch, both are changed, and now uses some heuristic to
differentiate between multi-cell text strings (like in the example
above), or single-cell combining characters. The difference is mainly
in which offset to use for the secondary glyphs.

In a multi-cell string, each glyph is mapped to its own cell, while in
the combining case, we try to map all glyphs to the same cell.
2025-02-06 07:42:38 +01:00
Daniel Eklöf
1111f7e918
grid: reflow: handle composed characters longer than 2 cells
The logic that tries to ensure we don't break a line in the middle of
a multi-cell character was flawed when the number of cells were larger
than 2.

In particular, if the number of cells to copy were limited by the
number of cells left on the current (new) line, and were less than the
length of the multi-cell character, then we failed to insert the
correct number of spacers, and also ended up misplacing the multi-cell
character; instead of pushing it to the next line, it was inserted on
the current line, even though it doesn't fit.

Also change how trailing SPACER cells are rendered (cells that are
"fillers" at then end of a line, when a multi-column character was
pushed over to the next line): don't copy the previous cell's
attributes (which may be wrong anyway), use default attributes
instead.
2025-02-06 07:42:38 +01:00
Daniel Eklöf
e248e73753
composed: refactor: break out lookup with collision detection 2025-02-06 07:42:37 +01:00
Daniel Eklöf
1181f74d19
composed: re-factor: break out key calculation from vt.c 2025-02-06 07:42:37 +01:00
Daniel Eklöf
88dcde3ed8
term: insert-mode: handle combining characters correctly
When the client application emits combining characters, for example
multi-codepoint emojis, in insert-mode, we ended up pushing partial
graphemes to the right, for each codepoint, resulting in too many
cells (and with the wrong content) being inserted.

The fix is fairly simple; don't "insert" when appending characters to
an existing grapheme cluster.

This isn't something we can detect easily in print_insert() (it would
require us to do grapheme clustering again). Fortunately, we do have
the required information in action_utf8_print(). So, pass this
information as a boolean to term_print().

Closes #1947
2025-02-06 07:37:55 +01:00
Daniel Eklöf
dd01783f88
Merge branch 'regex-mode'
Closes #1386
Closes #1872
2025-02-05 13:47:06 +01:00
Daniel Eklöf
9d8021de47
changelog: custom regex's 2025-02-05 13:46:00 +01:00
Daniel Eklöf
9e12f791c5
doc: regex: custom regex's aren't URLs 2025-02-05 13:43:11 +01:00
Daniel Eklöf
b1f16c84e0
doc: improve regex example 2025-02-05 13:35:17 +01:00
Daniel Eklöf
0a32dc3820
spawn template variables are on the form ${}, not {} 2025-02-05 13:35:17 +01:00
Daniel Eklöf
a984531ce5
url-mode: use the first *sub* expression as URL
When auto-matching URLs (or custom regular expressions), use the
first *subexpression* as URL, rather than the while regex match.

This allows us to write custom regular expressions with prefix/suffix
strings that should not be included in the presented match.
2025-02-05 13:35:17 +01:00
Daniel Eklöf
31f536ff8c
config: remove debug logging 2025-02-05 13:35:17 +01:00
Daniel Eklöf
cf4324e6c6
tests: config: handle regex key bindings 2025-02-05 13:35:17 +01:00
Daniel Eklöf
2f902c1f5b
doc: foot.ini: document custom regular expressions 2025-02-05 13:35:17 +01:00
Daniel Eklöf
9d0f5cbd2a
foot.ini: improve documentation of custom regex 2025-02-05 13:35:17 +01:00
Daniel Eklöf
051cd6ecfc
config+url: add support for user-defined regex patterns
Users can now define their own regex patterns, and use them via key
bindings:

    [regex:foo]
    regex=foo(bar)?
    launch=path-to-script-or-application {match}

    [key-bindings]
    regex-launch=[foo] Control+Shift+q
    regex-copy=[foo] Control+Mod1+Shift+q

That is, add a section called 'regex:', followed by an
identifier. Define a regex and a launcher command line.

Add a key-binding, regex-launch and/or regex-copy (similar to
show-urls-launch and show-urls-copy), and connect them to the regex
with the "[regex-name]" syntax (similar to how the pipe-* bindings
work).
2025-02-05 13:35:17 +01:00
Daniel Eklöf
f718cb3fb0
xmalloc: calling xrealloc() or xreallocarray() with a 0-size is UB in C23
And likely to in future POSIX too.
2025-02-05 13:35:17 +01:00
Daniel Eklöf
ab4426f987
url-mode: regex: make sure there's always room for the NULL terminator 2025-02-05 13:35:17 +01:00
Daniel Eklöf
130b05f02b
foot.ini+doc: add default value of url.regex 2025-02-05 13:35:17 +01:00
Daniel Eklöf
d41b28bd02
url-mode+config: wip: add url.regex option 2025-02-05 13:35:17 +01:00
Daniel Eklöf
e76d8dd7af
config: remove url.{uri-characters,protocols} 2025-02-05 13:35:17 +01:00
Daniel Eklöf
05207fcde3
url-mode: wip: regex: tweak debug log message 2025-02-05 13:35:17 +01:00
Daniel Eklöf
6d344f82ee
url-mode: wip: regex: mention changes from original regex 2025-02-05 13:35:16 +01:00
Daniel Eklöf
031382f428
url-mode: wip: regex: don't allow {}, do allow matched [] 2025-02-05 13:35:16 +01:00
Daniel Eklöf
859b4c8921
url-mode: wip: more work on regex matching
Remove the old auto-detection and instead use the regex matches.
2025-02-05 13:35:16 +01:00
Daniel Eklöf
1c15ee940d
url-mode: wip: convert to regex matching for auto-detection 2025-02-05 13:35:16 +01:00
Daniel Eklöf
32919b1049
grid: typo 2025-02-05 13:35:16 +01:00
Daniel Eklöf
aae794e9bd
xmalloc: add xreallocarray() 2025-02-05 13:35:16 +01:00
Thomas Bonnefille
9443ac7e29
box-drawings: handle architecture with soft-float
Currently, architecture using soft-floats doesn't support instructions
FE_INVALID, FE_DIVBYZERO, FE_OVERFLOW and FE_UNDERFLOW and so building
on those architectures results with a build error.
As the sqrt math function should set errno to EDOM if an error occurs,
fetestexcept shouldn't be mandatory.

This commit removes the float environment error handling.

Signed-off-by: Thomas Bonnefille <thomas.bonnefille@bootlin.com>
2025-02-05 13:31:46 +01:00