Commit graph

32 commits

Author SHA1 Message Date
Daniel Eklöf
bdb79e8b9f
osc: add support for OSC 133;A (prompt markers)
This patch adds support for the OSC-133;A sequence, introduced by
FinalTerm and implemented by iTerm2, Kitty and more. See
https://iterm2.com/documentation-one-page.html#documentation-escape-codes.html.

The shell emits the OSC just before printing the prompt. This lets the
terminal know where, in the scrollback, there are prompts.

We implement this using a simple boolean in the row struct ("this row
has a prompt"). The prompt marker must be reflowed along with the text
on window resizes.

In an ideal world, erasing, or overwriting the cell where the OSC was
emitted, would remove the prompt mark. Since we don't store this
information in the cell struct, we can't do that. The best we can do
is reset it in erase_line(). This works well enough in the "normal"
screen, when used with a "normal" shell. It doesn't really work in
fullscreen apps, on the alt screen. But that doesn't matter since we
don't support jumping between prompts on the alt screen anyway.

To be able to jump between prompts, two new key bindings have been
added: prompt-prev and prompt-next, bound to ctrl+shift+z and
ctrl+shift+x respectively.

prompt-prev will jump to the previous, not currently visible, prompt,
by moving the viewport, ensuring the prompt is at the top of the
screen.

prompt-next jumps to the next prompt, visible or not. Again, by moving
the viewport to ensure the prompt is at the top of the screen. If
we're at the bottom of the scrollback, the viewport is instead moved
as far down as possible.

Closes #30
2022-06-16 19:02:10 +02:00
Daniel Eklöf
497c31d9fc
commands: scroll up: simplify viewport clamping logic
When scrolling the viewport up, we need to ensure we don’t go past the
scrollback wrap around.

This was previously done using “custom” logic that tried to calculate
many rows away from the scrollback start the current viewport is.

But this is *exactly* what grid_row_abs_to_sb() does, except it
doesn’t account for uninitialized scrollback.

So, copy the logic from grid_row_abs_to_sb(), but ensure scrollback
start points to valid scrollback data. The maximum number of rows
we’re allowed to scroll is now the same as the current viewport’s
sb-relative coordinate.

Maybe closes #1074
2022-06-13 11:53:37 +02:00
Craig Barnes
7045c177fd
commands: fix LOG_DBG() usage in cmd_scrollback_{up,down}
The "end" variable was removed from both of these functions in
commit cb43c58150, but the references to it in the expansion
of LOG_DBG() weren't.
2022-04-27 20:44:14 +02:00
Daniel Eklöf
cb43c58150
commands: refactor scrollback up/down
When moving the viewport in the scrollback (i.e. “scrolling”), we need
to ensure the viewport is not moved past the beginning, or end, of the
scrollback.

This was previously accomplish by first limiting the number of lines
to scroll to the number of visible rows (i.e the viewport _size_), and
by adjusting the viewport after moving it, to ensure it doesn’t point
into an uninitialized scrollback area etc.

I.e. the implementation was _reactive_.

This patch rewrites the logic to be _proactive_; we now calculate
_where_ the beginning (or end) of the scrollback is, and then how many
lines there is from there, to the viewport. This is our _maximum_
number of lines to scroll.

When done correctly (which I hope this patch does), this allows us to
remove _all_ checks after moving the viewport - we already _know_ it’s
correct, and valid.

As a bonus, we can remove the old limit, where scrolling was only
allowed to be at most a single page.
2022-02-23 19:03:35 +01:00
Daniel Eklöf
0900d01ec9
input: clean up mouse scroll handling
* Allow scrolling on the normal (non-alt) screen, when application is
  grabbing the mouse (when user presses Shift).
* Use term_mouse_grabbed() instead of explicitly checking for
  MOUSE_NONE tracking.
* Remove mouse tracking check from cmd_scrollback_{up,down}. Caller is
  expected to have done the check.
* Don’t scroll down on mouse wheel tilt events.
2021-10-27 17:09:26 +02:00
Daniel Eklöf
3c123425fb
command: scrollback: don’t allow scrolling in URL mode 2021-02-26 09:15:46 +01:00
Daniel Eklöf
6726494f4c
url-mode: store absolute row numbers in start/end coordinates
This allows us to update the jump label positions when the viewport
changes.

This in turn allows us to stay in URL mode while the user is using the
mouse to scroll in the scrollback history.

Scrolling with the keyboard is currently not possible, since input
handling in URL mode does not recognize “regular” key bindings. We
_could_ add scrollback up/down bindings to URL mode too, but lets not,
for the time being.

(Note: an alternative to this patch is to disallow mouse scrolling
too. Then we could have kept the URL start/end as viewport local
coordinates).
2021-02-07 16:33:34 +01:00
Craig Barnes
e56136ce11 debug: rename assert() to xassert(), to avoid clashing with <assert.h> 2021-01-16 20:16:00 +00:00
Craig Barnes
104fe2fa55 Fix some spelling mistakes 2020-08-15 19:39:00 +01:00
Daniel Eklöf
483ea4ae73
scrolling: fix crash when offset was exactly at the wrap-around
When making sure we don't scroll past the scrollback history, and the
current offset was exactly at the wrap around, the new view port was
set to offset+1, which in this particular case meant outside the valid
row numbers.
2020-05-19 18:51:56 +02:00
Daniel Eklöf
08588cd0fc
selection: handle viewport wrap around correctly
When the viewport wraps around, the selection points may be
"incorrect".
2020-05-19 18:49:42 +02:00
Daniel Eklöf
69c3e74498
util.h: new header file defining commonly used macros 2020-05-01 11:46:24 +02:00
Daniel Eklöf
a1b5862db2
scroll-up: ensure view is valid after adjusting an overshot scrollback
When we scroll up, we need to ensure that we don't scroll too far,
"past" the scrollback limit. I.e. we need to ensure we don't wrap
around.

The code did this. But, in certain scenarios, the resulting view
points into uninitialized scrollback history.

This happens when we haven't yet filled the entire scrollback, and
scroll up enough lines to wrap around the scrollback. The old code
would adjust the view for the wrap around, but doing so pointed the
view at the not-yet utilized scrollback.
2020-02-21 23:35:43 +01:00
Daniel Eklöf
5d2b2dc8a7
commands: scrollback: don't scrollback if mouse tracking is enabled 2019-11-30 16:57:52 +01:00
Daniel Eklöf
caee8db89a
commands: scrollback: don't scrollback if mouse tracking is enabled 2019-11-30 16:49:38 +01:00
Daniel Eklöf
a42df2434b
scrollback: regression: fix rendering of scrollback diffs less than a screen
When doing "small" scrolls (typically done via mouse wheel or
similar), we render the scrolling by emitting a "scroll damage".

A recent commit changed how scroll damage is rendered; only when the
view is at the bottom ("following" the screen output) do we render the
damage.

To fix this, add a new type of scroll damage,
SCROLL_DAMAGE_IN_VIEW and SCROLL_DAMAGE_REVERSE_IN_VIEW.

These signal to the renderer that it should always render the damage.
2019-10-29 21:09:37 +01:00
Daniel Eklöf
7c7720a3ab
scrolling: optimize row access by assuming number of rows is a power of 2
With this assumption, we can replace 'a % b' with 'a & (b - 1)'. In
terms of instructions, this means a fast 'and' instead of a slow
'div'.

Further optimize scrolling by:

* not double-initializing empty rows. Previously, grid_row_alloc()
  called calloc(), which was then followed by a memset() when
  scrolling. This is of course unnecessary.

* Don't loop the entire set of visible rows (this was done to ensure
  all visible rows had been allocated, and to prefetch the cell
  contents).

  This isn't necessary; only newly pulled in rows can be NULL. For
  now, don't prefetch at all.
