1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-26 14:54:16 +03:00
Commit Graph

723 Commits

Author SHA1 Message Date
Wez Furlong
1e32ccbd2f shaping: fix an issue where we'd lose combining marks like U+20d7
For a sequence like `e U+20d7` the intent is to render the `e` with
a vector arrow over the top.

This is typically implemented by fonts as an `e` followed by the
vector glyph (or vice versa), where either one of those may have
a zero advance so that the two elements are combined.

There were two problems here:

* During shaping we'd see the zero advance and assume that the entry
  was useless and skip it
* During rendering, if we didn't think it had any cell width, we'd
  not render it

Cursoring through that particular sequence can hide the vector
mark if the cursor is set to the default block cursor due to annoyances
in how the block cursor is rendered (it changes the fg color to match
the bg, but for elements outside where we think the cursor is, this
makes those elements invisible).

refs: https://github.com/wez/wezterm/issues/1617
2022-02-05 06:19:25 -07:00
Wez Furlong
092663a332 slightly simplify compute_cell_fg_bg
Reduce the number of parameters passed down into it
2022-02-04 08:38:16 -07:00
Wez Furlong
f4c3eab3f8 remove some dead code 2022-02-04 07:54:47 -07:00
Wez Furlong
cb1f35a7f9 remove experimental_shape_post_processing option
This has been obsoleted by the work in 9de0e1ac90
2022-02-04 07:43:01 -07:00
Wez Furlong
024261672a maybe really fix the alignment issues!
refs: #1570
refs: #1607
refs: #1563
2022-02-02 08:46:10 -07:00
Wez Furlong
9de0e1ac90 shaping: improve glyph cell width math
This is a more robust approach; we make a separate pass to figure
out information about the (harfbuzz) cluster for a sequence of glyphs,
and then map that sequence back to the original cell sequence, and
from there compute the total cell width for the run, then distribute
the glyphs across the run.

This should yield more sane results for bidi.

Fixup the x-position math; it was still wonky despite the
efforts in 5f2c905db8 and
af92265ffb

refs: #1570
refs: #1607
refs: #1563
2022-02-01 22:03:50 -07:00
Wez Furlong
5f2c905db8 shaping: feed presentation width from the terminal through to glyph info
This allows unicode_version to be respected again when rendering.

The updated emoji-presentation.sh script now highlights this slightly
better by putting `.` characters after the emoji; unicode version 14
emoji presentation will show the `.` in the 3rd column, while earlier
versions will show it in the 2nd column for glyphs that are sensitive
to the version.

refs: #1607
refs: #1563
2022-02-01 09:23:57 -07:00
Wez Furlong
af92265ffb render: fix regression with emoji width rendering
refs: #1607
refs: #1609
2022-02-01 08:25:05 -07:00
Wez Furlong
cf518c9186 fun with sticky bits and RUNTIME_DIR
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
2022-01-31 07:29:15 -07:00
Wez Furlong
0da3e159a4 bidi: sort of make right-aligned text do something
with:

```
  bidi_enabled = false,
  bidi_direction = "RightToLeft",
```

lines are now rendered right-justified in the terminal.
I think there's still work to do on this, because the cluster
order seems weird to me, but it's hard for me to intuit how
this should really look.

refs: #784
2022-01-30 20:14:22 -07:00
Wez Furlong
98f35bbf24 bidi: tag Line with bidi mode
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
2022-01-30 09:50:04 -07:00
Wez Furlong
a2779cafec gui: fix rendering to account for RTL text
We were using the physical cell position to place the glyphs,
but we need to use the visual cell position (post-RTL-reordering).

refs: #784
2022-01-29 05:59:24 -07:00
Wez Furlong
e8f5463b7d adjust ls-fonts --text diagnostic output 2022-01-29 05:59:24 -07:00
Wez Furlong
66183ed336 fix test build 2022-01-28 18:51:49 -07:00
Wez Furlong
4ca1378f1f fonts: allow shaping with additional paragraph context
we don't really use this yet, except internally when we do fallback
2022-01-28 17:19:36 -07:00
Wez Furlong
0324ff66f0 wezterm: add experimental_bidi config option and very basic bidi
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
2022-01-25 09:00:53 -07:00
Wez Furlong
2deba1ece4 fonts: fix ligature widths at the cost of unicode version conformance
refs: #1563
2022-01-19 18:16:48 -07:00
Wez Furlong
a590955229 spawning a new tab didn't unfocus current pane
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
2022-01-18 18:56:26 -07:00
Wez Furlong
0bf1b8d13e Plumbing for unseen activity indication
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
2022-01-18 09:38:46 -07:00
Wez Furlong
0fe7a22f67 expose pixel positioning config option
refs: #1563
2022-01-18 08:13:30 -07:00
Wez Furlong
c930e333c4 fix an issue where ScrollToPrompt got confused by two prompts on same line
refs: https://github.com/wez/wezterm/issues/1121
2022-01-17 22:48:53 -07:00
Wez Furlong
2c44abc700 fix naming of get_semantic_prompt_zones
It previously had the more generic name of get_semantic_zones
which implied that it cached all zones, but this method is
scoped only to Prompt zones.
2022-01-17 22:25:43 -07:00
Wez Furlong
e4ed2c93e2 encoding my preferred import grouping in the rustfmt config
This uses an unstable option in rustfmt, you `cargo +nightly fmt`
needs to be used to format the code correctly.
2022-01-17 13:50:51 -07:00
Wez Furlong
db8f588c5e Add SwitchWorkspaceRelative key assignment 2022-01-17 09:54:11 -07:00
Wez Furlong
8d3d3e02a7 add default_workspace config option
refs: #1322
refs: #1531
2022-01-17 09:31:20 -07:00
Wez Furlong
d169088694 fix clipping issue in fancy tab bar
We budget size based on the x_advance, which can be 1 pixel less
than the width of the glyph texture, so we could often end up
omitting the last character in "Launcher" or "default" in the
tab title or right status area.

