Age | Commit message (Collapse) | Author |
|
The general style for errors, warnings and info messages is to start
with a capitalized letter and end without a period. The main exception
is when dealing with nouns that are clearer with special case handling,
e.g. "macOS failed to work" or "ioctl is borked".
|
|
This resolves a lot of NLL issues, however full NLL will be necessary to
handle a couple of remaining issues.
|
|
Due to the lazy initialization of lines in the Alacritty history, the
recording of ref tests was broken. Because a WM would often resize the
ref test window after it was spawned, some additional lines were
initialized in the stored ref test.
To make sure lazy initialization does not play any role in the recording
and replaying of reftests, before recording and replaying the tests, the
complete grid is initialized and then truncated. This should make sure
that only the relevant lines are kept.
|
|
|
|
To make sure that all error and information reporting to the user is
unified, all instances of `print!`, `eprint!`, `println!` and
`eprintln!` have been removed and replaced by logging.
When `RUST_LOG` is not specified, the default Alacritty logger now also
prints to both the stderr and a log file. The log file is only created
when a message is written to it and its name is printed to stdout the
first time it is used.
Whenever a warning or an error has been written to the log file/stderr,
a message is now displayed in Alacritty which points to the log file
where the full error is documented.
The message is cleared whenever the screen is cleared using either the
`clear` command or the `Ctrl+L` key binding.
To make sure that log files created by root don't prevent normal users
from interacting with them, the Alacritty log file is `/tmp/Alacritty-$PID.log`.
Since it's still possible that the log file can't be created, the UI
error/warning message now informs the user if the message was only
written to stderr. The reason why it couldn't be created is then printed
to stderr.
To make sure the deletion of the log file at runtime doesn't create any
issues, the file is re-created if a write is attempted without the file
being present.
To help with debugging Alacritty issues, a timestamp and the error
level are printed in all log messages.
All log messages now follow this format:
[YYYY-MM-DD HH:MM] [LEVEL] Message
Since it's not unusual to spawn a lot of different terminal emulators
without restarting, Alacritty can create a ton of different log files.
To combat this problem, logfiles are removed by default after
Alacritty has been closed. If the user wants to persist the log of a
single session, the `--persistent_logging` option can be used. For
persisting all log files, the `persistent_logging` option can be set in
the configuration file
|
|
Using the `bench` feature, `cargo test` was failing since one of the
benchmarks was running into a debug assertion for attempting to access a
line with an index beyond the grid length.
Since this issue was caused by the `len` property not being serialized
and deserialized, the `#[serde(skip)]` attribute has been changed to
`#[serde(default)]`. The ref-test has been edited to include the correct
grid length for proper deserialization.
This fixes #1604.
|
|
When rendering selections with both start and end outside of the visible
area, Alacritty would assume that both start and end are either above or
below the viewport and not render the selection at all.
To fix this the `buffer_line_to_visible` method now returns a
`ViewportPosition` instead of an `Option<Line>`, this allows giving more
feedback about where outside of the visible region the line is using the
`ViewportPosition::Above` and `ViewportPosition::Below` variants.
Using these newly introduced variants, a selection spanning the whole
screen is now rendered if the selection should go from above the visible
area to below it.
This fixes #1557.
|
|
Previously Alacritty has initialized all lines in the buffer as soon as
it is started. This had the effect that terminals which aren't making
use of the scrollback buffer yet, would still consume large amounts of
memory, potentially even freezing the system at startup.
To resolve this problem, the grid is now dynamically resized in chunks
of `1000` rows. The initial size is just the visible area itself, then
every time lines are written to the terminal emulator, the grid storage
is grown when required.
With the worst-case scenario of having 100_000 lines scrollback
configured, this change improves startup performance at the cost of
scrolling performance.
On my machine the startup changes from ~0.3 to ~0.2 seconds.
The scrolling performance with large throughput is not affected, however
it is slowed down when the number of lines scrolled are close to the
100_000 configured as scrollback. The most taxing benchmark I've found
for this was running `yes | dd count=500 > 500.txt` (note the relatively
small file size). This will cause a slowdown on the first run from 0.05s
to 0.15s. While this is significant, it lines up with the time saved at
startup.
This fixes #1236.
|
|
Alacritty has some checks in place to make sure that unsafe
code would not fail because of invalid struct sizes. This managed
to successfully catch an incorrect unsafe block on 32-bit machines.
To make sure this block works on both 32-bit and 64-bit systems,
it has been altered to make use of the platform-dependent `usize`
type. This will always make use of correct sizes without having to
rely on conditional compilation.
|
|
|
|
The clearing the screen for the `ansi::ClearMode::Saved` enum value
has been implemented. This is used to clear all lines which are
currently outside of the visible region but still inside the scrollback
buffer.
The specifications of XTerm indicate that the clearing of saved lines
should only clear the saved lines and not the saved lines plus the
currently visible part of the grid. Applications like `clear` send both
the escape for clearing history plus the escape for clearing history
when requested, so all sources seem to agree here.
To allow both clearing the screen and the saved lines when a key is
pressed the `process_key_bindings` method has been altered so multiple
bindings can be specified. So it is now possible to execute both `^L`
and `ClearHistory` with just a single binding. The
`process_mouse_bindings` method has also been changed for consistency.
To make sure everything works properly a test has been added which
clears the history and then attempts to scroll. Since scrolling is the
only way for a user to check if scrollback is available, this seems like
a nice abstraction to check if there is a scrollback.
|
|
Since Alacritty never had any scrollback history, the behavior when the
window height was increased was to just keep the prompt on the same line
it has been before the resize. However the usual behavior of terminal
emulators is to keep the distance from the prompt to the bottom of the
screen consistent whenever possible.
This fixes this behavior by loading lines from the scrollback buffer
when the window height is increased. This is only done when scrollback
is available, so there are only N lines available, the maximum amount of
lines which will be loaded when growing the height is N. Since the
number of lines available in the alternate screen buffer is 0, it still
behaves the same way it did before this patch.
Different terminal emulators have different behaviors when this is done
in the alt screen buffer, XTerm for example loads history from the
normal screen buffer when growing the height of the window from the
alternate screen buffer. Since this seems wrong (the alt screen is not
supposed to have any scrollback), the behavior of Termite (VTE) has been
chosen instead.
In Termite the alt screen buffer never loads any scrollback history
itself, however when the terminal height is grown while the alternate
screen is active, the normal screen's scrollback history lines are
loaded.
This fixes #1502.
|
|
When running bash and executing `echo -ne '\033c'`, the terminal should
be cleared. However there was an issue with the visible area not being
cleared, so all the text previously printed would still remain visible.
To fix this, whenever a `reset` call is received now, the complete
visible area is reset to `Cell::default()` (the default Cell) and the
length of the available scrollback history is reset to `0`, which
results in the scrollback history being cleared from the perspective of
the user.
This fixes #1483.
|
|
|
|
There were some unneeded codeblocks and TODO/XXX comments in the code
that have been removed. All issues marked with TODO/XXX have either been
already resolved or tracking issues exist.
|
|
There have been two instances of the scrollback trying to access indices
which were moved out of bounds due to new lines (`yes` command). These
have both been fixed.
The first instance was during semantic selection, since the logic of
limiting the selection start point was moved outside of `compute_index`,
it was necessary to add this to semantic selection too. Now semantic
selection, line selection and normal selection should all work without
crashing when new lines are shoving the selection out of bounds.
The other error was with the viewport being outside of the scrollback
history. Since the default is to keep the scrollback buffer at its
current position when new lines are added, it is possible that the
position the scrollback buffer is at is suddenly shoved out of the
visible area. To fix this the `display_offset` is now limited to always
be an allowed value.
If a single line of the viewport is moved out of the history now, the
viewport should move down a single line now, so only valid content is
displayed, with multiple lines this process is repeated.
This fixes #1400.
There was another error where the iterator would attempt to iterate
before the first line in the history buffer, this was because the bounds
of the `prev` iterator weren't setup correctly. The iterator should now
properly iterate from the first cell in the terminal until the last one.
This also fixes #1406, since these semantic selection errors were
partiall related to indexing.
|
|
The `compute_index` method in the `Storage` struct used to normalize
indices was responsible for a significant amount of the CPU time spent
while running the `alt-screen-random-write` benchmark (~50%).
The issue with this relatively simple method was that due to how often
the method is executed, the modulo operation was too expensive.
Instead of the modulo, a more conservative branch has been put
in place which has a very efficient best-case (which is hit most of the
time).
Until now the methods for growing/shrinking the storage buffer and
compute_index have been written with the assumption that `self.zero`
might be bigger than `self.inner.len()`. However there is no reason why
`self.zero` wouldn't be constrained to always be within the size of the
raw buffer, so this has been changed to make things a little simpler and
more explicit.
Instead of clamping the selection to be within the buffer inside the
storage, this is now checked in the selection logic to remove all
selection-specific logic from `storage.rs`.
|
|
Making use of the changes that have been introduced in #1234 and #1284,
this allows changing the size of the scrollback buffer at runtime.
This simply changes the size of the raw inner buffer making use of the
optimized mutation algorithms introduced in #1284. As a result,
shrinking the scrollback history size at runtime should be basically
free and growing will only introduce a performance cost when there are
no more buffered lines. However, as a result there will not be any
memory freed when shrinking the scrollback history size at runtime.
As discussed in #1234 a potential solution for this could be to truncate
the raw buffer whenever more than X lines are deleted, however this
issue should not be very significant PR and if a solution is desired a
separate issue/PR should be opened.
This fixes #1235.
|
|
|
|
Removes 4 movaps instructions from generated assembly.
|
|
This will allow certain optimizations around swap which are currently
only possible in a generalized way with specialization.
|
|
Shrinking columns wasn't updating hidden rows in the storage buffer on
resizing. When growing the columns again, this resulted in an endless
allocation loop.
Only one real change was made here, and that was `raw.iter_mut()` to
`raw.iter_mut_raw()`. The method `shrink_cols` was relocated to be
adjacent to `grow_cols` in the code.
|
|
This implementation avoids a few extra transformations by operating in
buffer-space. However, there is still a transformation from the logical
buffer-space to the underlying vector.
|
|
When resizing prior to this patch, hidden rows in Storage were not
having columns added along with everything else. This feels like a bit
of tech debt, but the patch is simple enough that it won't be much extra
to back out later when the underlying cause is addressed (see comments
in code).
|
|
Now, only cells that have been used are cleared. This is achieved by
using a "occupied" memo on the Row itself. The value, `occ`, is updated
wherever the Row is accessed mutably, and it's cleared to zero in
Row::reset.
The tests for grid scroll_up and scroll_down were updated to include a
test on the value `occ` and slightly refactored, but are otherwise
equivalent to the previous implementation of those tests.
Because of the change to the `Row` struct, the ref tests were updated so
Deserialization keeps working as expected.
|
|
Saves a few cycles in a *very* hot function.
|
|
Because there is no good way to store invisible lines in a backwards-
and forwards-compatible way, they buffer now gets truncated before
dumping the state of a grid when creating a ref-test.
This involved a few workaround of which a few required adding additional
methods which are only used in ref-tests, these should be minimal
though.
Since this required the creation of a truncation method anyways, some
logic has been added which automatically truncates the invisible buffer
when there are more than X (set to 100) invisible lines. This should not
impact performance because it rarely occurs, but it could save a bit of
memory when the history size is shrunk during runtime (see #1293).
This also adds an optional `config.json` file to the ref-test output
where it is possible to manually specify variables which should override
config defaults, this has been used only for history_size so far.
Creating a new ref-test does also still work, so there was no regression
here, if history size is altered, the config.json just has to be created
manually with the content `{"history_size":HIST_SIZE}`, where
`HIST_SIZE` is the desired history size.
|
|
Because the purpose of the `len` field wasn't obvious and collided with
other uses (like Vec::len()), some additional documentation has added to
make things a little easier to understand.
|
|
Since every line is allocated at startup anyways, the `push` method on
`Storage` has been removed and instead of pushing to the vector the
initialization has been moved to the `with_capacity` method.
This has the advantage that we don't need to keep track of the `len` in
push (like adding one), but we just need to worry about
growing/shrinking the visible area.
|
|
Until now the resizing implementation with scrollback has been really
inefficient because it made use of APIs like `Vec::insert`. This has
been rewored with this commit.
A `len` property has been added to the `Storage` struct which keeps
track of the actual length of the raw buffer. This has changed both
shrinking and growing implementations.
With shrinking, no more lines are removed, only the `len` property is
updated to set all lines shrunk to an "invisible" state which cannot be
accessed from the outside, this effectively changes it to a O(1)
operation. The only issue with this would be memory consumption, but
since the maximum shrinkage is the number of lines on one screen, it
should be a rather small impacte (probabl <100 lines usually). If
desired it would be possible to change this to shrink the raw inner
buffer whenever there are more than X lines hidden.
Growing now works in a similar way to shrinking, if the "invisible"
lines are enough, no new lines are inserted but rather the invisible
buffer is made visible again. Otherwise the amount of lines that still
needs to be inserted is added to the raw buffer, but instead of the
inefficient `Vec::insert`, the `Vec::push` API is used now.
This fixes #1271.
|
|
Resolves #1337
|
|
This enforces the invariant that Row::Grow is only called when the row
actually needs to be grown.
|
|
Instead of iterating over the raw storage vector because the offsets
don't allow direct comparison, the comparison is now done in chunks.
Based on benchmarking this is a lot more efficient than using split_off
+ append or iterating over the elements of the buffer.
The `history_size` field has also been removed from the storage
structure because it can be easily calculated by substracting the number
of visible lines from the length of the raw storage vector.
|
|
In the current scrollback PR the `reset` command does not affect the
scrollback history. To make sure the terminal is properly reset, it
should clear the scrollback history.
This commit fixes this by creating a new and empty grid whenever `reset`
is executed. It takes the current dimensions and history size from the
old grid.
Right now there's an empty ref-test called `grid_reset` without any
content, this should be implemented once #1244 is resolved.
This fixes #1242.
|
|
Previously ref-tests just ignored the scrollback history to keep
the old tests working, this would lead to new tests which rely on
scrollback history to succeeed even though they should not.
This has been fixed and it is now possible to create ref-tests with and
without scrollback history. When available the scrollback history is
compared, but the old tests still work without having to adjust them.
This fixes #1244.
|
|
In the current scrollback PR the `reset` command does not affect the
scrollback history. To make sure the terminal is properly reset, it
should clear the scrollback history.
To make resetting efficient, instead of resetting the history,
the scrollback history is hidden by setting `grid.scroll_limit` to `0`.
This will not clear the history but instead just make it inaccessible,
which should have the same effect.
The visible area is reset by the shell itself, so in combination this
clears the complete terminal grid from a user perspective.
This fixes #1242.
|
|
This bug was introduced by the commit which fixed the invisible cursor
in the first column (54b21b66ecc6f8f149d1425567e0e3d766a3ac54). To
resolve this the alternative implementation by @jwilm has been applied
which seems to work out.
This fixes #1259.
|
|
This reverts commit 54b21b66ecc6f8f149d1425567e0e3d766a3ac54.
|
|
|
|
There was an issue where the lines would be messed up when the terminal
was resized, this was because lines were just added/removed at the end
of the buffer instead of the actual end of the terminal (since the end
of the terminal might be in the middle of the buffer).
This has been fixed by relying on `self.zero` to determine the position
of the start of the terminal and then calculating where lines have to be
inserted/removed.
Some tests have also been added with documentation that should make it
a little easier to understand how the process works and how the raw
buffer is layed out.
This should all work no matter how big the scrollback history and even
when the currenty viewport is not at the bottom of the terminal output.
|
|
There was an issue where alacritty would panic whenever the scrollback
history size is set to 0, this fixes that issue.
The panic was caused by a substraction with unsigned integers which was
underflowing, this has been fixed to use `saturating_sub`.
After that was fixed there was still a bug where scrollback would not
behave correctly because the number of lines in the grid was decided at
startup.
This has been adapted so whenever the size of the terminal changes, the
scrollback history and grid adapts to make sure the number of lines in
the terminal is always the number of visible lines plus the amount of
scrollback lines configured in the config file.
This fixes #1150.
|
|
|
|
There was a bug in the display iterator where the first column was never
reached after the top line because it was instantly incremented to 1
after it was reset when iterator column reached the end of the terminal
width.
This has been fixed by making sure that the column is never incremented
when the column is reset due to a change in terminal line.
This fixes #1198.
|
|
BCE was broken in attempt to optimize row clearing. The fix is to revert
to passing in the current cursor state when clearing.
|
|
|
|
Some tests are still not passing, though.
A migration script was added to migrate serialized grids from
pre-scrollback to the current format. The script is included with this
commit for completeness, posterity, and as an example to be used in the
future.
A few tests in grid/tests.rs were removed due to becoming irrelevant.
|
|
Resolves #1154
|
|
The different scrolling methods added a bunch of boilerplate where the
call was just forwarded to the next struct, this has been removed by
making the scroll amount into a struct.
Now everything is called through one method and the parameter decides
how far the viewport should be scrolled.
|
|
This offers a few additional hotkeys that can be used in combination
with scrollback. None of these are used by default yet.
This implements the following bindings:
- ScrollPageUp: Scroll exactly one screen height up
- ScrollPageDown: Scroll exactly one screen height down
- ScrollToTop: Scroll as far up as possible
- ScrollToBottom: Scroll as far down as possible
This fixes #1151.
|
|
There was an issue where alacritty tries to convert the lines in a
selection to the on-screen lines even when the selection is not on the
screen. This results in a crash.
To prevent this from happening the selection now is not shown if it is
off the screen.
There currently still is a bug that when the selection is at the top of
the screen but still half visible, it will not show the top line as
selected but start in the second line.
This bug should be resolved with
https://github.com/jwilm/alacritty/pull/1171.
This fixes #1148.
|