2019-08-22 17:33:23 +02:00
Daniel Eklöf
42fdb3653d
scrollback: use scroll damage to speed up scrolling
When scrolling through the scrollback lines, use scroll damage instead
of re-rendering the entire screen whenever it makes sense. I.e. when
the number of lines isn't a whole page or more.
2019-08-04 19:06:49 +02:00
Daniel Eklöf
ebf0a11fa0
render: add render_refresh() 2019-07-24 20:11:41 +02:00
Daniel Eklöf
6e4c31960a
scrollback: limit maximum number of lines one can scrollback at once 2019-07-11 18:34:03 +02:00
Daniel Eklöf
cbac302ba1
scrollback: fix assertions in debug builds; need to wrap row number 2019-07-11 18:25:46 +02:00
Daniel Eklöf
5a92202a49
scrollback: in debug, verify all rows in the view are initialized 2019-07-10 16:36:10 +02:00
Daniel Eklöf
1ff1b3a71e
grid: don't pre-allocate the entire grid (with all scrollback lines)
The row array may now contain NULL pointers. This means the
corresponding row hasn't yet been allocated and initialized.

On a resize, we explicitly allocate the visible rows.

Uninitialized rows are then allocated the first time they are
referenced.
2019-07-10 16:27:55 +02:00
Daniel Eklöf
5144fcba0c
scrollback: disable debug logging 2019-07-10 14:45:00 +02:00
Daniel Eklöf
607755536f
scrollback: use term_damage_view() 2019-07-10 14:43:46 +02:00
Daniel Eklöf
a01efd07e3
scrollback: don't allow more scrolling when already at the top or bottom 2019-07-10 14:42:48 +02:00
Daniel Eklöf
d8d4b34362
scrollback: fix scrolling outside initialized lines in new terminal 2019-07-10 14:28:20 +02:00
Daniel Eklöf
18c61a9a2a
scrollback: fix off-by-one when grid size matches terminal/window size 2019-07-10 09:55:53 +02:00
Daniel Eklöf
ed0fd2d442
scrollback: don't redraw if view doesn't change 2019-07-10 09:30:35 +02:00
Daniel Eklöf
1d338f8477
scrollback: don't scroll past scrollback history 2019-07-10 09:29:36 +02:00
Daniel Eklöf
b058e6384a
scrollback: initial support for mouse scrolling 2019-07-10 09:15:37 +02:00
Daniel Eklöf
bcd111d203
wip: initial scroll back support
Can scroll up and down, and stops when the beginning/end of history is
reached.

However, it probably breaks when the entire scrollback buffer has been
filled - we need to detect when the view has wrapped around to the
current terminal offset.

The detection of when we've reached the bottom of the history is also
flawed, and only works when we overshoot the bottom with at least a
page.

Resizing the windows while in a view most likely doesn't work.

The view will not detect a wrapped around scrollback buffer. I.e. if
the user has scrolled back, and is stationary at a view, but there is
still output being produced. Then eventually the scrollback buffer
will wrap around. In this case, the correct thing to do is make the
view start following the beginning of the history. Right now it
doesn't, meaning once the scrollback buffer wraps around, you'll start
seeing command output...
2019-07-09 16:26:36 +02:00