This commit uses x_advance in both places.
2022-01-17 09:24:23 -07:00
Wez Furlong
e8900d47cd add window:active_workspace()
refs: #1531
refs: https://github.com/wez/wezterm/discussions/1322#discussioncomment-1984256
2022-01-17 09:11:06 -07:00
Wez Furlong
7eec41c284 Add ShowLauncherArgs key assignment
refs: https://github.com/wez/wezterm/issues/1485
2022-01-17 08:16:18 -07:00
Wez Furlong
631f7869a5 launcher: consistently order entries 2022-01-16 20:59:51 -07:00
Wez Furlong
b6141d650e launcher: improve scrolling through options and mouse selection
Make the scrolling mostly independent of the active row; adjust
the top row when hitting the top/bottom edges of the display.

Mouse movement no longer changes the scroll position.  Instead,
the wheel is used to scroll the list.

refs: https://github.com/wez/wezterm/issues/1485
2022-01-16 20:28:46 -07:00
Wez Furlong
25c0540875 fix bar cursors when moving through double-width cells
Don't render two copies of the cursor in the same cell,
and compute different graphics for double wide cells.

refs: #1548
2022-01-16 12:19:49 -07:00
Wez Furlong
71630844c8 fix warning 2022-01-16 09:53:34 -07:00
Wez Furlong
e575bc9ff9 simplify window reconciliation logic
refs: https://github.com/wez/wezterm/issues/1531
2022-01-16 09:50:16 -07:00
Wez Furlong
12f32aeda8 tidy up front end accessors 2022-01-15 21:46:40 -07:00
Wez Furlong
39c2da3bdf avoid race condition when closing last window in a workspace
This isn't ideal, but it is better than previously: we would
close the window and before the Drop impl had updated the
list of known windows, we'd try to re-assign that window
to another mux window in a different workspace, but it would
never appear because the window was closed.

refs: https://github.com/wez/wezterm/issues/1531
2022-01-15 20:02:14 -07:00
Wez Furlong
093b448624 When switching workspaces, resize workspace to fit the window
Originally I had this the other way around but it was problematic
when considering things like maximized, font scaling and full screen
states.

refs: https://github.com/wez/wezterm/issues/1531
2022-01-15 19:33:29 -07:00
Wez Furlong
bb9290f431 launcher: avoid subtract with overflow panic 2022-01-15 19:33:02 -07:00
Wez Furlong
76a213f7ab Gui switches to a different workspace when current workspace is emptied
Rather than just quitting the app and potentially silently killing off
a number of panes that might be running in other workspaces, we now
will pick one of those workspaces and activate it.

refs: #1531
2022-01-15 14:41:19 -07:00
Wez Furlong
aa52555fb8 add workspaces to launcher menu
refs: #1531
2022-01-15 14:16:41 -07:00
Wez Furlong
6ba9d7f72e Add --workspace parameter to most gui subcommands
These allow setting the initial workspace name
2022-01-15 14:01:30 -07:00
Wez Furlong
6d288696c8 Add SwitchToWorkspace keyassignment action
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
2022-01-15 13:53:34 -07:00
Wez Furlong
9a241509a4 mux: add current identity concept
The mux now has a notion of which client is actively doing things.
This allows, for example, newly spawned windows to take on the
active workspace for a given client.

The gui now assigns a client id on startup, and sets the active
workspace to `default`.

The mux server temporarily overrides the active id to that of
the currently dispatching client when processing PDUs.

refs: https://github.com/wez/wezterm/issues/1531
2022-01-15 06:25:11 -07:00
Wez Furlong
170bb31f4f refactor: move more spawn logic into new mux methods 2022-01-14 22:28:35 -07:00
Wez Furlong
30a9692f9d refactor: centralize some more spawn logic 2022-01-14 22:28:35 -07:00
Wez Furlong
3947014bad refactor: decouple domain from cwd matching in spawn.rs
This will make it easier to re-use other spawn functions in a later
commit.
2022-01-14 22:28:35 -07:00
Wez Furlong
1704af88ba refactor: move logic -> Mux::spawn_tab_or_window
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.
2022-01-14 22:28:35 -07:00
Wez Furlong
12de21df95 clarify debug_key_events logging
up/down events were ambiguous
2022-01-14 21:59:29 -07:00
Howard Huang
e01f9c0e7d FEATURE: Allow ScrollByPage f64 values
`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.
2022-01-12 17:01:38 -08:00
Wez Furlong
cefe45d206 Windows can be labelled with a workspace name
This is not exposed through any UX; the mux api allows setting
the workspace and propagating information about windows whose
workspace has changed.

Windows start with a blank workspace name.

This is just plumbing; nothing uses it yet.

refs: #1531
2022-01-12 16:47:08 -07:00
Wez Furlong
e314d84711 wezterm connect unix could exit on startup
This is a similar race condition to one we had before with the
multiplexer, where the connection UI made us think that we didn't
need to start a new process.

Additionally, the attach method would unconditionally create a
new client without checking whether we already had one.
2022-01-11 22:35:31 -07:00