2912 Commits

Author SHA1 Message Date
Mitchell Hashimoto
6fd082ed63 terminal: scroll region scroll up copied the wrong length of data
Fixes #315

This function has various cases that can be hit depending on the state
of the underlying circular buffer. It is a very well tested function but
this particular branch wasn't tested and unsurprisingly turns out there
is a bug in it.

Consider the following circular buffer state representing a terminal
screen with 1 column, 5 rows. Assume the circular buffer representing
this screen is such that `head == tail` and `head = 4` (zero-indexed,
full buffer size is 5). The head and tail are shown with an arrow below.

┌───────────────────────────────────────────────────────────────┐
│                               B                               │
├───────────────────────────────────────────────────────────────┤
│                               C                               │
├───────────────────────────────────────────────────────────────┤
│                               D                               │
├───────────────────────────────────────────────────────────────┤
│                               E                               │
├───────────────────────────────────────────────────────────────┤ ◀───  Head
│                               A                               │       Tail
└───────────────────────────────────────────────────────────────┘

The screen contents are "A B C D E" with each character on a new line.

Next, we set a scroll region from y=0 to y=3 (len=4). The scroll region
contents are "A B C D". Next, we issue a "delete lines" command with
n=2 (`CSI 2 M`) while the cursor is at the top-left corner. The delete
lines command deletes the given number of lines (n=2 in this case) and
shifts the remaining lines up. It does this only within the context
of the scroll region. Therefore, for `CSI 2 M` we would expect our
screen to become "C D _ _ E" (A, B are deleted, C, D shift up, and
E is untouched because its outside of the scroll region).

When executing this operation, we request the memory regions containing
the scroll region. This results in two pointers and lengths. For our
circular buffer state, we get the following:

┌───────────────────────────────────────────────────────────────┐ ◀──── ptr0
│                               A                               │
└───────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────┐ ◀──── ptr1
│                               B                               │
├───────────────────────────────────────────────────────────────┤
│                               C                               │
├───────────────────────────────────────────────────────────────┤
│                               D                               │
└───────────────────────────────────────────────────────────────┘

