This commit allows the following configuration:
```
wezterm -n --config 'colors = { selection_fg = "clear", selection_bg = "rgba:50% 50% 50% 50%" }'
```
which sets the selection_bg to fully transparent, and selection_bg to
50% transparent gray.
When selection_fg is fully transparent we'll use the normal fg color.
When selection_bg is partially (or fully!) transparent, it will be
alpha blended over the current cell background color.
To support this, the config file will now accept rgba colors specified
as 4 whitespace delimited numeric values. If a value ends with `%` it
is interpreted as a number in the range 0-100. Otherwise, it is
interpreted as a number in the range 0-255. The 4 values are
red, green, blue, alpha.
At this time, only the selection_fg and selection_bg settings accept
alpha values.
refs: #1615
This commit does two related things, from opposite ends of the spectrum:
* Sets the sticky bit on pid files and unix sockets to avoid tmpwatch
deleting them in cleanup scenarios
* Falls back to looking at the changed time if the filesystem doesn't
support reporting creation time when wezterm does its own liveness
and cleanup checks for unix domain sockets in the runtime dir
* Allow any wezterm instance to perform that cleanup
refs: #1601
This commit refines bidi property handling:
* experimental_bidi has been split into two new configuration settings;
`bidi_enabled` (which controls whether the terminal performs implicit
bidi processing) and `bidi_direction` which specifies the base
direction and whether auto detection is enabled.
* The `Line` type can now store those bidi properties (they are actually
split across 3 bits representing enabled, auto-detection and
direction)
* The terminal now has a concept of active bidi properties and default
bidi properties
* The default properties are pulled from the wezterm configuration
* active bidi properties are potentially set via escape sequences,
BDSM (which sets bidi_enabled) and SCP (which sets bidi_direction).
We don't support the 2501 temporary dec private mode suggested by
the BIDI recommendation doc at this time.
* When creating new `Line`'s or clearing from the start of a `Line`, the
effective bidi properties are computed (from the active props,
falling back to default propr) and applied to the `Line`.
* When rendering the line, we now look at its bidi properties instead
of just the global config.
The default bidi properties are `bidi_enabled: false` and
`bidi_direction: LeftToRight` which corresponds to the typical
bidi-unaware mode of most terminals.
It is possible to live reload the config to change the effective
defaults, but note that they apply, by design, to new lines being
processed through the terminal. That means existing output is
left unaffected by a config reload, but subsequently printed lines
will respect it. Pressing CTRL-L or otherwise contriving to have
the running application refresh its display should cause the
refreshed display to update and apply the new bidi mode.
refs: #784
Introduce a new config knob called 'local_echo_threshold_ms' to let
users configure when the local echo prediction should kick in. The
default value is 100ms to retain the current behavior.
This commit is larger than it appears to due fanout from threading
through bidi parameters. The main changes are:
* When clustering cells, add an additional phase to resolve embedding
levels and further sub-divide a cluster based on the resolved bidi
runs; this is where we get the direction for a run and this needs
to be passed through to the shaper.
* When doing bidi, the forced cluster boundary hack that we use to
de-ligature when cursoring through text needs to be disabled,
otherwise the cursor appears to push/rotate the text in that
cluster when moving through it! We'll need to find a different
way to handle shading the cursor that eliminates the original
cursor/ligature/black issue.
* In the shaper, the logic for coalescing unresolved runs for font
fallback assumed LTR and needed to be adjusted to cluster RTL.
That meant also computing a little index of codepoint lengths.
* Added `experimental_bidi` boolean option that defaults to false.
When enabled, it activates the bidi processing phase in clustering
with a strong hint that the paragraph is LTR.
This implementation is incomplete and/or wrong for a number of cases:
* The config option should probably allow specifying the paragraph
direction hint to use by default.
* https://terminal-wg.pages.freedesktop.org/bidi/recommendation/paragraphs.html
recommends that bidi be applied to logical lines, not physical
lines (or really: ranges within physical lines) that we're doing
at the moment
* The paragraph direction hint should be overridden by cell attributes
and other escapes; see 85a6b178cf
and probably others.
However, as of this commit, if you `experimental_bidi=true` then
```
echo This is RTL -> عربي فارسی bidi
```
(that text was sourced from:
https://github.com/microsoft/terminal/issues/538#issuecomment-677017322)
then wezterm will display the text in the same order as the text
renders in Chrome for that github comment.
```
; ./target/debug/wezterm --config experimental_bidi=false ls-fonts --text "عربي فارسی ->"
LeftToRight
0 ع \u{639} x_adv=8 glyph=300 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
2 ر \u{631} x_adv=3.78125 glyph=273 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
4 ب \u{628} x_adv=4 glyph=244 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
6 ي \u{64a} x_adv=4 glyph=363 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
8 \u{20} x_adv=8 glyph=2 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
9 ف \u{641} x_adv=11 glyph=328 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
11 ا \u{627} x_adv=4 glyph=240 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
13 ر \u{631} x_adv=3.78125 glyph=273 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
15 س \u{633} x_adv=10 glyph=278 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
17 ی \u{6cc} x_adv=4 glyph=664 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
19 \u{20} x_adv=8 glyph=2 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
20 - \u{2d} x_adv=8 glyph=276 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
21 > \u{3e} x_adv=8 glyph=338 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
```
```
; ./target/debug/wezterm --config experimental_bidi=true ls-fonts --text "عربي فارسی ->"
RightToLeft
17 ی \u{6cc} x_adv=9 glyph=906 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
15 س \u{633} x_adv=10 glyph=277 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
13 ر \u{631} x_adv=4.78125 glyph=272 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
11 ا \u{627} x_adv=4 glyph=241 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
9 ف \u{641} x_adv=5 glyph=329 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
8 \u{20} x_adv=8 glyph=2 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
6 ي \u{64a} x_adv=9 glyph=904 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
4 ب \u{628} x_adv=4 glyph=243 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
2 ر \u{631} x_adv=5 glyph=273 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
0 ع \u{639} x_adv=6 glyph=301 wezterm.font(".Geeza Pro Interface", {weight="Regular", stretch="Normal", italic=false})
/System/Library/Fonts/GeezaPro.ttc index=2 variation=0, CoreText
LeftToRight
0 \u{20} x_adv=8 glyph=2 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
1 - \u{2d} x_adv=8 glyph=480 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
2 > \u{3e} x_adv=8 glyph=470 wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
/Users/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
;
```
refs: https://github.com/wez/wezterm/issues/784
This setting now allows specifying what the canonical format is;
previously it was a boolean that meant "don't change anything"
if false, and rewrite to CRLF if true.
It's now an enum with None, CR, LF, and CRLF variants that express
more control.
The config accepts true (maps to CRLF) and false (maps to None)
for backwards compatibility.
The default behavior is unchanged by this commit, however, I did
uncover a bug in the canonicalizer for inputs like `\r\r\n`.
refs: #1575
I generated nerdfonts_data.rs with this shell script; it uses `i_all.sh`
from the nerdfonts repo to get the base mapping:
```
source ./lib/i_all.sh
echo "//! Data mapping nerd font symbol names to their char codepoints"
echo "pub const NERD_FONT_GLYPHS: &[(&str, char)] = &["
for var in "${!i@}"; do
# trim 'i_' prefix
glyph_name=${var#*_}
glyph_char=${!var}
glyph_code=$(printf "%x" "'$glyph_char'")
echo "(\"$glyph_name\", '\u{$glyph_code}'), // $glyph_char"
done
echo "];"
```
Then intent is to use it in wezterm:
```
local wezterm = require 'wezterm'
wezterm.log_info(wezterm.nerdfonts.dev_mozilla)
```
Built using:
```
./FontForge-2020-11-07-21ad4a1-x86_64.AppImage --script $PWD/font-patcher "$PWD/src/unpatched-fonts/NerdFontsSymbolsOnly/NerdFontsSymbolsOnly Template 1000 em.ttf" --powerline --use-single-width-glyphs -out /tmp/nerd-fonts-out --fontawesome --fontawesomeextension --fontlinux --octicons --codicons --powersymbols --powerline --powerlineextra --mdi --weathericons
```
which is everything *except* Pomicons at the time of writing, pending
clarifications of its distribution license
(https://github.com/ryanoasis/nerd-fonts/issues/266)
refs: https://github.com/wez/wezterm/issues/1521
This action causes the active workspace for the gui to change.
If the name is omitted a random name will be generated.
If the workspace doesn't exist, it will be be created.
The optional spawn parameter can be used to launch a specific
program into the new workspace; if omitted, the default prog
will be used.
The gui only supports a single active workspace. Switching workspaces
will repurpose existing gui windows and re-assign them to windows
in the new workspace, adjusting their size to fit those windows,
spawning new windows or closing unused windows as required.
The gui now exits when there are no panes in the active workspace,
rather than no panes at all.
refs: #1531
Tidies up some code duplication within the mux protocol handler.
Move some of the logic into Mux, remove legacy Spawn Pdu to reduce
more duplication.
I want to dedup some of the similar logic that exists in the gui
spawn implementation as well in a follow up.
The issue is that we work hard to match the keys pre-composition,
but for French and Norwegian layouts ALT-number are valid,
useful punctuation keys. It's awkward to make exceptions for
ALT keys when matching assignments, especially on macOS, and
the simplest thing to do is simply to remove the assignments
and leave it to our users to add their own if they want them.
The ctrl-shift and cmd based assignments are generally much
easier to keep, because those key combinations are not widely
used default mappings on any keyboard layout.
refs: #1543
refs: #1542
refs: https://github.com/wez/wezterm/pull/1132
This resolves some issues with non-US layouts (French, Norweigan)
where ALT-number are important and useful punctuation that we were
otherwise blocking.
This new behavior seems consistent with eg: vte terminals on linux
when switching to a French layout.
refs: #1543
refs: #1542
`ScrollByPage` can accept non-integer values in the configuration.
This allows fractional page scrolling, such as by half a page.
The default remains the same, at 1 page.
If we know that the remote host is a unix system, and that it uses some
version of the posix shell, then we can adjust our command line to cd to
the requested directory (as set by OSC 7) and then exec the requested
command.
That's what SshDomain::assume_unix indicates and what this commit does.
This puts us in a better position for the future to be able
to configure whether we use wezterm, tmux or no multiplexing.
Today we allow wezterm or no multiplexing.
Add docs on this new setting.
refs: https://github.com/wez/wezterm/issues/1456
That top level config/src/lib.rs has been too big for too long.
Break it up a little.
(I recommend running `cargo clean` if you're updating across
this change to avoid a rust ICE with it cached on-disk state)
Previously, it would skip loading the initial config and allow
loading it later by using the reload hotkey. That reload behavior
was an accident!
Another problem with the old approach is that everything else was
set up as if the config had been loaded, which is now causing
confusion for code that wants to decide whether we are using
that configuration or not.
This commit formalizes the skip by remembering that state globally.
This change helps to simplify some special cases around command
line overrides as well, as well as allows cli overrides to take
effect when the user doesn't have a config file.
They have their own versions of these options, and logically it doesn't
make sense to use the default_prog from the `local` domain with a wsl
domain.
refs: #1242
This returns the default set of domains that would be populated
in the wsl_domains config. This is useful if you want to override
eg: the default_prog for specific domain(s), or want to otherwise
add additional variations on the default list.
When set, changes the default domain to the domain with the specified
name, which potentially affects the default program.
eg: default_domain = "WSL:Ubuntu-18.04" will cause the initial tab
to be spawned via WSL.
The idea is that we want to be able to spawn into wsl with the
convenience of a local domain, but without the awkwardness of
it having a different filesystem namespace.
It would also be great to be able to spawn a new tab or pane
in the same domain and pick up the cwd of the existing one.
The WslDomain allows the user to explicitly list WslDomains
and control eg: default shell, username and so on, but wezterm
will pre-fill a default list of domains based on the `wsl -l`
output that we were already using in the launcher menu.
The existing LocalDomain has been augmented to understand that
it may need to fixup a command invocation and that gives it
the opportunity to rewrite the command so that we can launch
it via `wsl.exe` and pass down the cwd and so on.
This same technique might be extensible to eg: docker instances
in the future.
This commit:
* Introduces `wsl_domains` config and its default list of wsl
distributions
* Creates LocalDomain instances from that list
* The launcher menu allows spawning a new tab via one of those domains
Using the new publish/discovery stuff from the past couple of commits,
if we can find a matching socket path for a running gui, and the
configuration is likely a match, then use the mux protocol to talk
to the already running gui and ask it to spawn the equivalent program
into the same process.
refs: https://github.com/wez/wezterm/discussions/1486
We need 100% of the info for it to work correctly, so this commit:
* Exposes the keyboard encoding mode via the Pane trait
* Adds the scan code to the RawKeyEvent
* Has the GUI perform the encoding if the keyboard is set that way
* Removes the basic encoder from termwiz in favor of the gui level one
The net result is that we bypass the Pane::key_up/Pane::key_down methods
in almost all cases when the encoding mode is set to win32-input-mode.
There is now a config option: allow_win32_input_mode that can be
used to prevent using this mode.
refs: #1509
* Allow selecting the first few rows by number
* Allow scrolling through long lists of items
* Add actions from key assignments to list
refs: #1485
refs: #1413
This commit adjusts the config parsing layer so that:
```
return {
keys = {
{key="a", ...}
}
}
```
is now treated as being implicitly the same as `key="phys:A"`.
You can explicitly use `key="mapped:a"` to use the post-keyboard-map
processed value of a key to trigger an assignment, rather than
the physical key location.
refs: #1483
When set, the cursor will change to this color during dead key
or leader key processing.
```lua
return {
colors = {
dead_key_cursor = "orange",
},
}
```
refs: #686
refs: #688