The fixup callback can now by async, which makes it possible to use
other async functions in the callback.
There is an additional parameter to wezterm.exec_domain that allows
setting the label that is shown in the launcher menu.
It accepts either a string value or an async callback function
that can be used to compute the label dynamically.
An ExecDomain is a variation on WslDomain with the key difference
being that you can control how to map the command that would be
executed.
The idea is that the user can define eg: a domain for a docker
container, or a domain that chooses to run every command in its
own cgroup.
The example below shows a really crappy implementation as a
demonstration:
```
local wezterm = require 'wezterm'
return {
exec_domains = {
-- Commands executed in the woot domain have "WOOT" echoed
-- first and are then run via bash.
-- `cmd` is a SpawnCommand
wezterm.exec_domain("woot", function(cmd)
if cmd.args then
cmd.args = {
"bash",
"-c",
"echo WOOT && " .. wezterm.shell_join_args(cmd.args)
}
end
-- you must return the SpawnCommand that will be run
return cmd
end),
},
default_domain = "woot",
}
```
This commit unfortunately does more than should go into a single
commit, but I'm a bit too lazy to wrangle splitting it up.
* Reverts the nil/null stuff from #2177 and makes the
`ExtendSelectionToMouseCursor` parameter mandatory to dodge
a whole load of urgh around nil in table values. That is
necessary because SpawnCommand uses optional fields and the
userdata proxy was making that a PITA.
* Adds some shell quoting helper functions
* Adds ExecDomain itself, which is really just a way to
to run a callback to fixup the command that will be run.
That command is converted to a SpawnCommand for the callback
to process in lua and return an adjusted version of it,
then converted back to a command builder for execution.
refs: https://github.com/wez/wezterm/issues/1776
Previously, the mux layer had no internal understanding of titles other
than the Pane::get_title method to return state from a pane.
Users have asked for ways to explicitly set titles on windows and tabs,
so this commit is a step towards that.
The mux window and tab objects now store a title string.
The terminal layer now emits Alert::WindowTitleChanged when the window
title is changed via eg: OSC 0 or OSC 2.
The mux layer will respond to Alert::WindowTitleChanged by resolving the
window that corresponds to the source pane and amending its title.
The MuxWindow and MuxTab objects now provide accessor methods for the
title.
TabInformation (as used by format-tab-title and format-window-title) now
exposes the underlying window_id as well as tab_title and window_title.
The tab title can be changed via the lua MuxTab type, but there is not
currently an escape sequence associated with this.
The defaults for format-tab-title and format-window-title don't
currently consider these new title strings.
refs: https://github.com/wez/wezterm/issues/1598
Similar to 3b9be25161, but relax for
the ssh session when assume_shell="Posix".
Augument how we run the shell in this case as well, so that we make
an effort to run it as a login shell.
refs: #2092
refs: #2076
The heart of the issue is that `sudo -i` sets the cwd to the homedir
of the root user, and that isn't accessible to the regular unprivileged
user, and cannot be set as the cwd for the newly spawned panes/tabs.
A secondary issue is that it is hard to see what the error is without
improved diagnostics.
So this improves the diagnostics, and then changes the existence
check that we were doing for local domain spawns to try to read the
directory instead.
refs: https://github.com/wez/wezterm/issues/2120
This commit allows for the SplitPane internal action to use the
pane id of an existing pane as the source of the pane to be added
in the new split target, rather than spawning a new command.
This can be used to move a pane from one tab to another, and is
analagous to tmux's `join-pane` command.
refs: https://github.com/wez/wezterm/discussions/2043
refs: https://github.com/wez/wezterm/issues/1253
This, along with the plumbing included here, allows specifying
the destination of the split (now you can specify top/left, whereas
previously it was limited to right/bottom), as well as the size
of the split, and also whether the split targets the node at the
top level of the tab rather than the active pane--that is referred
to as full-width in tmux terminology.
https://github.com/wez/wezterm/issues/578
To do this, we split `Pattern` into the underlying pattern for the mux
layer (which is part of the codec), and another for the config layer,
so that we can specify this new mode.
At the gui layer, we translate the selection variant into the actual
selection text and map it to the mux Pattern enum.
When taking the selection text, we restrict it to just the first line.
refs: https://github.com/wez/wezterm/issues/1912
Turn on multi-line mode by default, and improve the localpane
search function to collapse runs of trailing whitespace into
just a newline.
That allows:
```
./target/debug/wezterm -n --config 'quick_select_patterns={"foo$"}'
```
to match the first line from this, but not the second:
```
printf "foo\nfoobar\n"
```
and this to match both:
```
./target/debug/wezterm -n --config 'quick_select_patterns={"^foo"}'
```
refs: https://github.com/wez/wezterm/issues/2008
Avoid using serde for mapping between Lua and Rust for the `Config`
struct.
This improves the build speed of the config crate by 2x; it goes down
from 30 seconds to 9 seconds on my 5950x.
I want to make some changes to the scrollback structure that
first require routing some operations through an accessor
method, so this commit does that.
It should have no functional difference.
The launcher menu code to perform attaching has been generalized
into a key assignment action and reimplemented in terms of that
action.
A detach action has been added to disconnect and detach.
refs: https://github.com/wez/wezterm/issues/1874
This commit allows the currently active window to:
* Spawn a new tab in the active window (rather than spawning
a new window) to host the connection status
* Auto-close that connection UI tab (rather than the whole window)
when the window is no longer needed
* Pass the current window through to use as the primary window when
assigning remote window/tabs.
The net effect of this is that there are fewer transient windows,
and that it is easier to connect a set of domains to the active
workspace.
refs: https://github.com/wez/wezterm/issues/1874
Previously, we'd create a clipboard handler associated with a GUI window
and take care to pass that down to the underlying Pane whenever we
spawned a new pane.
For the mux server, instead of being associated with a GUI window, the
clipboard was a special RemoteClipboard that would send a PDU through
to the client that spawned the window.
The bug here was that when that client went away, the clipboard for
that window was broken.
If the mux server was the built-in mux in a gui process this could
leave a tab without working OSC 52 clipboard support.
This commit restructures things so that the Mux is responsible for
assigning a clipboard handler that rephrases the clipboard event
as a MuxNotification.
Both the GUI frontend and the mux server dispatcher already listen
for mux notifications and translate those events into appropriate
operations on the system clipboard or Pdus to send to the client(s).
refs: #1790
Previously, we'd just default the resize quirk on for all programs on
Windows.
That pessimizes the otherwise fine behavior of `wezterm ssh` or mux
connections to unixy platforms.
This commit moves the quirk out of the config trait and makes it
a runtime property of the terminal, and then arranges for it
to be set when we know that we set up a conpty for the terminal.
refs: #1265
Pretty much the same test plan as b4c4c85683
but start wezterm:
./target/debug/wezterm -n --config 'ssh_domains={{name="s",remote_address="localhost"}}' connect s
This reliably propagates focus=true events, but if the client switches
focus away from a mux pane to a local pane, then the focus=false event
may not be propagated to the remote mux.
refs: #1608
wezterm cli spawn, and wezterm cli split-pane can use this information
to pick a default for the pane id when invoked from outside of wezterm.
refs: https://github.com/wez/wezterm/issues/1531
This commit centralizes the focus-loss logic to the Window so
that activating a new tab will deactivate the pane in the current
window.
Note that this cannot see overlays in the gui, but overlays shouldn't
care about focus, so it should be ok.
refs: https://github.com/wez/wezterm/discussions/796
This commit enables the following config to work for local (not mux yet!)
panes:
```lua
local wezterm = require 'wezterm'
wezterm.on("format-tab-title", function(tab, tabs, panes, config, hover, max_width)
if tab.is_active then
return {
{Background={Color="blue"}},
{Text=" " .. tab.active_pane.title .. " "},
}
end
local has_unseen_output = false
for _, pane in ipairs(tab.panes) do
if pane.has_unseen_output then
has_unseen_output = true
break;
end
end
if has_unseen_output then
return {
{Background={Color="Orange"}},
{Text=" " .. tab.active_pane.title .. " "},
}
end
return tab.active_pane.title
end)
return {
}
```
refs: https://github.com/wez/wezterm/discussions/796
This commit decomposes the main get_semantic_zones method into two
parts:
* A per-line portion, where the line ranges are cached (invalidated on
change)
* The overall screen portion, where the line ranges are merged
This changes the overall complexity of computing zones from
O(width * scrollback-height)
To an incremental:
O((width * number of changed lines since last query) + scrollback-height)
You can see some samples of elapsed time below; those show the times for
running both the old and the new implementation on the same data. The
number of lines/zones in the scrollback increases with each call and you
can see that the new implementation is a bit faster anyway at low
volumes but is significantly faster as the number of lines/zones
increases, because the amount of work is reduced.
```
get_semantic_zones: 71.708µs
get_semantic_zones_new: 59.041µs
get_semantic_zones: 71.166µs
get_semantic_zones_new: 9.166µs
get_semantic_zones: 44.291µs
get_semantic_zones_new: 4.208µs
get_semantic_zones: 69.791µs
get_semantic_zones_new: 10.291µs
get_semantic_zones: 59.375µs
get_semantic_zones_new: 7.958µs
get_semantic_zones: 52.5µs
get_semantic_zones_new: 4.5µs
get_semantic_zones: 91.791µs
get_semantic_zones_new: 20.916µs
get_semantic_zones: 229.916µs
get_semantic_zones_new: 109.208µs
get_semantic_zones: 224.125µs
get_semantic_zones_new: 15.208µs
get_semantic_zones: 291.791µs
get_semantic_zones_new: 11.833µs
get_semantic_zones: 238.875µs
get_semantic_zones_new: 12.625µs
get_semantic_zones: 468.458µs
get_semantic_zones_new: 126.583µs
get_semantic_zones: 460.5µs
get_semantic_zones_new: 25.666µs
get_semantic_zones: 358.291µs
get_semantic_zones_new: 19.541µs
get_semantic_zones: 436.833µs
get_semantic_zones_new: 17.875µs
get_semantic_zones: 313.166µs
get_semantic_zones_new: 15.25µs
get_semantic_zones: 333.958µs
get_semantic_zones_new: 16.541µs
get_semantic_zones: 364.666µs
get_semantic_zones_new: 14.041µs
```