We get two pointers because our circular buffer wraps around the bottom.
The diagram above shows them in top/bottom order not in memory order
(The value of `ptr0 > ptr1` but it doesn't matter for the bug).

The way the math works is as follows:

  1. We calculate the number of lines we need to shift up. That
     value is `height - n`. Our height is 4 (scroll region height) and
     our n is 2 (`CSI 2 M`), so we know we're shifting up 2 lines.
     Let's call this `shift_lines`.

  2. Our start copy offset is `n` because the lines we are retaining
     are exactly after the `n` we're deleting (i.e. we're deleting 2
     lines so the start of the lines we're shifting up is the 3rd line).
     Let's call this `start_offset`.

  3. We realize that our start offset is greater than the size of ptr0,
     so we must be copy from ptr1 into ptr0. Further, we know our start
     offset into ptr1 must be `start_offset - ptr0.len`.
     Let's call this `start_offset_ptr1 = 1`.

  4. Copy `ptr1[start_offset_ptr1]` to `ptr0`. We copy up to
     `shift_lines` amount. `shift_lines` is 2 but `ptr0.len` is only
     `1`. So, we actually copy `@min(shift_lines, ptr0.len)` and have
     `1` line remaining.
     Let's call that `remaining = 1`.

  5. Copy `remaining` from `ptr1[ptr0.len]` to `ptr1`.

  6. Next we need to zero our remaining lines. Our slices only contain
     our scroll region so we know we can zero the memory from
     `ptr1[remaining]` to the end of `ptr1`. We know this because step 5
     only copied `remaining` bytes.

The end result looks like this:

┌───────────────────────────────────────────────────────────────┐ ◀──── ptr[0]
│                               C                               │
└───────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────┐ ◀──── ptr[1]
│                               D                               │
├───────────────────────────────────────────────────────────────┤
│                                                               │
├───────────────────────────────────────────────────────────────┤
│                                                               │
└───────────────────────────────────────────────────────────────┘

The bug was in step 6. We were incorrectly zeroing from `start_offset_ptr1`
instead of `remaining`. This was just a simple typo. The results are
devastating, but only under the exactly correct circumstances (those
in this commit message). In that scenario, the bug produced the
following:

┌───────────────────────────────────────────────────────────────┐ ◀────────── ptr[0]
│                               C                               │
└───────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────┐ ◀────────── ptr[1]
│                               D                               │
├───────────────────────────────────────────────────────────────┤
│                               C                               │
├───────────────────────────────────────────────────────────────┤
│                                                               │
└───────────────────────────────────────────────────────────────┘

Notice the incorrect "C" that remains and is not zeroed.

This example showed a scenario with 1 column and leaving only 1 line out
of the scroll region. The real bug in #315 would often mistakingly leave
multiple lines in the scroll region. The effect was that scrolling
produced garbage lines because you'd "scroll" and part of what should've
scrolled would remain.

This garbage state was only in the terminal screen state, so it didn't
impact actual programs running or their data (i.e. vim). But, it made
the program unusable.
2023-09-28 21:10:37 -07:00
Mitchell Hashimoto
7c440dea5e update zig 2023-09-28 15:30:51 -07:00
Nathan Youngman
73331887fe fabs builtin was renamed
https://github.com/ziglang/zig/pull/17248

I just tried installing from source and ran into the error:

> error: invalid builtin function: '@fabs'
2023-09-28 15:29:08 -07:00
Mitchell Hashimoto
145017915e Merge pull request #579 from mitchellh/prettier-nix
nix: install prettier, also ignore zig-cache/out
2023-09-28 15:23:29 -07:00
Mitchell Hashimoto
779611c04b nix: install prettier, also ignore zig-cache/out 2023-09-28 15:16:12 -07:00
Mitchell Hashimoto
a0a8901d8b Merge pull request #577 from mitchellh/patrickf/lint-markdown
Introduce Prettier and lint entire repo
2023-09-28 15:04:03 -07:00
Patrick Fong
caf134401f don't lint macos/, undo macos/ changes 2023-09-28 11:53:31 -07:00
Patrick Fong
8eb042968c undo changes to vendor 2023-09-28 11:22:28 -07:00
Patrick Fong
4f6401e815 update linting doc 2023-09-28 11:20:48 -07:00
Patrick Fong
6bceea898b update linting doc 2023-09-28 11:18:58 -07:00
Patrick Fong
3c44c08ffd add linting doc 2023-09-28 11:14:31 -07:00
Patrick Fong
09bafd753a ignore some other stuff 2023-09-28 11:06:04 -07:00
Patrick Fong
c2ec3f75ad lint JSON and Typescript as well 2023-09-28 11:05:54 -07:00
Patrick Fong
1cb6b50331 add Prettier step to check formatting 2023-09-28 10:56:53 -07:00
Patrick Fong
9d2a85d9cd lint all Yaml files 2023-09-28 10:42:38 -07:00
Patrick Fong
8be80558c7 lint all Md files 2023-09-28 10:27:15 -07:00
Mitchell Hashimoto
28b7782bbe core: do not scroll viewport if mouse reporting is requested
Fixes #570
2023-09-28 09:50:44 -07:00
Mitchell Hashimoto
c987ce785b Merge pull request #576 from mitchellh/gtk-wide
apprt/gtk: make wide-style gtk tabs configurable
2023-09-28 08:56:11 -07:00
Mitchell Hashimoto
685495c896 apprt/gtk: make wide-style gtk tabs configurable 2023-09-28 08:54:15 -07:00
Mitchell Hashimoto
16f5af8b32 macos: relable tabs when config is reloaded 2023-09-28 08:36:02 -07:00
Mitchell Hashimoto
0e4b91de88 macos: stylistic changes 2023-09-28 08:34:27 -07:00
Gregory Anders
137d24db9c macos: display keybinding instead of index in tab label 2023-09-28 08:28:46 -07:00
Gregory Anders
1fbd5e5590 macos: add keyEquivalent overload to also return modifier string 2023-09-28 08:28:46 -07:00
Gregory Anders
4837d840f6 macos: create modifier flags as OptionSet instead of from array
Nit picky change, but the OptionSet class (which NSEvent.ModifierFlags
is an instance of) has an API for incrementally setting values without
needing to create an array.
2023-09-28 08:28:46 -07:00
Gregory Anders
8f75e83958 macos: rename indexTabs() to relabelTabs()
This is a better name because the tab label may not necessarily be an
index (if a user binds some non-numeric key, for instance).
2023-09-28 08:28:46 -07:00
Gregory Anders
59ba6fac2b macos: add tab index labels 2023-09-28 08:28:46 -07:00
Mitchell Hashimoto
752aa11930 Merge pull request #575 from rockorager/dev
Revert default TERM to "xterm-ghostty"
2023-09-28 08:08:59 -07:00
Tim Culverhouse
d0c673cdfc terminfo: use 'xterm-ghostty' as primary name
Use "xterm-ghostty" as the primary terminfo name. This is a hack on a
hack...we use "xterm-ghostty" to prevent vim from breaking, and when we
do this as the default we break tcell-based applications (lazygit, aerc,
etc). tcell has a bug where the primary terminfo name must be the
value of TERM. https://github.com/gdamore/tcell/pull/639 fixes the issue
but is not merged yet.

Fixes: 779186ad ("config: add term config option")
2023-09-28 10:00:37 -05:00
Tim Culverhouse
c540d18095 config: default TERM to xterm-ghostty
Default the TERM value to "xterm-ghostty" to prevent breaking vim.
Consider changing back to ghostty in the future
2023-09-28 09:45:57 -05:00
Tim Culverhouse
5e473ebdb0 terminfo: add additional entries, fix smkx/rmkx
Add entries for secondary device attributes, XTVERSION.
2023-09-28 06:57:00 -05:00
Mitchell Hashimoto
6be4e4d45d Revert "macos: on Sonoma, manually add menu height padding for visible-menu"
This reverts commit 1dab2f9dd3bb19f8decc30826fd75d59bf412cc2.
2023-09-27 22:13:55 -07:00
Mitchell Hashimoto
fa56d6325e Merge pull request #569 from nfisher1226/expanded_tabs
(Gtk) Set tab labels to fill the available space, so that they will
2023-09-27 21:57:21 -07:00
Mitchell Hashimoto
0529c8bc28 terminfo: increase buffer size for test 2023-09-27 21:56:55 -07:00
Nathan Fisher
dca0ddb7e1 (Gtk) Set tab labels to fill the available space, so that they will
divide up the avialable horizontal area instead of leaving a large
empty space in the tab bar.
2023-09-28 00:10:07 -04:00
Mitchell Hashimoto
1942baefc6 Merge pull request #568 from rockorager/dev
terminfo: add mouse entries, correct kmouse
2023-09-27 19:45:10 -07:00
Tim Culverhouse
25710dfa6d terminfo: add mouse entries, correct kmouse
Add entries for XM and xm, these tell certain applications how to enable
mouse and the format of response they will receive.

Fix 'kmous' entry to match standard terminfo files.
2023-09-27 21:42:13 -05:00
Mitchell Hashimoto
a672519394 Merge pull request #567 from rockorager/dev
termio: reset mouse shape on terminal reset
2023-09-27 19:13:55 -07:00
Tim Culverhouse
0231c61a50 termio: reset mouse shape on terminal reset
Reset the mouse shape to `.default` when a full reset is done on the
terminal. Prevents the terminal from appearing to be in a persistent
hang
2023-09-27 20:51:31 -05:00
Mitchell Hashimoto
3188056bb2 Merge pull request #565 from mitchellh/macos-fs-menu
macos: custom fullscreen menu item to respect non-native fullscreen
2023-09-27 18:43:13 -07:00
Mitchell Hashimoto
c9b5e27f58 Merge pull request #564 from mitchellh/sonoma-fs
macos: on Sonoma, manually add menu height padding for visible-menu
2023-09-27 18:42:49 -07:00
Mitchell Hashimoto
21b46bd612 macos: change text to "toggle full screen" 2023-09-27 18:41:30 -07:00
Mitchell Hashimoto
57213547cd macos: custom fullscreen menu item to respect non-native fullscreen
Related to #392
2023-09-27 18:34:04 -07:00
Mitchell Hashimoto
1dab2f9dd3 macos: on Sonoma, manually add menu height padding for visible-menu
See the comment.
2023-09-27 18:17:35 -07:00
Mitchell Hashimoto
dcb25c6aa6 Merge pull request #563 from mitchellh/xtgettcap
Implement XTGETTCAP
2023-09-27 15:07:47 -07:00
Mitchell Hashimoto
1dcb23de0f termio/exec: need to defer deinit for DCS command 2023-09-27 14:52:13 -07:00
Mitchell Hashimoto
4724e0dcb4 terminfo: numeric comptime buffer only needs to be 10 bytes 2023-09-27 14:35:22 -07:00
Mitchell Hashimoto
28329761a7 terminfo: xtgettcap map name should use the source name 2023-09-27 14:30:27 -07:00
Mitchell Hashimoto
8208947290 termio/exec: hook up xtgettcap 2023-09-27 14:27:56 -07:00
Mitchell Hashimoto
a02378f969 terminfo: comptime map for xtgettcap results 2023-09-27 14:23:57 -07:00
Mitchell Hashimoto
823f47f695 termio: hook up dcs callbacks 2023-09-27 13:32:00 -07:00