1610 Commits

Author SHA1 Message Date
Mitchell Hashimoto
809593473b terminal: PageList.pin doesn't allow out of bounds x values
Fixes #2958

The y was alround bounded but we allowed any x value and assumed the
caller would handle it. This is not the case so we now check the x and
return null if it's out of bounds (same as y, which was already doing
this).
2024-12-23 13:27:19 -08:00
Qwerasd
cb60f9d1da fix(RefCountedSet): Gracefully handle pathological cases
Poor hash uniformity and/or a crafted or unlucky input could cause the
bounds of the PSL stats array to be exceeded, which caused memory
corruption (not good!) -- we avoid such cases now by returning an
OutOfMemory error if we're about to insert and there's an item with a
PSL in the last slot.
2024-12-23 16:03:26 -05:00
Qwerasd
b44ebed798 Fix a scenario that could cause issues under some conditions
I don't know if this actually occurs in a way that can cause serious
problems, but it's better to nip it in the bud.
2024-12-23 15:45:30 -05:00
Qwerasd
a51871a3f7 RefCountedSet: simplify insert logic, cleanup, improve comments
Previous logic had multiple issues that were hiding in edge cases of
edge cases with the ressurected item handling among other things; the
added assertIntegrity method finds these issues, the primary one being
an edge case where an ID is present in two different buckets.

Added more comments to explain logic in more detail and fixed a couple
little things like always using `+%` when incrementing the probe pos,
and replacing a silent return on an integrity issue that should be
impossible (`table[item.meta.bucket] != id`) with an assert.
2024-12-23 15:43:57 -05:00
Jon Parise
82756f8b4c terminal: handle consecutive .input's in clearPrompt
Our semantic prompts are row-based, so the last prompt marker set on a
row "wins". In the case of at least our bash shell integration, this
means that consecutive prompt lines will all be marked as .input (OSC
133;B -- end-of-prompt, start of input).

Previously, clearPrompt() identified the current prompt's "area" by
searching upward from the current row until it encounters a .prompt
marker or some command output. In the bash case, .prompt is never the
dominant ("last") marker, so clearPrompt() would aggressively clear all
immediately preceding consecutive prompts.

With this change, we'll stop searching upwards when we encounter some
command output, a .prompt marker, _or another .input marker_. That last
case prevents clearPrompt() from unintentionally clearing earlier prompt
lines.

