This is unfortunately a bit of a muddy commit and I'm too lazy to split
it up.
* Removed `Position::NoChange`; use `Position::Relative(0)` instead
* Added missing cursor positioning cases in the terminfo renderer
* Taught line editor about the cursor position when the line spans
multiple physical lines
* Taught the Windows input layer to process escape sequences for eg:
the arrow keys when running with virtual terminal enabled.
* Removed the hack that under-reported the terminal width; the hack
was present to make some aspects of rendering with the native windows
console logic easier, but it was getting in the way of the line
editor. This may well break something, but it fixed up the line
editor :-/
cc: @markbt
The predictive echo feels pretty reasonable, but if the connection
is having problems and we're showing the tardiness indicator, the
echo can give the impression that your input is going to get processed.
That may not be (usually is not!) the case.
This commit makes it a bit more visually distinctive that something
isn't right by greying out the color palette in that case.
refs: https://github.com/wez/wezterm/issues/127
This should allow some basic reasoning about how in sync we are with
the remote system.
The immediate application of this is to try to avoid wiggling the
text cursor when the predictive echo updates the position locally.
I need to push this in order to test it on my higher latency setup,
so I don't know if this is totally effective yet.
This is used to indicate timeout/retries during connection establishment
and also to count down to the automatic window close.
The UI will render a progress bar underneath the reason text to show
the passage of time, as well as counting down the provided duration.
Extends the "predictions" to allow for some basic cursor movement
via cursor keys and text deletion.
In addition, show predictions for pasted text.
refs: https://github.com/wez/wezterm/issues/127
This is a mosh-like feature, but not as sophisticated.
The goal is to reduce perceived latency by making a reasonable
guess about how the line where the cursor is located will change
in response to a key press.
At the moment the guess has some very basic heuristics:
* The key is an unmodified (no CTRL, ALT, SUPER) `char` value
* The line containing the cursor doesn't appear to be a
password prompt (using a very simple English specific test)
In those conditions, we'll update the local line cache and cursor
position with how we think the text will appear, but we set the
underline attribute (which is relatively rarely used) to make it clearer
that this is synthetic.
For low latency environments (eg: local network) the underline
rarely appears unless you are able to type very quickly.
I've yet to test this on a higher latency link, but think
this is good enough to land and build out so that I can test
that scenario with my work systems.
refs: https://github.com/wez/wezterm/issues/127
I made this unbounded originally because I wanted to do something
smarter around config reloading. I'm still too lazy to make it
do that, but do recognize that we should have some limit on the
line cache size, so we just pick the value of the scrollback
size at the time we started.
This used to be effectively the same thing, but now that the launcher
menu allows attaching to other domains, it is best if the hotkey
matches the behavior of the + button on the tab bar and uses the
domain of the current tab instead.
* Increase timeout from 2 to 10 seconds, giving you more time to read it
* Make the timeout work even if the UI object is unexpectedly destroyed
* When attaching via the launcher, don't reconnect when the server
version mismatches the client version.
This adjusts the mux protocol so that we can tell when a remote tab
has been closed; previously we couldn't distinguish between an IO
error and the tab going away.
Similarly, if the remote mux has shut down (which we detect via an EOF),
then we won't try to reconnect and will proceed to detach that domain.
Hadn't noticed this until just now because the systems I've been
using have all had a pretty similar filesystem layout.
This commit avoids a failure to spawn a child process when the
desired directory doesn't exist locally.
This is accessible by right-clicking on the `+` button in the tab bar
and switches to an overlay offering options to spawn tabs and attach
domains.
The intent is to allow the configuration file to expand this list of
options, and on Windows, to auto-populate with the various combinations
of `cmd`, `powershell`, `elevated` and available `wsl` instances, but
for the moment the main value of this feature is the ability to attach
domains that were not set to connect automatically at startup.
This makes things more convenient when launching wezterm via the
gui: it is awkward to have to set up shortcuts that run
`wezterm connect foo`, or to type in the full path to `wezterm` when
you might want to run that manually.
Now you can double-click the icon and right-click the `+` and attach
the domain. (cc: @rjwalsh)
The launcher is a good candidate for being implemented on top of
native context menus where available... but we don't have any
such API plumbed through the `window` crate, so all platforms
get the wonderful terminal based overlay menu right now.
refs: https://github.com/wez/wezterm/issues/159
This commit tackles a couple of things in related areas:
Makes it possible to reference the KeyAssignment type directly from the
KeyAction action type. Previously, due to limitations in how TOML is
serialized, the enum values could be used here; while the compiler would allow
it, it is impossible to construct a TOML value for this sort of enum. Now that
we have lua we have more flexibility in the table type and this is unblocked.
In practical terms this means that we can do away with the janky `arg` field
and just use the `action` field directly, which also means that we can do away
with a whole extra enum that duplicates just the enum variants and makes
maintenance easier!
Adds `wezterm.action` to lua which helps to construct these enum variants. The
helper is used like this in the `.wezterm.lua` file:
```lua
local wezterm = require 'wezterm';
return {
keys = {
{key="{", mods="SHIFT|CTRL", action=wezterm.action{ActivateTabRelative=-1}},
{key="}", mods="SHIFT|CTRL", action=wezterm.action{ActivateTabRelative=1}},
}
}
```
the above creates values like `KeyAssignment::ActivateTabRelative(-1)`
in a not totally awful syntax.
On top of this, which was the main reason for doing this work, this
commit adds two new variants to KeyAssignment that are accessible
on from lua (because of the TOML limitations mentioned above);
`SpawnCommandInNewWindow` and `SpawnCommandInNewTab` that take a
`SpawnCommand` struct as their parameter. These actions are
conceptually similar to the existing `SpawnTab` key assignment
but allow specifying the program to be run as well as its cwd
and environment.
For example, this key assignment spawns `top` in a new window:
```lua
{key="y", mods="CMD", action=wezterm.action{SpawnCommandInNewWindow={
args={"top"}
}}},
```
The intent is to use this as a building block for saved/canned
commands.
refs: https://github.com/wez/wezterm/issues/159
implementing the `ToLua` and `FromLua` traits allows `create_function`
to automatically apply the appropriate conversions to the parameters
and return values in a callback function.
That makes it possible (and nicer!) to write properly typed callbacks.
Make a reasonable suggestion to the user based on similarity with
possible field names, but don't error out.
This facilitates evolving the configuration over time, and makes
the config more forgiving of typos.
Weirdly, this seemed specific to lua files rather than toml files,
which I don't have a good explanation for. When saving the file
in vim, we'd get a NoticeRemove but no Remove event.
This commit synthesizes the equivalent of a Remove after a NoticeRemove
and a slight delay.
If we hit a timeout for a tab we could mark it dead and remove it
from the containing window. This isn't desirable for a tls
session that we can reconnect, in part because the timeout is
likely to happen to the last focused tab if connectivity was
suddenly lost (that was the one we were interacting with, so are
likely to have PDUs about to go out), so only that one gets marked
dead and removed from the GUI.
When we re-attach later we may place the tab in the wrong ordinal
position, which is annoying.
This commit seeks to avoid the annoyance by not marking the tab
dead for reconnectable transports.
refs: https://github.com/wez/wezterm/issues/127
For full screen terminals it is common for scrolling through vim
to hit the prior default limit. This value feels better. This
comes at the cost of an increased delay for eg: CTRL-C processing
in the case where something is spamming the terminal, but that
is relatively rare.
This tidies up the part of the config syntax that I most disliked:
```lua
font = {
font = {{
family = "Operator Mono SSm Lig Medium",
}},
},
```
can now be as simple as:
```lua
font = wezterm.font("Operator Mono SSm Lig Medium"),
```
Here's the font related section from my config:
```lua
local wezterm = require 'wezterm';
return {
font = wezterm.font("Operator Mono SSm Lig Medium"),
font_rules= {
{
italic = true,
font = wezterm.font("Operator Mono SSm Lig Medium Italic"),
},
{
italic = true,
intensity = "Bold",
font = wezterm.font("Operator Mono SSm Lig Book Italic"),
},
{
intensity = "Bold",
font = wezterm.font("Operator Mono SSm Lig Bold", {foreground = "tomato"}),
},
{
intensity = "Half",
font = wezterm.font("Operator Mono SSm Lig Light"),
},
},
}
```
This allows for slightly more fancy configuration in the future, but for
now it is rather simple: your lua script returns a configuration struct
with the same shape as that from the TOML file.
A `wezterm` module is provided to the script that provides some
constants to help understand the environment in which wezterm
is running.
I want to add some helpers that make setting up the fonts feel less
weird (lots of nesting in the data model makes this weird).
The ability to conditionally construct configuration is powerful
and helps to address the broader request in
refs: https://github.com/wez/wezterm/issues/152
An example config looks like this:
```lua
local wezterm = require 'wezterm';
print(wezterm.config_dir);
print(wezterm.executable_dir);
wezterm.log_error("w00t! running " .. wezterm.version
.. " on " .. wezterm.target_triple .. " " .. wezterm.home_dir);
return {
enable_scroll_bar = true,
enable_tab_bar = true,
ratelimit_output_bytes_per_second = 400000,
scrollback_lines = 350000,
font_dirs = {".dotfiles/fonts"},
window_padding = {
left = 2,
bottom = 2,
},
font = {
font = {{
family = "Operator Mono SSm Lig Medium",
}},
},
unix_domains = {
{
name = "unix",
}
},
ssh_domains = {
{
name = "localhost",
remote_address = "localhost",
username = "wez",
},
},
tls_clients = {
{
name = "cubetls",
remote_address = "cube-localdomain:8080",
bootstrap_via_ssh = "cube-localdomain",
},
},
tls_servers = {
{
bind_address = "192.168.1.8:8080",
},
},
hyperlink_rules = {
{
regex = "\\b\\w+://(?:[\\w.-]+)\\.[a-z]{2,15}\\S*\\b",
format = "$0",
},
},
font_rules= {
{
italic = true,
font = {
font = {{
family = "Operator Mono SSm Lig Medium Italic",
}}
},
},
{
italic = true,
intensity = "Bold",
font = {
font = {{
family = "Operator Mono SSm Lig Book Italic",
}}
},
},
{
intensity = "Bold",
font = {
foreground = "tomato",
font = {{
family = "Operator Mono SSm Lig Bold",
}}
},
},
{
intensity = "Half",
font = {
font = {{
family = "Operator Mono SSm Lig Light",
}}
},
},
},
}
```
I saw that the server exited with a panic here in the case that the
connection was torn down and left the channel broken. We don't need
to terminate in this case and can simply ignore the error.
Add an update indicator to the top right of client tabs; this is
overlaid on top of the surface when the last update from the server was
more than ~3s ago and if we expected it sooner than that.
While making this work, I noticed that the exponential poll backoff
had gotten broken in an earlier refactor; instead of a series of polls
backing off slowly, we were aggressively running the backoff up to the
max 30 second interval over the span of a few ms. This commit fixes
up the backoff computation to only happen when we are ready to send
a poll.
refs: https://github.com/wez/wezterm/issues/127
When we're trying to use credentials from a session that was previously
bootstrapped via ssh but hit connection refused (eg: the server was
subsequently shut down), then we want to proceed to attempting to
re-boostrap via ssh.
That version has the ability to use SSH agent forwarding.
This commit doesn't enable that functionality, it's just updating
the version and adjusting for changes in the upstream.
If we'd decided to close a tab due to an error bubbling up in the
reader, we need to re-assign a local id when we enumerate tabs.
This is a bit of a crutch: ideally we'd not close the tab and
instead show some kind of UI to indicate that it is not responding.
refs: https://github.com/wez/wezterm/issues/127
Implement FromStr and Display for SshParameters, so that they can be
parsed and displayed in the standard way.
The motivation for this is that I want to add gateway hosts to the ssh command, and
would like to be able to add something like `gateway: Vec<SshParamters>` to SshCommand
to do it.
This allows child processes to "do something" with that information.
For example, portable wezterm deployments can use these paths to
bootstrap some other portable config paths.
refs: https://github.com/wez/wezterm/issues/152
The other default available macos monospace fonts have ligatures for
"fi" that are configured such that harfbuzz will render them when they
are part of a word like "finish" which results in a very weird
appearance.
This helps to restore any individually dropped tabs and to detect
tabs that were created by other clients across a reconnection.
refs: https://github.com/wez/wezterm/issues/127
This is useful for setting up a reasonable initial environment.
For example, on Windows you might want to set the `prompt` environment
so that some basic shell integration is enabled; this will cause new
tabs to open with the same cwd as the current tab:
```
set_environment_variables = { "prompt"="$E]7;file://localhost/$P$E\\$P$G" }
```
This setting is intended to apply only to the local domain.
refs: https://github.com/wez/wezterm/issues/146
This allows this prompt setting to work:
```
prompt $E]7;file://localhost/$P$E\$P$G
```
although this one sets it for future prompts:
```
setx prompt $E]7;file://localhost/$P$E\$P$G
```
refs: https://github.com/wez/wezterm/issues/146
This is conceptually slightly cleaner and allows sessionhandler to
be agnostic of the details of the channel used to communicate with
the client; it just has a Sender<DecodedPdu> to work with.
I suspect some race condition because adding these made the connect
time hang stop reproducing for me on my local network.
Will try this to the corp vpn.
refs: https://github.com/wez/wezterm/issues/127
This commit adjusts the features in Cargo.toml to allow building
without openssl on unix systems.
It teaches the native_tls flavor of the code to perform bootstrapping
via ssh, but is still not usable because there still isn't a way
to get native_tls to use PEM files.
This makes the tls channel much easier to use; the config can now be as
simple as this on the server side:
```toml
[[tls_servers]]
bind_address = "192.168.1.8:8080"
```
and this on the client side:
```
[[tls_clients]]
name = "hostname"
bootstrap_via_ssh = "192.168.1.8"
remote_address = "hostname:8080"
```
and then `wezterm connect hostname` will use ssh to connect to the
host, start the mux server, request the CA and client certs and
then connect to it over TLS.
This is implemented only for openssl at the moment.
If we're actively outputting to the window and the user closes it,
we don't need to panic.
Make the window a little larger now that it shows more data.
Adds a default 60 second timeout for read and write for the tls
and unix domain sockets that we create. This applies to ssh
domains, but not `wezterm ssh` sessions that go direct to ssh ptys.
I noticed that the reconnection UI for TLS mux sessions was annoying
on macOS: it would flash up and steal the focus, make a connection
attempt that would immediately fail because the destination was not
routable and then close the window. It would do this each time
a connection attempt was made (every few seconds in the early
stages of backoff).
This commit pulls the UI up a level so that we open the window at
the start of the connection (or re-connection) attempt, and keep
the same one for its lifetime.
This also introduces a headless UI object that doesn't output or
respond to anything. You can set the log level to trace to see
what is happening inside. It is used by the CLI mode. It could
perhaps be made smart enough to conditionally show a UI when needed,
but since it is targeting local unix domain sockets, that doesn't
seem like it is needed right now.
I'm adding this primarily to avoid repeatedly showing "No more
fallbacks" errors when moving the mouse over a terminal that contains
cells with no matching glyphs.
It has the nice side effect of changing the typical opengl tab render
time from ~2.9ms to ~1.3ms.
The opengl based render first clears the window to the background
color and then renders the cells over the top.
on macOS I noticed a weird lighter strip to the bottom and right of
the window and ran it down to the initial clear: our colors are SRGB
rather than plain RGB and the discrepancy from rendering SRGB as RGB
results in the color being made a brighter shade. This was less
noticeable for black backgrounds.
We now display a list of tabs and allow selecting them with either
the up/down arrows or the k/j keys. Enter activates the selected
tab, Escape cancels the overlay.
An overlay is a little termwiz app that can be overlaid over the
content of a gui tab.
The intent is for these to provide the mechanism for meta operations;
listing all tabs in a long-form list and switching between them,
dropping into configuration or error log review and so on.
We now show a little status window when we're making a connection
for a remote mux domain.
This should make things feel slightly nicer if there is a connectivity
problem.
refs: https://github.com/wez/wezterm/issues/127