select2 is only used on macOS so there's no need to compile it in
non-macOS builds. Originally it was compiled for all builds with the
allowed dead-code just to make development easier (i.e. get compiler
diagnostics without switching OSes).
The ioctl to get the window size may fail silently by returning zeroed
rows/columns which are nonsensical and unusable by terminal
applications. In this case Vim falls back to attempting to read the
LINES and COLUMNS environment variables, and then attempts to read
dimensions from the terminfo. That fallback can be done in the calling
application however.
Also see <https://github.com/helix-editor/helix/issues/14101#issuecomment-3149628173>
There was a mistake with the WindowResized event on Windows from some
code inherited from crossterm. Crossterm adds one to the dimensions
returned from a window resize event because it overwrites the dimensions
in the event with ones from `GetConsoleScreenBufferInfo` (zero-based).
The rows and columns in the event are already one-based.
This change also re-types the dimensions with the `OneBased` helper from
termwiz. The `OneBased` type is moved from the `escape` module to the
crate root.
Fixes#5.
This matches the same code in the Unix terminal module and produces
better behavior in some edge cases like running an application into
a pipe like `hx | echo`.
Instead of the filter closure being a type parameter we can erase its
type with `Arc<dyn Fn...>`. This means that the filter is executed with
dynamic dispatch instead of static but I doubt that it makes a
noticeable/significant difference. Erasing the type makes `EventStream`
easier to store on another struct since it's a hassle to specify
concrete type parameters for closures.
Also `EventReader::poll` and `read` are updated to use more specific
`FnMut` closures for the sake of flexibility. This is effectively the
same since `FnMut` is a supertrait of `Fn` but it enables mutating the
env of the closure.
Closes#3
We can gate EventStream behind a feature flag to make the futures-core
dependency optional. You may wish to roll your own event stream to avoid
futures and async. This change replaces `Terminal::event_stream` with
`Terminal::event_reader` and makes the `EventReader` type `pub` instead
of `pub(crate)`.
This change also removes the `DummyEventSource` since it is easy to
write that type in the consuming application.
See <https://redirect.github.com/helix-editor/helix/pull/13307#issuecomment-2813435388>.
Some terminals' VT parsers have conservative limits for the number of
parameters they will accept, sometimes as low as 10. For compatibility
with these terminals we should chunk the combined SGR attributes to fit
that limit. This is added as an option on `SgrAttributes` so that it can
be customized and changed dynamically. (As opposed to a constant.)
In my testing with these commands (PowerShell):
> cargo clean
> Measure-Command { cargo b --example event-read }
I see the time fall from 4s111ms to 3s845ms. It's not much but there's
really no reason to have this flag enabled for one constant.
This was a footgun since it isn't an opposite to `enter_raw_mode`. We
want to reset the mode in Helix when suspending but that only works on
Unix and on Unix it's the same thing to use `enter_cooked_mode`. On
Windows during Drop we want to reset the code pages (encoding) as well
but the code pages are not set in `enter_raw_mode`, they're set during
`WindowsTerminal::new`. This change removes `reset_mode` and moves its
code into `Drop for WindowsTerminal`.
I didn't realize signal-hook also exported a constant for this. This
change shaves off a fair percentage of compile time since we drop the
dependency on rustix's `process` feature flag:
$ cargo clean
$ time cargo b --release --example event-read
before
Executed in 2.41 secs fish external
usr time 6.78 secs 0.20 millis 6.78 secs
sys time 1.42 secs 1.08 millis 1.42 secs
after
Executed in 2.04 secs fish external
usr time 6.10 secs 410.00 micros 6.10 secs
sys time 1.45 secs 811.00 micros 1.44 secs
This new `SgrAttributes` type can contain all of the common `Sgr`
attributes together. It's like a `Vec<Sgr>` but flattened into a struct.
When displayed, all SGR updates are made at once. See the example in
the docs for the type: we can emit a change to set the foreground as
green and bold as 'CSI 32 ; 1 m' instead of two separate 'CSI 32 m' plus
'CSI 1 m' escapes. This is equivalent when writing exactly one SGR but
is a savings of two bytes (add one for ';', subtract three for CSI and
'm') per extra change made in the SGR.
A similar change in crossterm reportedly boosted FPS of an application
that sets a combined foreground+backgrouond SGR for every cell by
15-25%: <https://redirect.github.com/crossterm-rs/crossterm/pull/879>.
This type takes that change a step further and supports all SGR
attributes.
It's somewhat catastrophic to not reset console mode and code pages on
Windows - it seems to really mess up the terminal and can cause a crash
- so I think it's fine to reset mode automatically on drop. While we're
at it we might as well flush the writer buffers.
At some point recently I got rid of the Drop stuff. We need to reset the
mode or else Windows powershell crashes for me when trying to claim
CONIN$ twice. (Run an example before this commit and then run regular
`hx`).