There may be improvements we can make to the way that our bash shell
integration emits semantic prompt markers, but I think this logic is
generally sound for all cases, and it specifically improves the current
bash prompt-clearing experience.
2024-12-16 21:06:15 -08:00
Mitchell Hashimoto
6f01dbf792 Select boundary dollar (#2938)
Proposed fix for #2933
2024-12-12 16:30:19 -08:00
Mitchell Hashimoto
e5e090deaf test: big perf win by pausing integ checks while growing pages (#2956)
In multiple tests we create 1 or more pages by growing them 1 row at a
time, which results in an integrity check of the page for each row grown
which is just... horrible. By simply pausing integrity checks while
growing these pages (since growing them is not the point of the test) we
MASSIVELY speed up all of these tests.

Also reduced grapheme bytes during testing and made the Terminal "glitch
text" test actually assert what it intends to achieve, rather than just
blindly assuming 100 copies of the text will be the right amount -- this
lets us stop a lot earlier, making it take practically no time.
2024-12-12 16:12:22 -08:00
Qwerasd
10abeba414 test: big perf win by pausing integ checks while growing pages
In multiple tests we create 1 or more pages by growing them 1 row at a
time, which results in an integrity check of the page for each row grown
which is just... horrible. By simply pausing integrity checks while
growing these pages (since growing them is not the point of the test) we
MASSIVELY speed up all of these tests.

Also reduced grapheme bytes during testing and made the Terminal "glitch
text" test actually assert what it intends to achieve, rather than just
blindly assuming 100 copies of the text will be the right amount -- this
lets us stop a lot earlier, making it take practically no time.
2024-12-12 16:58:48 -05:00
Mitchell Hashimoto
c1a6319490 unicode: emoji modifier requires emoji modifier base preceding to not… (#2954)
… break

Fixes #2941

This fixes the rendering of the text below. For those that can't see it,
it is the following in UTF-32: `0x22 0x1F3FF 0x22`.

```
"🏿"
```

`0x1F3FF` is the Fitzpatrick modifier for dark skin tone. It has the
Unicode property `Emoji_Modifier`. Emoji modifiers are defined in UTS
#51 and are only valid based on ED-13:

```
emoji_modifier_sequence := emoji_modifier_base emoji_modifier
emoji_modifier_base := \p{Emoji_Modifier_Base}
emoji_modifier := \p{Emoji_Modifier}
```

Additional quote from UTS #51:

> To have an effect on an emoji, an emoji modifier must immediately
follow
> that base emoji character. Emoji presentation selectors are neither
needed
> nor recommended for emoji characters when they are followed by emoji
> modifiers, and should not be used in newly generated emoji modifier
> sequences; the emoji modifier automatically implies the emoji
presentation
> style.

Our precomputed grapheme break table was mistakingly not following this
rule. This commit fixes that by adding a check for that every
`Emoji_Modifier` character must be preceded by an `Emoji_Modifier_Base`.
This only has a cost during compilation (table generation). The runtime
cost is identical; the table size didn't increase since we had leftover
bits we could use.
2024-12-12 13:05:59 -08:00
Mitchell Hashimoto
fd1201323e unicode: emoji modifier requires emoji modifier base preceding to not break
Fixes #2941

This fixes the rendering of the text below. For those that can't see it,
it is the following in UTF-32: `0x22 0x1F3FF 0x22`.

```
"🏿"
```

`0x1F3FF` is the Fitzpatrick modifier for dark skin tone. It has the
Unicode property `Emoji_Modifier`. Emoji modifiers are defined in UTS
#51 and are only valid based on ED-13:

```
emoji_modifier_sequence := emoji_modifier_base emoji_modifier
emoji_modifier_base := \p{Emoji_Modifier_Base}
emoji_modifier := \p{Emoji_Modifier}
```

Additional quote from UTS #51:

> To have an effect on an emoji, an emoji modifier must immediately follow
> that base emoji character. Emoji presentation selectors are neither needed
> nor recommended for emoji characters when they are followed by emoji
> modifiers, and should not be used in newly generated emoji modifier
> sequences; the emoji modifier automatically implies the emoji presentation
> style.

Our precomputed grapheme break table was mistakingly not following this
rule. This commit fixes that by adding a check for that every
`Emoji_Modifier` character must be preceded by an `Emoji_Modifier_Base`.
This only has a cost during compilation (table generation). The runtime
cost is identical; the table size didn't increase since we had leftover
bits we could use.
2024-12-12 12:53:08 -08:00
Qwerasd
536ed60db1 fix(kittygfx): load & display command shouldn't respond to i=0,I=0
Load and display (`T`) was responding even with implicit IDs, because
the display was achieved with an early return in the transmit function
that bypassed the logic to silence implicit ID responses- by making it
not an early return we fix this.
2024-12-12 15:30:37 -05:00
Toby Jaffey
47273de4c3 Added "selectWord with character boundary" test for dollar sign. 2024-12-12 16:47:04 +00:00
Toby Jaffey
5ef422b69a Add '$' to select boundaries, for same behaviour as iTerm 2024-12-11 23:38:34 +00:00
Qwerasd
2f31e1b7fa fix(kittygfx): don't respond to T commands with no i or I
If a transmit and display command does not specify an ID or a number,
then it should not be responded to. We currently automatically assign
IDs in this situation, which isn't ideal since collisions can happen
which shouldn't, but this at least fixes the glaring observable issue
where transmit-and-display commands yield unexpected OK responses.
2024-12-10 14:30:59 -05:00
Mitchell Hashimoto
1ee7da174b flake: update to Nix 24.11 2024-12-05 12:15:48 -08:00
Mitchell Hashimoto
50b36c5d86 comments 2024-12-04 12:38:40 -08:00
Mitchell Hashimoto
b9dda6ad87 terminal: PageListSearch works! 2024-12-04 12:30:14 -08:00
Mitchell Hashimoto
6361bf47f7 terminal: update comments/docs on sliding window search 2024-12-04 11:25:25 -08:00
Mitchell Hashimoto
34fb840cf9 terminal: search match on overlap case 2024-12-04 11:16:45 -08:00
Mitchell Hashimoto
852e04fa00 terminal: test for match in second slice of circ buf 2024-12-04 10:58:38 -08:00
Mitchell Hashimoto
af1ee4d95f terminal: search match across page boundary 2024-12-04 10:36:22 -08:00
Mitchell Hashimoto
79026a1148 terminal: test no match pruning 2024-12-03 15:55:18 -08:00
Mitchell Hashimoto
09e4cccd2c terminal: remove unused pagesearch 2024-12-03 15:53:13 -08:00
Mitchell Hashimoto
b487aa8e1f terminal: search across two pages and pruning appears to be working 2024-12-03 15:53:12 -08:00
Mitchell Hashimoto
d307b02e40 terminal: sliding window search can move the cursor 2024-12-03 15:53:12 -08:00
Mitchell Hashimoto
6ed298c9c1 terminal: sliding window search starts working 2024-12-03 15:53:12 -08:00
Mitchell Hashimoto
2a13c6b6a3 terminal: working on a pagelist sliding window for search 2024-12-03 15:53:12 -08:00
Mitchell Hashimoto
61c5fb8115 terminal: single pagelist node search 2024-12-03 15:53:12 -08:00
Mitchell Hashimoto
204e4f8663 terminal: support cell_map for encodeUtf8 2024-12-03 15:53:12 -08:00
Mitchell Hashimoto
bcefbfd7b4 terminal: move UTF8 encoding to Page and wrap around it 2024-12-03 15:53:12 -08:00
Mitchell Hashimoto
e712314f31 terminal: PageList.reset has to zero arena memory to avoid reuse
Fixes #2877

As the comment in the diff states, we rely on `mmap` to zero our memory.
When we reset we are reusing previously allocated memory so we won't hit
an `mmap`. We need to zero the memory ourselves.

This is pretty slow if there is a lot of memory but in every case except
allocation failures, we expect there to be only a few pages allocated.
2024-12-03 08:58:57 -05:00
Mitchell Hashimoto
212bd3d5fb terminal: fullReset uses the new screen reset methods 2024-12-02 17:44:07 -05:00
Mitchell Hashimoto
d7fcaefdf3 terminal: PageList.reset 2024-12-02 17:26:19 -05:00
Mitchell Hashimoto
d57d1d2395 terminal: failing tracked pin test on fullReset 2024-12-02 09:39:43 -05:00
Mitchell Hashimoto
853ba9e3c7 terminal: reset should preserve desired default mode values
Fixes #2857

Some terminal modes always reset, but there are others that should be
conditional based on how the terminal's default state is configured.
Primarily from #2857 is the grapheme clustering mode (mode 2027) which
was always resetting to false but should be conditional based on the
the `grapheme-width-method` configuration.
2024-11-29 14:42:01 -08:00
Mitchell Hashimoto
e20b27de84 terminal: eraseChars was checking wide char split boundary on wrong cell
Fixes #2817

The test is pretty explanatory. I also renamed `end` to `count` since I
think this poor naming was the reason for the bug. In `eraseChars`, the
`count` (nee `end`) is the number of cells to erase, not the index of
the last cell to erase.
2024-11-26 14:29:58 -08:00
Mitchell Hashimoto
039f9231de terminal: parse CSI 22/23 for push/pop title
Related to #2668

This just implements the VT stream parsing. The actual handling of these
events still needs to be done.
2024-11-13 19:49:45 -08:00
Mitchell Hashimoto
e225eb9eff terminal: OSC7 with empty URL resets the pwd to nil
When an empty string is given to OSC7, the pwd is reset to nil (as if
the terminal never received a pwd report to begin with). This is
analogous to how OSC0/2 reset the title to nil when given an empty
string.

This is practically useful for macOS because it allows our proxy icon to
also be reset instead of being stuck on the last known path.

This breaks from any known terminal behavior. As far as I can find, this
is totally unspecified so we're somewhat free to do what we want. I
don't think any terminal programs depend on this behavior, so I think
it's safe to change it.
2024-11-13 13:43:49 -08:00
Mitchell Hashimoto
067a36d67c termio: handle empty titles (OSC 0/2)
Fixes #2651

First, our OSC parser didn't allow blank OSC 0 or 2 requests. This
should be allowed and this fixes that with a test.

Second, it seems many terminals (iTerm2, Kitty) treat setting a blank
title as resetting to whatever the default title is rather than
explicitly setting it as blank. If a program wants a title to be blank
they should send a single space. This commit follows this behavior.
2024-11-13 12:12:43 -08:00
Mitchell Hashimoto
1335af3e4a terminal: change pagelist linked list to an intrusive linked list 2024-11-07 15:12:54 -08:00
Mitchell Hashimoto
aed51fd0b0 terminal: PageList rename "page" to "node" everywhere
This is more correct: a pagelist is a linked list of nodes, not pages.
The nodes themselves contain pages but we were previously calling the
nodes "pages" which was confusing, especially as I plan some future
changes to the way pages are stored.
2024-11-07 13:44:39 -08:00
Rick Calixte
e0c5bdc53b Terminal: Reinitialize screens on scrollback reset
When resetting the terminal screen, the memory buffer allocated for the
scrollback is now cleared by reinitializing the screen and falling back to the
current method if any of the attempts to reinitialize fail.

Closes #2464
2024-10-30 17:21:38 -04:00
Qwerasd
487f08b1dd fix(PageList, Page): fix off-by-1 in map capacity checks
We're already using `>=`, we don't need to also use `- 1`
2024-10-28 15:41:34 -07:00
Mitchell Hashimoto
6109edd00b terminal: refactor hyperlink memory management
Fixes #2500
Based on #2508

This separates out the concept of a "hyperlink" from a "hyperlink page
entry." The difference is that the former has real Zig slices into
things like strings and the latter has offsets into terminal page
memory.

From this separation, the Page structure now has an `insertHyperlink`
function that takes a hyperlink and converts it to a page entry.

This does a couple things: (1) it moves page memory management out of
Screen and into Page which is historically more appropriate and (2) it
let's us more easily test hyperlinks from the Page unit tests.

Finally, this PR makes some error sets explicit.
2024-10-28 15:30:04 -07:00
Marijn Besseling
4496e7d314 implement overline decoration (SGR 53/55) 2024-10-21 08:36:08 -04:00
Tim Culverhouse
93643d1741 sgr: add support for legacy double underline
SGR 21 is defined to be a double underline. This behavior is common
among many terminals, notably xterm.

References: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_
2024-09-27 22:22:22 -05:00
Mitchell Hashimoto
fade882574 Merge pull request #2300 from vancluever/terminal-kitty-large-signed-ints
terminal/kitty: increase value buffer, make 'H' and 'V' i32
2024-09-25 09:41:40 -07:00
Chris Marchesi
861531a1fd terminal/kitty: increase value buffer, make 'H' and 'V' i32
This commit increases the value buffer to 11 characters - this is
technically what it should be to allow for large negative integers
(i.e., 2.4 billion plus the sign character).

Additionally corrected the types for 'H' (horizontal offset) and 'V'
(vertical offset) - these are supposed to be i32 versus u32.

Added some extra tests to test all of this stuff as well.

I've also added a few more tests to help track these cases.
2024-09-25 09:01:39 -07:00
Mitchell Hashimoto
f858ae13ae terminal: clarify comment 2024-09-21 21:05:46 -07:00
Mitchell Hashimoto
f0eb5d0d43 terminal: test for scenario where grow() has to prune with a single page
See comments in the test, also this:

> The scenario is if you adjustCapacity a page beyond a std_size then our
> precondition no longer holds. PageList.adjustCapacity makes no guarantee
> that the resulting capacity fits within a standard page size. It is in fact
> documented this way and that it is slow since we have to mmap out of our
> memory pool.
2024-09-21 21:05:01 -07:00