The issue is that the pane was only removed from the tab when explicitly
closed, leaving it to be later detected and flushed.
However, in the meantime, when performing eg: cursor blink maintenance,
if the set of panes in the tab is empty then the window would close.
The resolution is to ask the mux (rather than the tab) to kill the pane,
so that the cascading closure of the tab causes the window's active
tab to reference the correct remaining tab.
refs: #890
This changes the fill_rect function over to use the zeno crate.
zeno allows describing a path and filling or stroking.
This commit doesn't strictly need that, but it sets things
up for more interesting custom glyphs in later commits.
refs: #584
refs: #588
Same vein as 8931afba5cee07ab12990f06c2ff34d6f8426b19; the auth
window could sometimes get stuck until an input event was sent
to it.
Wire up a mux event so that the window can close itself.
When the client connected to an empty remote mux, it would allocate an
empty window and then spawn a new tab into it.
Meanwhile, the authentication window would close and trigger a prune of
all empty windows, causing the in-flight spawn to fail because its
destination window was removed.
This commit defers window pruning while Activity is in progress;
the MuxWindowBuilder has an associated Activity count.
in the same vein as d657721163, the
increased idle loop means we need to be careful not to suppress
invalidation events.
In this case, overlays aren't from the window in the mux model,
so we'd ignore invalidations for those.
While looking at this I realized that we'd also do the same
for output being emitted in panes that were not the active pane,
so tidy that up.
in the same vein as d657721163
this commit introduces more assertive signalling from the remote
mux when a pane is closed so that the client can update.
As part of reducing the amount of regularly scheduled stuff wezterm
does in the background, this commit restructures how an empty mux
is detected; now when the mux prunes dead windows it will emit
an Empty event.
The Activity type will now schedule a prune when it is dropped,
which will clean up and trigger the Empty event.
refs: https://github.com/wez/wezterm/issues/770
Adds a `ShowDebugOverlay` key assignment that will create a tab
overlay that shows a limited number of recently logged events.
refs: https://github.com/wez/wezterm/issues/641
This got a bit broken by the fix for https://github.com/wez/wezterm/issues/714
since we can be handed a range of logical line fragments, we should
test each of them to find our matching result.
Also, improve the logic for constraining the length when looking
backwards.
This commit introduces the knowledge about whether a font is
scalable or was using bitmap strikes (eg: color emoji bitmaps).
Then that information is used to help figure out whether and
how to scale a glyph.
refs: https://github.com/wez/wezterm/issues/685
* Better function for undercurl
* Setting lower alpha
* underline alpha in line-frag
* make undercurl alpha background independent
* Improved Shader
* Old Rasterization
Co-authored-by: Roland Fredenhagen <git@modprog.de>
When the title, icon, OSC 7 and SetUserVars sequences are processed,
notify the embedding application.
The gui layer uses this to trigger a titlebar update.
refs: #647
Previously, we used `git describe --tags` to produce a version number
for non-released builds derived from the most recent tag + some info
such as the number of commits since that tag and then `g{HASH}`.
That always confuses people because the date portion at the front
looks old (it is typically the previous release) and the hash at
the end has that `g` in it.
This commit simplifies both the tag name used when making a release
and the computed version number take the date/time from the current
commit, and then append the hash. That way the version number always
corresponds to a commit.
This scheme doesn't help detect situations where the commit is
dirty, but I don't think the old one would have helped with that
either.
the binary search would falsely extend the end of the match
to the start of the subsequent match for the wrapped line case.
The resolution is to emit a coordinate for the newline that we
add to the haystack between the wrapped lines.
closes: https://github.com/wez/wezterm/issues/732
In the situation where we have a full screen terminal (eg: 500 cells
wide), but very little output (eg: only 10's of columns on the left are
NOT blank), we would previously spend a non-trivial amount of time
calculating fg/bg colors for the blanks that trailed the actual
clusters; the calculation for each row was:
O(trailing-blanks * full cell color compute cost)
which was around 30us per row. For large numbers of rows this could
add up to >10ms per frame.
This commit changes the logic to run in two phases:
* O(selection-width) with simple fg/bg color updates for the selection
range
* O(1) full cell color compute cost for the cursor if the cursor
is somehow in the trailing blank region and not already handled
by the earlier clustering logic.
With the sequence of recent commits, the frame time for the large
terminal case has been reduced from ~22ms to ~7ms, which is approx 3x
improvement.
refs: #740
It looks like the mux search results include a trailing newline
in some cases, which means that a match can wrap onto a second
line.
If that line is shorter than the label length, we could panic.
This commit makes quickselect safer to use in this situation,
but the real fix is with the mux search code.
It's not perfect; this only handles the case where you move down
into the terminal. I couldn't easily make the same thing happen
when moving the mouse up or left outside of the window. It's
probably fixable but this is better than it was.
closes: https://github.com/wez/wezterm/issues/591
* Make alphabet and patterns configurable
* add docs
* Enhance scrollback search to support regex captures so that
searching for eg: `fo(o)` will select the last `o` in `foo`.
refs: https://github.com/wez/wezterm/issues/732
This is the first pass implementation, drawing on the alphabet logic
and default patterns from tmux-thumbs (thanks @fcsonline!).
ctrl-shift-space pops up the quick select overlay.
Typing the highlighted prefix will select the matching text and
copy it as though the `Copy` key assignment was used.
TODOs are to make the alphabet and patterns configurable, as well
as write up some docs.
refs: #732
I've built this on linux, which doesn't respect the timeout.
I've made speculative changes that should build on mac and windows,
but that don't plumb the timeout functionality on those systems
as of yet.
refs: #619
back out the portion of the cap height scaling that applied when
we knew the cap height of the primary font but not a fallback font.
That logic allowed some overly wide powerline fonts to be sized
correctly (a bit smaller), but also meant that a number of emoji
and other symbol glyphs were now undersized.
refs: https://github.com/wez/wezterm/issues/727
It now outputs something that you could conceivably put into
your config file, although the intent is to show the canonical
way to reference the individual fonts that were found, rather
than to specify a fully baked list to paste into a config.
eg:
```
; ./target/debug/wezterm ls-fonts
Primary font:
wezterm.font_with_fallback({
-- /home/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
{family="Operator Mono SSm Lig", weight="DemiLight"},
-- /home/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontConfig
{family="Operator Mono SSm Lig", weight="DemiLight"},
-- /home/wez/.fonts/MaterialDesignIconsDesktop.ttf, FontDirs
"Material Design Icons Desktop",
-- /home/wez/.fonts/terminus-bold.otb, FontDirs
{family="Terminus", weight="Bold"},
-- /home/wez/.fonts/JetBrainsMono-Regular.ttf, FontDirs
"JetBrains Mono",
-- /home/wez/.fonts/NotoColorEmoji.ttf, FontDirs
"Noto Color Emoji",
-- /home/wez/.fonts/MaterialDesignIconsDesktop.ttf, FontConfig
"Material Design Icons Desktop",
-- /usr/share/fonts/terminus-fonts/ter-u32n.otb, FontConfig
"Terminus",
-- /home/wez/.fonts/JetBrainsMono-Regular.ttf, FontConfig
"JetBrains Mono",
-- /home/wez/.fonts/NotoColorEmoji.ttf, FontConfig
"Noto Color Emoji",
-- <built-in>, BuiltIn
"Last Resort High-Efficiency",
})
```
we now compute the ratio of the cap height (the height of a capital
letter) vs. the em-square (which relates to our chosen point size) to
understand what proportion of the font point-size that a given font
occupies when rendered.
When rendering glyphs from secondary fonts we can use the cap height
ratios of both to scale the secondary font such that its effective
cap height matches that of the primary font.
In plainer-english: if you mix say bold, italic and regular text
style in the same line, and you have different font families for
those fonts, then they will now appear to be the same height where
previously they may have varied more noticeably.
For emoji and symbol fonts there may not be a cap-height metric
encoded in the font. We can however, improve our scaling: prior
to this commit we'd use the ratio of the cell metrics of the two
fonts to scale the icon/emoji glyph, but this could cause the glyph
to be slightly oversized as seen in https://github.com/wez/wezterm/issues/624
If we know the cap-height of the primary font then we can additionaly
apply that factor to scale the emoji to better fit the cell.
While looking at this, I noticed that the aspect ratio calculation
for when to apply to the allow_square_glyphs_to_overflow_width option
had width and height flipped :-(
See also: https://tonsky.me/blog/font-size/
refs: https://github.com/wez/wezterm/issues/624
This addresses the render artifacts aspect of https://github.com/wez/wezterm/issues/671
For whatever reason, some font(s) cannot be loaded on that system
and that results in the paint routine erroring out.
This commit avoids the error by substituting a blank glyph
instead of the glyph that failed to load.
refs: https://github.com/wez/wezterm/issues/671
This commit allows the x11 window implementation to detect changes
in the DPI that occur after a window is created.
These can occur when changing desktop resolution or when changing
the accessibility option for "Large Text" in gnome.
In order to avoid continually polling for the value on every resize,
we look for the `_GTK_EDGE_CONSTRAINTS` atom in our property change
notifications. This seems to be sent at least as often as the
dpi/scaling changes.
It's also worth noting that some dpi changes don't generate resize
events, so we can't just read the dpi value on every resize, because
we'd miss some of those changes.
Part of this commit changes the font scaling logic: previously
we'd keep a notion of "dpi scale" to apply. That dates from an
earlier time in wezterm where we didn't think that we knew an
actual dpi value.
The way that worked was that we'd compare our current guestimate
of the DPI against what we though the baseline OS dpi should be to
produce a scaling factor.
On X11 that dpi value is global and we'd effectively always produce
a revised scaling factor of 1 after we'd set up the initial window.
This commit changes that logic to just pass down the actual DPI value
to the font code. That DPI value already accounts for HiDPI scaling
so this is hopefully a NOP change for the other systems.
refs: https://github.com/wez/wezterm/issues/667
This was broken by b441be3ac9
For whatever reason, the breakage was only visible with the Iosveka
font on Windows. I couldn't reproduce it on my other systems, even
though the code technically applies to any system.
The breakage was: the metrics resulted in a difference of about 0.4
pixels being used for the descender with that particular font, resulting
in weird vertical alignment problems.
The offset needs to be computed against the ceil of the cell height,
which removes the fractional offset.
refs: https://github.com/wez/wezterm/issues/661
refs: https://github.com/wez/wezterm/issues/582
The repro scenario for this case was:
* open GNU nano
* hit enter twice
* type hello
* move the text cursor to the top line
* double click on hello
* hit enter
Prior to this commit, the selection would remain on the now-blank line
that previously held `hello`.
refs: #644
This has been a commonly requested feature in the past week,
and it's a reasonable one. The mux server inherited the
close-when-done behavior from when it used to be an alternate
front-end in the same executable as the gui, but it doesn't
need to be that way any more.
We also need to accomodate that case in the client: if the
newly attached domain doesn't result in any panes being imported,
we need to spawn a new command there in order to keep the client
alive. The pre-existing check for whether the mux was empty had
false positives because the local mux may still reference the
pane from the connection UI, which would finish closing out shortly
after we had decided not to spawn anything, and then the client
would close.
refs: https://github.com/wez/wezterm/issues/631
refs: https://github.com/wez/wezterm/issues/507
When line_height is specified, rather than applying the offset
to just the top of the cell, apply it in equal parts to the top
and the bottom so that the cell is vertically centered.
closes: https://github.com/wez/wezterm/issues/582
This replicates `last-window` in tmux. To pull this off, I
deliberately store the last tab whenever I'm activating a new one or
spawning a new one. I had to do this explicitly rather than hooking
set_active, because we end up setting the active tab briefly for some
common operations like moving a tab.
Allow overriding ssh config options from the command line.
I don't want to replicate the many options that `ssh(1)` has;
this just exposes the `-oNAME=VALUE` syntax. The config names
are those from `man ssh_config`; `IdentityFile` rather than `-i`.
refs: #457
I wonder how long this has been broken... rather than spawning
into domain "local" it would try to spawn into "`local`" and fail
silently because the error message wasn't logged.
So let's log it, and let's fix it.
refs: https://github.com/wez/wezterm/issues/468
There are a few notable changes as a result:
* A number of `.ssh/config` options are now respected; host matching
and aliasing and identity file are the main things
* The authentication prompt is inline in the window, rather than
popping up a separate authentication window
Refs: https://github.com/wez/wezterm/issues/457
These now operate in terms of logical lines so they deal with
lines that have wrapped outside the viewport better than in
previous releases.
closes: https://github.com/wez/wezterm/issues/408
Rust 1.51 allows addressesing a long-standing TODO which was that we
shouldn't need to build a vendored copy of openssl on most sensible unix
systems.
We do require a vendored copy on macOS and Windows, but due to the way
that Cargo's feature resolver worked, it wasn't possible for this
requirement to be respected.
Rust 1.51 introduces `resolver="2"` which can deal with this feature
resolution!
https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2
The upshot of this is that building wezterm on real unix systems that
are not macos will now link against the system libssl, resulting in both
a shorter compile time and less headaches arising from having a slightly
different openssl used by wezterm than the rest of the system.
cc: @jsgf
If shaping can't resolve some glyphs, queue the font locator
fallback resolution to another thread; meanwhile, a last resort
glyph is used.
That thread can trigger an invalidation once the fallback resolve
is complete, the window is invalidated and the last resort glyph
is replaced by the resolve glyph.
refs: https://github.com/wez/wezterm/issues/559
refs: https://github.com/wez/wezterm/issues/508
Default `allow_square_glyphs_to_overflow_width="WhenFollowedBySpace"`,
and expand its meaning from mostly square glyphs to glyphs that are
also wider than they are tall.
refs: https://github.com/wez/wezterm/issues/565
There's something fishy with colorspaces and blending.
This commit removes the `window::Color` type and replaces
it and the confusing array of color types exposed by the
`palette` crate with a pair of much simpler types:
`LinearRgb` - a tuple of f32 linear color components
`SrgbaPixel` - the u32 sRGBA pixel representation
This doesn't change anything about rendering, it just
makes it a bit simpler and makes the SrgbaPixel -> LinearRgb
conversion happen slightly earlier which shaves off some
ad-hoc conversions.
Refs: https://github.com/wez/wezterm/issues/544
hoist the underlyine glyph retrieval out of the loop.
Precompute some color conversions (less effective until
the gamma branch is merged).
refs: https://github.com/wez/wezterm/issues/546
Switches from using a dynamic vertex buffer to an immutable
vertex buffer. This feels counter-intuitive to me; the purpose
of dynamic is to sustain frequent updates, but mapping the buffer
needs to synchronize with the GPU, and if we are rapidly invalidating
the window that can stall painting by tens of milliseconds.
Switching to an immutable buffer avoids the stall and makes
quad mapping more consistently < 10ms, but its still not
ideal.
refs: https://github.com/wez/wezterm/issues/546
* Make window invalidation more efficient by avoiding spawning a call
that spawns a call to invalidate the window. Just directly mark as
invalidated.
* Suppress default background erase
* hoist the bg_color calc for quads that don't have Cells outside of
its loop.
refs: https://github.com/wez/wezterm/issues/546
I'm not convinced that this is 100% good, but @fanzeyi reported
some latency when using tmux to mirror two sessions. The session
that was accepting interactive input responded quickly, but the
mirroring session was laggy.
This change connects the mux pane output event to window invalidation,
which should cause repaints to happen more often.
I couldn't reproduce the scenario above on my M1 mac, but that may
just be because M1 has dark magicks.
A casualty of b8dcfba9a4 was that
the decoded gif would get reset each time the texture filled up.
Take care to move that cached into the newly minted glyphcache.
Continuing along the same lines as the prior commit, the goal
of this commit is to remove the buffer transformation that was
part of uploading the texture to the GPU provided surface.
In order to do so:
* The sense of our local textures needs to change from bgra32 to rgba32.
bgra32 was a hangover from earlier versions of our window crate that
allowed direct-to-fb writes in software mode. We had to pick bgra32
for that for the broadest OS compatibility. I believe that that
constraint has been totally removed, although there is a chance that
this will flip the colors on macos.
* There was an additional linear-to-srgb conversion inlined in that
buffer transformation. I have no idea where that is needed because
the source data is carefully constructed as SRGB. I don't yet know
how to signal that, but for now I've moved that gamma correction
into the shader when we sample the texture.
With this change, timg playback now has vtparse as the hottest
region of code.
refs: #537
Two issues highlighted by profiling:
* Clearing the texture takes a non-trivial percentage of the profile.
The docs suggest that it is better to create a new texture than
to update large portions of a texture, so add some plumbing so
that we can do that in the first texture-full case.
* Next on the list is the code that translates from linear BGRA to
SRGBA. This is present for reasons that I believe are now legacy,
but for the moment: those two primitives now have faster and
easier implementations, so simplify to those.
This improves the timg video playback performance by ~10% for me.
refs: #537
I've been meaning to do this for a while; this commit moves
the escape sequence parsing into the thread that reads the
pty output which achieves two goals:
* Large escape sequences (eg: image protocols) that span multiple
4k buffers can be processed without ping-ponging between the
reader thread and the main gui thread
* That parsing can happen in the reader thread, keeping the gui
thread more responsive.
These changes free up the CPU during intensive operations such
as timg video playback.
This is a slight layering violation, in that this processing
really belongs to local pane (or any pane that embeds Terminal),
rather than generically at the Mux layer, but it's not any
worse a violation than `advance_bytes` already was.
refs: https://github.com/wez/wezterm/issues/537
The leftmost pixel was being set to at least 1 by the scale
function.
Fix that up by computing the x coordinate without calling
the scale function.
refs: https://github.com/wez/wezterm/issues/536
Using a boxed slice means that we hold exactly the memory required
for the file data, rather than the next-power-of-two, which can
be wasteful when a large number of images are being sent to
the terminal.
This is a API breaking change for termwiz, so bump its version.
refs: #534
While adding gif support I let this become unbounded.
This commit resolves that by categorizing images as either
single frame or animations.
Single frame images are decoded and held entirely in the texture
atlas, so occupy no additional space beyond the image file contents
and their sprite region in the texture atlas.
Animations are decoded into a set of frame bitmaps. There can be
up to 16 animations (each with their full set of frames) cached.
The individual frames may also exist within the texture atlas
if space permits.
refs: #534
https://i.giphy.com/media/3owvKqP4VSydZE4pvq/200w.gif cannot
be decoded as an animated gif due to this error: `No end code in lzw stream`
Ensure that we don't completely fail to process the render phase
as a result.
Previously, invalidation for animation was driven by the cursor
blink rate, which meant that animated gifs/pngs could not play
faster than 5fps (default blink interval is 200ms).
This commit calculates the next invalidation time based on the
closes next frame time of all animated cells in the viewport.
This is first draft; the animation rate is currently tied
to the cursor_blink_rate setting, so if the gif has frames that
are intended to display more frequently than that, they will
animate more slowly.
Animation is only carried out while the window has focus.
Animation increases the load on the GPU and thus uses more power.
It's kinda fun to stick one of these animated pixel gifs in the background:
https://imgur.com/gallery/F9DAH
During a live resize, we could queue up a lot of `window-resized`
events, which is undesirable.
This commit introduces a simple but effective mechanism to manage this;
a given event can have at most one executing and one pending copy.
So if we get a burst of resize events (eg: during a live window resize)
that might have previously queued hundreds of discrete events, we now
get a more manageable situation with 1 executing and 1 queued.
With this change, a given event can only have 1 executing instance at a
time (with the exception that the open-uri event doesn't go through this
mechanism).
refs: https://github.com/wez/wezterm/issues/291
The previous behavior was to always treat ctrl-alt as altgr on Windows,
this has been done to better support altgr through a VNC session,
but this is very unintuitive when you don't need this behavior.
ref: #472
This is to support <https://github.com/wez/wezterm/issues/291>.
The window resized event happens asynchronously wrt. processing
a window resize, triggering at the end of the normal window
resize handling.
This commit introduces the notion of whether we are in full screen
mode or not in the underlying event callback, which is useful to
gate the desired feature, which is: when in full screen mode,
increase the padding for the window to center its content.
While poking around at this, I noticed that we weren't passing
the per-window config down to the code that computes the quad
locations for the window.
This commit also changes the font size increase/decrease behavior
so that in full screen mode it doesn't try to resize the window.
```lua
local wezterm = require 'wezterm';
wezterm.on("window-resized", function(window, pane)
local window_dims = window:get_dimensions();
local pane_dims = pane:get_dimensions();
local overrides = window:get_config_overrides() or {}
if not window_dims.is_full_screen then
if not overrides.window_padding then
-- not changing anything
return;
end
overrides.window_padding = nil;
else
-- Use only the middle 33%
local third = math.floor(window_dims.pixel_width / 3)
local new_padding = {
left = third,
right = third,
top = 0,
bottom = 0
};
if overrides.window_padding and new_padding.left == overrides.window_padding.left then
-- padding is same, avoid triggering further changes
return
end
overrides.window_padding = new_padding
end
window:set_config_overrides(overrides)
end);
return {
}
```
I'm calling it a temporary defeat on the shaping changes;
this commit effectively reverts the series of changes made
to support slicing up ligatures like `->` when the cursor
moves through them.
They've introduced so many issues and I've spent hours
that haven't resulted in a complete solution, so I've
disabled those changes by putting them behind a boolean
option.
I'll revisit them after I've cut the next release.
refs: https://github.com/wez/wezterm/issues/478
Manual test scenario:
```
wezterm -n --config adjust_window_size_when_changing_font_size=false --config 'exit_behavior="Hold"' start -- sh -c "echo '(...)'"
```
then CTRL +/- to change font size; the first cell of the `...` was
previously random garbage, now is more consistent.
refs: https://github.com/wez/wezterm/issues/478
mouse move events in the tab bar, and paint events, could cause
the title bar state to be recomputed.
Make sure that we don't trigger the status event to trigger for those.
refs: https://github.com/wez/wezterm/issues/500
I've only tested this on macos, but it should be cross platform,
with the caveat that Wayland doesn't let a window position itself,
so this won't work there.
We were using the value that was active when the window was created,
and never updating it.
This commit sweeps the interval check into the existing periodic
window maintenance routine.
refs: https://github.com/wez/wezterm/issues/500
The API isn't finalized; this is proof of concept for putting something
in the area to the right of the new tab button.
The info will be right aligned to the tab area.
```lua
local wezterm = require 'wezterm';
wezterm.on("update-right-status", function(window, pane)
-- demonstrates shelling out to get some external status.
-- wezterm will parse escape sequences output by the
-- child process and include them in the status area, too.
local success, date, stderr = wezterm.run_child_process({"date"})
-- Make it italic and underlined
window:set_right_status(wezterm.format({
{Attribute={Underline="Single"}},
{Attribute={Italic=true}},
{Text="Hello "..date},
}));
end)
return {
}
```
refs: https://github.com/wez/wezterm/issues/500
As explained in the docs included in this commit, ideally this
wouldn't be needed, but due to a long-standing hinting bug in
freetype <https://gitlab.freedesktop.org/freetype/freetype/-/issues/761>
it seems most expedient to just render our own block glyphs,
so that's what this does!
refs: #433
This commit expands on the prior commits to introduce the concept
of per-window configuration overrides.
Each TermWindow maintains json compatible object value holding
a map of config key -> config value overrides.
When the window notices that the config has changed, the config
file is loaded, the CLI overrides (if any) are applied, and then
finally the per-window overrides, before attempting to coerce
the resultant lua value into a Config object.
This mechanism has some important constraints:
* Only data can be assigned to the overrides. Closures or special
lua userdata object handles are not permitted. This is because
the lifetime of those objects is tied to the lua context in which
they were parsed, which doesn't really exist in the context of
the window.
* Only simple keys are supported for the per-window overrides.
That means that trying to override a very specific field of
a deeply structured value (eg: something like `font_rules[1].italic = false`
isn't able to be expressed in this scheme. Instead, you would
need to assign the entire `font_rules` key. I don't anticipate
this being a common desire at this time; if more advance manipulations
are required, then I have some thoughts on an event where arbitrary
lua modifications can be applied.
The implementation details are fairly straight-forward, but in testing
the two examplary use cases I noticed that some hangovers from
supporting overrides for a couple of font related options meant that the
window-specific config wasn't being honored. I've removed the code that
handled those overrides in favor of the newer more general CLI option
override support, and threaded the config through to the font code.
closes: #469closes: #329
`wezterm`, `wezterm-gui` and `wezterm-mux-server` now all support
a new `--config name=value` CLI option that can be specified
multiple times to supply config overrides.
Since there isn't a simple, direct way to update arbitrary fields
of a struct in Rust (there's no runtime reflection), we do this
work in lua.
The config file returns a config table. Before that is mapped
to the Rust Config type, we have a new phase that takes each
of the `--config` values and applies it to the config table.
For example, you can think of configuration as working like this
if wezterm is started as `wezterm --config foo="bar"`:
```lua
config = load_config_file();
config.foo = "bar";
return config;
```
The `--config name=value` option is split into `name` and `value`
parts. The name part is literally concatenated with `config` in
the generated lua code, so the name MUST be valid in that context.
The `value` portion is literally inserted verbatim as the rvalue in the
assignment. Not quoting or other processing is done, which means
that you can (and must!) use the same form that you would use in
the config file for the RHS. Strings must be quoted. This allows
you to use more complicated expressions on the right hand side,
such as:
```
wezterm --config 'font=wezterm.font("Fira Code")'
```
The overrides stick for the lifetime of the process; even if
you change the config file and reload, then the value specified
by the override will take precedence.
refs: https://github.com/wez/wezterm/issues/469
refs: https://github.com/wez/wezterm/issues/499