WezTerm Icon WezTerm is a GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust

Download

Features

Looking for a configuration reference?

These docs are searchable: press S or click on the magnifying glass icon to activate the search function!

Screenshot

Screenshot of wezterm on macOS, running vim

WezTerm is available pre-built for the major platforms and, because it is open source, you may also build it for yourself.

Installing on Windows

64-bit Windows 10.0.17763 or later is required to run WezTerm; running on earlier versions of Windows is not possible, as WezTerm requires Pseudo Console support that was first released in Windows 10.0.17763.

You can download a setup.exe style installer to guide the installation (requires admin privileges) or a simple zip file and manage the files for yourself (no special privileges required).

Windows (setup.exe) Nightly Windows (setup.exe)

WezTerm is available in a setup.exe style installer; the installer is produced with Inno Setup and will install wezterm to your program files directory and register that location in your PATH environment. The installer can be run as a GUI to guide you through the install, but also offers the standard Inno Setup command line options to configure/script the installation process.

Windows (zip) Nightly Windows (zip)

WezTerm is also available in a simple zip file that can be extracted and run from anywhere, including a flash drive for a portable/relocatable installation.

  1. Download Release
  2. Extract the zipfile and double-click wezterm.exe to run the UI
  3. Configuration instructions can be found here

For winget users

If you prefer to use the command line to manage installing software, then you may wish to try winget. winget is installed as part of the App Installer that is available from the Microsoft Store.

Once you have winget, you can install wezterm like so:

winget install wez.wezterm

and to later upgrade it:

winget upgrade wez.wezterm

For Scoop users

Another option if you prefer to use the command line to manage installing software, is Scoop.

Wezterm is available from the "Extras" bucket and once you have installed scoop itself can be installed like so:

scoop bucket add extras
scoop install wezterm

For Chocolatey users

If you prefer to use Chocolatey to manage software, wezterm is availabe from the Community Repository. It can be installed like so:

choco install wezterm -y

Installing on macOS

The CI system builds the package on macOS Big Sur and should run on systems as "old" as Mojave. It may run on earlier versions of macOS, but that has not been tested.

Starting with version 20210203-095643-70a364eb, WezTerm is a Universal binary with support for both Apple Silicon and Intel hardware.

Download for macOS Nightly for macOS

  1. Download Release
  2. Extract the zipfile and drag the WezTerm.app bundle to your Applications folder
  3. First time around, you may need to right click and select Open to allow launching the application that your just downloaded from the internet.
  4. Subsequently, a simple double-click will launch the UI
  5. Configuration instructions can be found here

Homebrew

WezTerm is available for brew users in a tap:

$ brew tap wez/wezterm
$ brew install --cask wez/wezterm/wezterm

If you'd like to use a nightly build:

$ brew install --cask wez/wezterm/wezterm-nightly

to upgrade to a newer nightly (normal brew upgrade will not upgrade it!):

$ brew upgrade --cask wezterm-nightly --no-quarantine --greedy-latest

MacPorts

WezTerm is also available via MacPorts:

$ sudo port selfupdate
$ sudo port install wezterm

Installing on Linux using AppImage

WezTerm is available in AppImage format; a self-contained single file that doesn't require installation or any special privileges to run, and that is compatible with a wide range of Linux distributions.

Download and make the file executable and you're ready to run!

AppImage Nightly AppImage

curl -LO https://github.com/wez/wezterm/releases/download/20220624-141144-bd1b7c5d/WezTerm-20220624-141144-bd1b7c5d-Ubuntu18.04.AppImage
chmod +x WezTerm-20220624-141144-bd1b7c5d-Ubuntu18.04.AppImage

You may then execute the appimage directly to launch wezterm, with no specific installation steps required:

./WezTerm-20220624-141144-bd1b7c5d-Ubuntu18.04.AppImage

That said, you may wish to make it a bit more convenient:

mkdir ~/bin
mv ./WezTerm-20220624-141144-bd1b7c5d-Ubuntu18.04.AppImage ~/bin/wezterm
~/bin/wezterm

Installing on Ubuntu and Debian-based Systems

The CI system builds .deb files for a variety of Ubuntu and Debian distributions. These are often compatible with other Debian style systems; if you don't find one that exactly matches your system you can try installing one from an older version of your distribution, or use one of the Debian packages linked below. Failing that, you can try the AppImage download which should work on most Linux systems.

DistroStableNightly
Ubuntu18wezterm-20220624-141144-bd1b7c5d.Ubuntu18.04.debwezterm-nightly.Ubuntu18.04.deb
Ubuntu20wezterm-20220624-141144-bd1b7c5d.Ubuntu20.04.debwezterm-nightly.Ubuntu20.04.deb
Ubuntu22wezterm-20220624-141144-bd1b7c5d.Ubuntu22.04.debwezterm-nightly.Ubuntu22.04.deb
Debian9wezterm-20220624-141144-bd1b7c5d.Debian9.12.debNo longer supported
Debian10wezterm-20220624-141144-bd1b7c5d.Debian10.debwezterm-nightly.Debian10.deb
Debian11wezterm-20220624-141144-bd1b7c5d.Debian11.debwezterm-nightly.Debian11.deb

To download and install from the CLI, you can use something like this, which shows how to install the Ubuntu 20 package:

curl -LO https://github.com/wez/wezterm/releases/download/20220624-141144-bd1b7c5d/wezterm-20220624-141144-bd1b7c5d.Ubuntu20.04.deb
sudo apt install -y ./wezterm-20220624-141144-bd1b7c5d.Ubuntu20.04.deb
  • The package installs /usr/bin/wezterm and /usr/share/applications/org.wezfurlong.wezterm.desktop
  • Configuration instructions can be found here

Installing on Fedora and rpm-based Systems

The CI system builds .rpm files on CentOS, Fedora and openSUSE systems. These are likely compatible with other rpm-based distributions. Alternatively, you can try the AppImage download with should work on most Linux systems.

DistroStableNightly
CentOS7wezterm-20220624_141144_bd1b7c5d-1.el7.x86_64.rpmwezterm-nightly-centos7.rpm
CentOS8wezterm-20220624_141144_bd1b7c5d-1.el8.x86_64.rpmwezterm-nightly-centos8.rpm
CentOS9wezterm-20220624_141144_bd1b7c5d-1.el9.x86_64.rpmwezterm-nightly-centos9.rpm
Fedora33wezterm-20220624_141144_bd1b7c5d-1.fc33.x86_64.rpmwezterm-nightly-fedora33.rpm
Fedora34wezterm-20220624_141144_bd1b7c5d-1.fc34.x86_64.rpmwezterm-nightly-fedora34.rpm
Fedora35wezterm-20220624_141144_bd1b7c5d-1.fc35.x86_64.rpmwezterm-nightly-fedora35.rpm
Fedora36wezterm-20220624_141144_bd1b7c5d-1.fc36.x86_64.rpmwezterm-nightly-fedora36.rpm
openSUSE LeapNighty builds onlywezterm-nightly-opensuse_leap.rpm
openSUSE TumbleweedNighty builds onlywezterm-nightly-opensuse_tumbleweed.rpm

To download and install from the CLI you can use something like this, which shows how to install the Fedora 35 package:

sudo dnf install -y https://github.com/wez/wezterm/releases/download/20220624-141144-bd1b7c5d/wezterm-20220624_141144_bd1b7c5d-1.fc35.x86_64.rpm

WezTerm is also available in the official Factory repo in openSUSE Tumbleweed. To install from Factory instead from the rpm provided by WezTerm's Github repository, you can use Yast. If you prefer the CLI, you can install it as root user with

zypper addrepo https://download.opensuse.org/repositories/openSUSE:Factory/standard/openSUSE:Factory.repo
zypper refresh
zypper install wezterm
  • The package installs /usr/bin/wezterm and /usr/share/applications/org.wezfurlong.wezterm.desktop
  • Configuration instructions can be found here

Arch Linux

WezTerm is available in the Community repository.

The version available in the community repository may lag behind the latest wezterm release, so you may wish to use one of these AUR options:

WhatWhere
Nightly Binarieshttps://aur.archlinux.org/packages/wezterm-nightly-bin/
Build from sourcehttps://aur.archlinux.org/packages/wezterm-git/

Alpine Linux

APKs are built out from the main branch.

VersionStableNightly
3.12wezterm-nightly-alpine3.12.apk
3.13wezterm-nightly-alpine3.13.apk
3.14wezterm-nightly-alpine3.14.apk
3.15wezterm-nightly-alpine3.15.apk

Linuxbrew Tap

If you are a Linuxbrew user, you can install wezterm from our tap:

$ brew tap wez/wezterm-linuxbrew
$ brew install wezterm

If you'd like to use a nightly build you can perform a head install:

$ brew install --HEAD wezterm

to upgrade to a newer nightly, it is simplest to remove then install:

$ brew rm wezterm
$ brew install --HEAD wezterm

Raw Linux Binary

Another option for linux is a raw binary archive. These are the same binaries that are built for Ubuntu but provided in a tarball.

Download raw Linux binaries Nightly raw Linux binaries

Installing on FreeBSD

WezTerm is available via the ports system.

The most common FreeBSD architectures have pre-built binaries which you can install via:

$ pkg install wezterm

The version available in ports is not directly managed by the release automation of the WezTerm project and may lag behind the latest release. If you need to run a newer version, then the build from source instructions also apply to FreeBSD.

Installing from source

If your system isn't covered by the pre-built packages then you can build it for yourself. WezTerm should run on any modern unix as well as Windows 10 and macOS.

  • Install rustup to get the rust compiler installed on your system. Install rustup
  • Rust version 1.56 or later is required
  • Build in release mode: cargo build --release
  • Run it via either cargo run --release --bin wezterm or target/release/wezterm

You will need a collection of support libraries; the get-deps script will attempt to install them for you. If it doesn't know about your system, please contribute instructions!

If you don't plan to submit a pull request to the wezterm repo, you can download a smaller source tarball using these steps:

curl https://sh.rustup.rs -sSf | sh -s
curl -LO https://github.com/wez/wezterm/releases/download/20220624-141144-bd1b7c5d/wezterm-20220624-141144-bd1b7c5d-src.tar.gz
tar -xzf wezterm-20220624-141144-bd1b7c5d-src.tar.gz
cd wezterm-20220624-141144-bd1b7c5d
./get-deps
cargo build --release
cargo run --release --bin wezterm -- start

Alternatively, use the full git repo:

curl https://sh.rustup.rs -sSf | sh -s
git clone --depth=1 --branch=main --recursive https://github.com/wez/wezterm.git
cd wezterm
git submodule update --init --recursive
./get-deps
cargo build --release
cargo run --release --bin wezterm -- start

If you get an error about zlib then you most likely didn't initialize the submodules; take a closer look at the instructions!

Building without Wayland support on Unix systems

By default, support for both X11 and Wayland is included on Unix systems. If your distribution has X11 but not Wayland, then you can build WezTerm without Wayland support by changing the build invocation:

cargo build --release --no-default-features

Building without X11 is not supported.

Available Features

Changes

Releases are named using the date, time and git commit hash.

Continuous/Nightly

A bleeding edge build is produced continually (as commits are made, and at least a daily scheduled build) from the main branch. It may not be usable and the feature set may change, but since @wez uses this as a daily driver, its usually the best available version.

As features stabilize some brief notes about them will accumulate here.

New

Fixed

  • ActivateKeyTable's replace_current field was not actually optional. Made it optional. #2179
  • winget causes toast notification spam #2185
  • wezterm connect sshdomain could hang on startup if password authentication was required #2194
  • colors.indexed would error out with Cannot convert String to u8. #2197
  • X11: closing a window when multiple were open could result in an X protocol error that closed all windows #2198
  • Config will now automatically reload after error. Previously, you would need to manually reload the config using ReloadConfiguration. #1174
  • Config will now automatically reload for changes made to required lua files. Previously, only the main config file and any files that you explicitly passed to add_to_config_reload_watch_list would trigger a reload.
  • macOS: numeric keypad enter generated CTRL-C instead of enter. Regression of #739. #2204
  • Wayland: inconsistent pasting. Thanks to @Funami580! #2225 #2226

Updated

  • Bundled harfbuzz to 4.4.1

20220624-141144-bd1b7c5d

New

Updated

  • Bundled harfbuzz to 4.3.0

Changed

  • Debian packages now register wezterm as an alternative for x-terminal-emulator. Thanks to @xpufx! #1883
  • Windows: wezterm will now read the default environment variables from the HKLM\System\CurrentControlSet\Control\Session Manager\Environment and HKCU\Environment and apply those to the base environment prior to applying set_environment_variables. #1848
  • Key Table lookups will now keep searching the activation stack until a matching assignment is found, allowing for layered key tables. #993
  • Search mode's search term is now remembered per-tab between activations of search mode. #1912
  • Quickselect no longer jumps to the bottom of the viewport when activated, allowing you to quickselect within the current viewport region
  • Quickselect now supports multi-line anchors such as ^ and $. #2008
  • Overriding config using the cli --config option will now error out and prevent starting up if unknown config options are specified, or if the value evaluates to nil. Unknown options continue to generate warnings (rather than errors) when observed in the config file so that you're not "locked out" of wezterm if you make a typo in the config file.
  • Windows: allow_win32_input_mode now defaults to true and enables using win32-input-mode to send high-fidelity keyboard input to ConPTY. This means that win32 console applications, such as FAR Manager that use the low level INPUT_RECORD API will now receive key-up events as well as events for modifier-only key presses. #1509 #2009 #2098 #1904
  • Wayland: enable_wayland now defaults to true. #2104
  • exit_behavior now defaults to "Close". #2105
  • Improved wezterm.action syntax for slightly more ergnomic and understandable key assignments. #1150

Fixed

  • Flush after replying to XTGETTCAP, DECRQM, XTVERSION, DA2, DA3 #2060 #1850 #1950
  • macOS: CMD-. was treated as CTRL-ESC #1867
  • macOS: CTRL-Backslash on German layouts was incorrect #1891
  • nf-mdi-contacts nerdfont symbol treated as zero-width #1864
  • X11/Wayland: CTRL-i, CTRL-j, CTRL-m misinterpreted as CTRL-Tab, CTRL-Enter, CTRL-Return #1851
  • Scrollbar stopped working after a lot of output scrolled outside of the scrollback limit. Thanks to @davidrios! #1866
  • Windows: uncommitted IME composition could get stuck when switching input methods. #1922
  • OSC sequences, such as those that change the window or tab title, that accept a single string parameter will now join multiple parameters together. This allows window and tab titles to contain a semicolon. Thanks to @kumattau! #1939
  • Unable to use ALT as a modifier for the leader key. #1958
  • IME Candidate window position was incorrect. Thanks to @kumattau and @aznhe21! #1976 #2001 #2022
  • Prevent panic for some classes of invalid input, found while fuzzing. Thanks to @5225225! #1990 #1986
  • Detaching an ssh multiplexer domain sometimes killed the associated panes! #1993
  • DecreaseFontSize wasn't quite the inverse of IncreaseFontSize. Thanks to @Funami580! #1997
  • Wayland: unable to paste text that was copied before starting the initial wezterm window. Thanks to @Funami580! #1994 #1385
  • Unicode NFD text could incorrectly render with repeated glyphs #2032
  • Windows: spawning new panes/tabs wouldn't automatically use the working directory of the current pane when OSC 7 was not being used #2036
  • Wayland: panic when display scaling is enabled. #1727
  • Dark+ color scheme background color #2013
  • Synthesized bold didn't kick in for automatically computed font_rules. #2074
  • Added freetype_pcf_long_family_names option to workaround PCF font naming issues on certain Linux distributions. #2100
  • X11/Wayland: wezterm.desktop now specifies StartupWMClass. Thanks to @uncomfyhalomacro! #2052 #2125
  • sudo -i in a pane would cause subsequent pane/tab creation to fail until the cwd was changed to an accessible directory #2120
  • X11: Fixed an issue where some events could get lost around resize events, especially prevalent when using the NVIDIA proprietary drivers. Thanks to @pjones123 and @yuttie for working through this! #1992 #2063 #2111 #1628
  • macOS: SHIFT-Tab and CTRL-SHIFT-Tab produced incorrect results #1902
  • X11: Fixed an issue where copy and paste between two wezterm windows could produce stale results. #2110
  • Mouse selection spanning multiple lines always included the first column even when the mouse was to the left of the first column. Thanks to @Funami580! #2106
  • Fonts: Codepoints for eg: symbol glyphs that were not explicitly listed in your font fallback list may not be resolved when used in styled (eg: bold) text. #1913 #2158

20220408-101518-b908e2dd

New

  • Key Tables feature for powerful modal key assignments
  • wezterm start --position x,y, wezterm start --position displayname:30%,30% option to control starting window position on all systems except for Wayland. See wezterm start --help for more info. #1794

Changed

  • Default key assignments are mapped: again. A new key_map_preference option allows the defaults to use "Mapped" or "Physical".
  • Disabled ligatures for "Monaco" and "Menlo" fonts, as those have "fi" ligatures that match even for words such as find. #1786 #1736
  • Removed the send_composed_key_when_alt_is_pressed option. When processing generic ALT (eg: that has neither left nor right), if either send_composed_key_when_left_alt_is_pressed or send_composed_key_when_right_alt_is_pressed is true, then the composed form of the key event will be generated.

Updated and Improved

  • Bundled harfbuzz to 4.2.0
  • On macOS, non-native fullscreen mode now attempts to avoid the notch on systems that have one. #1737
  • Sixel parsing performance has been improved
  • You may now specify a scaling factor per fallback font, which is useful when your preferred CJK font renders smaller than your Roman primary font, for example.
  • Color schemes: Retro, GitHub Dark, Blazer
  • Wayland: touchpad scroll is now more responsive/precise. Thanks to @davidrios! #1800 #1840
  • Kitty image protocol: now also supports shared memory data transmission. Thanks to @tantei3! #1810
  • Secondary DA response bumped up to persuade vim to set ttymouse=sgr by default. #1825

Fixed

  • Incorrect csi-u encoding with non-ascii characters. #1746
  • X11 _NET_WM_ICON had red/blue channels swapped #1754
  • ls-fonts output didn't quote the style field #1762
  • window_decorations = "RESIZE" on Windows prevented minimize/maximize and aerosnap, double click to maximize, and had an ugly top border. Many thanks to @davidrios! #1674 #1675 #1771
  • On Windows, explorer shortcut icons with the maximized setting would fall out of maximized state on startup. Thanks to @davidrios! #1502
  • LANG environment variable was not always set on macOS, leading to mojibake when entering CJK. #1761 #1765
  • Fonts with only non-unicode names (eg: only using a Chinese multibyte string encoding) were treated as having names like ????? and were not accessible. #1761
  • Hover state of leftmost retro style tab was overly sticky when the mouse moved out of the tab. #1764
  • On macOS, the font size could incorrectly double or halve after waking from sleep or moving the window to/from an external monitor. #1566 #1745
  • On Windows, touchpad scrolling was janky. Many thanks to @davidrios! #1773 #1725 #949
  • X11: workaround i3-gaps not sending initial CONFIGURE_NOTIFY or FOCUS events, leading to weird initial window size and broken focus status. #1710 #1757
  • Hyperlink rules with more captures than replacements could panic wezterm when text matched. #1780
  • Malformed XTGETTCAP response. #1781
  • Multiplexer performance with images was unusuable for all but tiny images. #1237
  • CloseCurrentPane{confirm=false} would leave behind a phantom tab/pane when used with the multiplexer. #1277
  • CloseCurrentPane{confirm=true} artifacts when used with the multiplexer. #783
  • Scrollbar thumb could jump around/move out of bounds. Thanks to @davidrios! #1525
  • OSC 52 could stop working for tabs/panes spawned into the GUI via the CLI. #1790
  • Workaround for fonts with broken horizontal advance metrics #1787
  • Improved mouse based selection. Thanks to @davidrios! #1805 #1199 #1386 #354
  • X11 KP_End wasn't recognized #1804
  • fontconfig matches now also treat "charcell" spacing as monospace. #1820
  • Multiplexer render update laggy, especially when using multiple windows. #1814 #1841

20220319-142410-0fcdea07

New

Changed

  • Key Assignments now use Physical Key locations by default!! Read more #1483 #601 #1080 #1391
  • Key assignments now match prior to any dead-key or IME composition #877
  • Removed the ALT-[NUMBER] default key assignments as they are not good for non-US layouts. #1542
  • wezterm cli, when run outside of a wezterm pane, now prefers to connect to the main GUI instance rather than background mux server. Use wezterm cli --prefer-mux to ignore the GUI instance and talk only to the mux server. See wezterm cli --help for additional information.
  • ScrollByPage now accepts fractional numbers like 0.5 to scroll by half a page at time. Thanks to @hahuang65! #1534
  • use_ime now defaults to true on all platforms; previously it was not enabled by default on macOS.
  • canonicalize_pasted_newlines default has changed to be more compatible for nano users, and now provides more control over the text format that is pasted. #1575
  • Blinking text is now eased rather than binary-blinked. See text_blink_ease_in and text_blink_ease_out, text_blink_rapid_ease_in and text_blink_rapid_ease_out for more information.
  • Blinking text cursor is now eased rather than binary-blinked. See cursor_blink_ease_in and cursor_blink_ease_out.

Updated and Improved

  • IME and dead key composition state now shows inline in the terminal using the terminal font (All platforms, except Wayland where we only support dead key composition)
  • macOS: use_ime=true no longer prevents key repeat from working with some keys #1131
  • Bundled harfbuzz to 4.0.1

Fixed

  • Regression that broke fontconfig aliases such as "monospace" #1250
  • Windows/X11/Wayland: CTRL+C in non-latin keyboard layouts wouldn't send CTRL+C #678
  • The new tab button in the fancy tab didn't respect new_tab_hover colors #1498
  • Font baseline alignment when mixing symbols/emoji with the main text #1499
  • Glitchy window resize #1491
  • Ligatured glyphs no longer turn partially black when cursoring through them #478
  • Kitty Image Protocol: didn't respect c and r parameters to scale images
  • Cursor location on the primary screen wasn't updated correctly if the window was resized while the alternate screen was active #1512
  • Windows: latency issue with AltSnap and other window-managery things #1013 #1398 #1075 #1099
  • Multiplexer sessions now propagate user vars #1528
  • Config reloads on the multiplexer server didn't cause the palette to update on the client #1526
  • ScrollToPrompt could get confused when there were multiple prompts on the same line #1121
  • Hangul text in NFD was not always correctly composed when shaping fonts. #1573
  • Avoid OOM when processing sixels with huge repeat counts #1610
  • Set the sticky bit on socket and pid files created in XDG_RUNTIME_DIR to avoid removal by tmpwatch #1601
  • Shaping combining sequences like e U+20d7 could "lose" the vector symbol if the font produced an entry with no x_advance. #1617
  • Setting the cursor color via escape sequences now take precedence over force_reverse_video_cursor. #1625
  • Fixed Detection of DECSDM support via DECRQM/DECRPM, Correct sixel image placement when DECSDM is set and VT340 default sixel colors. Thanks to Autumn! #1577
  • Fixed missing whitespace from intermediate lines when copying a wrapped logical line #1635
  • Unable to match Iosevka Term when multiple iosevka ttc files were installed on macOS #1630
  • Incorrect umask for panes spawned via the multiplexer server #1633
  • Fall back from top_left_arrow to left_ptr when loading XCursor themes #1655
  • Fixed lingering hover state in titlebar when the mouse pointer left the window. Thanks to @davidrios! #1434
  • We now respect the difference between Italic and Oblique font styles when matching fonts. You may explicitly specify style="Oblique" rather than using italic=true for fonts that offer both italic and oblique variants. #1646
  • Hang when clicking a URL would launch the browser for the first time on unix systems #1721
  • Wayland input handling gets broken after suspend/resume. Thanks to @LawnGnome! #1497

20220101-133340-7edc5b5a

New

Changed

  • quickselect: we now de-duplicate labels for results with the same textual content. #1271
  • The default CompleteSelectionOrOpenLinkAtMouseCursor left button release assignment now also accepts SHIFT being held in order to make SHIFT-click ExtendSelectionToMouseCursor feel more ergonomic if the mouse button is released before the SHIFT key. #1204
  • Unicode BIDI and other zero-width graphemes are now filtered out from the terminal model. It's not ideal in the sense that that information is essentially lost when copying to the clipboard, but it makes the presentation correct. #1422
  • use_ime now defaults to true on X11 systems

Updated and Improved

  • Bundled harfbuzz to 3.2.0
  • Bundled freetype to 2.11.1
  • Bundled NotoColorEmoji to 2.034 (with Unicode 14 support) Thanks to @4cm4k1! #1440
  • macos: removing the titlebar from window_decorations now preserves rounded window corners #1034
  • Colors can now be specified in the HSL colorspace using syntax like "hsl:235 100 50" #1436
  • Line/Bar cursors in force_reverse_video_cursor mode now use the text foreground color rather than the cursor border color. #1076
  • Improved logo appearance. Thanks to @ghifarit53! #1454
  • You can now pass SendKey to wezterm.action and make your keys config look more consistent
  • Mouse wheel events are now routed to the hovered pane, rather than sent to the focused pane #798

Fixed

  • DECSTR (terminal soft reset) now turns off DECLRMM (left and right margin mode). Thanks to @ninjalj! #1376
  • Improved conformance of CUP, HVP, SLRM, STBM escape sequences by support empty first parameter. Thanks to @ninjalj! #1377
  • tab bar didn't correctly handle double-wide cells and could truncate at edges when using format-tab-title #1371
  • wezterm cli --no-auto-start was not respected
  • Pixel geometry configured on the PTY in new windows could be incorrect on HiDPI displays until the window was resized #1387
  • Image attachment geometry for imgcat and sixels could stretch the image across the rounded up number of cells that contained the image. #1300, #1270
  • Closing a split pane created inside a wezterm ssh session wouldn't actually close the pane #1197
  • Clicking when unfocused could lead to unwanted text selection #1140 #1310
  • Changing font scaling on Windows no longer causes the initial terminal rows/cols to be under-sized #1381
  • New version update notifications are now more coordinated between multiple wezterm GUI instances, and update related configuration now respects configuration reloading. #1402
  • TLS domains bootstrapping via SSH now use the libssh backend by default and work more reliably on Windows
  • Closing a window will no longer recursively terminate contained multiplexer client panes; the window will instead be restored when you next connect to that multiplexer server. Killing/closing individual tabs/panes will kill the panes; this change only affects closing the window. #848 #917 #1224
  • Colors were too intense due to over gamma correction #1025
  • Mesa and EGL colors were too dim due to under gamma correction #1373
  • wezterm ssh no longer tries to use default_prog or default_cwd when spawning additional panes on the remote host #1456
  • Launcher menu WSL items now launch correctly on non-US versions of Windows #1462
  • Korean text in NFD form is now correctly sized and rendered #1474
  • macOS: use_ime=true conflicted with LEADER key assignments #1409
  • macOS: certain keys (eg: F8 and F9) did nothing when use_ime=true. #975
  • Splitting a tab would cause the window to lose its transparency #1459

20211205-192649-672c1cc1

Fixed

  • Windows: wezterm <something> would fail silently when spawning wezterm-gui under the covers. Regression introduced by #1278. Workaround is to directly spawn wezterm-gui.
  • Windows: the PTY handles were ignored in favor of the redirected stdio handles of the parent of the wezterm mux process #1358
  • Windows: Failure to spawn wezterm when launching an ssh mux domain session no longer waits forever
  • "Update available" message kept showing even though already running the latest version #1365

20211204-082213-a66c61ee9

New

  • X11 now supports IME. It currently defaults to disabled, but you can set use_ime = true in your config to enable it (you need to restart wezterm for this to take effect). Many thanks to @H-M-H for bringing xcb-imdkit to Rust and implementing this in wezterm! #250 #1043
  • it is now possible to define colors in the range 16-255 in colors and color scheme definitions. Thanks to @potamides! #841 #1056
  • Added SendKey key assignment action that makes it more convenient to rebind the key input that is sent to a pane.
  • Added Multiple key assignment action for combining multuple actions in a single press.
  • Added use_resize_increments option to tell X11, Wayland, macOS window resizing to prefers to step in increments of the cell size
  • visual_bell and audible_bell configuration options, as well as a bell event allows you to trigger lua code when the bell is rung. #3
  • wezterm.action_callback function to make it easier to use custom events. Thanks to @bew! #1151
  • wezterm connect now also supports the --class parameter to override the window class
  • window_padding now accepts values such as "1cell" or "30%" to compute values based on font or window metrics.
  • BSDish systems now support toast notifications
  • wezterm.background_child_process function to spawn a process without waiting.
  • mux_env_remove setting to control which environment variables should be cleared prior to spawning processes in the multiplexer server #1225
  • canonicalize_pasted_newlines option to help Windows users manage newlines in pastes #1213
  • SSH client now uses libssh by default. ssh_backend can be used to change this.
  • unzoom_on_switch_pane option. Thanks to @yyogo #1301
  • unicode_version option and corresponding OSC escape sequences that affects how the width of certain unicode sequences are interpreted.
  • macOS: binaries produced by wezterm's CI are now codesigned, which resolves some spurious permission dialogs that affected some users #482

Changed

  • new default key assignments: CTRL+PageUp and CTRL+Tab activate next tab, CTRL+PageDown and CTRL+SHIFT+Tab activate previous tab. ALT+{1..8} directly select the first through 8th tabs. Thanks to @friederbluemle! #1132
  • X11: we now allow matching visuals with >= 8 bits per rgb value. Previously, we only matched exactly 8 bits. This improve compatibility with systems that have the COMPOSITE extension disabled. Thanks to @shizeeg! #1083
  • The incomplete Allsorts shaper was removed.
  • Windows: wezterm-gui.exe now only grabs the parent process' console handle when spawned from wezterm.exe, which prevents some frustrating interactions when launching wezterm-gui.exe via start in cmd/powershell. #1278
  • AppImage: take care to remove APPIMAGE related environment when spawning child processes. Thanks to @srevinsaju! #1338

Updated and Improved

  • bundled harfbuzz updated to version 3.0.0, bundled freetype updated to 2.11
  • window close confirmations now accept both uppercase and lowercase Y/N key presses. Thanks to @SpyrosRoum! #1119
  • multi-click-streaks are now interrupted by the cursor moving to a different cell. Thanks to @unrelentingtech! #1126
  • .deb packages now Provides: x-terminal-emulator. #1139
  • use_cap_height_to_scale_fallback_fonts now computes cap-height based on the rasterized glyph bitmap which means that the data is accurate in more cases, including for bitmap fonts. Scaling is now also applied across varying text styles; previously it only applied to a font within an wezterm.font_with_fallback font list.
  • Can now match fontconfig aliases, such as monospace, on systems that use fontconfig. Thanks to @unrelentingtech! #1149
  • Powerline semicircle glyphs now look much better. Thanks to @bew and @sdrik! #1311
  • Splits now look better, especially when using escape sequences to change the default background color #1256

Fixed

  • wezterm cli spawn would use the initial terminal size for a new tab, rather than using the current tab size #920
  • text_background_opacity opacity was not respected
  • spawning commands via the mux didn't respect the PATH configured in set_environment_variables. #1029
  • cursor could have a transparent "hole" through the window with certain cursor styles
  • Consolas font + random input could cause a divide-by-zero when computing glyph metrics #1042
  • Emoji fallback was too strict in respecting VS15/VS16 presentation selection, adjust the fallback to allow showing Emoji/Text presentation if Text/Emoji was requested but not found.
  • X11: laggy input after selecting text. #1027
  • macOS: send_composed_key_when_left_alt_is_pressed and send_composed_key_when_right_alt_is_pressed are now respected when use_ime=true. Thanks to @jakelinnzy! #1096
  • X11: jittery resize with some window managers #1051
  • X11: window:get_appearance now actually returns Dark when the theme is dark. #1098
  • ALT + Arrow, PageUp/PageDown, Ins, Del, Home, End incorrectly sent ESC prefixed key sequences. #892
  • Crash due to Out of Memory condition when the iTerm2 protocol was used to send excessively large PNG files #1031
  • DCH (delete char) sequence would remove cells and replace them with default-blank cells instead of blank-cells-with-current-bg-color. #789
  • invisible I-beam or underline cursor when force_reverse_video_cursor = true #1076
  • SU (scroll up) sequence would fill with default-blank cells instead of blank-cells-with-current-bg-color. #1102
  • X11: computed but did not use the correct DPI for HiDPI screens #947
  • performance when resolving fallback fonts via fontconfig, and of coverage calculation with freetype. Thanks to @H-M-H!
  • Wayland: incorrect initial surface size for HiDPI screens. Thanks to @unrelentingtech! #1111 #1112
  • invisible cursor in CopyMode when using kakoune #1113
  • Wayland: bypass_mouse_reporting_modifiers didn't work. Thanks to @unrelentingtech! #1122
  • new tabs could have the wrong number of rows and columns if a tiling WM resizes the window before OpenGL has been setup. #1074
  • Wayland: dragging the window using the tab bar now works. Thanks to @unrelentingtech! #1127
  • error matching a font when that font is in a .ttc that contains multiple font families. #1137
  • Wayland: panic with most recent wlroots. Thanks to @unrelentingtech! #1144
  • incorrect spacing for IDEOGRAPHIC SPACE. #1161
  • italic fonts weren't always recognized as being italic, resulting in italic variants being used instead of the non-italic variants in some cases! #1162
  • Ask freetype for cell metrics in bitmap-only fonts, rather than simply taking the bitmap width. #1165
  • wezterm can now match bitmap fonts that are spread across multiple font files #1189
  • ssh config parser incorrectly split Host patterns with commas instead of whitespace #1196
  • search now auto-updates when the pane content changes #1205
  • fonts with emoji presentation are shifted to better align with the primary font baseline #1203
  • the whole tab was closed when only the zoomed pane exited. #1235
  • multiplexer: wrong WEZTERM_UNIX_SOCKET environment passed to children when using unix domain sockets and connect_automatically=true #1222
  • multiplexer: spawning remote tabs didn't correctly record local tab mapping, resulting in phantom additional tabs showing in the client. #1222
  • wezterm ls-fonts --text "✘" didn't account for the system fallback list. #849
  • macOS: The Menlo font is now implicitly included in the system fallback list, as it is the only font that contains U+2718 ✘
  • wezterm cli spawn --cwd .. and wezterm cli split-pane --cwd .. now resolve relative paths #1243
  • Incorrect DECRPTUI response to DA3. Thanks to @ninjalj! #1330
  • Reloading config now loads newly defined multiplexer domains, however, existing domains are not updated. #1279

20210814-124438-54e29167

  • Fixed: ssh client would read /etc/ssh/config rather than the proper /etc/ssh/ssh_config
  • Updated: ssh client now processes Include statements in ssh config
  • x11: support for VoidSymbol in key assignments. Thanks to @digitallyserviced! #759
  • Fixed: UTF8-encoded-C1 control codes were not always recognized as control codes, and could result in a panic when later attempting to update the line. #768
  • Fixed: wezterm cli split-pane didn't use the current working dir of the source pane. #766
  • Fixed: double-click-drag selection could panic when crossing line boundaries #762
  • Fixed: wrong scaling for ligatures in Recursive Mono font #699
  • Fixed: incorrect Sixel HLS hue handling #775
  • Fixed: we now recognize the CSI 48:2:0:214:255m form of specifying true color text attributes #785
  • Fixed: split separators didn't respect tab_bar_at_bottom=true and were rendered in the wrong place #797
  • Improved: messaging around exit_behavior
  • Fixed: errors loading custom color schemes are now logged to the error log #794
  • Fixed: OSC 7 (current working directory) now works with paths that contain spaces and other special characters. Thanks to @Arvedui! #799
  • Changed: the homebrew tap is now a Cask that installs to the /Applications directory on macOS. Thanks to @laggardkernel!
  • New: bold/dim and/or italics are now synthesized for fonts when the matching font is not actually italic or doesn't match the requested weight. #815
  • Updated: conpty.dll to v1.9.1445.0; fixes color bar artifacts when resizing window and allows win32 console applications to use mouse events
  • Fixed: Windows: pane could linger after the process has died, closing only when a new pane/tab event occurs
  • Fixed: Windows: first character after wezterm ssh keyboard authention was swallowed #771
  • Fixed: Windows: detect window resizes while authenticating for wezterm ssh #696
  • Fixed: OSC 52 clipboard escape didn't work in the initial pane spawned in the multiplexer server #764
  • Fixed: splitting panes in multiplexer could fail after a network reconnect #781
  • Fixed: multiplexer now propagates toast notifications and color palette to client #489 #748
  • Fixed: neovim interprets drags as double clicks #823
  • New: CTRL+SHIFT+L is assigned to ShowDebugOverlay #641
  • Improved: antialiasing for undercurl. Thanks to @ModProg! #838
  • Fixed: wezterm start --cwd c:/ didn't run default_prog. Thanks to @exactly-one-kas! #851
  • Improved: skip_close_confirmation_for_processes_named now includes common windows shell processes cmd.exe, pwsh.exe and powershell.exe. #843
  • Fixed: don't keep the window alive after running something & disown ; exit #839
  • Improved: we now draw sextant glyphs from the Unicode Symbols for Legacy Computing block (1FB00) when custom_block_glyphs is enabled.
  • Changed: COLORTERM=truecolor is now set in the environment. #875
  • New: wezterm cli spawn --new-window flag for creating a new window via the CLI #887
  • Fixed: closing last pane in a tab via CloseCurrentPane could cause the window to close #890
  • Improved: wezterm ls-fonts --list-system shows all available fonts, wezterm ls-fonts --text "hello" explains which fonts are used for each glyph in the supplied text
  • Fixed: mouse cursor is now Arrow rather than I-beam when the application in the terminal has enabled mouse reporting #859
  • Improved: DEC Special Graphics mode conformance and complete coverage of the graphics character set. Thanks to Autumn Lamonte! #891
  • Fixed: click to focus now focuses the pane under the mouse cursor #881
  • Removed: Parasio Dark color scheme; it was a duplicate of the correctly named Paraiso Dark scheme. Thanks to @adrian5! #906
  • Fixed: key repeat on Wayland now respects the system specified key repeat rate, and doesn't "stick". #669
  • Fixed: force_reverse_video_cursor wasn't correctly swapping the cursor colors in all cases. #706
  • Fixed: allow multuple IdentityFile lines in an ssh_config block to be considered
  • Improved: implement braille characters as custom glyphs, to have perfect rendering when custom_block_glyphs is enabled. Thanks to @bew!
  • Fixed: Mod3 is no longer treater as SUPER on X11 and Wayland #933
  • Fixed: paste now respects scroll_to_bottom_on_input. #931
  • New: bypass_mouse_reporting_modifiers to specify which modifier(s) override application mouse reporting mode.
  • Fixed: focus tracking events are now also generated when switching between panes #941
  • New: window_frame option to configure Wayland window decorations #761
  • New: window:get_appearance() to determine if the window has a dark mode appearance, and adjust color scheme to match #806
  • Improved: improve the new-tab button formatting. Thanks to @sdrik! #950
  • Fixed: if a line of text was exactly the width of the terminal it would get marked as wrappable even when followed by a newline, causing text to reflow incorrectly on resize. #971
  • Fixed: wezterm ssh could loop forever in the background if the connection drops and the window is closed. #857
  • Improved: VT102 conformance. Many thanks to Autumn Lamonte! #904
  • New: text_blink_rate and text_blink_rate_rapid options to control blinking text. Thanks to Autumn Lamonte! #904
  • New: Added support for Synchronized Rendering #882
  • New: wezterm now draws its own pixel-perfect versions of more block drawing glyphs. See custom_block_glyphs for more details. #584
  • Fixed: wayland: CursorNotFound error with the whiteglass theme. #532
  • Improved: Can now recover from exhausting available texture space by clearing the screen. #879
  • Updated bundled Noto Color Emoji font to version 2.028 featuring a design update. Thanks to @4cm4k1! #1003
  • Fixed: wayland: putting a window in the Sway scratchpad no longer blocks the wezterm process #884
  • Fixed: mouse reporting now correctly reports release events when multiple buttons are pressed and released at the same time. #973
  • Fixed: incorrect initial window/pty size when running with some tiling window managers. #695
  • New: CTRL-SHIFT-L shows the debug overlay, which shows the error log and a lua repl. #641
  • Fixed: macOS: bright window padding on Intel-based macs #653, #716 and #1000
  • Improved: wezterm now uses the Dual Source Blending feature of OpenGL to manage subpixel anti-aliasing alpha blending, resulting in improved appearance particularly when using a transparent window over the top of something with a light background. #932
  • Fixed: copying really long lines could falsely introduce line breaks on line wrap boundaries #874
  • New: wezterm.add_to_config_reload_watch_list function to aid with automatically reloading the config when you've split your config across multiple files. Thanks to @AusCyberman! #989
  • Improved: wezterm now respects default emoji presentation and explicit emoji variation selectors (VS15 and VS16) so that glyphs that have both textual (usually monochrome, single cell width) and emoji (color, double width) presentations can be more faithfully rendered. #997
  • New: window_background_gradient option to configure color gradients for your window background
  • New: wezterm.gradient_colors function to compute RGB values for gradients for use in your config.
  • New: color schemes: Abernathy, Ayu Mirage, darkmatrix, Fairyfloss, GitHub Dark, HaX0R_BLUE, HaX0R_GR33N, HaX0R_R3D, Mariana, matrix, Peppermint and UltraDark

20210502-154244-3f7122cb

  • Fixed: red and blue subpixel channels were swapped, leading to excessively blurry text when using freetype_load_flags="HorizontalLcd". #639
  • Fixed: the selection wouldn't always clear when the intersecting lines change #644
  • Fixed: vertical alignment issue with Iosevka on Windows #661
  • Fixed: support for "Variable" fonts such as Cascadia Code and Inconsolata on all platforms #655
  • New: wezterm.font and wezterm.font_with_fallback attributes parameter now allows matching more granular font weights and font stretch. e.g.: wezterm.font('Iosevka Term', {stretch="Expanded", weight="Regular"}), as fallback can specify weight/stretch/style for each individual font in the fallback.
  • New: freetype_render_target option for additional control over glyph rasterization.
  • Fixed: wezterm ssh HOST no longer overrides the User config specified by ~/.ssh/config
  • Fixed: X11: detect when gnome DPI scaling changes #667
  • Fixed: potential panic when pasting large amounts of multi-byte text #668
  • Fixed: X11: non-ascii text could appear mangled in titlebars #673
  • Improved font IO performance and memory usage on all platforms
  • New window:toast_notification method for showing desktop notifications. #619
  • Fixed: half-pixel gaps in ligatured/double-wide glyphs depending on the font size #614
  • Fixed: Window could vanish if a tab closed while the rightmost tab was active(!) #690
  • Fixed: macOS: mouse cursor could get stuck in the hidden state. #618
  • Improved: font_rules behavior to always append reasonable default font_rules to those that you may have specified in your config. font_rules now also include defaults for half-bright text styles.
  • Improved: added use_cap_height_to_scale_fallback_fonts option to scale secondary fonts according to relative their cap-height metric to improve size consistency. This partially applies to some symbol/emoji fonts, but is dependent upon the font having reliable metrics.
  • Improved: font-config queries now run much faster, resulting in snappier startup on unix systems
  • Fixed: Hide had no effect on macOS when the titlebar was disabled #679
  • Fixed: key and mouse assignments set via window:set_config_overrides were not respected. #656
  • Fixed: potential panic when word selecting off top of viewport #713
  • Fixed: really long busy wait when displaying single logical json line of 1.5MB in length #714
  • New: swallow_mouse_click_on_pane_focus option #724
  • New: pane_focus_follows_mouse option #600
  • Fixed: splitting a pane while a pane is in the zoomed state would swallow the new pane #723
  • Fixed: multi-cell glyphs weren't displayed in tab titles #711
  • New: format-window-title hook for customizing the text in the window titlebar
  • New: format-tab-title hook for customizing the text in tab titles. #647
  • Removed: active and inactive tab_bar_style config values; use the new format-tab-title event instead
  • New: force_reverse_video_cursor setting to override the cursor color scheme settings. #706
  • Fixed: ssh config parsing now expands ~ to your home directory for appropriate options; previously only %d and ${HOME} were substituted. #729
  • New: Quick Select Mode for a tmux-fingers/tmux-thumbs style mouse-less select and copy flow #732
  • Fixed: tabs would remain hovered after moving the mouse down into the main terminal area #591
  • New: tab_bar_at_bottom setting to put the tab bar at the bottom of the window #278
  • New: wezterm.column_width function for measuring the displayed width of a string
  • New: wezterm.pad_left, wwezterm.pad_right, wezterm.truncate_left and wezterm.truncate_right function for truncating/padding a string based on its displayed width
  • Updated bundled Noto Color Emoji font to version 2.020 with unicode 13.1 support. Thanks to @4cm4k1! #742
  • Fixed: Numpad Enter reported as CTRL-C on macOS #739
  • Fixed: mouse reporting button state not cleared when focus is lost, eg: from clicking a link #744
  • Improved: better looking curly underline. Thanks to @ModProg! #733
  • Fixed: wezterm now sets argv0 to -$SHELL to invoke a login shell, rather than running $SHELL -l. #753
  • Improved: ssh_config parsing now supports Match for Host, LocalUser.
  • Improved render performance for wide windows #740
  • New color schemes: Aurora, BlueDolphin, BlulocoDark, BlulocoLight, Doom Peacock, Galizur, Guezwhoz, PaleNightHC, Raycast_Dark, Raycast_Light, Sublette, iceberg-dark and iceberg-light.

20210405-110924-a5bb5be8

  • Fixed: bold text got broken as part of fixing #617 :-( #648

20210404-112810-b63a949d

  • Fixed: 100% CPU due to spurious resize events generated by herbstluftwm. #557
  • Fixed: improved conformance with xterm for keys like CTRL-6 and CTRL-/. #556
  • Fixed: detection and handling of fonts such as terminus-bold.otb that contain only bitmap strikes. #560
  • Fixed: the pixel size reported by the pty to the kernel wasn't adjusted for font metrics/dpi until the config was reloaded or window resized. #563
  • Fixed: greatly reduce memory consumption when system fallback fonts are loaded #559
  • Fixed: Windows: window_background_opacity was only taking effect when window_decorations="NONE" #553
  • Fixed: an issue where wezterm could hang if the process spawned by a pane doesn't quit when asked #558
  • Fixed: panic when dismissing the tab navigator #542
  • Fixed: font fallback on macOS returns unresolvable .AppleSymbolsFB rather than Apple Symbols, leading to slowdowns when rendering symbols #506
  • Fixed: laggy repaints for large windows particularly on Windows, but applicable to all systems. Tuned and triple-buffered vertex buffer updates. #546
  • Changed: allow_square_glyphs_to_overflow_width now defaults to WhenFollowedBySpace and applies to more symbol glyphs. #565
  • Changed: macOS: CMD-Q is now bound by default to QuitApplication
  • New: added skip_close_confirmation_for_processes_named option which specifies a list of processes for which it is considered safe to allow closing a pane/tab/window without a prompt. #562
  • Fixed: triggering the search overlay again while the search overlay is active no longer closes the underlying pane #572
  • Fixed: X10 mouse coordinate reporting encoding could produce invalid outputs for large windows. Capped coordinate values to the maximum value that is representable in UTF-8 encoding
  • Fixed: font fallback now happens asynchronously from painting #508
  • New: added window:get_selection_text_for_pane method #575
  • Fixed: implicit hyperlink rules, word and line selection now operate on logical lines which means that they deal with wrapped lines outside of the viewport. #408
  • New: wezterm ssh now supports reading ~/.ssh/config and overriding options via the command line. IdentityFile and ProxyCommand are the two main new supported options. Read more about it in ssh.
  • Fixed: ssh support will now try all available identities from the SSH agent rather than just the first.
  • New: splitting panes in wezterm ssh now works like spawning new tabs: the new program is started on the remote host with no additional authentication required.
  • Fixed: Multiplexer sessions would fail to bootstrap via ssh because the bootstrap process exited too soon. #507
  • Fixed: Windows: we now compile libssh2 against openssl on all platforms to improve overall key and crypto algorithm support
  • Fixed: spawning a new tab via the launcher menu failed because it used the pretty printed multiplexer domain label rather than the multiplexer domain name.
  • Fixed: macOS: middle mouse button wasn't recognized. Thanks to @guswynn! #599
  • New: added ActivateLastTab key assignment for jumping back to a previously active tab. Thanks to @alexgartrell #610
  • Fixed: added missing XTSMGRAPHICS query/response for sixel support #609
  • Fixed: avoid showing an error dialog for synthesized font_rules when the configuration specifies a font that doesn't have bold/italic variants. #617
  • New: mouse cursor hides when keyboard input is sent to a pane, and shows again when the mouse is moved. #618
  • Fixed: macOS: CTRL-Tab key combination was not recognized. #630
  • Fixed: wezterm-mux-server will now continue running even after all tabs/panes have been closed. #631
  • Fixed: macOS: wezterm-gui could linger in the background until the mouse moves after all tabs/panes have closed
  • Fixed: when using line_height, wezterm now vertically centers the cell rather than padding only the top #582
  • Fixed: macOS: in US layouts, SUPER+SHIFT+[ was incorrectly recognized as SUPER+SHIFT+{ instead of SUPER+{ #601
  • Fixed: wezterm.config_dir was returning the config file path instead of the directory!
  • New: wezterm.config_file which returns the config file path

20210314-114017-04b7cedd

  • New: tab_bar_style allows customizing the appearance of the rest of tha tab bar.
  • New: animated gif and png images displayed via wezterm imgcat (the iTerm2 image protocol), or attached to the window background via window_background_image will now animate while the window has focus.
  • New: added foreground_text_hsb setting to adjust hue, saturation and brightness when text is rendered.
  • New: added ResetFontAndWindowSize key assignment.
  • New: added ScrollByLine key assignment.
  • New: OSC 777 and OSC 9 escapes now generate Toast Notifications. printf "\e]777;notify;%s;%s\e\\" "title" "body" and printf "\e]9;%s\e\\" "hello there". These don't currently pass through multiplexer connections. #489.
  • New: exit_behavior config option to keep panes open after the program has completed. #499
  • New: added --config name=value options to wezterm, wezterm-gui and wezterm-mux-server. The --front-end, --font-locator, --font-rasterizer and --font-shaper CLI options have been removed in favor of this new mechanism.
  • New: window:set_config_overrides method that can be used to override GUI related configuration options on a per-window basis. Click through to see examples of dynamically toggling ligatures and window opacity. #469 #329
  • New: introduced custom_block_glyphs option to ensure that block glyphs don't have gaps. #433
  • New: you can now drag the wezterm window via the tab bar
  • New: holding SUPER+Drag (or CTRL+SHIFT+Drag) will drag the wezterm window. Use StartWindowDrag to configure your own binding.
  • New: configure window_decorations to remove the title bar and/or window border
  • New: we now bundle PowerlineExtraSymbols as a built-in fallback font, so that you can use powerline glyphs with any font without patching the font.
  • New: window:set_right_status allows setting additional status information in the tab bar. #500
  • New: Search Mode: Added CTRL-u key assignment to clear the current search pattern. Thanks to @bew! #465
  • Fonts: font_antialias and font_hinting are now deprecated in favor of the new freetype_load_target and freetype_load_flags options. The deprecated options have no effect and will be removed in a future release. The new options provide more direct control over how freetype rasterizes text.
  • Fonts: when computing default font_rules for bold and italic fonts, strip italic and bold components from the family name. eg: if you set font = wezterm.font("Source Code Pro Medium") then the Medium text will be stripped from the font name used to locate bold and italic variants so that we don't report an error loading a non-sensical Source Code Pro Medium Bold. #456
  • Fonts: fix a regression where bright windows behind wezterm could "shine through" on the alpha channel, and adjust the tinting operation to avoid anti-aliased dark fringes #470 #491
  • Fonts: macOS: fix an issue where wezterm could hang when loading a font located via Core Text #475
  • Fonts: Changed the default font_size to 12 points. #517
  • Fonts: Updated bundled JetBrainsMono font to version 2.225
  • Added --config-file CLI option to specify an alternate config file location. Read more about config file resolution. Thanks to @bew! #459
  • OSC 52 (Clipboard manipulation) now respects the difference between PRIMARY and CLIPBOARD on X11 systems.
  • Fixed an issue where large pastes could result in a hang
  • Closing the configuration error window no longer requires confirmation
  • Fixed: an issue where the window would be redrawn on mouse move. This was most noticeable as a laggy mouse pointer when moving the mouse across a window running on the nouveau display driver on X11 and Wayland systems
  • Fixed: an issue where closing a pane would immediately SIGKILL the associated process, rather than sending SIGHUP. Thanks to @bew!
  • Fixed: line-based mouse selection (default: triple click) now extends forwards to include wrapped lines. #466
  • Fixed: the RIS escape wasn't clearing the scrollback. #511
  • Wayland: fixed opengl context creation issues. Thanks to @unrelentingtech! #481
  • Wayland: the raw key modifiers are now correctly propagated so that they activate when used with key assignments using the key = "raw:123" binding syntax.
  • Wayland: fixed window decoration and full screen handling #224
  • Wayland: fixed an issue where key repeat processing could "run away" and hang the application
  • Windows: the portable .zip file download now includes ANGLE EGL, just like the setup.exe installer has done since version 20201031-154415-9614e117
  • Windows: Fixed ToggleFullScreen so that it once again toggles between full screen and normal placement. #177
  • Windows: fix the unexpected default behavior of Ctrl-Alt being converted to AltGr for layouts supporting this key, the previous behavior is still possible by enabling the option treat_left_ctrlalt_as_altgr (to solve #392). Thanks to @bew! #512
  • Windows: fixed "Open WezTerm Here" context menu in explorer when used on the root of a drive (eg: C:\). Thanks to @flyxyz123! #526 #451
  • X11: fix an issue where SHIFT-Enter was not recognized #516
  • X11: improved DPI detection for high-DPI displays. #515
  • X11: we now load the XCursor themes when possible, which means that the mouse cursor is now generally a bit larger and clearer as well as conforming more with the prevailing style of the desktop environment. #524
  • Improved and optimized image processing so that watching videos via timg - Terminal Image and Video Viewer works better #537 #535 #534

20210203-095643-70a364eb

  • Fix cursor position after using iTerm2 image protocol #317
  • Fix pixel dimensions after changing the pane size; this was mostly invisible but impacted image scaling when using sixel or iTerm2 image protocols. #312
  • Add support for OSC 133 which allows annotating output as Output, Input (that you typed) and Prompt (shell "chrome"). Learn more about Semantic prompt and OSC 133
  • Add ScrollToPrompt key assignment that scrolls the viewport to the prior/next shell prompt emitted using OSC 133 Semantic Prompt escapes. This assignment is not bound by default.
  • Fixed an issue where SpawnWindow didn't use the current working directory from the current pane to spawn the new window
  • Added wezterm start --class CLASSNAME option to specify the window class name under X11 and Windows, or the app_id under Wayland. See wezterm start --help for more information.
  • Added shell integration for setting OSC 7 (working directory) and OSC 133 (semantic zones) for Zsh and Bash. See Shell Integration docs.
  • Added SemanticZone as a possible parameter for SelectTextAtMouseCursor, making it possible to conveniently select complete input or output regions.
  • Improved font rendering #320 #331 #413 and changed font_antialias = "Greyscale" by default.
  • Updated internal harfbuzz shaper to 2.7.2
  • Fixed ALT-Escape not sending ESC-ESC #338
  • Added allow_square_glyphs_to_overflow_width = "WhenFollowedBySpace" option to allow square symbol glyphs to deliberately overflow their specified cell width when the next cell is a space. Can be set to Always to allow overflowing regardless of the next cell being a space, or Never to strictly respect the cell width. The default is Never. #342
  • macOS: Improved key input when Option is pressed. Fixed dead key processing when use_ime=true. #357
  • macOS: Adjusted default dpi to 72 to bring point sizes into alignment with other macOS apps. #332
  • Improved font fallback; we now try harder to find a system-provided font for glyphs that are not found in your explicitly configured fonts.
  • Revised pty output processing and removed the related ratelimit_output_bytes_per_second option
  • Workaround Cocoa leaking window position saved state file descriptors to child processes on macOS Big Sur, and Gnome/Mutter doing something similar under X11
  • The 256 color cube now uses slightly brighter colors #348
  • New: added line_height configuration option to scale the computed cell height. The default is 1.0, resulting in using the font-specified metrics. Setting it to 1.2 will result in a 20% larger cell height.
  • macOS: Fixed an issue where hovering over the split between panes could result in wezterm becoming unresponsive #391
  • Closing windows and QuitApplication will now prompt for confirmation before proceeding with the close/quit. Added window_close_confirmation to control this; valid values are AlwaysPrompt and NeverPrompt. #280
  • Tidied up logging. Previously ERROR level logging was used to make sure that informational things showed up in the stderr stream. Now we use INFO level logging for this to avoid alarming the user. You can set WEZTERM_LOG=trace in the environment to get more verbose logging for troubleshooting purposes.
  • Windows: fix an issue where VNC-server-emulated AltGr was not treated as AltGr #392
  • X11: fix an issue where keys that produce unicode characters retained SHIFT as a modifier instead of normalizing it away. #394
  • Fixed an issue where a symbol-only font would be seen as 0-width and panic wezterm #404
  • Tweaked mouse selection: we now round the x-coordinate to the nearest cell which makes it a bit more forgiving if the mouse cursor is slightly to the left of the intended cell start. #350
  • Added selection_word_boundary option to control double-click word selection boundaries. The default is \t\n{}[]()"'`. #405
  • Added support for Curly, Dotted and Dashed underlines. See this documentation on the escape sequences how enable undercurl support in vim and nvim. #415
  • Fixed an issue where wezterm would spawn processes with umask 077 on unix systems, rather than the more commonly expected umask 022. #416
  • macOS: We now ship a Universal binary containing both Intel and "Apple Silicon" architectures
  • Setting a really large or really small font scale (using CTRL +/-) no longer causes a panic #428
  • Fixed an issue where the mouse wheel wasn't mapped to cursor up/down when the alternate screen was active #429
  • Fixed ToggleFullScreen not working on macOS and X11. It still doesn't function on Windows. native_macos_fullscreen_mode = false uses a fast full-screen window on macOS. Set it to true to use the slower macOS native "Spaces" style fullscreen mode. #177
  • Windows: fix an issue where the initial window size didn't factor the correct DPI when the system-wide display scaling was not 100%. #427
  • New: adjust_window_size_when_changing_font_size option to control whether changing the font size adjusts the dimensions of the window (true) or adjusts the number of terminal rows/columns (false). The default is true. #431
  • macOS: we no longer use MetalANGLE to render the gui; it was short lived as macOS Big Sur now uses Metal in its CGL implementation. Support for using MetalANGLE is still present if the dylib is found on startup, but we no longer ship the dylib.
  • Windows: when pasting text, ensure that the text has CRLF line endings unless bracketed paste is enabled. This imperfect heuristic helps to keep multi-line pastes on multiple lines when using Windows console applications and to avoid interleaved blank lines when using unix applications. #411
  • New: ClearScrollback now accepts a parameter to control whether the viewport is cleared along with the scrollback. Thanks to @dfrankland!
  • New: default_cwd to specify an alternative current working directory. Thanks to @dfrankland!
  • New: CopyTo and PasteFrom actions. Copy, Paste and PastePrimarySelection are now deprecated in favor of these new options.
  • X11: Mouse-based selection now copies-to and pastes-from the PrimarySelection by default. The CompleteSelection and CompleteSelectionOrOpenLinkAtMouseCursor actions now require a parameter to specify the clipboard.
  • X11: SHIFT-CTRL-C and SHIFT-CTRL-V now copy-to and paste from the Clipboard by default. SHIFT-Insert pastes from the PrimarySelection by default.
  • New: Added a new default CTRL-Insert key assignment bound to CopyTo(PrimarySelection)
  • macOS: Windows now have drop-shadows when they are opaque. These were disabled due transparency support was added. Thanks to Rice! #445
  • Unix: adjust font-config patterns to also match "dual spacing" fonts such as Iosevka Term. Thanks to Leiser! #446
  • New: Added alternate_buffer_wheel_scroll_speed option to control how many cursor key presses are generated by the mouse wheel when the alternate screen is active. The new default for this is a faster-than-previous-releases 3 lines per wheel tick. #432
  • macOS: Dead Keys are now processed even when use_ime=false. More details in the docs. #410.
  • X11: attempt to load cursors from the XCursor.theme resource specified on the root window #524
  • Added file:// URL matching to the default list of implicit hyperlink rules #525

20201101-103216-403d002d

  • Whoops! fixed a crash on macOS when using multiple windows in the new Metal renderer #316

20201031-154415-9614e117

  • New: split/pane support! CTRL+SHIFT+ALT+" to SplitVertical, and CTRL+SHIFT+ALT+% to SplitHorizontal.
  • New: LEADER modifier key support
  • New: window_background_opacity and window_background_image options to control using background images, transparent windows. More info
  • New color schemes: Dracula+, Gruvbox Light, MaterialDarker, Overnight Slumber, Popping and Locking, Rapture, jubi, nord.
  • New: expanded lua API allows handling URI clicks and keyboard events with lua callbacks. See wezterm.on docs.
  • The GUI layer now normalizes SHIFT state for keyboard processing. If a keypress is ASCII uppercase and SHIFT is held then the SHIFT modifier is removed from the set of active modifiers. This has implications for your key assignment configuration; previously you would write {key="T", mods="CTRL|SHIFT"}, after updating to this release you need to write {key="T", mods="CTRL"} in order for your key bindings to take effect.
  • Added show_tab_index_in_tab_bar option which defaults to true. Causes the tab's ordinal index to be prefixed to tab titles. The displayed number is 1-based. You can set tab_and_split_indices_are_zero_based=true if you prefer the number to be zero based.
  • On Linux and macOS systems, wezterm can now attempt to guess the current working directory that should be set in newly spawned local panes/tabs, in case you don't have OSC 7 integration setup in your shell.
  • We now bundle JetBrains Mono and use it as the default font, and add it as a default fallback font. Similarly, we also bundle Noto Color Emoji as a default fallback for emoji.
  • Added automatically_reload_config=false option to disable automatic config reloading. When set to false, you will need to manually trigger a config reload (default: SUPER+R or CTRL+SHIFT+R)
  • CloseCurrentTab now requires a confirm parameter.
  • Halved the memory usage requirements per Cell in the common case (saving 32 bytes per cell), which gives more headroom for users with large scrollback.
  • Reduced initial GPU VRAM requirement to 2MiB. Improved texture allocation to avoid needing lots of VRAM.
  • macOS: Fix issue where new windows would open as Cocoa tabs when wezterm was maximized.
  • macOS: Fix issue where wezterm wouldn't adjust to DPI changes when dragging across monitors or the screen resolution changed
  • macOS: Reduced trackpad based scrolling sensitivity; it was hyper sensitive in previous releases, and now it is more reasonable.
  • Fix an issue where EGL failed to initialize on Linux
  • If EGL/WGL/OpenGL fail to initialize, we now try to fallback to Mesa OpenGL in software render mode. This should result in its llvmpipe renderer being used as a fallback, which has improved visuals compared to wezterm's own basic CPU based renderer. (This applies to X11/Wayland and Windows systems).
  • Setting front_end="Software" will try to use the Mesa OpenGL software renderer if available (X11/Wayland/Windows). The old basic CPU renderer has been removed.
  • The multiplexer server has been moved into its own wezterm-mux-server executable. You will need to revise your serve_command configuration.
  • Windows: when started in an RDP session, force the use of the Mesa software renderer to work around problems with RDP GPU emulation.
  • Fixed an issue with TLS Multiplexing where bootstrapping certificates would usually fail.
  • Windows: Fixed an issue that prevented ALT-Space from showing the system menu in the window.
  • Windows: Fixed dead key handling. By default dead keys behave the same as in other programs and produce diacritics. However, setting use_dead_keys = false in the config will cause dead keys to behave like a regular key; eg: ^ would just emit ^ as its own character.
  • Windows: Fixed an issue with the Hide key assignment; it would hide the window with no way to show it again! Hide now minimizes the window instead.
  • macOS: we now use Metal to render the gui, via MetalANGLE
  • Windows: we now prefer to use Direct3D11 to render the gui, via ANGLE EGL. The primary benefit of this is that upgrading your graphics drivers while you have a stateful wezterm session will no longer terminate the wezterm process. Resize behavior is not as smooth with ANGLE as the prior WGL. If you wish, you can set prefer_egl = false to use WGL.
  • Improved image protocol support to have better render fidelity and to reduce VRAM usage when the same image it displayed multiple times in the same pane.

20200909-002054-4c9af461

  • Added support for OSC 1 (Icon Title changing), and changed how that interacts with OSC 2 (Window Title changing). If you specify OSC 1 as a non-empty string, then that will be used for the title of that terminal instance in the GUI. Otherwise the Window Title will be reported instead.
  • Added missing mappings for Application Keypad keys on Linux
  • Workaround an EGL issue where Mesa reports the least-best alpha value when enumerating configs, rather than the best alpha. This could lead to incorrect alpha under XWayland and failure to initialize EGL and fallbacks to the Software renderer in some other cases.
  • enable_wayland now defaults to false; mutter keeps breaking client-side window decoration so let's just make it opt-in so that the default experience is better.
  • Fixed a crash on Linux/X11 when using wezterm connect HOST
  • Added tab_max_width config setting to limit the maximum width of tabs in the tab bar. This defaults to 16 glyphs in width.

20200718-095447-d2315640

  • Added support for DECSET 1004 Focus Reporting to local (not multiplexer) terminal sessions.
  • Added support for SGR 53/55 which enable/disable Overline style. printf "\x1b[53moverline\x1b[0m\n"
  • Windows: updated bundled openconsole.exe to efb1fdd to resolve an issue where bold text didn't respect the configured color scheme.
  • Added bold_brightens_ansi_colors option to allow disabling the automatic brightening of bold text.
  • Unix: fix an issue where setting the current working directory for a custom spawned command would not take effect (thanks @john01dav!)
  • Windows: fixed buffering/timing issue where a response to a color query in vim could be misinterpreted and replace a character in the editor with the letter g.
  • X11: Improved support for non-24bpp display depths. WezTerm now tries harder to obtain an 8bpc surface on both 16bpp and 30bpp (10bpc) displays.
  • Windows: fixed falling back to a simpler OpenGL context if WGL is unable to negotiate a robust context. This is useful on systems with dual high/low power GPU hardware where the OpenGL versions for the two GPUs are different!
  • Color Schemes: synced with ea2c841 which includes new schemes: Adventure, Banana Blueberry, Blue Matrix, BlueBerryPie, Cyberdyne, Django, DjangoRebornAgain, DjangoSmooth, DoomOne, Konsolas, Laser, Mirage, Rouge 2, Sakura, Scarlet Protocol, synthwave-everything, Tinacious Design (Dark), Tinacious Design (Light).

20200620-160318-e00b076c

  • Fixed default mapping of ambiguous ctrl key combinations (i, m, [, {, @) so that they emit the old school tab, newline, escape etc. values. These got broken as part of prototyping CSI-u support a while back.
  • Added option to enable CSI-u key encodings. This is a new mapping scheme defined here http://www.leonerd.org.uk/hacks/fixterms/ that disambiguates and otherwise enables more key binding combinations. You can enable this setting using enable_csi_u_key_encoding = true in your config file.
  • Very early support for sixel graphics
  • macos: use_ime now defaults to false; this is a better out of the box experience for most users.
  • macos: we now attempt to set a reasonable default LANG environment based on the locale settings at the time that wezterm is launched.
  • macos: introduce send_composed_key_when_left_alt_is_pressed and send_composed_key_when_right_alt_is_pressed boolean config settings. Like the existing send_composed_key_when_alt_is_pressed option, these control whether the Alt or Option modifier produce composed output or generate the raw key position with the ALT modifier applied. The difference from the existing config option is that on systems where Left and Right Alt can be distinguished you now have the ability to control this behavior independently. The default behavior on these systems is send_composed_key_when_left_alt_is_pressed=false and send_composed_key_when_right_alt_is_pressed=true so that the right Alt key behaves more like an AltGr key and generates the composed input, while the Left Alt is regular uncomposed Alt.
  • Fonts: fixed an issue where specifying italic or bold in the second parameter of wezterm.font didn't work as intended or documented
  • Improved terminal emulation conformance; added left/right margin support and now passes esctest to a similar degree as iTerm2
  • Fixed an issue where unmodified F5+ would use the CSI-u encoded-modifiers format, and confused eg: htop.
  • ActivateTab now accepts negative numbers as a way to reference the last tab in the Window. The default assignment for CTRL+SHIFT+9 and CMD+9 is now ActivateTab=-1, which selects the last tab.
  • Fixed an issue when applying hyperlink rules to lines that had mixed width characters

20200607-144723-74889cd4

  • Windows: Fixed AltGr handling for European layouts
  • X11: Added PastePrimarySelection key assignment that pastes the contents of the primary selection rather than the clipboard.
  • Removed old TOML config file parsing code
  • Removed old arg="something" key binding parameter. This was a remnant from the TOML based configuration. You're unlikely to notice this unless you followed an example from the docs; migrate instead to using eg: action=wezterm.action{ActivateTab=i-1} to pass the integer argument.
  • Windows: now also available with a setup.exe installer. The installer enables "Open WezTerm Here" in the explorer.exe context menu.
  • Added ClearScrollback key assignment to clear the scrollback. This is bound to CMD-K and CTRL-SHIFT-K by default.
  • Added Search key assignment to search the scrollback. Read the new scrollback section for more information!
  • Fixed an issue where ALT+number would send the wrong output for European keyboard layouts on macOS and Linux. As part of this the default behavior has changed: we used to force ALT+number to produce ALT+number instead of the composed key for that layout. We now emit the composed key by default. You can switch to the old behavior either by explicitly binding those keys or by setting send_composed_key_when_alt_is_pressed = false in your configuration file.
  • Windows: the launcher menu now automatically lists out any WSL environments you have installed so that you can quickly spawn a shell in any of them. You can suppress this behavior if you wish by setting add_wsl_distributions_to_launch_menu = false. Read more about the launcher menu
  • Added ActivateCopyMode key assignment to put the tab into mouseless-copy mode; use the keyboard to define the selected text region. This is bound to CTRL-SHIFT-X by default.

20200517-122836-92c201c6

  • AppImage: Support looking for configuration in WezTerm.AppImage.config and WezTerm.AppImage.home to support portable thumbdrive use of wezterm on linux systems
  • We now check the github releases section for updated stable releases and show a simple UI to let you know about the update, with links to download/install it. We don't automatically download the release: just make a small REST API call to github. There is no data collection performed by the wezterm project as part of this. We check once every 24 hours. You can set check_for_updates = false in your config to disable this completely if desired, or set check_for_updates_interval_seconds to an alternative update interval.
  • Added support for OSC 110-119 to reset dynamic colors, improving our support for Neovim.
  • Change OSC rendering to use the long-form ST sequence ESC \ rather than the more convenient alternative BEL representation, which was not recognized by Neovim when querying for color information.
  • Fixed Shift-Tab key on X11 and Wayland
  • WezTerm is now also available to Windows users via Scoop

20200503-171512-b13ef15f

  • Added the launch_menu configuration for the launcher menu as described in Launching Programs.
  • Fixed a crash when reloading a config with enable_tab_bar=false
  • Fixed missing icon when running under X11 and Wayland
  • Wayland client-side-decorations improved and now also render window title
  • Implicitly SGR reset when switching alt and primary screen
  • Improved config error reporting UI: we now show just a single window with all errors rather than one window per failed reload.

20200406-151651-5b700e4

  • Added lua based configuration. Reading TOML configuration will be rapidly phased out in favor of the more flexible lua config; for now, both are supported, but new features may not be available via TOML.
  • Added launcher overlay. Right click the + button on the tab bar or bind a key to ShowLauncher to activate it. It allows spawning tabs in various domains as well as attaching multiplexer sessions that were not connected automatically at startup.
  • Windows: we now support mouse reporting on Windows native ptys. For this to work, conpty.dll and OpenConsole.exe must be present alongside wezterm.exe when starting wezterm.
  • Added initial_rows and initial_cols config options to set the starting size of new terminal windows
  • Added hide_tab_bar_if_only_one_tab = true config option to hide the tab bar when the window contains only a single tab.
  • Added HideApplication key action (defaults to CMD-H on macOS only) which hides the wezterm application. This is macOS specific.
  • Added QuitApplication key action which causes the gui loop to terminate and the application to exit. This is not bound by default, but you may choose to assign it to something like CMD-Q.
  • Added set_environment_variables configuration section to allow defining some environment variables to be passed to your shell.
  • Improved connectivity UI that shows ssh and mux connection progress/status
  • Fixed a bug where the baud rate was not applied when opening a serial port
  • Added predictive local echo to the multiplexer for higher latency connections
  • We now grey out the UI for lagging multiplexer connections
  • Set an upper bound on the memory usage for multiplexer connections

20200202-181957-765184e5

  • Improved font shaping performance 2-3x by adding a shaper cache
  • Windows: now has support for TLS based multiplexer connections
  • Multiplexer: TLS multiplexer can now be bootstrapped via SSH, and automatically manages certificates
  • Unix: We now default to spawning shells with the -l argument to request a login shell. This is important on macOS where the default GUI environment doesn't source a working PATH from the shell, resulting in an anemic PATH unless the user has taken care to cover this in their shell startup. -l works to enable a login shell in zsh, bash, fish and tcsh. If it doesn't work with your shell, you can use the default_prog configuration option to override this.
  • We now accept rgb:XX/XX/XX color syntax for OSC 4 and related escape sequences; previously only #XXXXXX and named colors were accepted.
  • We now accept OSC 104 to reset custom colors to their defaults.
  • Added Tab Navigator overlay for folks that hoard tabs; it presents an interactive UI for selecting and activating a tab from a vertically oriented list. This is bound to Alt-9 by default.
  • Added support for DEC Origin Mode (DECOM) which improves cursor positioning with some applications
  • Added support for DEC AutoWrap Mode (DECAWM) which was previously always on. This improves rendering for applications that explicitly disable it.
  • We now show a connection status window while establishing MUX and SSH connections. The status window is also where any interactive authentication is carried out for eg: SSH sessions.
  • Improved SSH authentication handling; we now give you a few opportunities to authenticate and are now able to successfully authenticate with sites that have configured 2-Factor authentication in their server side SSH configuration.
  • Fixed an issue where SHIFT-Space would swallow the space key.
  • Nightly builds are now available for Linux in AppImage format.
  • Shift+Left Mouse button can now be used to extend the selection to the clicked location. This is particularly helpful when you want to select something that is larger than the viewport.
  • Windows: a single mouse wheel tick now scrolls by the number of positions configured in the Windows system settings (default 3)
  • Windows: fixed IME position when the tab bar is enabled
  • Windows: removed support for WinPty, which was too difficult to obtain, configure and use.
  • Configuration errors now show in a separate window on startup, or when the configuration is reloaded
  • Improved reliability and performance of MUX sessions, although they still have room for further improvement

20200113-214446-bb6251f

  • Added color_scheme configuration option and more than 200 color schemes
  • Improved resize behavior; lines that were split due to the width of the terminal are now rewrapped on resize. Issue 14
  • Double-click and triple-click and hold followed by a drag now extends the selection by word and line respectively.
  • The OSC 7 (CurrentWorkingDirectory) escape sequence is now supported; wezterm records the cwd in a tab and that will be used to set the working directory when spawning new tabs in the same domain. You will need to configure your shell to emit OSC 7 when appropriate.
  • Changed Backspace/Delete handling
  • Added MoveTabRelative for changing the ordering of tabs within a window using key assignments CTRL+SHIFT+PageUp and CTRL+SHIFT+PageDown
  • The multiplexer protocol is undergoing major changes. The multiplexer will now raise an error if the client and server are incompatible.
  • Fixed an issue where wezterm would linger for a few seconds after the last tab was closed
  • Fixed an issue where wezterm wouldn't repaint the screen after a tab was closed
  • Clicking the OS window close button in the titlebar now closes the window rather than the active tab
  • Added use_ime option to optionally disable the use of the IME on macOS. You might consider enabling this if you don't like the way that the IME swallows key repeats for some keys.
  • Fix an issue where the pidfile would leak into child processes and block restarting the mux server
  • Fix an issue where the title bars of remote tabs were not picked up at domain attach time
  • Fixed selection and scrollbar position for multiplexer tabs
  • Added ScrollByPage key assignment and moved the SHIFT+PageUp handling up to the gui layer so that it can be rebound.
  • X11: a single mouse wheel tick now scrolls by 5 rows rather than 1
  • Wayland: normalize line endings to unix line endings when pasting
  • Windows: fixed handling of focus related messages, which impacted both the appearance of the text cursor and copy and paste handling.
  • When hovering over implicitly hyperlinked items, we no longer show the underline for every other URL with the same destination

20191229-193639-e7aa2f3

  • Fixed a hang when using middle mouse button to paste
  • Recognize 8-bit C1 codes encoded as UTF-8, which are used in the Fedora 31 bash prexec notification for gnome terminal
  • Ensure that underlines are a minimum of 1 pixel tall
  • Reduced CPU utilization on some Wayland compositors
  • Added $WEZTERM_CONFIG_FILE to the start of the config file search path
  • Added new font rendering options:
font_antialias = "Subpixel" # None, Greyscale, Subpixel
font_hinting = "Full" # None, Vertical, VerticalSubpixel, Full
  • Early startup errors now generate a "toast" notification, giving you more of a clue about what went wrong
  • We now use the default configuration if the config file had errors, rather than refusing to start
  • Wayland compositors: Improved detection of display scaling on startup
  • Added harfbuzz_features option to specify stylistic sets for fonts such as Fira Code, and to control various typographical options
  • Added a window_padding config section to add padding to the window display
  • We now respect DECSCUSR and DECTCEM escape sequence to select between hidden, block, underline and bar cursor types, as well as blinking cursors. New configuration options have been added to control the appearance and blink rate.
  • We now support an optional basic scroll bar. The scroll bar occupies the right window padding and has a configurable color. Scroll bars are not yet supported for multiplexer connections and remain disabled by default for the moment.
  • Color scheme changes made in the config file now take effect at config reload time for all tabs that have not applied a dynamic color scheme.

20191218-101156-bf35707

  • Configuration errors detected during config loading are now shown as a system notification
  • New font_dirs configuration option to specify a set of dirs to search for fonts. Useful for self-contained wezterm deployments.
  • The font_system option has been split into font_locator, font_shaper and font_rasterizer options.
  • Don't allow child processes to inherit open font files on posix systems!
  • Disable Nagle's algorithm for wezterm ssh sessions
  • Add native Wayland window system support

20191124-233250-cb9fd7d

  • New tab bar UI displays tabs and allows creating new tabs
  • Configuration file changes are hot reloaded and take effect automatically on save
  • wezterm ssh user@host for ad-hoc SSH sessions. You may also define SSH multiplexer sessions.
  • wezterm serial /dev/ttyUSB0 to connect to your Arduino
  • wezterm imgcat /some/image.png to display images inline in the terminal using the iTerm2 image protocol
  • IME support on macOS and Windows systems
  • Automatic fallback to software rendering if no GPU is available (eg: certain types of remote desktop sessions)

Configuration Files

wezterm will look for a lua configuration file using the logic shown below.

The recommendation is to place your configuration file at $HOME/.wezterm.lua to get started.

More complex configurations that need to span multiple files can be placed in $XDG_CONFIG_HOME/wezterm/wezterm.lua (for X11/Wayland) or $HOME/.config/wezterm/wezterm.lua (for all other systems).

graph TD
  X[Locate Configuration file] --> A{{--config-file CLI argument specified?}}
  A -->|Yes| B{{Can that file be loaded?}}
  B -->|Yes| C[Use it]
  B -->|No| D[Use built-in default configuration]
  A -->|No| E{{$WEZTERM_CONFIG_FILE<br/>environment set?}}
  E -->|Yes| B
  E -->|No| F{{"Running on Windows and<br/>wezterm.lua exists in same<br/>dir as wezterm.exe?<br/>(Thumb drive mode)"}}
  F -->|Yes| B
  F -->|No| H{{Is $XDG_CONFIG_HOME<br/>environment set and<br/>wezterm/wezterm.lua<br/>exists inside it?}}
  H -->|Yes| C
  J --> B
  H -->|No| K{{Does $HOME/.config/wezterm/wezterm.lua exist?}}
  K -->|Yes| B
  K -->|No| J[Use $HOME/.wezterm.lua]

Prior to version 20210314-114017-04b7cedd, if the candidate file exists but failed to parse, wezterm would treat it as though it didn't exist and continue to try other candidate file locations. In all current versions of wezterm, an error will be shown and the default configuration will be used instead.

Note that on Windows, to support uses that carry their wezterm application and configuration around on a thumb drive, wezterm will look for the config file in the same location as wezterm.exe. That is shown in the chart above as thumb drive mode.

wezterm will watch the config file that it loads; if/when it changes, the configuration will be automatically reloaded and the majority of options will take effect immediately. You may also use the CTRL+SHIFT+R keyboard shortcut to force the configuration to be reloaded.

The configuration file may be evaluated multiple times for each wezterm process both at startup and in response to the configuration file being reloaded. You should avoid taking actions in the main flow of the config file that have side effects; for example, unconditionally launching background processes can result in many of them being spawned over time if you launch many copies of wezterm, or are frequently reloading your config file.

Configuration Overrides

since: 20210314-114017-04b7cedd

wezterm allows overriding configuration values via the command line; here are a couple of examples:

$ wezterm --config enable_scroll_bar=true
$ wezterm --config 'exit_behavior="Hold"'

Configuration specified via the command line will always override the values provided by the configuration file, even if the configuration file is reloaded.

Each window can have an additional set of window-specific overrides applied to it by code in your configuration file. That's useful for eg: setting transparency or any other arbitrary option on a per-window basis. Read the window:set_config_overrides documentation for more information and examples of how to use that functionality.

Configuration File Structure

The wezterm.lua configuration file is a lua script which allows for a high degree of flexibility. The script is expected to return a configuration table, so a basic empty configuration file will look like this:

return {
}

Throughout these docs you'll find configuration fragments that demonstrate configuration and that look something like this:

return {
  color_scheme = "Batman",
}

and perhaps another one like this:

local wezterm = require 'wezterm';
return {
  font = wezterm.font("JetBrains Mono"),
}

If you wanted to use both of these in the same file, you would merge them together like this:

local wezterm = require 'wezterm';
return {
  font = wezterm.font("JetBrains Mono"),
  color_scheme = "Batman",
}

Launching Programs

By default, when opening new tabs or windows, your shell will be spawned.

Your shell is determined by the following rules:

On Posix Systems

  1. The value of the $SHELL environment variable is used if it is set
  2. Otherwise, it will resolve your current uid and try to look up your home directory from the password database.

wezterm will spawn the shell and pass -l as an argument to request a login shell. A login shell generally loads additional startup files and sets up more environment than a non-login shell.

Since: 20210502-154244-3f7122cb: instead of passing -l to the shell, wezterm will spawn the shell as -$SHELL to invoke it as a login shell.

Note: if you have recently changed your shell using chsh and you have $SHELL set in the environment, you will need to sign out and sign back in again for the environment to pick up your new $SHELL value.

On Windows Systems

  1. The value of the %COMSPEC% environment variable is used if it is set.
  2. Otherwise, cmd.exe

Changing the default program

If you'd like wezterm to run a different program than the shell as described above, you can use the default_prog config setting to specify the argument array; the array allows specifying the program and arguments portably:

return {
  -- Spawn a fish shell in login mode
  default_prog = {"/usr/local/bin/fish", "-l"},
}

Launching a different program as a one off via the CLI

If you want to make a shortcut for your desktop environment that will, for example, open an editor in wezterm you can use the start subcommand to launch it. This example opens up a new terminal window running vim to edit your wezterm configuration:

wezterm start -- vim ~/.wezterm.lua

Specifying the current working directory

If you'd like wezterm to start running a program in a specific working directory you can do so via the config, CLI, and when using SpawnCommand:

  • Setting the default_cwd via the config:

    return {
      default_cwd = "/some/path",
    }
    
  • One off program in a specific working directory via the CLI:

    wezterm start --cwd /some/path
    
  • The SpawnCommandInNewTab, and SpawnCommandInNewWindow key assignments, and the Launcher Menu described below all accept a SpawnCommand object that accepts an optional cwd field:

    {
      label = "List files in /some/path",
      args = {"ls", "-al"},
      cwd = "/some/path",
    }
    

Panes/Tabs/Windows created after the first will generally try to resolve the current working directory of the current Pane, preferring a value set by OSC 7 and falling back to attempting to lookup the cwd of the current process group leader attached to a local Pane. If no cwd can be resolved, then the default_cwd will be used. If default_cwd is not specified, then the home directory of the user will be used.

See default_cwd for an easier to understand visualization.

Passing Environment variables to the spawned program

The set_environment_variables configuration setting can be used to add environment variables to the environment of the spawned program.

The behavior is to take the environment of the wezterm process and then set the specified variables for the spawned process.

return {
  set_environment_variables = {
    -- This changes the default prompt for cmd.exe to report the
    -- current directory using OSC 7, show the current time and
    -- the current directory colored in the prompt.
    prompt = "$E]7;file://localhost/$P$E\\$E[32m$T$E[0m $E[35m$P$E[36m$_$G$E[0m "
  },
}

The Launcher Menu

The launcher menu is accessed from the new tab button in the tab bar UI; the + button to the right of the tabs. Left clicking on the button will spawn a new tab, but right clicking on it will open the launcher menu. You may also bind a key to the ShowLauncher or ShowLauncherArgs action to trigger the menu.

The launcher menu by default lists the various multiplexer domains and offers the option of connecting and spawning tabs/windows in those domains.

You can define your own entries using the launch_menu configuration setting. The snippet below adds two new entries to the menu; one that runs the top program to monitor process activity and a second one that explicitly launches the bash shell.

Each entry in launch_menu is an instance of a SpawnCommand object.

return {
  launch_menu = {
    {
      args = {"top"},
    },
    {
      -- Optional label to show in the launcher. If omitted, a label
      -- is derived from the `args`
      label = "Bash",
      -- The argument array to spawn.  If omitted the default program
      -- will be used as described in the documentation above
      args = {"bash", "-l"},

      -- You can specify an alternative current working directory;
      -- if you don't specify one then a default based on the OSC 7
      -- escape sequence will be used (see the Shell Integration
      -- docs), falling back to the home directory.
      -- cwd = "/some/path"

      -- You can override environment variables just for this command
      -- by setting this here.  It has the same semantics as the main
      -- set_environment_variables configuration option described above
      -- set_environment_variables = { FOO = "bar" },
    },
  }
}
Screenshot

Here's a fancy example that will add some helpful entries to the launcher menu when running on Windows:

since: 20200607-144723-74889cd4: The launcher menu automatically includes WSL entries by default, unless disabled using add_wsl_distributions_to_launch_menu = false.

local wezterm = require 'wezterm';

local launch_menu = {}

if wezterm.target_triple == "x86_64-pc-windows-msvc" then
  table.insert(launch_menu, {
    label = "PowerShell",
    args = {"powershell.exe", "-NoLogo"},
  })

  -- Find installed visual studio version(s) and add their compilation
  -- environment command prompts to the menu
  for _, vsvers in ipairs(wezterm.glob("Microsoft Visual Studio/20*", "C:/Program Files (x86)")) do
    local year = vsvers:gsub("Microsoft Visual Studio/", "")
    table.insert(launch_menu, {
      label = "x64 Native Tools VS " .. year,
      args = {"cmd.exe", "/k", "C:/Program Files (x86)/" .. vsvers .. "/BuildTools/VC/Auxiliary/Build/vcvars64.bat"},
    })
  end

  -- Enumerate any WSL distributions that are installed and add those to the menu
  local success, wsl_list, wsl_err = wezterm.run_child_process({"wsl.exe", "-l"})
  -- `wsl.exe -l` has a bug where it always outputs utf16:
  -- https://github.com/microsoft/WSL/issues/4607
  -- So we get to convert it
  wsl_list = wezterm.utf16_to_utf8(wsl_list)

  for idx, line in ipairs(wezterm.split_by_newlines(wsl_list)) do
    -- Skip the first line of output; it's just a header
    if idx > 1 then
      -- Remove the "(Default)" marker from the default line to arrive
      -- at the distribution name on its own
      local distro = line:gsub(" %(Default%)", "")

      -- Add an entry that will spawn into the distro with the default shell
      table.insert(launch_menu, {
        label = distro .. " (WSL default shell)",
        args = {"wsl.exe", "--distribution", distro},
      })

      -- Here's how to jump directly into some other program; in this example
      -- its a shell that probably isn't the default, but it could also be
      -- any other program that you want to run in that environment
      table.insert(launch_menu, {
        label = distro .. " (WSL zsh login shell)",
        args = {"wsl.exe", "--distribution", distro, "--exec", "/bin/zsh", "-l"},
      })
    end
  end
end

return {
  launch_menu = launch_menu,
}

WezTerm bundles JetBrains Mono, PowerlineExtraSymbols and Noto Color Emoji fonts and uses those for the default font configuration.

If you wish to use a different font face, then you can use the wezterm.font function to specify it:

local wezterm = require 'wezterm';

return {
  font = wezterm.font("Fira Code"),
  -- You can specify some parameters to influence the font selection;
  -- for example, this selects a Bold, Italic font variant.
  font = wezterm.font("JetBrains Mono", {weight="Bold", italic=true})
}

Fallback

WezTerm allows specifying an ordered list of fonts; when resolving text into glyphs the first font in the list is consulted, and if the glyph isn't present in that font, WezTerm proceeds to the next font in the fallback list.

The default fallback includes the popular PowerlineExtraSymbols font, which means that you don't need to use specially patched fonts to use the powerline glyphs.

You can specify your own fallback; that's useful if you've got a killer monospace font, but it doesn't have glyphs for the asian script that you sometimes work with:

local wezterm = require 'wezterm';
return {
  font = wezterm.font_with_fallback({
    "Fira Code",
    "DengXian",
  }),
}

WezTerm will still append its default fallback to whatever list you specify, so you needn't worry about replicating that list if you set your own fallback.

If none of the fonts in the fallback list (including WezTerm's default fallback list) contain a given glyph, then wezterm will resolve the system fallback list and try those fonts too. If a glyph cannot be resolved, wezterm will render a special "Last Resort" glyph as a placeholder. You may notice the placeholder appear momentarily and then refresh itself to the system fallback glyph on some systems.

Additional options for configuring fonts can be found elsewhere in the docs:

Troubleshooting Fonts

You may use wezterm ls-fonts to have wezterm explain information about which font files it will use for the different text styles.

It shows output like this:

$ 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/MaterialDesignIconsDesktop.ttf, FontDirs
  "Material Design Icons Desktop",

  -- /usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.ttf, FontConfig
  "JetBrains Mono",

  -- /usr/share/fonts/google-noto-emoji/NotoColorEmoji.ttf, FontConfig
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Half Italic=true:
wezterm.font_with_fallback({
  -- /home/wez/.fonts/OperatorMonoSSmLig-BookItalic.otf, FontDirs
  {family="Operator Mono SSm Lig", weight=325, italic=true},

  -- /home/wez/.fonts/MaterialDesignIconsDesktop.ttf, FontDirs
  "Material Design Icons Desktop",

  -- /usr/share/fonts/jetbrains-mono-fonts/JetBrainsMono-Regular.ttf, FontConfig
  "JetBrains Mono",

  -- /usr/share/fonts/google-noto-emoji/NotoColorEmoji.ttf, FontConfig
  -- Assumed to have Emoji Presentation
  -- Pixel sizes: [128]
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})
...

You can ask wezterm to including a listing of all of the fonts on the system in a form that can be copied and pasted into the configuration file:

$ wezterm ls-fonts --list-system
<same output as above, but then:>
112 fonts found in your font_dirs + built-in fonts:
wezterm.font("Cascadia Code", {weight="ExtraLight", stretch="Normal", italic=false}) -- /home/wez/.fonts/CascadiaCode.ttf index=0 variation=1, FontDirs
wezterm.font("Cascadia Code", {weight="Light", stretch="Normal", italic=false}) -- /home/wez/.fonts/CascadiaCode.ttf index=0 variation=2, FontDirs
wezterm.font("Cascadia Code", {weight="DemiLight", stretch="Normal", italic=false}) -- /home/wez/.fonts/CascadiaCode.ttf index=0 variation=3, FontDirs
wezterm.font("Cascadia Code", {weight="Regular", stretch="Normal", italic=false}) -- /home/wez/.fonts/CascadiaCode.ttf index=0 variation=4, FontDirs
wezterm.font("Cascadia Code", {weight="DemiBold", stretch="Normal", italic=false}) -- /home/wez/.fonts/CascadiaCode.ttf index=0 variation=5, FontDirs
wezterm.font("Cascadia Code", {weight="Bold", stretch="Normal", italic=false}) -- /home/wez/.fonts/CascadiaCode.ttf index=0 variation=6, FontDirs
wezterm.font("Fira Code", {weight="Light", stretch="Normal", italic=false}) -- /home/wez/.fonts/FiraCode-Light.otf, FontDirs
wezterm.font("Fira Code", {weight="Regular", stretch="Normal", italic=false}) -- /home/wez/.fonts/FiraCode-Regular.otf, FontDirs
wezterm.font("Fira Code", {weight=450, stretch="Normal", italic=false}) -- /home/wez/.fonts/FiraCode-Retina.otf, FontDirs
wezterm.font("Fira Code", {weight="Medium", stretch="Normal", italic=false}) -- /home/wez/.fonts/FiraCode-Medium.otf, FontDirs
wezterm.font("Fira Code", {weight="Bold", stretch="Normal", italic=false}) -- /home/wez/.fonts/FiraCode-Bold.otf, FontDirs
wezterm.font("Font Awesome 5 Free", {weight="Black", stretch="Normal", italic=false}) -- /home/wez/.fonts/Font Awesome 5 Free-Solid-900.otf, FontDirs
...
690 system fonts found using FontConfig:
wezterm.font("Abyssinica SIL", {weight="Regular", stretch="Normal", italic=false}) -- /usr/share/fonts/sil-abyssinica-fonts/AbyssinicaSIL-R.ttf, FontConfig
wezterm.font("C059", {weight="Regular", stretch="Normal", italic=false}) -- /usr/share/fonts/urw-base35/C059-Bold.t1, FontConfig
wezterm.font("C059", {weight="Regular", stretch="Normal", italic=false}) -- /usr/share/fonts/urw-base35/C059-Roman.otf, FontConfig
wezterm.font("C059", {weight="Regular", stretch="Normal", italic=false}) -- /usr/share/fonts/urw-base35/C059-Roman.t1, FontConfig
wezterm.font("C059", {weight="Regular", stretch="Normal", italic=true}) -- /usr/share/fonts/urw-base35/C059-BdIta.t1, FontConfig
wezterm.font("C059", {weight="Regular", stretch="Normal", italic=true}) -- /usr/share/fonts/urw-base35/C059-Italic.otf, FontConfig
...

You may also display the shaping plan for a given text string; in this example, the a and the b are separated by a special symbol which is not present in the main font, so we expect to see a different font used for that glyph:

wezterm ls-fonts --text a🞄b
a    \u{61}       x_adv=8  glyph=29   wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
                                      /home/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs
🞄    \u{1f784}    x_adv=4  glyph=9129 wezterm.font("Symbola", {weight="Regular", stretch="SemiCondensed", italic=false})
                                      /usr/share/fonts/gdouros-symbola/Symbola.ttf, FontConfig
b    \u{62}       x_adv=8  glyph=30   wezterm.font("Operator Mono SSm Lig", {weight="DemiLight", stretch="Normal", italic=false})
                                      /home/wez/.fonts/OperatorMonoSSmLig-Medium.otf, FontDirs

Advanced Font Shaping Options

The harfbuzz_features option allows specifying the features to enable when using harfbuzz for font shaping.

There is some light documentation here: https://harfbuzz.github.io/shaping-opentype-features.html but it boils down to allowing opentype feature names to be specified using syntax similar to the CSS font-feature-settings options: https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings. The OpenType spec lists a number of features here: https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist

Options of likely interest will be:

If you want to disable ligatures in most fonts, then you may want to use a setting like this:

return {
  harfbuzz_features = {"calt=0", "clig=0", "liga=0"},
}

Some fonts make available extended options via stylistic sets. If you use the Fira Code font, it lists available stylistic sets here: https://github.com/tonsky/FiraCode/wiki/How-to-enable-stylistic-sets

and you can set them in wezterm:

return {
  -- Use this for a zero with a dot rather than a line through it
  -- when using the Fira Code font
  harfbuzz_features = {"zero"}
}

Since: 20220101-133340-7edc5b5a

You can specify harfbuzz_features on a per-font basis, rather than globally for all fonts:

local wezterm = require 'wezterm'
return {
  font = wezterm.font({
    family="JetBrains Mono",
    harfbuzz_features={"calt=0", "clig=0", "liga=0"}
  })
}

and this example disables ligatures for JetBrains Mono, but keeps the default for the other fonts in the fallback:

local wezterm = require 'wezterm';

return {
  font = wezterm.font_with_fallback({
    {
       family="JetBrains Mono",
       weight="Medium",
       harfbuzz_features={"calt=0", "clig=0", "liga=0"}
    },
    {family="Terminus", weight="Bold"},
    "Noto Color Emoji"
  }),
}

Keyboard Concepts

wezterm allows assigning action(s) to specific key events, and comes pre-configured with a number of commonly useful assignments.

This page describes how key presses are handled and turned into actions or sent to the terminal as text.

It's important to understand these concepts when considering keyboard input; first, some operating system concepts:

  • Input Method Editor (IME) - An OS-provided service which allows for rich composition of input, often with a pop-over candidate selection window. This is commonly used for Asian input, but on some systems the IME may also be responsible for emoji input or dead keys. The IME may have multiple modes per language and those modes can be changed dynamically.
  • Keyboard Layout - An OS configuration that describes how to translate physical key button presses into inputs appropriate to the user's preferred input locale. The mapping performed by the layout is largely opaque to applications and, on most systems, can be changed dynamically.
  • Dead Key - a keyboard layout may define these modal keys which don't immediately produce output (and thus appears to be "dead"), but instead holds some state that will compose with a subsequently pressed key. Most commonly used for example in European layouts to produce accented versions of the plain latin alphabet.
  • Physical Key - a way to identify a key based on its hardware-dependent location. wezterm can refer to keys based on code they would emit if configured to use an ANSI US English keyboard layout (even if that layout is not currently active), or based on its raw scan code.
  • Mapped key - a way to identify a key after the keyboard layout has been applied by the OS.
  • Modifier - A key such as SHIFT, CTRL, CMD, ALT that can be held simultaneously while other keys are pressed. Modifier keys are special because keyboard hardware traditionally only supports those four modifiers, and that detail is ingrained into most OS input APIs.

And then some wezterm concepts:

  • Key Assignment - an action assigned to a matching key and modifier combination.
  • Key Table - a grouping of key assignments. For each window, wezterm maintains a stack of table activations, allowing for rich modal keyboard input customization

Keyboard Processing Flow

This schematic depicts the processing flow for keyboard events in wezterm:

flowchart TD
A[OS Generates a Key Event]
A --> B{{Is IME enabled?}}
B -->|Yes| C[Deliver event to IME] --> C1{{IME Response}}
B -->|No| F
C1 -->|Composed| D[Make RawKeyEvent from<br/> Composed text] --> RAW1
C1 -->|Composing| E[Render composing status]
C1 -->|Continue| F[Make RawKeyEvent] --> RAW1
RAW3 -->|No| DEAD1{{Does RawKeyEvent complete a dead-key?}}
DEAD1 -->|Yes| I[Make KeyEvent from<br/>expanded dead key] --> KEY1
DEAD1 -->|No| DEAD2{{Does RawKeyEvent start a dead-key?}}
DEAD2 -->|Yes| DEADCOMP[Render composing status]
DEAD2 -->|No| J[Make KeyEvent from RawKeyEvent] --> KEY1
KEY3 -->|No| M[Send key to terminal]

RAW1{{match a phys: mapping?}}
RAW1 -->|Yes| RAWDONE[Perform assignment action]
RAW1 -->|No| RAW2{{match a raw: mapping?}}
RAW2 -->|Yes| RAWDONE
RAW2 -->|No| RAW3{{match a mapped: mapping?}}
RAW3 -->|Yes| RAWDONE2[Perform assignment action]

KEY1{{match a phys: mapping?}}
KEY1 -->|Yes| KEYDONE[Perform assignment action]
KEY1 -->|No| KEY2{{match a raw: mapping?}}
KEY2 -->|Yes| KEYDONE
KEY2 -->|No| KEY3{{match a mapped: mapping?}}
KEY3 -->|Yes| KEYDONE2[Perform assignment action]

Alt / Option Key Behavior & Composed Keys

The operating system has its own user selectable keymap that is sometimes at odds with old-school terminal emulation that pre-dates internationalization as a concept. WezTerm tries to behave reasonably by default, but also give you control in other situations.

Layouts with an AltGr key

If you have, for example, a European keyboard layout with an AltGr key then wezterm will respect the composition effects of AltGr produced by the system. For example, in a German keymap, AltGr < will produce |.

If your physical keyboard doesn't match the keyboard layout (eg: using a US keyboard with DEU selected in the OS), then the right hand Alt key is often re-interpreted as having the AltGr function with behavior as described above.

The left Alt will be treated as a modifier with no composition effects.

Microsoft Windows and Ctrl-Alt <-> AltGr

If you are using VNC and a keyboard layout with dead keys, then you may wish to enable treat_left_ctrlalt_as_altgr.

macOS Left and Right Option Key

since: 20200620-160318-e00b076c

The default behavior is to treat the left Option key as the Alt modifier with no composition effects, while the right Option key performs composition (making it approximately equivalent to AltGr on other operating systems).

You can control this behavior in your configuration:

return {
  send_composed_key_when_left_alt_is_pressed=false,
  send_composed_key_when_right_alt_is_pressed=true,
}

since: 20210203-095643-70a364eb

WezTerm is now able to perform dead-key expansion when use_ime = false. Dead keys are treated as composition effects, so with the default settings of send_composed_key_when_left_alt_is_pressed and send_composed_key_when_right_alt_is_pressed above, in a US layout, Left-Opt n will produce Alt N and Right-Opt n will will for a subsequent key press before generating an event; Right-Opt n SPACE will emit ~ whereas Right-Opt n n will emit ñ.

You may also set use_dead_keys = false to skip the hold state; continuing the example above, Right-Opt n will then immediately produce ~.

Input Method Editor (IME)

WezTerm has support for using the operating system Input Method Editor (IME) on some operating systems.

The use_ime docs have more information.

Dead Keys

since: 20201031-154415-9614e117

By default, if you are using a layout with dead keys (eg: US International layout, or a number of European layouts such as German or French) pressing a dead key in wezterm will "hold" the dead key until the next character is pressed, resulting in a combined character with a diacritic. For example, pressing ^ and then e will produce ê. Pressing ^ then SPACE will produce ^ on its own.

If you are a heavy user of Vi style editors then you may wish to disable dead key processing so that ^ can be used with a single keypress.

You can tell WezTerm to disable dead keys by setting this in your configuration file:

return {
  use_dead_keys = false
}

Note that for X11 systems with use_ime=true, depending on the configured IME, the IME may handle dead key processing implicitly. There is no way for wezterm to prevent it from doing that, short of disabling the IME.

Defining Assignments for key combinations that may be composed

When a key combination produces a composed key result, wezterm will look up both the composed and uncomposed versions of the keypress in your key mappings. If either lookup matches your assignment, that will take precedence over the normal key processing.

Configuring Key Assignments

The default key table assignments can be overridden or extended using the keys section in your ~/.wezterm.lua config file. For example, you can disable a default assignment like this:

local wezterm = require 'wezterm';

return {
  keys = {
    -- Turn off the default CMD-m Hide action, allowing CMD-m to
    -- be potentially recognized and handled by the tab
    {key="m", mods="CMD", action="DisableDefaultAssignment"}
  }
}

The action value can be one of the available key assignments. Every action has an example that shows how to use it.

Possible Modifier labels are:

  • SUPER, CMD, WIN - these are all equivalent: on macOS the Command key, on Windows the Windows key, on Linux this can also be the Super or Hyper key. Left and right are equivalent.
  • SHIFT - The shift key. Left and right are equivalent.
  • ALT, OPT, META - these are all equivalent: on macOS the Option key, on other systems the Alt or Meta key. Left and right are equivalent.
  • LEADER - a special modal modifier state managed by wezterm. See Leader Key for more information.
  • VoidSymbol - This keycode is emitted in special cases where the original function of the key has been removed. Such as in Linux and using setxkbmap. setxkbmap -option caps:none. The CapsLock will no longer function as before in all applications, instead emitting VoidSymbol.

You can combine modifiers using the | symbol (eg: "CMD|CTRL").

The key value can be one of the following keycode identifiers. Note that not all of these are meaningful on all platforms:

Hyper, Super, Meta, Cancel, Backspace, Tab, Clear, Enter, Shift, Escape, LeftShift, RightShift, Control, LeftControl, RightControl, Alt, LeftAlt, RightAlt, Menu, LeftMenu, RightMenu, Pause, CapsLock, VoidSymbol, PageUp, PageDown, End, Home, LeftArrow, RightArrow, UpArrow, DownArrow, Select, Print, Execute, PrintScreen, Insert, Delete, Help, LeftWindows, RightWindows, Applications, Sleep, Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9, Multiply, Add, Separator, Subtract, Decimal, Divide, NumLock, ScrollLock, BrowserBack, BrowserForward, BrowserRefresh, BrowserStop, BrowserSearch, BrowserFavorites, BrowserHome, VolumeMute, VolumeDown, VolumeUp, MediaNextTrack, MediaPrevTrack, MediaStop, MediaPlayPause, ApplicationLeftArrow, ApplicationRightArrow, ApplicationUpArrow, ApplicationDownArrow, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24.

Alternatively, a single unicode character can be specified to indicate pressing the corresponding key.

Pay attention to the case of the text that you use and the state of the SHIFT modifier, as key="A" will match

Physical vs Mapped Key Assignments

Since: 20220319-142410-0fcdea07

The key value can refer either to the physical position of a key on an ANSI US keyboard or to the post-keyboard-layout-mapped value produced by a key press.

You can explicitly assign using the physical position by adding a phys: prefix to the value, for example: key="phys:A". This will match key presses for the key that would be in the position of the A key on an ANSI US keyboard.

You can explicitly assign the mapped key by adding a mapped: prefix to the value, for example: key="mapped:a" will match a key press where the OS keyboard layout produces a, regardless of its physical position.

If you omit an explicit prefix, wezterm will assume phys: and use the physical position of the specified key.

The default key assignments listed above use phys:. In previous releases there was no physical position support and those assignments were all mapped:.

When upgrading from earlier releases, if you had {key="N", mods="CMD", ..} in your config, you will need to change it to either {key="N", mods="CMD|SHIFT", ..} or {key="mapped:N", mods="CMD", ..} in order to continue to respect the SHIFT modifier.

Since: 20220408-101518-b908e2dd

A new key_map_preference option controls how keys without an explicit phys: or mapped: prefix are treated. If key_map_preference = "Mapped" (the default), then mapped: is assumed. If key_map_preference = "Physical" then phys: is assumed.

The default key assignments will respect key_map_preference.

Raw Key Assignments

In some cases, wezterm may not know how to represent a key event in either its phys: or mapped: forms. In that case, you may wish to define an assignment in terms of the underlying operating system key code, using a raw: prefix.

Similar in concept to the phys: mapping described above, the raw: mapping is independent of the OS keyboard layout. Raw codes are hardware and windowing system dependent, so there is no portable way to list which key does what.

To discover these values, you can set debug_key_events = true and press the keys of interest.

You can specify a raw key value of 123 by using key="raw:123" in your config rather than one of the other key values.

Leader Key

Since: 20201031-154415-9614e117

A leader key is a a modal modifier key. If leader is specified in the configuration then pressing that key combination will enable a virtual LEADER modifier.

While LEADER is active, only defined key assignments that include LEADER in the mods mask will be recognized. Other keypresses will be swallowed and NOT passed through to the terminal.

LEADER stays active until a keypress is registered (whether it matches a key binding or not), or until it has been active for the duration specified by timeout_milliseconds, at which point it will automatically cancel itself.

Here's an example configuration using LEADER. In this configuration, pressing CTRL-A activates the leader key for up to 1 second (1000 milliseconds). While LEADER is active, the | key (with no other modifiers) will trigger the current pane to be split.

local wezterm = require 'wezterm';

return {
  -- timeout_milliseconds defaults to 1000 and can be omitted
  leader = { key="a", mods="CTRL", timeout_milliseconds=1000 },
  keys = {
    {key="|", mods="LEADER|SHIFT", action=wezterm.action.SplitHorizontal{domain="CurrentPaneDomain"}},
    -- Send "CTRL-A" to the terminal when pressing CTRL-A, CTRL-A
    {key="a", mods="LEADER|CTRL", action=wezterm.action.SendString("\x01")},
  }
}

VoidSymbol

Since: 20210814-124438-54e29167

On X11 systems, If you decide to change certain keys on the keyboard to VoidSymbol (like CapsLock), then you can utilize it as a LEADER or any other part of key bindings. The following example now uses VoidSymbol and uses CapsLock as a LEADER without it affecting the shift / capital state as long as you have setxkbmap -option caps:none configured.

local wezterm = require 'wezterm';

return {
  -- timeout_milliseconds defaults to 1000 and can be omitted
  -- for this example use `setxkbmap -option caps:none` in your terminal.
  leader = { key="VoidSymbol", mods="", timeout_milliseconds=1000 },
  keys = {
    {key="|", mods="LEADER|SHIFT", action=wezterm.action.SplitHorizontal{domain="CurrentPaneDomain"}},
    {key="-", mods="LEADER", action=wezterm.action.SplitVertical{domain="CurrentPaneDomain"}},
  }
}

Available Actions

See the KeyAssignment reference for information on available actions.

Key Tables

Since: 20220408-101518-b908e2dd

In addition to the default key table defined by the keys configuration option, wezterm supports defining additional named key tables using the key_tables configuration option.

On its own, a named table doesn't do anything, but when paired with the ActivateKeyTable action, some powerful keyboard customization is possible.

As a motivating example, let's consider working with panes. In the default config CTRL+SHIFT+ArrowKey will activate a pane in the direction of the arrow key, while CTRL+SHIFT+ALT+ArrowKey will resize a pane in the direction of the arrow key. Our goal is to avoid holding down so many keys at once, or even having to remember so many key combinations, so what we'd like to do is use CTRL-SHIFT-SPACE as a leader prefix to select between resize and activation modes, using r for resize and a for activation:

local wezterm = require 'wezterm'
local act = wezterm.action

-- Show which key table is active in the status area
wezterm.on("update-right-status", function(window, pane)
  local name = window:active_key_table()
  if name then
    name = "TABLE: " .. name
  end
  window:set_right_status(name or "")
end)

return {
  leader = {key="Space", mods="CTRL|SHIFT"},
  keys = {
    -- CTRL+SHIFT+Space, followed by 'r' will put us in resize-pane
    -- mode until we cancel that mode.
    {key="r", mods="LEADER", action=act.ActivateKeyTable{
      name="resize_pane",
      one_shot=false,
    }},

    -- CTRL+SHIFT+Space, followed by 'a' will put us in activate-pane
    -- mode until we press some other key or until 1 second (1000ms)
    -- of time elapses
    {key="a", mods="LEADER", action=act.ActivateKeyTable{
      name="activate_pane",
      timeout_milliseconds=1000,
    }},
  },

  key_tables = {
    -- Defines the keys that are active in our resize-pane mode.
    -- Since we're likely to want to make multiple adjustments,
    -- we made the activation one_shot=false. We therefore need
    -- to define a key assignment for getting out of this mode.
    -- 'resize_pane' here corresponds to the name="resize_pane" in
    -- the key assignments above.
    resize_pane = {
      {key="LeftArrow", action=act.AdjustPaneSize{"Left", 1}},
      {key="h",         action=act.AdjustPaneSize{"Left", 1}},

      {key="RightArrow", action=act.AdjustPaneSize{"Right", 1}},
      {key="l",          action=act.AdjustPaneSize{"Right", 1}},

      {key="UpArrow", action=act.AdjustPaneSize{"Up", 1}},
      {key="k",       action=act.AdjustPaneSize{"Up", 1}},

      {key="DownArrow", action=act.AdjustPaneSize{"Down", 1}},
      {key="j",         action=act.AdjustPaneSize{"Down", 1}},

      -- Cancel the mode by pressing escape
      {key="Escape", action="PopKeyTable"},

    },

    -- Defines the keys that are active in our activate-pane mode.
    -- 'activate_pane' here corresponds to the name="activate_pane" in
    -- the key assignments above.
    activate_pane = {
      {key="LeftArrow", action=act.ActivatePaneDirection("Left")},
      {key="h",         action=act.ActivatePaneDirection("Left")},

      {key="RightArrow", action=act.ActivatePaneDirection("Right")},
      {key="l",          action=act.ActivatePaneDirection("Right")},

      {key="UpArrow", action=act.ActivatePaneDirection("Up")},
      {key="k",       action=act.ActivatePaneDirection("Up")},

      {key="DownArrow", action=act.ActivatePaneDirection("Down")},
      {key="j",         action=act.ActivatePaneDirection("Down")},
    },

  },
}

Key Table Activation Stack

Each wezterm GUI window maintains a stack of activations, which allows you to create complex layering of keyboard customization.

The ActivateKeyTable action will push an entry to the stack, and provides one_shot and timeout_milliseconds fields to affect when/how it will pop itself from the stack, and replace_current to implicitly pop the current entry from the stack.

The PopKeyTable action will explicitly pop an entry from the stack.

The ClearKeyTableStack action will clear the entire stack.

The stack is also cleared when the configuration is reloaded, so if you're working on a complex key table setup and get stuck, you may be able to unstick yourself by re-saving your wezterm configuration to trigger a reload.

Since: 20220624-141144-bd1b7c5d

When resolving a key assignment, the top of stack is first searched for a match, and if one is not found, the next entry on the stack is searched and so on until a match is found.

In previous releases, only a single lookup was performed on the top of the stack.

The new behavior allows key table activations to effectively layer over the top of previously activated key assignments, making it a bit easier to compose key assignments.

Default Shortcut / Key Binding Assignments

The default key assignments are:

ModifiersKeyAction
SUPERcCopyTo="Clipboard"
SUPERvPasteFrom="Clipboard"
CTRL+SHIFTcCopyTo="Clipboard"
CTRL+SHIFTvPasteFrom="Clipboard"
CopyCopyTo="Clipboard"
PastePasteFrom="Clipboard"
CTRLInsertCopyTo="PrimarySelection" (since: 20210203-095643-70a364eb)
SHIFTInsertPasteFrom="PrimarySelection"
SUPERmHide
SUPERnSpawnWindow
CTRL+SHIFTnSpawnWindow
ALTEnterToggleFullScreen
SUPER-DecreaseFontSize
CTRL-DecreaseFontSize
SUPER=IncreaseFontSize
CTRL=IncreaseFontSize
SUPER0ResetFontSize
CTRL0ResetFontSize
SUPERtSpawnTab="CurrentPaneDomain"
CTRL+SHIFTtSpawnTab="CurrentPaneDomain"
SUPER+SHIFTTSpawnTab="DefaultDomain"
SUPERwCloseCurrentTab{confirm=true}
SUPER1ActivateTab=0
SUPER2ActivateTab=1
SUPER3ActivateTab=2
SUPER4ActivateTab=3
SUPER5ActivateTab=4
SUPER6ActivateTab=5
SUPER7ActivateTab=6
SUPER8ActivateTab=7
SUPER9ActivateTab=-1
CTRL+SHIFTwCloseCurrentTab{confirm=true}
CTRL+SHIFT1ActivateTab=0
CTRL+SHIFT2ActivateTab=1
CTRL+SHIFT3ActivateTab=2
CTRL+SHIFT4ActivateTab=3
CTRL+SHIFT5ActivateTab=4
CTRL+SHIFT6ActivateTab=5
CTRL+SHIFT7ActivateTab=6
CTRL+SHIFT8ActivateTab=7
CTRL+SHIFT9ActivateTab=-1
SUPER+SHIFT[ActivateTabRelative=-1
CTRL+SHIFTTabActivateTabRelative=-1
CTRLPageUpActivateTabRelative=-1
SUPER+SHIFT]ActivateTabRelative=1
CTRLTabActivateTabRelative=1
CTRLPageDownActivateTabRelative=1
CTRL+SHIFTPageUpMoveTabRelative=-1
CTRL+SHIFTPageDownMoveTabRelative=1
SHIFTPageUpScrollByPage=-1
SHIFTPageDownScrollByPage=1
SUPERrReloadConfiguration
CTRL+SHIFTRReloadConfiguration
SUPERhHideApplication (macOS only)
SUPERkClearScrollback="ScrollbackOnly"
CTRL+SHIFTKClearScrollback="ScrollbackOnly"
CTRL+SHIFTLShowDebugOverlay (Since: 20210814-124438-54e29167)
SUPERfSearch={CaseSensitiveString=""}
CTRL+SHIFTFSearch={CaseSensitiveString=""}
CTRL+SHIFTXActivateCopyMode
CTRL+SHIFTSpaceQuickSelect (since: 20210502-130208-bff6815d)
CTRL+SHIFT+ALT"SplitVertical={domain="CurrentPaneDomain"}
CTRL+SHIFT+ALT%SplitHorizontal={domain="CurrentPaneDomain"}
CTRL+SHIFT+ALTLeftArrowAdjustPaneSize={"Left", 1}
CTRL+SHIFT+ALTRightArrowAdjustPaneSize={"Right", 1}
CTRL+SHIFT+ALTUpArrowAdjustPaneSize={"Up", 1}
CTRL+SHIFT+ALTDownArrowAdjustPaneSize={"Down", 1}
CTRL+SHIFTLeftArrowActivatePaneDirection="Left"
CTRL+SHIFTRightArrowActivatePaneDirection="Right"
CTRL+SHIFTUpArrowActivatePaneDirection="Up"
CTRL+SHIFTDownArrowActivatePaneDirection="Down"
CTRL+SHIFTZTogglePaneZoomState

If you don't want the default assignments to be registered, you can disable all of them with this configuration; if you chose to do this, you must explicitly register every binding.

return {
  disable_default_key_bindings = true,
}

Keyboard Encoding

When input that doesn't match a key assignment is processed, it is encoded into a byte stream and sent to the PTY associated with the program that is running in the active pane.

The default encoding scheme used by wezterm is xterm compatible, but there are some configuration options that can modify the encoding.

The standard xterm compatible encoding generates events for key presses (but not releases) and can represent the set of keys that existed on terminal hardware of the 1980's.

That scheme has worked well for quite some time, but has some ambiguity due to the way that the Control modifier "shifts" the ASCII representation of keypresses like Control-I to be ASCII Tab, as an example.

CSI-u/fixterms/libtickit

Fix Keyboard Input on Terminals is an attempt at resolving the ambiguous encoding and doing a better job at representing more modifiers. It's not a perfect attempt as there are a number of issues with it.

You can enable support for this encoding by setting enable_csi_u_key_encoding = true, however, it is not recommended as it does change the behavior of some keys in backwards incompatible ways and there isn't a way for applications to detect or request this behavior.

See also: enable_csi_u_key_encoding.

Note that allow_win32_input_mode takes precedence over this option.

Kitty Keyboard Protocol

The Kitty terminal extended and enhanced the CSI-u based encoding scheme with its Comprehensive keyboard handling protocol.

The kitty protocol allows applications to request varying degrees of enhancement over the standard encoding scheme and also allows for more modifier keys (notably: CMD/Super/Windows) to be reported to the application.

enable_kitty_keyboard controls whether wezterm will honor the application requests to modify the keyboard encoding.

Windows

On Windows, allow_win32_input_mode defaults to true which causes wezterm to listen for an escape sequence generated by the ConPTY layer of Windows to enable Win32 Input Mode.

In this mode, key release events as well as events that can distinguish between positional (left/right) modifier keys are generated and this mode provides the best compatibility with win32 console applications such as Far Manager.

allow_win32_input_mode takes precedence over enable_csi_u_key_encoding.

Mouse bindings are configurable, and there are a number of default assignments described below.

The assignments are based around a triggering mouse event which may be combined with a set of modifier keys to produce an action.

By default applications running in the terminal don't respond to the mouse. However, applications can emit escape sequences to request mouse event tracking. When mouse event tracking is enabled, mouse events are NOT matched against the mouse assignments and are instead passed through to the application.

You can bypass the mouse reporting capture by holding down the SHIFT key; that will prevent the event from being passed to the application and allow matching it against your assignments as though the SHIFT key were not pressed.

The bypass_mouse_reporting_modifiers option allows you to specify an alternative set of modifiers to use for bypassing mouse reporting capture.

Default Mouse Assignments

In the table below, Triple Left Down means that the left mouse button is being triple clicked and that the event matches the downstroke of the third quick consecutive press. Triple Left Up matches the subsequent release event of that triple click, so for a triple click both SelectTextAtMouseCursor="Line" and CompleteSelection will be triggered in that order.

NOTE: In the action column, act is an alias to wezterm.action (to avoid repetition).

EventModifiersAction
Triple Left DownNONEact.SelectTextAtMouseCursor("Line")
Double Left DownNONEact.SelectTextAtMouseCursor("Word")
Single Left DownNONEact.SelectTextAtMouseCursor("Cell")
Single Left DownSHIFTact.ExtendSelectionToMouseCursor("Cell")
Single Left DownALTact.SelectTextAtMouseCursor("Block") (since: 20220624-141144-bd1b7c5d)
Single Left UpSHIFTact.CompleteSelectionOrOpenLinkAtMouseCursor("PrimarySelection")
Single Left UpNONEact.CompleteSelectionOrOpenLinkAtMouseCursor("PrimarySelection")
Single Left UpALTact.CompleteSelection("PrimarySelection") (since: 20220624-141144-bd1b7c5d)
Double Left UpNONEact.CompleteSelection("PrimarySelection")
Triple Left UpNONEact.CompleteSelection("PrimarySelection")
Single Left DragNONEact.ExtendSelectionToMouseCursor("Cell")
Single Left DragALTact.ExtendSelectionToMouseCursor("Block") (since: 20220624-141144-bd1b7c5d)
Single Left DownALT+SHIFTact.ExtendSelectionToMouseCursor("Block") (since: 20220624-141144-bd1b7c5d)
Single Left UpALT+SHIFTact.CompleteSelection("PrimarySelection") (since: 20220624-141144-bd1b7c5d)
Double Left DragNONEact.ExtendSelectionToMouseCursor("Word")
Triple Left DragNONEact.ExtendSelectionToMouseCursor("Line")
Single Middle DownNONEact.PasteFrom("PrimarySelection")
Single Left DragSUPERact.StartWindowDrag (since 20210314-114017-04b7cedd)
Single Left DragCTRL+SHIFTact.StartWindowDrag (since 20210314-114017-04b7cedd)

If you don't want the default assignments to be registered, you can disable all of them with this configuration; if you chose to do this, you must explicitly register every binding.

return {
  disable_default_mouse_bindings = true,
}

Configuring Mouse Assignments

since: 20200607-144723-74889cd4

You can define mouse actions using the mouse_bindings configuration section:

local wezterm = require 'wezterm';
local act = wezterm.action

return {
  mouse_bindings = {
    -- Right click sends "woot" to the terminal
    {
      event={Down={streak=1, button="Right"}},
      mods="NONE",
      action=act.SendString("woot"),
    },

    -- Change the default click behavior so that it only selects
    -- text and doesn't open hyperlinks
    {
      event={Up={streak=1, button="Left"}},
      mods="NONE",
      action=act.CompleteSelection("PrimarySelection"),
    },

    -- and make CTRL-Click open hyperlinks
    {
      event={Up={streak=1, button="Left"}},
      mods="CTRL",
      action=act.OpenLinkAtMouseCursor,
    },
    -- NOTE that binding only the 'Up' event can give unexpected behaviors.
    -- Read more below on the gotcha of binding an 'Up' event only.
  },
}

The action and mods portions are described in more detail in the key assignment information below.

The event portion has three components:

  • Whether it is a Down, Up or Drag event
  • The number of consecutive clicks within the click threshold (the click streak)
  • The mouse button; Left, Right, or Middle.

A double click is a down-up-down sequence where either the second button down is held for long enough or is released and no subsequent down event occurs within the click threshold. When recognized, it emits a Down event with streak=2. If the mouse is moved while the button is held, a Drag event with streak=2 is generated. When the mouse button is released an Up event with streak=2 is generated.

The mouse event recognizer supports an arbitrary click streak, so if you wanted quadruple-click bindings you can specify streak=4.

EventLua Representation
Triple Left Downevent={Down={streak=3, button="Left"}}
Double Left Upevent={Up={streak=2, button="Left"}}
Single Left Dragevent={Drag={streak=1, button="Left"}}

Gotcha on binding an 'Up' event only

If you only have a mouse bind on the 'Up' event and not on the 'Down' event, the 'Down' event will still be sent to the running program. If that program is tracking mouse inputs (like tmux or vim with mouse support), you may experience unintuitive behavior as the program receives the 'Down' event, but not the 'Up' event (which is bound to something in your config).

To avoid this, it is recommended to disable the 'Down' event (to ensure it won't be sent to the running program), for example:

local wezterm = require "wezterm"
local act = wezterm.action

return {
  mouse_bindings = {
    -- Bind 'Up' event of CTRL-Click to open hyperlinks
    {
      event={Up={streak=1, button="Left"}},
      mods="CTRL",
      action=act.OpenLinkAtMouseCursor,
    },
    -- Disable the 'Down' event of CTRL-Click to avoid weird program behaviors
    {
      event={Down={streak=1, button="Left"}},
      mods="CTRL",
      action=act.Nop,
    },
  },
}

Available Actions

See the KeyAssignment reference for information on available actions.

Color Scheme

WezTerm ships with the full set of over 200 color schemes available from iTerm2-Color-Schemes. You can select a color scheme with a line like this:

return {
  color_scheme = "Batman",
}

You can find a list of available color schemes and screenshots in The Color Schemes Section.

The color_scheme option takes precedence over the colors section below.

Defining your own colors

Rather than using a color scheme, you can specify the color palette using the colors configuration section. Note that color_scheme takes precedence over this section.

You can configure colors with a section like this. In addition to specifying SVG/CSS3 color names, you can use #RRGGBB to specify a color code using the usual hex notation; eg: #000000 is equivalent to black:

return {
  colors = {
      -- The default text color
      foreground = "silver",
      -- The default background color
      background = "black",

      -- Overrides the cell background color when the current cell is occupied by the
      -- cursor and the cursor style is set to Block
      cursor_bg = "#52ad70",
      -- Overrides the text color when the current cell is occupied by the cursor
      cursor_fg = "black",
      -- Specifies the border color of the cursor when the cursor style is set to Block,
      -- or the color of the vertical or horizontal bar when the cursor style is set to
      -- Bar or Underline.
      cursor_border = "#52ad70",

      -- the foreground color of selected text
      selection_fg = "black",
      -- the background color of selected text
      selection_bg = "#fffacd",

      -- The color of the scrollbar "thumb"; the portion that represents the current viewport
      scrollbar_thumb = "#222222",

      -- The color of the split lines between panes
      split = "#444444",

      ansi = {"black", "maroon", "green", "olive", "navy", "purple", "teal", "silver"},
      brights = {"grey", "red", "lime", "yellow", "blue", "fuchsia", "aqua", "white"},

      -- Arbitrary colors of the palette in the range from 16 to 255
      indexed = {[136] = "#af8700"},

      -- Since: 20220319-142410-0fcdea07
      -- When the IME, a dead key or a leader key are being processed and are effectively
      -- holding input pending the result of input composition, change the cursor
      -- to this color to give a visual cue about the compose state.
      compose_cursor = "orange",
  }
}

Since: 20220101-133340-7edc5b5a

You may specify colors in the HSL color space, if you prefer that over RGB, by using:

return {
  colors = {
      -- the first number is the hue measured in degrees with a range
      -- of 0-360.
      -- The second number is the saturation measured in percentage with
      -- a range of 0-100.
      -- The third number is the lightness measured in percentage with
      -- a range of 0-100.
      foreground = "hsl:235 100 50",
  }
}

Since: 20220319-142410-0fcdea07

Colors now also accept the following CSS-style color specifications:

rgb(0,255,0)
rgb(0% 100% 0%)
rgb(0 255 0 / 100%)
rgba(0,255,0,1)
hsl(120,100%,50%)
hsl(120deg 100% 50%)
hsl(-240 100% 50%)
hsl(-240deg 100% 50%)
hsl(0.3333turn 100% 50%)
hsl(133.333grad 100% 50%)
hsl(2.0944rad 100% 50%)
hsla(120,100%,50%,100%)
hwb(120 0% 0%)
hwb(480deg 0% 0% / 100%)
hsv(120,100%,100%)
hsv(120deg 100% 100% / 100%)

The alpha value is ignored except when used with selection_fg and selection_bg:

return {
  colors = {
    -- Make the selection text color fully transparent.
    -- When fully transparent, the current text color will be used.
    selection_fg = "none",
    -- Set the selection background color with alpha.
    -- When selection_bg is transparent, it will be alpha blended over
    -- the current cell background color, rather than replace it
    selection_bg = "rgba(50% 50% 50% 50%)"
  }
}

Defining a Color Scheme in your .wezterm.lua

If you'd like to keep a couple of color schemes handy in your configuration file, rather than filling out the colors section, place it in a color_schemes section as shown below; you can then reference it using the color_scheme setting.

Color schemes names that you define in your wezterm.lua take precedence over all other color schemes.

All of the settings available from the colors section are available to use in the color_schemes sections.

return {
  color_scheme = "Red Scheme",

  color_schemes = {
    ["Red Scheme"] = {
      background = "red",
    }
    ["Blue Scheme"] = {
      background = "blue",
    }
  },
}

See also wezterm.get_builtin_color_schemes() for some more advanced examples, such as picking a random color scheme, or deriving from a builting color scheme.

Defining a Color Scheme in a separate file

If you'd like to factor your color schemes out into separate files, you can create a file with a [colors] section; take a look at one of the available color schemes for an example.

It is recommended that you place your custom scheme in a directory named $HOME/.config/wezterm/colors if you're on a POSIX system.

On a Windows system, wezterm will search for schemes in a directory named colors that is in the same directory as the wezterm.exe.

If you wish to place your color scheme files in some other location, then you will need to instruct wezterm where to look for your scheme files; the color_scheme_dirs setting specifies a list of directories to be searched:

return {
  color_scheme_dirs = {"/some/path/to/my/color/schemes"},
}

Color scheme names that are defined in files in your color_scheme_dirs list take precedence over the built-in color schemes.

Dynamic Color Escape Sequences

Wezterm supports dynamically changing its color palette via escape sequences.

The dynamic-colors directory of the color scheme repo contains shell scripts that can change the color scheme immediately on the fly. This can be used in your own scripts to alter the terminal appearance programmatically:

$ git clone https://github.com/mbadolato/iTerm2-Color-Schemes.git
$ cd iTerm2-Color-Schemes/dynamic-colors
$ for scheme in *.sh ; do ; echo $scheme ; \
   bash "$scheme" ; ../tools/screenshotTable.sh; sleep 0.5; done

Tab Bar Appearance & Colors

The tab bar has two modes; the default is a native looking style, but is is also possible to enable a retro aesthetic. The configuration for the two styles is broadly similar, but there are a few different details.

Native (Fancy) Tab Bar appearance

The following options affect the fancy tab bar:

local wezterm = require 'wezterm'

return {
  window_frame = {
    -- The font used in the tab bar.
    -- Roboto Bold is the default; this font is bundled
    -- with wezterm.
    -- Whatever font is selected here, it will have the
    -- main font setting appended to it to pick up any
    -- fallback fonts you may have used there.
    font = wezterm.font({family="Roboto", weight="Bold"}),

    -- The size of the font in the tab bar.
    -- Default to 10. on Windows but 12.0 on other systems
    font_size = 12.0,

    -- The overall background color of the tab bar when
    -- the window is focused
    active_titlebar_bg = "#333333",

    -- The overall background color of the tab bar when
    -- the window is not focused
    inactive_titlebar_bg = "#333333",
  },

  colors = {
    tab_bar = {
      -- The color of the inactive tab bar edge/divider
      inactive_tab_edge = "#575757",
    },
  },
}

In addition, the tab bar colors mentioned below also apply to the items displayed in the tab bar.

Retro Tab Bar appearance

The following options control the appearance of the tab bar:

return {
  colors = {
    tab_bar = {
      -- The color of the strip that goes along the top of the window
      -- (does not apply when fancy tab bar is in use)
      background = "#0b0022",

      -- The active tab is the one that has focus in the window
      active_tab = {
        -- The color of the background area for the tab
        bg_color = "#2b2042",
        -- The color of the text for the tab
        fg_color = "#c0c0c0",

        -- Specify whether you want "Half", "Normal" or "Bold" intensity for the
        -- label shown for this tab.
        -- The default is "Normal"
        intensity = "Normal",

        -- Specify whether you want "None", "Single" or "Double" underline for
        -- label shown for this tab.
        -- The default is "None"
        underline = "None",

        -- Specify whether you want the text to be italic (true) or not (false)
        -- for this tab.  The default is false.
        italic = false,

        -- Specify whether you want the text to be rendered with strikethrough (true)
        -- or not for this tab.  The default is false.
        strikethrough = false,
      },

      -- Inactive tabs are the tabs that do not have focus
      inactive_tab = {
        bg_color = "#1b1032",
        fg_color = "#808080",

        -- The same options that were listed under the `active_tab` section above
        -- can also be used for `inactive_tab`.
      },

      -- You can configure some alternate styling when the mouse pointer
      -- moves over inactive tabs
      inactive_tab_hover = {
        bg_color = "#3b3052",
        fg_color = "#909090",
        italic = true,

        -- The same options that were listed under the `active_tab` section above
        -- can also be used for `inactive_tab_hover`.
      },

      -- The new tab button that let you create new tabs
      new_tab = {
        bg_color = "#1b1032",
        fg_color = "#808080",

        -- The same options that were listed under the `active_tab` section above
        -- can also be used for `new_tab`.
      },

      -- You can configure some alternate styling when the mouse pointer
      -- moves over the new tab button
      new_tab_hover = {
        bg_color = "#3b3052",
        fg_color = "#909090",
        italic = true,

        -- The same options that were listed under the `active_tab` section above
        -- can also be used for `new_tab_hover`.
      }
    }
  }
}

Window Padding

You may add padding around the edges of the terminal area.

See the window_padding docs for more info

Styling Inactive Panes

since: 20201031-154415-9614e117

To make it easier to see which pane is active, the inactive panes are dimmed and de-saturated slightly.

You can specify your own transformation to the pane colors with a hue, saturation, brightness (HSB) multipler.

In this example, inactive panes will be slightly de-saturated and dimmed; this is the default configuration:

return {
  inactive_pane_hsb = {
    saturation = 0.9,
    brightness = 0.8,
  }
}

The transform works by converting the RGB colors to HSV values and then multiplying the HSV by the numbers specified in inactive_pane_hsb.

Modifying the hue changes the hue of the color by rotating it through the color wheel. It is not as useful as the other components, but is available "for free" as part of the colorspace conversion.

Modifying the saturation can add or reduce the amount of "colorfulness". Making the value smaller can make it appear more washed out.

Modifying the brightness can be used to dim or increase the perceived amount of light.

The range of these values is 0.0 and up; they are used to multiply the existing values, so the default of 1.0 preserves the existing component, whilst 0.5 will reduce it by half, and 2.0 will double the value.

Window Background Image

Screenshot

since: 20201031-154415-9614e117

You can attach an image to the background of the wezterm window:

return {
  window_background_image = "/path/to/wallpaper.jpg"
}

If the path is a relative path then it will be expanded relative to the directory containing your wezterm.lua config file.

PNG, JPEG, GIF, BMP, ICO, TIFF, PNM, DDS, TGA and farbfeld files can be loaded. Animated GIF and PNG files will animate while the window has focus.

The image will be scaled to fit the window contents. Very large images may decrease render performance and take up VRAM from the GPU, so you may wish to resize the image file before using it.

You can optionally transform the background image by specifying a hue, saturation, brightness multiplier:


return {
  window_background_image = "/path/to/wallpaper.jpg",

  window_background_image_hsb = {
    -- Darken the background image by reducing it to 1/3rd
    brightness = 0.3,

    -- You can adjust the hue by scaling its value.
    -- a multiplier of 1.0 leaves the value unchanged.
    hue = 1.0,

    -- You can adjust the saturation also.
    saturation = 1.0,
  },
}

See Styling Inactive Panes for more information on hue, saturation, brigthness transformations.

Window Background Gradient

Since: 20210814-124438-54e29167

See window_background_gradient for configuration information on gradients.

Window Background Opacity

since: 20201031-154415-9614e117

If your Operating System provides Compositing support then WezTerm is able to specify the alpha channel value for the background content, rendering the window background translucent (some refer to this as transparent rather than translucent) and causing the windows/desktop behind it to show through the window.

macOS, Windows and Wayland support compositing out of the box. X11 may require installing or configuring a compositing window manager. XWayland under Mutter/Wayland also works without any additional configuration.

window_background_opacity specifies the alpha channel value with floating point numbers in the range 0.0 (meaning completely translucent/transparent) through to 1.0 (meaning completely opaque).

Setting this to a value other than the default 1.0 may impact render performance.

return {
  window_background_opacity = 1.0,
}

Text Background Opacity

since: 20201031-154415-9614e117

When using a background image or background opacity, the image content can have relatively low contrast with respect to the text you are trying to read in your terminal.

The text_background_opacity setting specifies the alpha channel value to use for the background color of cells other than the default background color.

The default for this setting is 1.0, which means that the background color is fully opaque.

The range of values permitted are 0.0 (completely translucent) through to 1.0 (completely opaque).

return {
  text_background_opacity = 0.3,
}

Color schemes listed by first letter

3024 Day

3024 Day

To use this scheme, add this to your config:

return {
  color_scheme = "3024 Day",
}

3024 Night

3024 Night

To use this scheme, add this to your config:

return {
  color_scheme = "3024 Night",
}

Abernathy

Abernathy

To use this scheme, add this to your config:

return {
  color_scheme = "Abernathy",
}

Adventure

Adventure

To use this scheme, add this to your config:

return {
  color_scheme = "Adventure",
}

AdventureTime

AdventureTime

To use this scheme, add this to your config:

return {
  color_scheme = "AdventureTime",
}

Afterglow

Afterglow

To use this scheme, add this to your config:

return {
  color_scheme = "Afterglow",
}

Alabaster

Alabaster

To use this scheme, add this to your config:

return {
  color_scheme = "Alabaster",
}

AlienBlood

AlienBlood

To use this scheme, add this to your config:

return {
  color_scheme = "AlienBlood",
}

Andromeda

Andromeda

To use this scheme, add this to your config:

return {
  color_scheme = "Andromeda",
}

Argonaut

Argonaut

To use this scheme, add this to your config:

return {
  color_scheme = "Argonaut",
}

Arthur

Arthur

To use this scheme, add this to your config:

return {
  color_scheme = "Arthur",
}

AtelierSulphurpool

AtelierSulphurpool

To use this scheme, add this to your config:

return {
  color_scheme = "AtelierSulphurpool",
}

Atom

Atom

To use this scheme, add this to your config:

return {
  color_scheme = "Atom",
}

AtomOneLight

AtomOneLight

To use this scheme, add this to your config:

return {
  color_scheme = "AtomOneLight",
}

Aurora

Aurora

To use this scheme, add this to your config:

return {
  color_scheme = "Aurora",
}

Ayu Mirage

Ayu Mirage

To use this scheme, add this to your config:

return {
  color_scheme = "Ayu Mirage",
}

arcoiris

arcoiris

To use this scheme, add this to your config:

return {
  color_scheme = "arcoiris",
}

ayu

ayu

To use this scheme, add this to your config:

return {
  color_scheme = "ayu",
}

ayu_light

ayu_light

To use this scheme, add this to your config:

return {
  color_scheme = "ayu_light",
}

Banana Blueberry

Banana Blueberry

To use this scheme, add this to your config:

return {
  color_scheme = "Banana Blueberry",
}

Batman

Batman

To use this scheme, add this to your config:

return {
  color_scheme = "Batman",
}

Belafonte Day

Belafonte Day

To use this scheme, add this to your config:

return {
  color_scheme = "Belafonte Day",
}

Belafonte Night

Belafonte Night

To use this scheme, add this to your config:

return {
  color_scheme = "Belafonte Night",
}

BirdsOfParadise

BirdsOfParadise

To use this scheme, add this to your config:

return {
  color_scheme = "BirdsOfParadise",
}

Blazer

Blazer

To use this scheme, add this to your config:

return {
  color_scheme = "Blazer",
}

Blue Matrix

Blue Matrix

To use this scheme, add this to your config:

return {
  color_scheme = "Blue Matrix",
}

BlueBerryPie

BlueBerryPie

To use this scheme, add this to your config:

return {
  color_scheme = "BlueBerryPie",
}

BlueDolphin

BlueDolphin

To use this scheme, add this to your config:

return {
  color_scheme = "BlueDolphin",
}

BlulocoDark

BlulocoDark

To use this scheme, add this to your config:

return {
  color_scheme = "BlulocoDark",
}

BlulocoLight

BlulocoLight

To use this scheme, add this to your config:

return {
  color_scheme = "BlulocoLight",
}

Borland

Borland

To use this scheme, add this to your config:

return {
  color_scheme = "Borland",
}

Breeze

Breeze

To use this scheme, add this to your config:

return {
  color_scheme = "Breeze",
}

Bright Lights

Bright Lights

To use this scheme, add this to your config:

return {
  color_scheme = "Bright Lights",
}

Broadcast

Broadcast

To use this scheme, add this to your config:

return {
  color_scheme = "Broadcast",
}

Brogrammer

Brogrammer

To use this scheme, add this to your config:

return {
  color_scheme = "Brogrammer",
}

Builtin Dark

Builtin Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Builtin Dark",
}

Builtin Light

Builtin Light

To use this scheme, add this to your config:

return {
  color_scheme = "Builtin Light",
}

Builtin Pastel Dark

Builtin Pastel Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Builtin Pastel Dark",
}

Builtin Solarized Dark

Builtin Solarized Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Builtin Solarized Dark",
}

Builtin Solarized Light

Builtin Solarized Light

To use this scheme, add this to your config:

return {
  color_scheme = "Builtin Solarized Light",
}

Builtin Tango Dark

Builtin Tango Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Builtin Tango Dark",
}

Builtin Tango Light

Builtin Tango Light

To use this scheme, add this to your config:

return {
  color_scheme = "Builtin Tango Light",
}

C64

C64

To use this scheme, add this to your config:

return {
  color_scheme = "C64",
}

CGA

CGA

To use this scheme, add this to your config:

return {
  color_scheme = "CGA",
}

CLRS

CLRS

To use this scheme, add this to your config:

return {
  color_scheme = "CLRS",
}

Calamity

Calamity

To use this scheme, add this to your config:

return {
  color_scheme = "Calamity",
}

Chalk

Chalk

To use this scheme, add this to your config:

return {
  color_scheme = "Chalk",
}

Chalkboard

Chalkboard

To use this scheme, add this to your config:

return {
  color_scheme = "Chalkboard",
}

ChallengerDeep

ChallengerDeep

To use this scheme, add this to your config:

return {
  color_scheme = "ChallengerDeep",
}

Chester

Chester

To use this scheme, add this to your config:

return {
  color_scheme = "Chester",
}

Ciapre

Ciapre

To use this scheme, add this to your config:

return {
  color_scheme = "Ciapre",
}

Cobalt Neon

Cobalt Neon

To use this scheme, add this to your config:

return {
  color_scheme = "Cobalt Neon",
}

Cobalt2

Cobalt2

To use this scheme, add this to your config:

return {
  color_scheme = "Cobalt2",
}

CrayonPonyFish

CrayonPonyFish

To use this scheme, add this to your config:

return {
  color_scheme = "CrayonPonyFish",
}

Cyberdyne

Cyberdyne

To use this scheme, add this to your config:

return {
  color_scheme = "Cyberdyne",
}

coffee_theme

coffee_theme

To use this scheme, add this to your config:

return {
  color_scheme = "coffee_theme",
}

cyberpunk

cyberpunk

To use this scheme, add this to your config:

return {
  color_scheme = "cyberpunk",
}

Dark Pastel

Dark Pastel

To use this scheme, add this to your config:

return {
  color_scheme = "Dark Pastel",
}

Dark+

Dark+

To use this scheme, add this to your config:

return {
  color_scheme = "Dark+",
}

Darkside

Darkside

To use this scheme, add this to your config:

return {
  color_scheme = "Darkside",
}

Desert

Desert

To use this scheme, add this to your config:

return {
  color_scheme = "Desert",
}

DimmedMonokai

DimmedMonokai

To use this scheme, add this to your config:

return {
  color_scheme = "DimmedMonokai",
}

Django

Django

To use this scheme, add this to your config:

return {
  color_scheme = "Django",
}

DjangoRebornAgain

DjangoRebornAgain

To use this scheme, add this to your config:

return {
  color_scheme = "DjangoRebornAgain",
}

DjangoSmooth

DjangoSmooth

To use this scheme, add this to your config:

return {
  color_scheme = "DjangoSmooth",
}

Doom Peacock

Doom Peacock

To use this scheme, add this to your config:

return {
  color_scheme = "Doom Peacock",
}

DoomOne

DoomOne

To use this scheme, add this to your config:

return {
  color_scheme = "DoomOne",
}

DotGov

DotGov

To use this scheme, add this to your config:

return {
  color_scheme = "DotGov",
}

Dracula+

Dracula+

To use this scheme, add this to your config:

return {
  color_scheme = "Dracula+",
}

Dracula

Dracula

To use this scheme, add this to your config:

return {
  color_scheme = "Dracula",
}

Duotone Dark

Duotone Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Duotone Dark",
}

darkermatrix

darkermatrix

To use this scheme, add this to your config:

return {
  color_scheme = "darkermatrix",
}

darkmatrix

darkmatrix

To use this scheme, add this to your config:

return {
  color_scheme = "darkmatrix",
}

deep

deep

To use this scheme, add this to your config:

return {
  color_scheme = "deep",
}

duckbones

duckbones

To use this scheme, add this to your config:

return {
  color_scheme = "duckbones",
}

ENCOM

ENCOM

To use this scheme, add this to your config:

return {
  color_scheme = "ENCOM",
}

Earthsong

Earthsong

To use this scheme, add this to your config:

return {
  color_scheme = "Earthsong",
}

Elemental

Elemental

To use this scheme, add this to your config:

return {
  color_scheme = "Elemental",
}

Elementary

Elementary

To use this scheme, add this to your config:

return {
  color_scheme = "Elementary",
}

Espresso Libre

Espresso Libre

To use this scheme, add this to your config:

return {
  color_scheme = "Espresso Libre",
}

Espresso

Espresso

To use this scheme, add this to your config:

return {
  color_scheme = "Espresso",
}

Fahrenheit

Fahrenheit

To use this scheme, add this to your config:

return {
  color_scheme = "Fahrenheit",
}

Fairyfloss

Fairyfloss

To use this scheme, add this to your config:

return {
  color_scheme = "Fairyfloss",
}

Fideloper

Fideloper

To use this scheme, add this to your config:

return {
  color_scheme = "Fideloper",
}

FirefoxDev

FirefoxDev

To use this scheme, add this to your config:

return {
  color_scheme = "FirefoxDev",
}

Firewatch

Firewatch

To use this scheme, add this to your config:

return {
  color_scheme = "Firewatch",
}

FishTank

FishTank

To use this scheme, add this to your config:

return {
  color_scheme = "FishTank",
}

Flat

Flat

To use this scheme, add this to your config:

return {
  color_scheme = "Flat",
}

Flatland

Flatland

To use this scheme, add this to your config:

return {
  color_scheme = "Flatland",
}

Floraverse

Floraverse

To use this scheme, add this to your config:

return {
  color_scheme = "Floraverse",
}

ForestBlue

ForestBlue

To use this scheme, add this to your config:

return {
  color_scheme = "ForestBlue",
}

Framer

Framer

To use this scheme, add this to your config:

return {
  color_scheme = "Framer",
}

FrontEndDelight

FrontEndDelight

To use this scheme, add this to your config:

return {
  color_scheme = "FrontEndDelight",
}

FunForrest

FunForrest

To use this scheme, add this to your config:

return {
  color_scheme = "FunForrest",
}

Galaxy

Galaxy

To use this scheme, add this to your config:

return {
  color_scheme = "Galaxy",
}

Galizur

Galizur

To use this scheme, add this to your config:

return {
  color_scheme = "Galizur",
}

GitHub Dark

GitHub Dark

To use this scheme, add this to your config:

return {
  color_scheme = "GitHub Dark",
}

Github

Github

To use this scheme, add this to your config:

return {
  color_scheme = "Github",
}

Glacier

Glacier

To use this scheme, add this to your config:

return {
  color_scheme = "Glacier",
}

Grape

Grape

To use this scheme, add this to your config:

return {
  color_scheme = "Grape",
}

Grass

Grass

To use this scheme, add this to your config:

return {
  color_scheme = "Grass",
}

Grey-green

Grey-green

To use this scheme, add this to your config:

return {
  color_scheme = "Grey-green",
}

Gruvbox Dark

Gruvbox Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Gruvbox Dark",
}

Gruvbox Light

Gruvbox Light

To use this scheme, add this to your config:

return {
  color_scheme = "Gruvbox Light",
}

Guezwhoz

Guezwhoz

To use this scheme, add this to your config:

return {
  color_scheme = "Guezwhoz",
}

HaX0R_BLUE

HaX0R_BLUE

To use this scheme, add this to your config:

return {
  color_scheme = "HaX0R_BLUE",
}

HaX0R_GR33N

HaX0R_GR33N

To use this scheme, add this to your config:

return {
  color_scheme = "HaX0R_GR33N",
}

HaX0R_R3D

HaX0R_R3D

To use this scheme, add this to your config:

return {
  color_scheme = "HaX0R_R3D",
}

Hacktober

Hacktober

To use this scheme, add this to your config:

return {
  color_scheme = "Hacktober",
}

Hardcore

Hardcore

To use this scheme, add this to your config:

return {
  color_scheme = "Hardcore",
}

Harper

Harper

To use this scheme, add this to your config:

return {
  color_scheme = "Harper",
}

Highway

Highway

To use this scheme, add this to your config:

return {
  color_scheme = "Highway",
}

Hipster Green

Hipster Green

To use this scheme, add this to your config:

return {
  color_scheme = "Hipster Green",
}

Hivacruz

Hivacruz

To use this scheme, add this to your config:

return {
  color_scheme = "Hivacruz",
}

Homebrew

Homebrew

To use this scheme, add this to your config:

return {
  color_scheme = "Homebrew",
}

Hopscotch.256

Hopscotch.256

To use this scheme, add this to your config:

return {
  color_scheme = "Hopscotch.256",
}

Hopscotch

Hopscotch

To use this scheme, add this to your config:

return {
  color_scheme = "Hopscotch",
}

Hurtado

Hurtado

To use this scheme, add this to your config:

return {
  color_scheme = "Hurtado",
}

Hybrid

Hybrid

To use this scheme, add this to your config:

return {
  color_scheme = "Hybrid",
}

IC_Green_PPL

IC_Green_PPL

To use this scheme, add this to your config:

return {
  color_scheme = "IC_Green_PPL",
}

IC_Orange_PPL

IC_Orange_PPL

To use this scheme, add this to your config:

return {
  color_scheme = "IC_Orange_PPL",
}

IR_Black

IR_Black

To use this scheme, add this to your config:

return {
  color_scheme = "IR_Black",
}

iceberg-dark

iceberg-dark

To use this scheme, add this to your config:

return {
  color_scheme = "iceberg-dark",
}

iceberg-light

iceberg-light

To use this scheme, add this to your config:

return {
  color_scheme = "iceberg-light",
}

idea

idea

To use this scheme, add this to your config:

return {
  color_scheme = "idea",
}

idleToes

idleToes

To use this scheme, add this to your config:

return {
  color_scheme = "idleToes",
}

Jackie Brown

Jackie Brown

To use this scheme, add this to your config:

return {
  color_scheme = "Jackie Brown",
}

Japanesque

Japanesque

To use this scheme, add this to your config:

return {
  color_scheme = "Japanesque",
}

Jellybeans

Jellybeans

To use this scheme, add this to your config:

return {
  color_scheme = "Jellybeans",
}

JetBrains Darcula

JetBrains Darcula

To use this scheme, add this to your config:

return {
  color_scheme = "JetBrains Darcula",
}

jubi

jubi

To use this scheme, add this to your config:

return {
  color_scheme = "jubi",
}

Kibble

Kibble

To use this scheme, add this to your config:

return {
  color_scheme = "Kibble",
}

Kolorit

Kolorit

To use this scheme, add this to your config:

return {
  color_scheme = "Kolorit",
}

Konsolas

Konsolas

To use this scheme, add this to your config:

return {
  color_scheme = "Konsolas",
}

kanagawabones

kanagawabones

To use this scheme, add this to your config:

return {
  color_scheme = "kanagawabones",
}

Lab Fox

Lab Fox

To use this scheme, add this to your config:

return {
  color_scheme = "Lab Fox",
}

Laser

Laser

To use this scheme, add this to your config:

return {
  color_scheme = "Laser",
}

Later This Evening

Later This Evening

To use this scheme, add this to your config:

return {
  color_scheme = "Later This Evening",
}

Lavandula

Lavandula

To use this scheme, add this to your config:

return {
  color_scheme = "Lavandula",
}

LiquidCarbon

LiquidCarbon

To use this scheme, add this to your config:

return {
  color_scheme = "LiquidCarbon",
}

LiquidCarbonTransparent

LiquidCarbonTransparent

To use this scheme, add this to your config:

return {
  color_scheme = "LiquidCarbonTransparent",
}

LiquidCarbonTransparentInverse

LiquidCarbonTransparentInverse

To use this scheme, add this to your config:

return {
  color_scheme = "LiquidCarbonTransparentInverse",
}

lovelace

lovelace

To use this scheme, add this to your config:

return {
  color_scheme = "lovelace",
}

Man Page

Man Page

To use this scheme, add this to your config:

return {
  color_scheme = "Man Page",
}

Mariana

Mariana

To use this scheme, add this to your config:

return {
  color_scheme = "Mariana",
}

Material

Material

To use this scheme, add this to your config:

return {
  color_scheme = "Material",
}

MaterialDark

MaterialDark

To use this scheme, add this to your config:

return {
  color_scheme = "MaterialDark",
}

MaterialDarker

MaterialDarker

To use this scheme, add this to your config:

return {
  color_scheme = "MaterialDarker",
}

MaterialDesignColors

MaterialDesignColors

To use this scheme, add this to your config:

return {
  color_scheme = "MaterialDesignColors",
}

MaterialOcean

MaterialOcean

To use this scheme, add this to your config:

return {
  color_scheme = "MaterialOcean",
}

Mathias

Mathias

To use this scheme, add this to your config:

return {
  color_scheme = "Mathias",
}

Medallion

Medallion

To use this scheme, add this to your config:

return {
  color_scheme = "Medallion",
}

Mirage

Mirage

To use this scheme, add this to your config:

return {
  color_scheme = "Mirage",
}

Misterioso

Misterioso

To use this scheme, add this to your config:

return {
  color_scheme = "Misterioso",
}

Molokai

Molokai

To use this scheme, add this to your config:

return {
  color_scheme = "Molokai",
}

MonaLisa

MonaLisa

To use this scheme, add this to your config:

return {
  color_scheme = "MonaLisa",
}

Monokai Remastered

Monokai Remastered

To use this scheme, add this to your config:

return {
  color_scheme = "Monokai Remastered",
}

Monokai Soda

Monokai Soda

To use this scheme, add this to your config:

return {
  color_scheme = "Monokai Soda",
}

Monokai Vivid

Monokai Vivid

To use this scheme, add this to your config:

return {
  color_scheme = "Monokai Vivid",
}

matrix

matrix

To use this scheme, add this to your config:

return {
  color_scheme = "matrix",
}

midnight-in-mojave

midnight-in-mojave

To use this scheme, add this to your config:

return {
  color_scheme = "midnight-in-mojave",
}

N0tch2k

N0tch2k

To use this scheme, add this to your config:

return {
  color_scheme = "N0tch2k",
}

Neon

Neon

To use this scheme, add this to your config:

return {
  color_scheme = "Neon",
}

Neopolitan

Neopolitan

To use this scheme, add this to your config:

return {
  color_scheme = "Neopolitan",
}

Neutron

Neutron

To use this scheme, add this to your config:

return {
  color_scheme = "Neutron",
}

Night Owlish Light

Night Owlish Light

To use this scheme, add this to your config:

return {
  color_scheme = "Night Owlish Light",
}

NightLion v1

NightLion v1

To use this scheme, add this to your config:

return {
  color_scheme = "NightLion v1",
}

NightLion v2

NightLion v2

To use this scheme, add this to your config:

return {
  color_scheme = "NightLion v2",
}

Nocturnal Winter

Nocturnal Winter

To use this scheme, add this to your config:

return {
  color_scheme = "Nocturnal Winter",
}

Novel

Novel

To use this scheme, add this to your config:

return {
  color_scheme = "Novel",
}

neobones_dark

neobones_dark

To use this scheme, add this to your config:

return {
  color_scheme = "neobones_dark",
}

neobones_light

neobones_light

To use this scheme, add this to your config:

return {
  color_scheme = "neobones_light",
}

nord-light

nord-light

To use this scheme, add this to your config:

return {
  color_scheme = "nord-light",
}

nord

nord

To use this scheme, add this to your config:

return {
  color_scheme = "nord",
}

Obsidian

Obsidian

To use this scheme, add this to your config:

return {
  color_scheme = "Obsidian",
}

Ocean

Ocean

To use this scheme, add this to your config:

return {
  color_scheme = "Ocean",
}

OceanicMaterial

OceanicMaterial

To use this scheme, add this to your config:

return {
  color_scheme = "OceanicMaterial",
}

Ollie

Ollie

To use this scheme, add this to your config:

return {
  color_scheme = "Ollie",
}

OneHalfDark

OneHalfDark

To use this scheme, add this to your config:

return {
  color_scheme = "OneHalfDark",
}

OneHalfLight

OneHalfLight

To use this scheme, add this to your config:

return {
  color_scheme = "OneHalfLight",
}

Operator Mono Dark

Operator Mono Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Operator Mono Dark",
}

Overnight Slumber

Overnight Slumber

To use this scheme, add this to your config:

return {
  color_scheme = "Overnight Slumber",
}

PaleNightHC

PaleNightHC

To use this scheme, add this to your config:

return {
  color_scheme = "PaleNightHC",
}

Pandora

Pandora

To use this scheme, add this to your config:

return {
  color_scheme = "Pandora",
}

Paraiso Dark

Paraiso Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Paraiso Dark",
}

PaulMillr

PaulMillr

To use this scheme, add this to your config:

return {
  color_scheme = "PaulMillr",
}

PencilDark

PencilDark

To use this scheme, add this to your config:

return {
  color_scheme = "PencilDark",
}

PencilLight

PencilLight

To use this scheme, add this to your config:

return {
  color_scheme = "PencilLight",
}

Peppermint

Peppermint

To use this scheme, add this to your config:

return {
  color_scheme = "Peppermint",
}

Piatto Light

Piatto Light

To use this scheme, add this to your config:

return {
  color_scheme = "Piatto Light",
}

Pnevma

Pnevma

To use this scheme, add this to your config:

return {
  color_scheme = "Pnevma",
}

Popping and Locking

Popping and Locking

To use this scheme, add this to your config:

return {
  color_scheme = "Popping and Locking",
}

Pro Light

Pro Light

To use this scheme, add this to your config:

return {
  color_scheme = "Pro Light",
}

Pro

Pro

To use this scheme, add this to your config:

return {
  color_scheme = "Pro",
}

Purple Rain

Purple Rain

To use this scheme, add this to your config:

return {
  color_scheme = "Purple Rain",
}

primary

primary

To use this scheme, add this to your config:

return {
  color_scheme = "primary",
}

purplepeter

purplepeter

To use this scheme, add this to your config:

return {
  color_scheme = "purplepeter",
}

Rapture

Rapture

To use this scheme, add this to your config:

return {
  color_scheme = "Rapture",
}

Raycast_Dark

Raycast_Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Raycast_Dark",
}

Raycast_Light

Raycast_Light

To use this scheme, add this to your config:

return {
  color_scheme = "Raycast_Light",
}

Red Alert

Red Alert

To use this scheme, add this to your config:

return {
  color_scheme = "Red Alert",
}

Red Planet

Red Planet

To use this scheme, add this to your config:

return {
  color_scheme = "Red Planet",
}

Red Sands

Red Sands

To use this scheme, add this to your config:

return {
  color_scheme = "Red Sands",
}

Relaxed

Relaxed

To use this scheme, add this to your config:

return {
  color_scheme = "Relaxed",
}

Retro

Retro

To use this scheme, add this to your config:

return {
  color_scheme = "Retro",
}

Rippedcasts

Rippedcasts

To use this scheme, add this to your config:

return {
  color_scheme = "Rippedcasts",
}

Rouge 2

Rouge 2

To use this scheme, add this to your config:

return {
  color_scheme = "Rouge 2",
}

Royal

Royal

To use this scheme, add this to your config:

return {
  color_scheme = "Royal",
}

Ryuuko

Ryuuko

To use this scheme, add this to your config:

return {
  color_scheme = "Ryuuko",
}

rebecca

rebecca

To use this scheme, add this to your config:

return {
  color_scheme = "rebecca",
}

Sakura

Sakura

To use this scheme, add this to your config:

return {
  color_scheme = "Sakura",
}

Scarlet Protocol

Scarlet Protocol

To use this scheme, add this to your config:

return {
  color_scheme = "Scarlet Protocol",
}

SeaShells

SeaShells

To use this scheme, add this to your config:

return {
  color_scheme = "SeaShells",
}

Seafoam Pastel

Seafoam Pastel

To use this scheme, add this to your config:

return {
  color_scheme = "Seafoam Pastel",
}

Seti

Seti

To use this scheme, add this to your config:

return {
  color_scheme = "Seti",
}

Shaman

Shaman

To use this scheme, add this to your config:

return {
  color_scheme = "Shaman",
}

Slate

Slate

To use this scheme, add this to your config:

return {
  color_scheme = "Slate",
}

SleepyHollow

SleepyHollow

To use this scheme, add this to your config:

return {
  color_scheme = "SleepyHollow",
}

Smyck

Smyck

To use this scheme, add this to your config:

return {
  color_scheme = "Smyck",
}

Snazzy

Snazzy

To use this scheme, add this to your config:

return {
  color_scheme = "Snazzy",
}

SoftServer

SoftServer

To use this scheme, add this to your config:

return {
  color_scheme = "SoftServer",
}

Solarized Darcula

Solarized Darcula

To use this scheme, add this to your config:

return {
  color_scheme = "Solarized Darcula",
}

Solarized Dark - Patched

Solarized Dark - Patched

To use this scheme, add this to your config:

return {
  color_scheme = "Solarized Dark - Patched",
}

Solarized Dark Higher Contrast

Solarized Dark Higher Contrast

To use this scheme, add this to your config:

return {
  color_scheme = "Solarized Dark Higher Contrast",
}

SpaceGray Eighties Dull

SpaceGray Eighties Dull

To use this scheme, add this to your config:

return {
  color_scheme = "SpaceGray Eighties Dull",
}

SpaceGray Eighties

SpaceGray Eighties

To use this scheme, add this to your config:

return {
  color_scheme = "SpaceGray Eighties",
}

SpaceGray

SpaceGray

To use this scheme, add this to your config:

return {
  color_scheme = "SpaceGray",
}

Spacedust

Spacedust

To use this scheme, add this to your config:

return {
  color_scheme = "Spacedust",
}

Spiderman

Spiderman

To use this scheme, add this to your config:

return {
  color_scheme = "Spiderman",
}

Spring

Spring

To use this scheme, add this to your config:

return {
  color_scheme = "Spring",
}

Square

Square

To use this scheme, add this to your config:

return {
  color_scheme = "Square",
}

Sublette

Sublette

To use this scheme, add this to your config:

return {
  color_scheme = "Sublette",
}

Subliminal

Subliminal

To use this scheme, add this to your config:

return {
  color_scheme = "Subliminal",
}

Sundried

Sundried

To use this scheme, add this to your config:

return {
  color_scheme = "Sundried",
}

Symfonic

Symfonic

To use this scheme, add this to your config:

return {
  color_scheme = "Symfonic",
}

seoulbones_dark

seoulbones_dark

To use this scheme, add this to your config:

return {
  color_scheme = "seoulbones_dark",
}

seoulbones_light

seoulbones_light

To use this scheme, add this to your config:

return {
  color_scheme = "seoulbones_light",
}

shades-of-purple

shades-of-purple

To use this scheme, add this to your config:

return {
  color_scheme = "shades-of-purple",
}

synthwave-everything

synthwave-everything

To use this scheme, add this to your config:

return {
  color_scheme = "synthwave-everything",
}

synthwave

synthwave

To use this scheme, add this to your config:

return {
  color_scheme = "synthwave",
}

Tango Adapted

Tango Adapted

To use this scheme, add this to your config:

return {
  color_scheme = "Tango Adapted",
}

Tango Half Adapted

Tango Half Adapted

To use this scheme, add this to your config:

return {
  color_scheme = "Tango Half Adapted",
}

Teerb

Teerb

To use this scheme, add this to your config:

return {
  color_scheme = "Teerb",
}

Terminal Basic

Terminal Basic

To use this scheme, add this to your config:

return {
  color_scheme = "Terminal Basic",
}

Thayer Bright

Thayer Bright

To use this scheme, add this to your config:

return {
  color_scheme = "Thayer Bright",
}

The Hulk

The Hulk

To use this scheme, add this to your config:

return {
  color_scheme = "The Hulk",
}

Tinacious Design (Dark)

Tinacious Design (Dark)

To use this scheme, add this to your config:

return {
  color_scheme = "Tinacious Design (Dark)",
}

Tinacious Design (Light)

Tinacious Design (Light)

To use this scheme, add this to your config:

return {
  color_scheme = "Tinacious Design (Light)",
}

Tomorrow Night Blue

Tomorrow Night Blue

To use this scheme, add this to your config:

return {
  color_scheme = "Tomorrow Night Blue",
}

Tomorrow Night Bright

Tomorrow Night Bright

To use this scheme, add this to your config:

return {
  color_scheme = "Tomorrow Night Bright",
}

Tomorrow Night Burns

Tomorrow Night Burns

To use this scheme, add this to your config:

return {
  color_scheme = "Tomorrow Night Burns",
}

Tomorrow Night Eighties

Tomorrow Night Eighties

To use this scheme, add this to your config:

return {
  color_scheme = "Tomorrow Night Eighties",
}

Tomorrow Night

Tomorrow Night

To use this scheme, add this to your config:

return {
  color_scheme = "Tomorrow Night",
}

Tomorrow

Tomorrow

To use this scheme, add this to your config:

return {
  color_scheme = "Tomorrow",
}

ToyChest

ToyChest

To use this scheme, add this to your config:

return {
  color_scheme = "ToyChest",
}

Treehouse

Treehouse

To use this scheme, add this to your config:

return {
  color_scheme = "Treehouse",
}

Twilight

Twilight

To use this scheme, add this to your config:

return {
  color_scheme = "Twilight",
}

tokyonight-day

tokyonight-day

To use this scheme, add this to your config:

return {
  color_scheme = "tokyonight-day",
}

tokyonight-storm

tokyonight-storm

To use this scheme, add this to your config:

return {
  color_scheme = "tokyonight-storm",
}

tokyonight

tokyonight

To use this scheme, add this to your config:

return {
  color_scheme = "tokyonight",
}

Ubuntu

Ubuntu

To use this scheme, add this to your config:

return {
  color_scheme = "Ubuntu",
}

UltraDark

UltraDark

To use this scheme, add this to your config:

return {
  color_scheme = "UltraDark",
}

UltraViolent

UltraViolent

To use this scheme, add this to your config:

return {
  color_scheme = "UltraViolent",
}

UnderTheSea

UnderTheSea

To use this scheme, add this to your config:

return {
  color_scheme = "UnderTheSea",
}

Unikitty

Unikitty

To use this scheme, add this to your config:

return {
  color_scheme = "Unikitty",
}

Urple

Urple

To use this scheme, add this to your config:

return {
  color_scheme = "Urple",
}

Vaughn

Vaughn

To use this scheme, add this to your config:

return {
  color_scheme = "Vaughn",
}

VibrantInk

VibrantInk

To use this scheme, add this to your config:

return {
  color_scheme = "VibrantInk",
}

Violet Dark

Violet Dark

To use this scheme, add this to your config:

return {
  color_scheme = "Violet Dark",
}

Violet Light

Violet Light

To use this scheme, add this to your config:

return {
  color_scheme = "Violet Light",
}

vimbones

vimbones

To use this scheme, add this to your config:

return {
  color_scheme = "vimbones",
}

WarmNeon

WarmNeon

To use this scheme, add this to your config:

return {
  color_scheme = "WarmNeon",
}

Wez

Wez

To use this scheme, add this to your config:

return {
  color_scheme = "Wez",
}

Whimsy

Whimsy

To use this scheme, add this to your config:

return {
  color_scheme = "Whimsy",
}

WildCherry

WildCherry

To use this scheme, add this to your config:

return {
  color_scheme = "WildCherry",
}

Wombat

Wombat

To use this scheme, add this to your config:

return {
  color_scheme = "Wombat",
}

Wryan

Wryan

To use this scheme, add this to your config:

return {
  color_scheme = "Wryan",
}

Zenburn

Zenburn

To use this scheme, add this to your config:

return {
  color_scheme = "Zenburn",
}

zenbones

zenbones

To use this scheme, add this to your config:

return {
  color_scheme = "zenbones",
}

zenbones_dark

zenbones_dark

To use this scheme, add this to your config:

return {
  color_scheme = "zenbones_dark",
}

zenbones_light

zenbones_light

To use this scheme, add this to your config:

return {
  color_scheme = "zenbones_light",
}

zenburned

zenburned

To use this scheme, add this to your config:

return {
  color_scheme = "zenburned",
}

zenwritten_dark

zenwritten_dark

To use this scheme, add this to your config:

return {
  color_scheme = "zenwritten_dark",
}

zenwritten_light

zenwritten_light

To use this scheme, add this to your config:

return {
  color_scheme = "zenwritten_light",
}

Scrollback

WezTerm provides a searchable scrollback buffer with a configurable maximum size limit that allows you to review information that doesn't fit in the physical window size. As content is printed to the display the display may be scrolled up to accommodate newly added lines. The scrolled lines are moved into the scrollback buffer and can be reviewed by scrolling the window up or down.

This section describes working with the scrollback and discusses some configuration options; be sure to read the configuration docs to learn how to change your settings!

Controlling the scrollback size

This value serves as an upper bound on the number of lines. The larger this value, the more memory is required to manage the tab. If you have a lot of long lived tabs then making this value very large may put some pressure on your system depending on the amount of RAM you have available.

return {
  -- How many lines of scrollback you want to retain per tab
  scrollback_lines = 3500,
}

Clearing the scrollback buffer

By default, CTRL-SHIFT-K and CMD-K will trigger the ClearScrollback action and discard the contents of the scrollback buffer. There is no way to undo discarding the scrollback.

See the ClearScrollback docs for information on rebinding this key.

Enable/Disable scrollbar

You can control whether WezTerm displays a scrollbar via your configuration file:

return {
  -- Enable the scrollbar.
  -- It will occupy the right window padding space.
  -- If right padding is set to 0 then it will be increased
  -- to a single cell width
  enable_scroll_bar = true,
}

You may change the color of the scrollbar if you wish!

Scrolling without a scrollbar

By default, SHIFT-PageUp and SHIFT-PageDown will adjust the viewport scrollback position by one full screen for each press.

See the ScrollByPage docs for more information on this key binding assignment.

Searching the scrollback

By default, CTRL-SHIFT-F and CMD-F (F for Find) will activate the search overlay in the current tab.

When the search overlay is active the behavior of wezterm changes:

  • Typing (or pasting) text will populate the search pattern in the bar at the bottom of the screen.
  • Text from the scrollback that matches the search pattern will be highlighted and the number of matches shown in the search bar.
  • The bottom-most match will be selected and the viewport scrolled to show the selected text.
  • Enter, UpArrow and CTRL-P will cause the selection to move to any prior matching text.
  • PageUp will traverse to previous matches one page at a time.
  • CTRL-N and DownArrow will cause the selection to move to any next matching text.
  • PageDown will traverse to the next match one page at a time.
  • CTRL-R will cycle through the pattern matching mode; the initial mode is case-sensitive text matching, the next will match ignoring case and the last will match using the regular expression syntax described here. The matching mode is indicated in the search bar.
  • CTRL-U will clear the search pattern so you can start over.
  • CTRL-SHIFT-C will copy the selected text to the clipboard.
  • Escape will cancel the search overlay, leaving the currently selected text selected with the viewport scrolled to that location.

Configurable search mode key assignments

Since: 20220624-141144-bd1b7c5d

The key assignments for copy mode are specified by the search_mode Key Table.

You may provide your own definition of this key table if you wish to customize it. There isn't a way to override portions of the key table, only to replace the entire table.

The default configuration is equivalent to:

local wezterm = require 'wezterm'
local act = wezterm.action

return {
  key_tables = {
    search_mode = {
      {key="Escape", mods="NONE", action=act.CopyMode("Close")},
      {key="UpArrow", mods="NONE", action=act.CopyMode("PriorMatch")},
      {key="Enter", mods="NONE", action=act.CopyMode("PriorMatch")},
      {key="p", mods="CTRL", action=act.CopyMode("PriorMatch")},
      {key="PageUp", mods="NONE", action=act.CopyMode("PriorMatchPage")},
      {key="PageDown", mods="NONE", action=act.CopyMode("NextMatchPage")},
      {key="n", mods="CTRL", action=act.CopyMode("NextMatchPage")},
      {key="DownArrow", mods="NONE", action=act.CopyMode("NextMatch")},
      {key="r", mods="CTRL", action=act.CopyMode("CycleMatchType")},
      {key="u", mods="CTRL", action=act.CopyMode("ClearPattern")},
    }
  }
}

(Those assignments reference CopyMode because search mode is a facet of Copy Mode).

Configuring Saved Searches

since: 20200607-144723-74889cd4

If you find that you're often searching for the same things then you may wish to assign a keybinding to trigger that search.

For example, if you find that you're frequently running git log and then reaching for your mouse to copy and paste a relevant git commit hash then you might like this:

local wezterm = require 'wezterm';
return {
  keys = {
    -- search for things that look like git hashes
    {key="H", mods="SHIFT|CTRL", action=wezterm.action.Search{Regex="[a-f0-9]{6,}"}},
  },
}

With that in your config you can now:

  • CTRL-SHIFT-H to highlight all the git hashes and select the closest one to the bottom of the screen.
  • Use ENTER/CTRL-N/CTRL-P to cycle through the git hashes
  • CTRL-SHIFT-C to copy
  • Escape
  • CTRL-SHIFT-V (or SHIFT-Insert) to Paste

without needing to reach for your mouse.

See the Search action docs for more information on using the Search action.

Quick Select Mode

Since: 20210502-154244-3f7122cb

Quick Select mode allows you to quickly highlight text that matches commonly copied patterns, select a match by typing a one-or-two character prefix and copy it to the clipboard.

The QuickSelect key assignment is used to enter quick select mode; it is bound to CTRL-SHIFT-SPACE by default.

When quick select mode is activated, the terminal is searched for items that match the patterns defined by the quick_select_patterns configuration combined with a default set of patterns that match things such as URL and path fragments, git hashes, ip addresses and numbers.

Matches are highlighted and shown with a one or two character prefix derived from the quick_select_alphabet configuration.

The bottom of the screen shows your input text along with a hint as to what to do next; typing in a highlighted prefix will cause that text to be selected and copied to the clipboard, and quick select mode will be cancelled.

Typing in the uppercase form of the prefix will copy AND paste the highlighted text, and cancel quick select mod.

Pressing ESCAPE will cancel quick select mode.

Screenshot demonstrating the quickselect text highlights

Copy Mode

since: 20200607-144723-74889cd4

Copy mode allows you to make selections using the keyboard; no need to reach for your mouse or trackpad. Copy mode is similar to quick select mode but is geared up for describing selections based on keyboard control, whereas quick select mode is used to quickly select and copy commonly used patterns.

The ActivateCopyMode key assignment is used to enter copy mode; it is bound to CTRL-SHIFT-X by default.

When copy mode is activated, the title is prefixed with "Copy Mode" and the behavior of the tab is changed; keyboard input now controls the cursor and allows moving it through the scrollback, scrolling the viewport as needed, in a style similar to that of the Vim editor.

Move the cursor to the start of the region you wish to select and press v to toggle selection mode (it is off by default), then move the cursor to the end of that region. You can then use Copy (by default: CTRl-SHIFT-C) to copy that region to the clipboard.

Key Assignments

The key assignments in copy mode are as follows. They are not currently reassignable.

ActionKey Assignment
Exit copy modeEsc
CTRL-C
CTRL-g
q
Cell selectionv
Line selectionV
Rectangular selectionCTRL-v (since: 20220624-141144-bd1b7c5d)
Move LeftLeftArrow
h
Move DownDownArrow
j
Move UpUpArrow
k
Move RightRightArrow
l
Move forward one wordAlt-RightArrow
Alt-f
Tab
w
Move backward one wordAlt-LeftArrow
alt-b
Shift-Tab
b
Move to start of this line0
Move to start of next lineEnter
Move to end of this line$
Move to start of indented lineAlt-m
^
Move to bottom of scrollbackG
Move to top of scrollbackg
Move to top of viewportH
Move to middle of viewportM
Move to bottom of viewportL
Move up one screenPageUp
CTRL-b
Move down one screenPageDown
CTRL-f
Move to other end of the selectiono
Move to other end of the selection horizontallyO (useful in Rectangular mode)

Configurable Key Assignments

Since: 20220624-141144-bd1b7c5d

The key assignments for copy mode are specified by the copy_mode Key Table.

You may provide your own definition of this key table if you wish to customize it. There isn't a way to override portions of the key table, only to replace the entire table.

The default configuration is equivalent to:

local wezterm = require 'wezterm'
local act = wezterm.action

return {
  key_tables = {
    copy_mode = {
      {key="c", mods="CTRL", action=act.CopyMode("Close")},
      {key="g", mods="CTRL", action=act.CopyMode("Close")},
      {key="q", mods="NONE", action=act.CopyMode("Close")},
      {key="Escape", mods="NONE", action=act.CopyMode("Close")},

      {key="h", mods="NONE", action=act.CopyMode("MoveLeft")},
      {key="j", mods="NONE", action=act.CopyMode("MoveDown")},
      {key="k", mods="NONE", action=act.CopyMode("MoveUp")},
      {key="l", mods="NONE", action=act.CopyMode("MoveRight")},

      {key="LeftArrow",  mods="NONE", action=act.CopyMode("MoveLeft")},
      {key="DownArrow",  mods="NONE", action=act.CopyMode("MoveDown")},
      {key="UpArrow",    mods="NONE", action=act.CopyMode("MoveUp")},
      {key="RightArrow", mods="NONE", action=act.CopyMode("MoveRight")},

      {key="RightArrow", mods="ALT",  action=act.CopyMode("MoveForwardWord")},
      {key="f",          mods="ALT",  action=act.CopyMode("MoveForwardWord")},
      {key="Tab",        mods="NONE", action=act.CopyMode("MoveForwardWord")},
      {key="w",          mods="NONE", action=act.CopyMode("MoveForwardWord")},

      {key="LeftArrow", mods="ALT",   action=act.CopyMode("MoveBackwardWord")},
      {key="b",         mods="ALT",   action=act.CopyMode("MoveBackwardWord")},
      {key="Tab",       mods="SHIFT", action=act.CopyMode("MoveBackwardWord")},
      {key="b",         mods="NONE",  action=act.CopyMode("MoveBackwardWord")},

      {key="0",     mods="NONE",  action=act.CopyMode("MoveToStartOfLine")},
      {key="Enter", mods="NONE",  action=act.CopyMode("MoveToStartOfNextLine")},

      {key="$",     mods="NONE",  action=act.CopyMode("MoveToEndOfLineContent")},
      {key="$",     mods="SHIFT", action=act.CopyMode("MoveToEndOfLineContent")},
      {key="^",     mods="NONE",  action=act.CopyMode("MoveToStartOfLineContent")},
      {key="^",     mods="SHIFT", action=act.CopyMode("MoveToStartOfLineContent")},
      {key="m",     mods="ALT",   action=act.CopyMode("MoveToStartOfLineContent")},

      {key=" ", mods="NONE",  action=act.CopyMode{SetSelectionMode="Cell"}},
      {key="v", mods="NONE",  action=act.CopyMode{SetSelectionMode="Cell"}},
      {key="V", mods="NONE",  action=act.CopyMode{SetSelectionMode="Line"}},
      {key="V", mods="SHIFT", action=act.CopyMode{SetSelectionMode="Line"}},
      {key="v", mods="CTRL",  action=act.CopyMode{SetSelectionMode="Block"}},

      {key="G", mods="NONE",  action=act.CopyMode("MoveToScrollbackBottom")},
      {key="G", mods="SHIFT", action=act.CopyMode("MoveToScrollbackBottom")},
      {key="g", mods="NONE",  action=act.CopyMode("MoveToScrollbackTop")},

      {key="H", mods="NONE",  action=act.CopyMode("MoveToViewportTop")},
      {key="H", mods="SHIFT", action=act.CopyMode("MoveToViewportTop")},
      {key="M", mods="NONE",  action=act.CopyMode("MoveToViewportMiddle")},
      {key="M", mods="SHIFT", action=act.CopyMode("MoveToViewportMiddle")},
      {key="L", mods="NONE",  action=act.CopyMode("MoveToViewportBottom")},
      {key="L", mods="SHIFT", action=act.CopyMode("MoveToViewportBottom")},

      {key="o", mods="NONE",  action=act.CopyMode("MoveToSelectionOtherEnd")},
      {key="O", mods="NONE",  action=act.CopyMode("MoveToSelectionOtherEndHoriz")},
      {key="O", mods="SHIFT", action=act.CopyMode("MoveToSelectionOtherEndHoriz")},

      {key="PageUp",   mods="NONE", action=act.CopyMode("PageUp")},
      {key="PageDown", mods="NONE", action=act.CopyMode("PageDown")},

      {key="b", mods="CTRL", action=act.CopyMode("PageUp")},
      {key="f", mods="CTRL", action=act.CopyMode("PageDown")},
    },
  },
}

wezterm has support for both implicit and explicit hyperlinks.

Implicit hyperlinks are produced by running a series of rules over the output displayed in the terminal to produce a hyperlink. There is a default rule to match URLs and make them clickable, but you can also specify your own rules to make your own links. As an example, at my place of work many of our internal tools use T123 to indicate task number 123 in our internal task tracking system. It is desirable to make this clickable, and that can be done with the following configuration in your ~/.wezterm.lua:

return {
  hyperlink_rules = {
    -- Linkify things that look like URLs and the host has a TLD name.
    -- Compiled-in default. Used if you don't specify any hyperlink_rules.
    {
      regex = "\\b\\w+://[\\w.-]+\\.[a-z]{2,15}\\S*\\b",
      format = "$0",
    },

    -- linkify email addresses
    -- Compiled-in default. Used if you don't specify any hyperlink_rules.
    {
      regex = [[\b\w+@[\w-]+(\.[\w-]+)+\b]],
      format = "mailto:$0",
    },

    -- file:// URI
    -- Compiled-in default. Used if you don't specify any hyperlink_rules.
    {
      regex = [[\bfile://\S*\b]],
      format = "$0",
    },

    -- Linkify things that look like URLs with numeric addresses as hosts.
    -- E.g. http://127.0.0.1:8000 for a local development server,
    -- or http://192.168.1.1 for the web interface of many routers.
    {
      regex = [[\b\w+://(?:[\d]{1,3}\.){3}[\d]{1,3}\S*\b]],
      format = "$0",
    },

    -- Make task numbers clickable
    -- The first matched regex group is captured in $1.
    {
      regex = [[\b[tT](\d+)\b]],
      format = "https://example.com/tasks/?t=$1",
    },
    
    -- Make username/project paths clickable. This implies paths like the following are for GitHub.
    -- ( "nvim-treesitter/nvim-treesitter" | wbthomason/packer.nvim | wez/wezterm | "wez/wezterm.git" )
    -- As long as a full URL hyperlink regex exists above this it should not match a full URL to 
    -- GitHub or GitLab / BitBucket (i.e. https://gitlab.com/user/project.git is still a whole clickable URL)
    {
      regex = [[["]?([\w\d]{1}[-\w\d]+)(/){1}([-\w\d\.]+)["]?]],
      format = "https://www.github.com/$1/$3",
    }
  }
}

Note that it is generally convenient to use literal strings ([[...]]) when declaring your hyperlink rules, so you won't have to escape backslashes. In the example above, all cases except the first use literal strings for their regular expressions.

wezterm supports the relatively new Hyperlinks in Terminal Emulators specification that allows emitting text that can be clicked and resolve to a specific URL, without the URL being part of the display text. This allows for a cleaner presentation.

The gist of it is that running the following bash one-liner:

printf '\e]8;;http://example.com\e\\This is a link\e]8;;\e\\\n'

will output the text This is a link that when clicked will open http://example.com in your browser.

Shell Integration

wezterm supports integrating with the shell through the following means:

  • OSC 7 Escape sequences to advise the terminal of the working directory
  • OSC 133 Escape sequence to define Input, Output and Prompt zones

These sequences enable some improved user experiences, such as being able to spawn new panes, tabs and windows with the same current working directory as the current pane, jumping through the scrollback to the start of an earlier command, or conveniently selecting the complete output from a command.

In order for these features to be enabled, you will need to configure your shell program to emit the escape sequences at the appropriate place.

You can find some examples for various shells in the wezterm repo.

Starting with version 20210314-114017-04b7cedd, the Fedora and Debian packages automatically activate shell integration for Bash and Zsh.

If you're on another system, more information on how these escapes work can be found below.

Learn more about OSC 133 Semantic Prompt Escapes.

OSC 7 Escape sequence to set the working directory

OSC is escape sequence jargon for Operating System Command; OSC 7 means Operating System Command number 7. This is an escape sequence that originated in the macOS Terminal application that is used to advise the terminal of the current working directory.

An application (usually your shell) can be configured to emit this escape sequence when the current directory changes, or just to emit it each time it prints the prompt.

The current working directory can be specified as a URL like this:

printf "\033]7;file://HOSTNAME/CURRENT/DIR\033\\"

When the current working directory has been set via OSC 7, spawning a new tab will use the current working directory of the current tab, so that you don't have to manually change the directory.

If you are on a modern Fedora installation, the defaults for bash and zsh source a vte.sh script that configures the shell to emit this sequence. On other systems you will likely need to configure this for yourself.

OSC 7 on Windows with cmd.exe

cmd.exe doesn't allow a lot of flexibility in configuring the prompt, but fortunately it does allow for emitting escape sequences. You can use the set_environment_variables configuration to pre-configure the prompt environment in your .wezterm.lua; this example configures the use of OSC 7 as well as including the time and current directory in the visible prompt with green and purple colors, and makes the prompt span multiple lines:

return {
  set_environment_variables = {
    prompt = "$E]7;file://localhost/$P$E\\$E[32m$T$E[0m $E[35m$P$E[36m$_$G$E[0m ",
  }
}

OSC 7 on Windows with powershell

You can configure a custom prompt in powershell by creating/editing your powershell profile and defining a function like this:

function prompt {
    $p = $executionContext.SessionState.Path.CurrentLocation
    $osc7 = ""
    if ($p.Provider.Name -eq "FileSystem") {
        $ansi_escape = [char]27
        $provider_path = $p.ProviderPath -Replace "\\", "/"
        $osc7 = "$ansi_escape]7;file://${env:COMPUTERNAME}/${provider_path}${ansi_escape}\"
    }
    "${osc7}PS $p$('>' * ($nestedPromptLevel + 1)) ";
}

Clink brings bash style line editing, completions and autosuggestions to your Windows cmd.exe experience. If you haven't installed clink to be the global default on your system, you can configure wezterm to launch clink by setting the default_prog configuration in your .wezterm.lua; for example, if you have extracted clink to c:\clink you might configure this:

local wezterm = require 'wezterm';

local default_prog;
local set_environment_variables = {}

if wezterm.target_triple == "x86_64-pc-windows-msvc" then
  -- Use OSC 7 as per the above example
  set_environment_variables["prompt"] = "$E]7;file://localhost/$P$E\\$E[32m$T$E[0m $E[35m$P$E[36m$_$G$E[0m "
  -- use a more ls-like output format for dir
  set_environment_variables["DIRCMD"] = "/d"
  -- And inject clink into the command prompt
  default_prog = {"cmd.exe", "/s", "/k", "c:/clink/clink_x64.exe", "inject", "-q"}
end

return {
  default_prog = default_prog,
  set_environment_variables = set_environment_variables,
}

Now, rather than just running cmd.exe on its own, this will cause cmd.exe to self-inject the clink line editor.

iTerm Image Protocol Support

wezterm implements support for the iTerm2 inline images protocol and provides a handy imgcat subcommand to make it easy to try out. Because the protocol is just a protocol, wezterm's imgcat also renders images in iTerm2.

To render an image inline in your terminal:

$ wezterm imgcat /path/to/image.png
inline image display

Note that the image protocol isn't fully handled by multiplexer sessions at this time.

Since: 20220319-142410-0fcdea07

WezTerm supports an extension to the protocol; passing doNotMoveCursor=1 as an argument to the File escape sequence causes wezterm to not move the cursor position after processing the image.

SSH Connections

wezterm uses an embedded ssh library to provide an integrated SSH client. The client can be used to make ad-hoc SSH connections to remote hosts by invoking the client like this:

$ wezterm ssh wez@my.server

(checkout wezterm ssh -h for more options).

When invoked in this way, wezterm may prompt you for SSH authentication and once a connection is established, open a new terminal window with your requested command, or your shell if you didn't specify one.

Creating new tabs or panes will each create a new channel in your existing session so you won't need to re-authenticate for additional tabs that you create.

SSH sessions created in this way are non-persistent and all associated tabs will die if your network connection is interrupted.

Take a look at the multiplexing section for an alternative configuration that connects to a remote wezterm instance and preserves your tabs.

The ssh_backend configuration can be used to specify which ssh library is used.

Since: 20210404-112810-b63a949d

wezterm is now able to parse ~/.ssh/config and /etc/ssh/ssh_config and respects the following options:

  • IdentityFile
  • Hostname
  • User
  • Port
  • ProxyCommand
  • Host (including wildcard matching)
  • UserKnownHostsFile
  • IdentitiesOnly
  • BindAddress

All other options are parsed but have no effect. Notably, neither Match or Include will do anything.

Since: 20210502-154244-3f7122cb:

Match is now recognized but currently supports only single-phase (final, canonical are not supported) configuration parsing for Host and LocalUser. Exec based matches are recognized but not supported.

Since: 20210814-124438-54e29167:

Include is now supported.

CLI Overrides

wezterm ssh CLI allows overriding config settings via the command line. This example shows how to specify the private key to use when connecting to some-host:

wezterm ssh -oIdentityFile=/secret/id_ed25519 some-host

Serial Ports

wezterm can also connect to serial ports as a client. This is useful for example when working with embedded devices such as Arduino, or when connecting to a serial console on a headless server.

For example, on Linux:

$ wezterm serial /dev/ttyUSB0

or on Windows:

$ wezterm serial COM0

You can also specify the baud rate:

$ wezterm serial --baud 38400 /dev/ttyUSB0

When a wezterm window is operating in serial mode it is not possible to create new tabs.

Notice: multiplexing is still a young feature and is evolving rapidly. Your feedback is welcomed!

Multiplexing

The out-of-the-box experience with wezterm allows you to multiplex local tabs and windows which will persist until they are closed. With a little extra configuration you can enable local terminal multiplexing with features similar to those in tmux or screen.

Multiplexing in wezterm is based around the concept of multiplexing domains; a domain is a distinct set of windows and tabs. When wezterm starts up it creates a default local domain to manage the windows and tabs in the UI, but it can also be configured to start or connect to additional domains.

Once connected to a domain, wezterm can attach its windows and tabs to the local native UI, providing a more natural experience for interacting with the mouse, clipboard and scrollback features of the terminal.

Key bindings allow you to spawn new tabs in the default local domain, the domain of the current tab, or a specific numbered domain.

SSH Domains

wezterm also supports regular ad-hoc ssh connections. This section of the docs refers to running a wezterm daemon on the remote end of a multiplexing session that uses ssh as a channel

A connection to a remote wezterm multiplexer made via an ssh connection is referred to as an SSH domain. A compatible version of wezterm must be installed on the remote system in order to use SSH domains. SSH domains are supported on all systems via libssh2.

To configure an SSH domain, place something like the following in your .wezterm.lua file:

return {
  ssh_domains = {
    {
      -- This name identifies the domain
      name = "my.server",
      -- The hostname or address to connect to. Will be used to match settings
      -- from your ssh config file
      remote_address = "192.168.1.1",
      -- The username to use on the remote host
      username = "wez",
    }
  }
}

See SshDomain for more information on possible settings to use with SSH domains.

To connect to the system, run:

$ wezterm connect my.server

This will launch an SSH session that connects to the specified address and may pop up authentication dialogs (using SSH keys for auth is strongly recommended!). Once connected, it will attempt to spawn the wezterm multiplexer daemon on the remote host and connect to it via a unix domain socket using a similar mechanism to that described in the Unix Domains section below.

Unix Domains

A connection to a multiplexer made via a unix socket is referred to as a unix domain. Unix domains are supported on all systems, even Windows and are a way to connect the native win32 GUI into the Windows Subsystem for Linux (WSL).

The bare minimum configuration to enable a unix domain is this, which will spawn a server if needed and then connect the gui to it automatically when wezterm is launched:

return {
  unix_domains = {
    {
      name = "unix",
    }
  },

  -- This causes `wezterm` to act as though it was started as
  -- `wezterm connect unix` by default, connecting to the unix
  -- domain on startup.
  -- If you prefer to connect manually, leave out this line.
  default_gui_startup_args = {"connect", "unix"},
}

If you prefer to connect manually, omit the default_gui_startup_args setting and then run:

$ wezterm connect unix

Note that in earlier versions of wezterm, a connect_automatically domain option was shown as the way to connect on startup. Using default_gui_startup_args is recommended instead as it works more reliably.

The possible configuration values are:

return {
  unix_domains = {
    {
      -- The name; must be unique amongst all domains
      name = "unix",

      -- The path to the socket.  If unspecified, a resonable default
      -- value will be computed.

      -- socket_path = "/some/path",

      -- If true, do not attempt to start this server if we try and fail to
      -- connect to it.

      -- no_serve_automatically = false,

      -- If true, bypass checking for secure ownership of the
      -- socket_path.  This is not recommended on a multi-user
      -- system, but is useful for example when running the
      -- server inside a WSL container but with the socket
      -- on the host NTFS volume.

      -- skip_permissions_check = false,

    }
  }
}

Since: 20220101-133340-7edc5b5a

It is now possible to specify a proxy_command that will be used in place of making a direct unix connection. When proxy_command is specified, it will be used instead of the optional socket_path.

This example shows a redundant use of nc (netcat) to connect to the unix socket path on my mac. This isn't useful on its own, but may help with the WSL 2 issue mentioned below when translated to an appropriate invocation of netcat/socat on Windows:

return {
  unix_domains = {
    {
      name = "unix",
      proxy_command = {"nc", "-U", "/Users/wez/.local/share/wezterm/sock"},
    }
  }
}

Since: 20220319-142410-0fcdea07

You may now specify the round-trip latency threshold for enabling predictive local echo using local_echo_threshold_ms. If the measured round-trip latency between the wezterm client and the server exceeds the specified threshold, the client will attempt to predict the server's response to key events and echo the result of that prediction locally without waiting, hence hiding latency to the user. This option only applies when multiplexing = "WezTerm".

return {
  unix_domains = {
    {
      name = "unix",
      local_echo_threshold_ms = 10,
    }
  },
}

Connecting into Windows Subsystem for Linux

Note: this only works with WSL 1. WSL 2 doesn't support AF_UNIX interop

Inside your WSL instance, configure .wezterm.lua with this snippet:

return {
  unix_domains = {
    {
      name = "wsl"
      -- Override the default path to match the default on the host win32
      -- filesystem.  This will allow the host to connect into the WSL
      -- container.
      socket_path = "/mnt/c/Users/USERNAME/.local/share/wezterm/sock",
      -- NTFS permissions will always be "wrong", so skip that check
      skip_permissions_check = true,
    }
  }
}

In the host win32 configuration, use this snippet:

return {
  unix_domains = {
    {
      name = "wsl",
      serve_command = {"wsl", "wezterm-mux-server", "--daemonize"},
    }
  },
  default_gui_startup_args = {"connect", "wsl"},
}

Now when you start wezterm you'll be presented with a WSL tab.

You can also omit default_gui_startup_args and use:

$ wezterm connect wsl

to manually connect into your WSL instance.

TLS Domains

A connection to a multiplexer made via a TLS encrypted TCP connection is referred to as a TLS Domain.

Starting with version 20200202-180558-2489abf9, wezterm can bootstrap a TLS session by performing an initial connection via SSH to start the wezterm multiplexer on the remote host and securely obtain a key. Once bootstrapped, the client will use a TLS protected TCP connection to communicate with the server.

Configuring the client

For each server that you wish to connect to, add a client section like this:

return {
  tls_clients = {
    {
      -- A handy alias for this session; you will use `wezterm connect server.name`
      -- to connect to it.
      name = "server.name",
      -- The host:port for the remote host
      remote_address = "server.hostname:8080",
      -- The value can be "user@host:port"; it accepts the same syntax as the
      -- `wezterm ssh` subcommand.
      bootstrap_via_ssh = "server.hostname",
    }
  }
}

See TlsDomainClient for more information on possible settings.

Configuring the server

return {
  tls_servers = {
    {
      -- The host:port combination on which the server will listen
      -- for connections
      bind_address = "server.hostname:8080"
    }
  }
}

See TlsDomainServer for more information on possible settings.

Connecting

On the client, running this will connect to the server, start up the multiplexer and obtain a certificate for the TLS connection. A connection window will show the progress and may prompt you for SSH authentication. Once the connection has been initiated, wezterm will automatically reconnect using the certificate it obtained during bootstrapping if your connection was interrupted and resume your remote terminal session

$ wezterm connect server.name

Please note that this is a "living document" and may lag or lead the state of the current stable release in a number of areas--as you might imagine, precisely documenting escape codes and their behaviors and cross-checking with the various technical documents is laborious and tedious and I only have so much spare time!

If you notice that something is inaccurate or missing, please do file an issue so that it can be resolved!

Output/Escape Sequences

WezTerm considers the output from the terminal to be a UTF-8 encoded stream of codepoints. No other encoding is supported. As described below, some C1 control codes have both 7-bit ASCII compatible as well as 8-bit representations. As ASCII is a compatible subset of UTF-8, the 7-bit representations are preferred and processed without any special consideration.

The 8-bit values are recognized, but only if the 8-bit value is treated as a unicode code point and encoded via a UTF-8 multi-byte sequence.

Printable Codepoints

Codepoints with value 0x20 and higher are considered to be printable and are applied to the terminal display using the following rules:

  • Codepoints are buffered until a C0, C1 or other escape/control sequence is encountered, which triggers a flush and processing continues with the next step.
  • The buffered codepoint sequence is split into unicode graphemes, which means that combining sequences and emoji are decoded. Processing continues for below for each individually recognized grapheme.
  • If DEC line drawing mode is active, graphemes j-n, q, t-x are translated to equivalent line drawing graphemes and processing continues.
  • If prior output/actions require it, the cursor position may be moved to a new line and the terminal display may be scrolled to make accomodate it.
  • An appropriate number of cells, starting at the current cursor position, are allocated based on the column width of the current grapheme and are assigned to the grapheme. The current current graphics rendition state (such as colors and other presentation attributes) is also applied to those cells. If insert mode is active, those cells will be inserted at the current cursor position, otherwise they will overwrite cells at the current cursor position.
  • The cursor position will be updated based on the column width of the grapheme.

After the graphemes are applied to the terminal display, the rendering portion of WezTerm will attempt to apply your font shaping configuration based on runs of graphemes with matching graphic attributes to determine which glyphs should be rendered from your fonts; it is at this stage that emoji and ligatures are resolved.

C0 Control Codes

Codepoints in the range 0x00-0x1F are considered to be C0 control codes. C0 controls will flush any buffered printable codepoints before triggering the action described below.

SeqHexNameDescriptionAction
^@0x00NULNullIgnored
^A0x01SOHStart of HeadingIgnored
^B0x02STXStart of TextIgnored
^C0x03ETXEnd of TextIgnored
^D0x04EOTEnd of TransmissionIgnored
^E0x05ENQEnquiryIgnored
^F0x06ACKAcknowledgeIgnored
^G0x07BELBellLogs Ding! (this is the bell) to stderr of the WezTerm process. See #3
^H0x08BSBackspaceMove cursor left by 1, constrained by the left margin. If Reverse Wraparound and dec auto wrap modes are enabled, moving left of the left margin will jump the cursor to the right margin, jumping to bottom right margin if it was at the top left.
^I0x09HTHorizontal TabMove cursor right to the next tab stop
^J0x0ALFLine FeedIf cursor is at the bottom margin, scroll the region up, otherwise move cursor down 1 row
^K0x0BVTVertical TabTreated as Line Feed
^L0x0CFFForm FeedTreated as Line Feed
^M0x0DCRCarriage ReturnIf cursor is left of leftmost margin, move to column 0. Otherwise move to left margin
^N0x0ESOShift OutIgnored
^O0x0FSIShift InIgnored
^P0x10DLEData Link EscapeIgnored
^Q0x11DC1Device Control OneIgnored
^R0x12DC2Device Control TwoIgnored
^S0x13DC3Device Control ThreeIgnored
^T0x14DC4Device Control FourIgnored
^U0x15NAKNegative AcknowledgeIgnored
^V0x16SYNSynchronous IdleIgnored
^W0x17ETBEnd Transmission BlockIgnored
^X0x18CANCancelIgnored
^Y0x19EMEnd of MediumIgnored
^Z0x1ASUBSubstituteIgnored
^[0x1BESCEscapeIntroduces various escape sequences described below
^\0x1CFSFile SeparatorIgnored
^]0x1DGSGroup SeparatorIgnored
^^0x1ERSRecord SeparatorIgnored
^_0x1FUSUnit SeparatorIgnored

C1 Control Codes

As mentioned above, WezTerm only supports UTF-8 encoding. C1 control codes have an 8-bit representation as well as a multi-codepoint 7-bit escape sequence.

The 8-bit representation is recognized if the 8-bit value is treated as a unicode code point and encoded as a multi-byte UTF-8 sequence. Sending the 8-bit binary value will not be recognized as intended, as those bitsequences are passing through a UTF-8 decoder.

The table below lists the 7-bit C1 sequence (which is preferred) as well as the codepoint value, along with the corresponding meaning.

As with C0 control codes, C1 controls will flush any buffered printable codepoints before triggering the action described below.

SeqCodepointNameDescriptionAction
ESC D0x84INDIndexMoves the cursor down one line in the same column. If the cursor is at the bottom margin, the page scrolls up
ESC E0x85NELNext LineMoves the cursor to the left margin on the next line. If the cursor is at the bottom margin, scroll the page up
ESC H0x88HTSHorizontal Tab SetSets a horizontal tab stop at the column where the cursor is
ESC M0x8DRIReverse IndexMove the cursor up one line. If the cursor is at the top margin, scroll the region down
ESC P0x90DCSDevice Control StringDiscussed below
ESC [0x9BCSIControl Sequence IntroducerDiscussed below
ESC \0x9CSTString TerminatorNo direct effect; ST is used to delimit the end of OSC style escape sequences

Other Escape Sequences

As these sequences start with an ESC, which is a C0 control, these will flush any buffered printable codepoints before triggering the associated action.

SeqNameDescriptionAction
ESC cRISReset to Initial StateResets tab stops, margins, modes, graphic rendition, palette, activates primary screen, erases the display and moves cursor to home position
ESC 7DECSCSave Cursor PositionRecords cursor position
ESC 8DECRCRestored Saved Cursor PositionMoves cursor to location it had when DECSC was used
ESC =DECPAMApplication KeypadEnable Application Keypad Mode
ESC >DECPNMNormal KeypadSet Normal Keypad Mode
ESC (0DEC Line Drawing character setTranslate characters j-x to line drawing glyphs
ESC (BUS ASCII character setDisables DEC Line Drawing character translation
ESC #8DECALNScreen Alignment DisplayFills the display with E characters for diagnostic/test purposes (for vttest)

CSI - Control Sequence Introducer Sequences

CSI sequences begin with the C1 CSI sequence, which is either the 7-bit ESC [ sequence or the codepoint 0x9B.

WezTerm classifies these sequences into a number of functional families which are broken out below.

Graphic Rendition (SGR)

SGR sequences are of the form CSI DIGITS [; DIGITS ]+ m. That is, any number of semicolon separated numbers, terminated by the m codepoint. There are a handful of slightly more modern sequences that use colon : codepoints to encode additional context.

The digits map to one of the codes in the table below, which manipulate the presentation attributes of subsequently printed characters.

It is valid to omit the code number; for example CSI m is equivalent to CSI 0 m which resets the presentation attributes.

CodeDescriptionAction
0ResetReset to default foreground/background colors, reset all presentation attributes, clear any explicit hyperlinks
1IntensityBoldSet the intensity level to Bold. This causes subsequent text to be rendered in a bold font variant and, if the foreground color is set to a palette index in the 0-7 range, effectively shifts it to the brighter value in the 8-15 range
2IntensityDimSet the intensity level to Dim or Half-Bright. This causes text to be rendered in a lighter weight font variant
3ItalicOnSets the italic attribute on the text, causing an italic font variant to be selected
4UnderlineOnText will have a single underline
4:0UnderlineOffText will have no underline
4:1UnderlineOnText will have a single underline
4:2UnderlineDoubleText will be rendered with double underline
4:3UnderlineCurlyText will be rendered with a curly underline
4:4UnderlineDottedText will be rendered with a dotted underline
4:5UnderlineDashedText will be rendered with a dashed underline
5BlinkOnIndicates that the text should blink <150 times per minute
6RapidBlinkOnIndicates that the text should blink >150 times per minute
7InverseOnCauses the foreground and background colors to be swapped
8InvisibleOnMarks text as invisible.
9StrikeThroughOnText will be rendered with a single line struck through the middle
21UnderlineDoubleText will be rendered with double underline
22NormalIntensityCancels the effect of IntensityBold and IntensityDim, returning the text to normal intensity
23ItalicOffCancels the effect of ItalicOn
24UnderlineOffText will have no underline
25BlinkOffCancels the effect of BlinkOn and RapidBlinkOn
27InverseOffCancels the effect of InverseOn
28InvisibleOffcancels the effect of InvisibleOn
29StrikeThroughOffCancels the effect of StrikeThroughOn
30ForegroundBlackSets the foreground color to ANSI Black, which is palette index 0
31ForegroundRedSets the foreground color to ANSI Red, which is palette index 1
32ForegroundGreenSets the foreground color to ANSI Green, which is palette index 2
33ForegroundYellowSets the foreground color to ANSI Yellow, which is palette index 3
34ForegroundBlueSets the foreground color to ANSI Blue, which is palette index 4
35ForegroundMagentaSets the foreground color to ANSI Magenta, which is palette index 5
36ForegroundCyanSets the foreground color to ANSI Cyan, which is palette index 6
37ForegroundWhiteSets the foreground color to ANSI White, which is palette index 7
39ForegroundDefaultSets the foreground color to the user's configured default text color
40BackgroundBlackSets the background color to ANSI Black, which is palette index 0
41BackgroundRedSets the background color to ANSI Red, which is palette index 1
42BackgroundGreenSets the background color to ANSI Green, which is palette index 2
43BackgroundYellowSets the background color to ANSI Yellow, which is palette index 3
44BackgroundBlueSets the background color to ANSI Blue, which is palette index 4
45BackgroundMagentaSets the background color to ANSI Magenta, which is palette index 5
46BackgroundCyanSets the background color to ANSI Cyan, which is palette index 6
47BackgroundWhiteSets the background color to ANSI White, which is palette index 7
49BackgroundDefaultSets the background color to the user's configured default background color
53OverlineOnRenders text with a single overline/overbar
55OverlineOffCancels OverlineOn
59UnderlineColorDefaultResets the underline color to default, which is to match the foreground color
90ForegroundBrightBlackSets the foreground color to Bright Black, which is palette index 8
91ForegroundBrightRedSets the foreground color to Bright Red, which is palette index 9
92ForegroundBrightGreenSets the foreground color to Bright Green, which is palette index 10
93ForegroundBrightYellowSets the foreground color to Bright Yellow, which is palette index 11
94ForegroundBrightBlueSets the foreground color to Bright Blue, which is palette index 12
95ForegroundBrightMagentaSets the foreground color to Bright Magenta, which is palette index 13
96ForegroundBrightCyanSets the foreground color to Bright Cyan, which is palette index 14
97ForegroundBrightWhiteSets the foreground color to Bright White, which is palette index 15
100BackgroundBrightBlackSets the background color to Bright Black, which is palette index 8
101BackgroundBrightRedSets the background color to Bright Red, which is palette index 9
102BackgroundBrightGreenSets the background color to Bright Green, which is palette index 10
103BackgroundBrightYellowSets the background color to Bright Yellow, which is palette index 11
104BackgroundBrightBlueSets the background color to Bright Blue, which is palette index 12
105BackgroundBrightMagentaSets the background color to Bright Magenta, which is palette index 13
106BackgroundBrightCyanSets the background color to Bright Cyan, which is palette index 14
107BackgroundBrightWhiteSets the background color to Bright White, which is palette index 15

There are a handful of additional SGR codes that allow setting extended colors; unlike the codes above, which are activated by a single numeric parameter out of SGR sequence, these the extended color codes require multiple parameters. The canonical representation of these sequences is to have the multiple parameters be separated by colons (:), but for compatibility reasons WezTerm also accepts an ambiguous semicolon (;) separated variation. The colon form is unambiguous and should be preferred; the semicolon form should not be used by new applications and is not documented here in the interest of avoiding accidental new implementations.

This sequence will set the foreground color to the specified palette INDEX, which can be a decimal number in the range 0-255.

CSI 38 : 5 : INDEX m

This sequence will set the background color to the specified palette INDEX, which can be a decimal number in the range 0-255.

CSI 48 : 5 : INDEX m

This sequence will set the underline color to the specified palette INDEX, which can be a decimal number in the range 0-255.

CSI 58 : 5 : INDEX m

This sequence will set the foreground color to an arbitrary color in RGB colorspace. The R, G and B symbols below are decimal numbers in the range 0-255. Note that after the 2 parameter two colons are present; its really an omitted colorspace ID parameter but that nature of that parameter is not specified in the accompanying ITU T.416 specification and is ignored by WezTerm and most (all?) other terminal emulators:

CSI 38 : 2 : : R : G : B m

(Since 20210814-124438-54e29167) For the sake of compatibility with some other terminal emulators this additional form is also supported where the colorspace ID argument is not specified:

CSI 38 : 2 : R : G : B m

This sequence will set the background color to an arbitrary color in RGB colorspace. The R, G and B symbols below are decimal numbers in the range 0-255:

CSI 48 : 2 : : R : G : B m

(Since 20210814-124438-54e29167) For the sake of compatibility with some other terminal emulators this additional form is also supported where the colorspace ID argument is not specified:

CSI 48 : 2 : R : G : B m

This sequence will set the underline color to an arbitrary color in RGB colorspace. The R, G and B symbols below are decimal numbers in the range 0-255:

CSI 58 : 2 : : R : G : B m

(Since 20210814-124438-54e29167) For the sake of compatibility with some other terminal emulators this additional form is also supported where the colorspace ID argument is not specified:

CSI 58 : 2 : R : G : B m

Cursor Movement

Editing Functions

Mode Functions

Since: 20210814-124438-54e29167

WezTerm supports Synchronized Rendering. DECSET 2026 is set to batch (hold) rendering until DECSET 2026 is reset to flush the queued screen data.

Device Functions

Window Functions

DCS - Device Control String

The C1 DCS escape places the terminal parser into a device control mode until the C1 ST is encountered.

In the table below, DCS can be either the 7-bit representation (ESC P) or the 8-bit codepoint (0x90).

SeqNameDescription
DCS $ q " p STDECRQSS for DECSCLRequest Conformance Level; Reports the conformance level
DCS $ q r STDECRQSS for DECSTBMRequest top and bottom margin report; Reports the margins
DCS $ q s STDECRQSS for DECSLRMRequest left and right margin report; Reports the margins
DCS [PARAMS] q [DATA] STSixel Graphic DataDecodes Sixel graphic data and apply the image to the terminal model. Support is preliminary and incomplete; see this issue for status.
DCS 1000 qtmux control modeBridges tmux into the WezTerm multiplexer. Currently incomplete, see this issue for status.

Operating System Command Sequences

Operating System Command (OSC) sequences are introduced via ESC ] followed by a numeric code and typically have parameters delimited by ;. OSC sequences are canonically delimited by the ST (String Terminator) sequence, but WezTerm also accepts delimiting them with the BEL control.

The table below is keyed by the OSC code.

OSCDescriptionActionExample
0Set Icon Name and Window TitleClears Icon Name, sets Window Title.\x1b]0;title\x1b\\
1Set Icon NameSets Icon Name, which is used as the Tab title when it is non-empty\x1b]1;tab-title\x1b\\
2Set Window TitleSet Window Title\x1b]2;window-title\x1b\\
3Set X11 Window PropertyIgnored
4Change/Query Color NumberSet or query color palette entries 0-255.query color number 1: \x1b]4;1;?\x1b\\
Set color number 2: \x1b]4;2;#cccccc\x1b\\
5Change/Query Special Color NumberIgnored
6iTerm2 Change Title Tab ColorIgnored
7Set Current Working DirectorySee Shell Integration
8Set HyperlinkSee Explicit Hyperlinks
9iTerm2 Show System NotificationShow a "toast" notificationprintf "\e]9;%s\e\\" "hello there"
10Set Default Text Foreground Color\x1b]10;#ff0000\x1b\\
11Set Default Text Background Color\x1b]11;#0000ff\x1b\\
12Set Text Cursor Color\x1b]12;#00ff00\x1b\\
52Manipulate clipboardRequests to query the clipboard are ignored. Allows setting or clearing the clipboard
104ResetColorsReset color palette entries to their default values
133FinalTerm semantic escapesInforms the terminal about Input, Output and Prompt regions on the displaySee Shell Integration
777Call rxvt extensionOnly the notify extension is supported; it shows a "toast" notificationprintf "\e]777;notify;%s;%s\e\\" "title" "body"
1337iTerm2 File Upload ProtocolAllows displaying images inlineSee iTerm Image Protocol
LSet Icon Name (Sun)Same as OSC 1\x1b]Ltab-title\x1b\\
lSet Window Title (Sun)Same as OSC 2\x1b]lwindow-title\x1b\\

Additional Resources

Frequently Asked Questions

Unicode glyphs render as underscores in my tmux!

This is likely an issue with LANG and locale. tmux will substitute unicode glyphs with underscores if it believes that your environment doesn't support UTF-8.

If you're running on macOS, upgrade to 20200620-160318-e00b076c or newer and WezTerm will automatically set LANG appropriately.

Note that if you change your environment you will likely need to kill and restart your tmux server before it will take effect.

You probably should also review this relevant section from the TMUX FAQ, and read on for more information about LANG and locale below.

Some glyphs look messed up, why is that?

There's a surprisingly amount of work that goes into rendering text, and if you're connected to a remote host, it may span both systems. Read on for some gory details!

LANG and locale

Terminals operate on byte streams and don't necessarily know anything about the encoding of the text that you're sending through. The unix model for this is that the end user (that's you!) will instruct the applications that you're running to use a particular locale to interpret the byte stream.

It is common for these environment variables to not be set, or to be set to invalid values by default!

If you're running on macOS, upgrade to 20200620-160318-e00b076c or newer and WezTerm will automatically set LANG appropriately.

You need to select a unicode locale for best results; for example:

export LANG=en_US.UTF-8
# You don't strictly need this collation, but most technical people
# probably want C collation for sane results
export LC_COLLATE=C

If you have other LC_XXX values in your environment, either remove them from your environment (if applicable) or adjust them to use a UTF-8 locale.

You can run locale -a to list the available locales on your system.

You need to make sure that this setting applies both locally and on systems that you log in to via ssh or the mux connection protocol.

If you're seeing multiple garbage characters in your terminal in place of what should be a single glyph then you most likely have a problem with your locale environment variables.

Pasting or entering unicode in zsh looks broken

By default, zsh's line editor doesn't support combining character sequences. Make sure that you have LANG and local configured correctly as shown above, and then tell zsh to enable combining characters:

setopt COMBINING_CHARS

You'll want to put that into your zshrc so that it is always enabled.

See this stackexchange question for more information.

Fonts and fallback

If you have configured the use of a font that contains only latin characters and then try to display a glyph that isn't present in that font (perhaps an emoji, or perhaps some kanji) then wezterm will try to locate a fallback font that does contain that glyph.

Wezterm uses freetype and harfbuzz to perform font shaping and rendering in a cross platform way, and as a consequence, doesn't have access to the system font fallback selection. Instead it has a short list of fallback fonts that are likely to be present on the system and tries to use those.

If you're seeing the unicode replacement character, a question mark or in the worst cases spaces where a glyph should be, then you have an issue with font fallback.

You can resolve this by explicitly adding fallback font(s) the have the glyphs that you need in your .wezterm.lua:

local wezterm = require 'wezterm';

return {
  font = wezterm.font_with_fallback({
    "My Preferred Font",
    -- This font has a broader selection of Chinese glyphs than my preferred font
    "DengXian"
  })
}

See also Troubleshooting Fonts.

Some (but not all) Emoji don't render properly

To some extent this issue can manifest in a similar way to the LANG and locale issue. There are different versions of the Emoji specifications and the level of support in different applications can vary. Emoji can be comprised from a sequence of codepoints and some combine in interesting ways such as a foot and a skin tone. Applications that don't support this correctly may end up emitting incorrect output. For example, pasting some emoji into the zsh REPL confuses its input parser and results in broken emoji output. However, if you were to emit that same emoji from a script, wezterm would render it correctly.

If you're seeing this sort of issue, then you may be able to upgrade the affected application on that system to see if a newer version resolves that issue.

Multiple characters being rendered/combined as one character?

wezterm supports advanced font shaping, which, amongst other things, allows for multiple characters/glyphs to be combined into one ligature. You may be experiencing this if, e.g., != becomes rendered as in wezterm.

If you are seeing this kind of "font combining" and wish to disable it, then this is documented in advanced font shaping options page.

How to troubleshoot keys that don't work or produce weird characters!?

There are a number of layers in input processing that can influence this.

The first thing to note is that wezterm will always and only output UTF-8 encoded text. Your LANG and locale related environment must be set to reflect this; there is more information on that above.

If the key in question is produced in combination with Alt/Option then this section of the docs describes how wezterm processes Alt/Option, as well as options that influence that behavior.

The next thing to verify is what byte sequences are being produced when you press keys. I generally suggest running xxd, pressing the relevant key, then enter, then CTRL-D. This should show a hex dump of the the byte sequence. This step helps to isolate the input from input processing layers in other applications.

Interactive Unix programs generally depend upon the TERM environment variable being set appropriately. wezterm sets this to xterm-256color by default, because wezterm aims to be compatible with with the settings defined by that terminfo entry. Setting TERM to something else can change the byte sequences that interactive applications expect to see for some keys, effectively disabling those keys.

On top of this, a number of programs use libraries such as GNU readline to perform input processing. That means that settings in your ~/.inputrc may changing the behavior of bash. Verify any settings in there that might influence how input is resolved and see the question below about convert-meta!

If you are using tmux be aware that it introduces its own set of input/output processing layers that are also sensitive to LANG, TERM and locale and how they are set in the environment of the tmux server when it was spawned, the tmux client and inside the processes spawned by tmux. It is generally best to troubleshoot input/output weirdness independent of tmux first to minimize the number of variables!

If after experimenting with your environment and related settings you believe that wezterm isn't sending the correct input then please open an issue and include the xxd hexdump, and output from env and any other pertinent information about what you're trying and why it doesn't match your expectations.

I have set convert-meta on in my ~/.inputrc and latin characters are broken!?

That setting causes Readline to re-encode latin-1 and other characters as a different sequence (eg: £ will have the high bit stripped and turn it into #).

You should consider disabling that setting when working with a UTF-8 environment.

How do I enable undercurl (curly underlines)?

Starting in version 20210314-114017-04b7cedd, WezTerm has support for colored and curly underlines.

The relevant escape sequences are:

 CSI 24 m   -> No underline
 CSI 4 m    -> Single underline
 CSI 4:0 m  -> No underline
 CSI 4:1 m  -> Single underline
 CSI 4:2 m  -> Double underline
 CSI 4:3 m  -> Curly underline
 CSI 4:4 m  -> Dotted underline
 CSI 4:5 m  -> Dashed underline

 CSI 58:2::R:G:B m   -> set underline color to specified true color RGB
 CSI 58:5:I m        -> set underline color to palette index I (0-255)
 CSI 59              -> restore underline color to default

You can try these out in your shell; this example will print the various underline styles with a red underline:

$ printf "\x1b[58:2::255:0:0m\x1b[4:1msingle\x1b[4:2mdouble\x1b[4:3mcurly\x1b[4:4mdotted\x1b[4:5mdashed\x1b[0m\n"

To use this in vim, add something like the following to your .vimrc:

let &t_Cs = "\e[4:3m"
let &t_Ce = "\e[4:0m"
hi SpellBad   guisp=red gui=undercurl guifg=NONE guibg=NONE \
     ctermfg=NONE ctermbg=NONE term=underline cterm=undercurl ctermul=red
hi SpellCap   guisp=yellow gui=undercurl guifg=NONE guibg=NONE \
     ctermfg=NONE ctermbg=NONE term=underline cterm=undercurl ctermul=yellow

If you are a neovim user then you will need to install a terminfo file that tells neovim about this support.

You may wish to try these steps to install a copy of a wezterm terminfo file; this will compile a copy of the terminfo and install it into your ~/.terminfo directory:

tempfile=$(mktemp) \
  && curl -o $tempfile https://raw.githubusercontent.com/wez/wezterm/master/termwiz/data/wezterm.terminfo \
  && tic -x -o ~/.terminfo $tempfile \
  && rm $tempfile

With that in place, you can then start neovim like this, and it should enable undercurl:

env TERM=wezterm nvim

Note: on Windows, the ConPTY layer strips out the curly underline escape sequences. If you're missing this feature in your WSL instance, you will need to use either wezterm ssh or multiplexing to bypass ConPTY.

I use Powershell for my shell, and I have problems with cursor keys in other apps

Powershell has an open issue where it enables the DECCKM mode of the terminal and does not restore it prior to launching external commands.

The consequence of enabling DECCKM is that cursor keys switch from being reported as eg: ESC [ A (for UpArrow) to ESC O A.

Some applications don't know how to deal with this and as a consequence, won't see the cursor keys.

This is not an issue in WezTerm; the same issue manifests in any terminal emulator that runs powershell.

I use X11 or Wayland and my mouse cursor theme doesn't seem to work

What is this old school X11 mouse pointer thing?!

Resolving the mouse cursor style in these environments is surprisingly complicated:

  • Determine the XCursor theme:

    1. is xcursor_theme set in the wezterm configuration?
    2. X11: Does the root window publish the XCursor.theme resource? (You can manually run xprop -root | grep RESOURCE_MANAGER | perl -pe 's/\\n/\n/g' | grep -i cursor to check for yourself)
    3. Wayland: from the XCURSOR_THEME environment variable
    4. Otherwise, assume default
  • Determine the icon path:

    1. Is XCURSOR_PATH set in the environment? If so, use that.
    2. Construct a default path derived from some hard coded locations and the contents of the XDG_DATA_HOME and XDG_DATA_DIRS environment variables.

When a cursor is needed, the XCursor theme is tried first:

  1. X11: the X Server must support the RENDER extension, version 0.5 or later, and support ARGB32
  2. A set of candidate cursor names is produced for the desired cursor
  3. For each location in the icon path, the XCursor theme and the candidate name are combined to produce a candidate file name
  4. If the file exists, then wezterm will try to load it

If no XCursor was found, wezterm will fall back to using the default X11 cursor font provided by the system.

Since: 20220624-141144-bd1b7c5d

When troubleshooting xcursor issues, you can enable tracing by turning on the log level shown below, and then moving the mouse over the wezterm window:

; WEZTERM_LOG=window::os::x11::cursor=trace wezterm
07:34:40.001  TRACE  window::os::x11::cursor > Constructing default icon path because $XCURSOR_PATH is not set
07:34:40.001  TRACE  window::os::x11::cursor > Using ~/.local/share because $XDG_DATA_HOME is not set
07:34:40.001  TRACE  window::os::x11::cursor > Using $XDG_DATA_DIRS location "/home/wez/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/"
07:34:40.001  TRACE  window::os::x11::cursor > icon_path is ["/home/wez/.local/share/icons", "/home/wez/.icons", "/home/wez/.local/share/flatpak/exports/share/icons", "/var/lib/flatpak/exports/share/icons", "/usr/local/share/icons", "/usr/share/icons", "/usr/share/pixmaps", "/home/wez/.cursors", "/usr/share/cursors/xorg-x11", "/usr/X11R6/lib/X11/icons"]
07:34:41.838  TRACE  window::os::x11::cursor > candidate for Some(Text) is "/home/wez/.local/share/icons/Adwaita/cursors/xterm"
07:34:41.838  TRACE  window::os::x11::cursor > candidate for Some(Text) is "/home/wez/.icons/Adwaita/cursors/xterm"
07:34:41.839  TRACE  window::os::x11::cursor > candidate for Some(Text) is "/home/wez/.local/share/flatpak/exports/share/icons/Adwaita/cursors/xterm"
07:34:41.839  TRACE  window::os::x11::cursor > candidate for Some(Text) is "/var/lib/flatpak/exports/share/icons/Adwaita/cursors/xterm"
07:34:41.839  TRACE  window::os::x11::cursor > candidate for Some(Text) is "/usr/local/share/icons/Adwaita/cursors/xterm"
07:34:41.839  TRACE  window::os::x11::cursor > candidate for Some(Text) is "/usr/share/icons/Adwaita/cursors/xterm"
07:34:41.839  TRACE  window::os::x11::cursor > Some(Text) resolved to "/usr/share/icons/Adwaita/cursors/xterm"
07:34:42.915  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/home/wez/.local/share/icons/Adwaita/cursors/top_left_arrow"
07:34:42.915  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/home/wez/.local/share/icons/Adwaita/cursors/left_ptr"
07:34:42.915  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/home/wez/.icons/Adwaita/cursors/top_left_arrow"
07:34:42.915  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/home/wez/.icons/Adwaita/cursors/left_ptr"
07:34:42.915  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/home/wez/.local/share/flatpak/exports/share/icons/Adwaita/cursors/top_left_arrow"
07:34:42.915  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/home/wez/.local/share/flatpak/exports/share/icons/Adwaita/cursors/left_ptr"
07:34:42.916  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/var/lib/flatpak/exports/share/icons/Adwaita/cursors/top_left_arrow"
07:34:42.916  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/var/lib/flatpak/exports/share/icons/Adwaita/cursors/left_ptr"
07:34:42.916  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/usr/local/share/icons/Adwaita/cursors/top_left_arrow"
07:34:42.916  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/usr/local/share/icons/Adwaita/cursors/left_ptr"
07:34:42.916  TRACE  window::os::x11::cursor > candidate for Some(Arrow) is "/usr/share/icons/Adwaita/cursors/top_left_arrow"
07:34:42.917  TRACE  window::os::x11::cursor > Some(Arrow) resolved to "/usr/share/icons/Adwaita/cursors/top_left_arrow"

Getting Help

This is a spare time project, so please bear with me. There are a couple of channels for support:

The GitHub Discussions and Element/Gitter rooms are better suited to questions than it is to bug reports, but don't be afraid to use whichever you are most comfortable using and we'll work it out.

Contributing

Thanks for considering donating your time and energy! I value any contribution, even if it is just to highlight a typo.

If you're thinking of helping out, then the following resources may be helpful:

I like to think that I have an open mind and I try to be open to ideas, suggestions and other improvements. We can discuss in realtime in the Matrix/Gitter room or we can do it asynchronously via the issue tracker on GitHub.

You needn't be a crack Rust coder; if you spot a typo or feel like you can see a way to improve these docs or have a talent for design and would like to help make WezTerm look cooler, I'd also welcome your contribution!

Command Line

This section documents the wezterm command line.

Note that wezterm --help or wezterm SUBCOMMAND --help will show the precise set of options that are applicable to your installed version of wezterm.

wezterm is deployed with two major executables:

  • wezterm (or wezterm.exe on Windows) - for interacting with wezterm from the terminal
  • wezterm-gui (or wezterm-gui.exe on Windows) - for spawning wezterm from a desktop environment

You will typically use wezterm when scripting wezterm; it knows when to delegate to to wezterm-gui under the covers.

If you are are setting up a launcher for wezterm to run in the Windows GUI environment then you will want to explicitly target wezterm-gui so that Windows itself doesn't pop up a console host for its logging output.

wezterm cli

The cli subcommand interacts with a running wezterm GUI or multiplexer instance, and can be used to spawn programs and manipulate tabs and panes.

Targeting the correct instance

There may be multiple GUI processes running in addition to a multiplexer server. wezterm uses the following logic to decide which one it should connect to.

  • If the --prefer-mux flag is passed, then the wezterm.lua config file is consulted to determine the first unix domain defined by the config.
  • If the $WEZTERM_UNIX_SOCKET environment variable is set, use that location to identify the running instance
  • Try to locate a running GUI instance. The --class argument specifies an optional window class that can be used to select the appropriate GUI window if that GUI window was also spawned using --class to override the default.

Targeting Panes

Various subcommands target panes via a (typically optional) --pane-id argument.

The following rules are used to determine a pane if --pane-id is not specified:

  • If the $WEZTERM_PANE environment variable is set, it will be used
  • The list of clients is retrieved and sorted by the most recently interacted session. The focused pane id from that session is used

See also: wezterm cli list

Available Subcommands

wezterm cli list-clients

Run wezterm cli list-clients --help to see more help

Lists the set of connected clients and some additional information about them:

$ wezterm cli list-clients
USER HOST     PID CONNECTED     IDLE       WORKSPACE FOCUS
wez  foo  1098536 166.03140978s 31.40978ms default       0

The meanings of the fields are:

  • USER - the username associated with the session
  • HOST - the hostname associated with the session
  • PID - the process id of the client session
  • CONNECTED - shows how long the connection has been established
  • IDLE - shows how long it has been since input was received from that client
  • WORKSPACE - shows the active workspace for that session
  • FOCUS - shows the pane id of the pane that has focus in that session

Since: 20220624-141144-bd1b7c5d

You may request JSON output:

$ wezterm cli list-clients --format json
[
  {
    "username": "wez",
    "hostname": "foo",
    "pid": 1098536,
    "connection_elapsed": {
      "secs": 226,
      "nanos": 502667166
    },
    "idle_time": {
      "secs": 0,
      "nanos": 502667166
    },
    "workspace": "default",
    "focused_pane_id": 0
  }
]

wezterm cli list

Run wezterm cli list --help to see more help

Lists the set of windows, tabs and panes that are being managed.

The default output is tabular:

$ wezterm cli list
WINID TABID PANEID WORKSPACE SIZE  TITLE                          CWD
    0     0      0 default   80x24 wezterm cli list  -- wez@foo:~ file://foo/home/wez/

Each row describes a pane. The meaning of the fields are:

  • WINID - the window id of the window that contains the pane
  • TABID - the tab id of the tab that contains the pane
  • PANEID - the pane id
  • WORKSPACE - the workspace that the pane is associated with
  • SIZE - the dimensions of the pane, measured in terminal cell columns x rows
  • TITLE - the pane title
  • CWD - the current working directory associated with the pane

Since: 20220624-141144-bd1b7c5d

You may request JSON output:

$ wezterm cli list --format json
[
  {
    "window_id": 0,
    "tab_id": 0,
    "pane_id": 0,
    "workspace": "default",
    "size": {
      "rows": 24,
      "cols": 80
    },
    "title": "wezterm cli list --format json -- wez@foo:~",
    "cwd": "file://foo/home/wez/"
  }
]

wezterm cli move-pane-to-new-tab

Since: 20220624-141144-bd1b7c5d

Run wezterm cli move-pane-to-new-tab --help to see more help

Allows moving a pane into a new tab either in the same window or in a new window.

The default action is to move the current pane into a new tab in the same window. The following arguments modify the behavior:

  • --new-window - Create tab in a new window
  • --window-id WINDOW_ID - Create the new tab in the specified window id rather than the current window.
  • --workspace WORKSPACE - When using --new-window, use WORKSPACE as the name of the workspace for the newly created window rather than the default workspace name "default".
  • --pane-id - Specifies which pane to move. See also Targeting Panes.

wezterm cli send-text

Run wezterm cli send-text --help to see more help

Send text to a pane as though it were pasted. If bracketed paste mode is enabled in the pane, then the text will be sent as a bracketed paste.

For example:

$ wezterm cli send-text "hello there"

will cause hello there to be sent to the input in the current pane.

You can also pipe text in via stdin:

$ echo hello there | wezterm cli send-text

The following arguments modify the behavior:

  • --no-paste - Send the text directly, rather than as a bracketed paste. (Since: 20220624-141144-bd1b7c5d)
  • --pane-id - Specifies which pane to send the text to. See also Targeting Panes.

wezterm cli spawn

Run wezterm cli spawn --help to see more help

Spawn a command into a new tab or window. Outputs the pane-id for the newly created pane on success.

When run with no arguments, it will spawn a new tab running the default program; this example spawns a new pane with id 1 running that default program (most likely: your shell):

$ wezterm cli spawn
1

You may spawn an alternative program by passing the argument list; it is recommended that you use -- to denote the end of the arguments being passed to wezterm cli spawn so that any parameters you may wish to pass to the program are not confused with parameters to wezterm cli spawn. This example launches top in a new tab:

$ wezterm cli spawn -- top
2

This example explicitly runs bash as a login shell:

$ wezterm cli spawn -- bash -l
3

The following options affect the behavior:

  • --cwd CWD - Specifies the current working directory that should be set for the spawned program
  • --domain-name DOMAIN_NAME - Spawn into the named multiplexer domain. The default is to spawn into the domain of the current pane.
  • --new-window - Spawns the tab into a window of its own.
  • --workspace WORKSPACE - when using --new-window, set the workspace name rather than using the default name of "default".
  • --window-id WINDOW_ID - Spawn the tab into the specified window, rather than using the current window

wezterm cli split-pane

Run wezterm cli split-pane --help to see more help

Split the current pane. Outputs the pane-id for the newly created pane on success.

This command will create a split in the current pane and spawn a command into it. This splits the pane and creates a new one at the bottom running the default command:

$ wezterm cli split-pane
2

You may spawn an alternative program by passing the argument list; it is recommended that you use -- to denote the end of the arguments being passed to wezterm cli split-pane so that any parameters you may wish to pass to the program are not confused with parameters to wezterm cli split-pane. This example launches bash as a login shell in a new pane at the bottom:

$ wezterm cli split-pane -- bash -l
3

This example creates a split to the left, occupying 30% of the available space:

$ wezterm cli split-pane --left --percent 30
4

The following options affect the behavior:

  • --cwd CWD - Specify the current working directory for the initially spawned program.
  • --horizontal - Equivalent to --right. If neither this nor any other direction is specified, the default is equivalent to --bottom.
  • --pane-id - Specifies the pane that should be split. See also Targeting Panes.

Since 20220624-141144-bd1b7c5d

  • --bottom - Split vertically, with the new pane on the bottom.
  • --cells CELLS - The number of cells that the new split should have. If omitted, 50% of the available space is used.
  • --left - Split horizontally, with the new pane on the left.
  • --move-pane-id MOVE_PANE_ID - Instead of spawning a new command, move the specified pane into the newly created split.
  • --percent PERCENT - Specify the number of cells that the new split should have, expressed as a percentage of the available space.
  • --right - Split horizontally, with the new pane on the right.
  • --top - Split vertically, with the new pane on the top.
  • --top-level - Rather than splitting the active pane, split the entire window.

wezterm show-keys

Since: 20220624-141144-bd1b7c5d

Prints the complete set of key assignments based on your config file.

The command shows each key table as well as the set of mouse bindings.

A truncated example of the output is shown below.

Default key table
-----------------

        CTRL                 Tab                ->   ActivateTabRelative(1)
        SHIFT | CTRL         Tab                ->   ActivateTabRelative(-1)
        ...

Key Table: copy_mode
--------------------

                Tab          ->   CopyMode(MoveForwardWord)
        SHIFT   Tab          ->   CopyMode(MoveBackwardWord)
        SHIFT   $            ->   CopyMode(MoveToEndOfLineContent)
        ...

Key Table: search_mode
----------------------

               Enter       ->   CopyMode(PriorMatch)
               Escape      ->   CopyMode(Close)
        CTRL   n           ->   CopyMode(NextMatch)
        ...

Mouse
-----

                       Down { streak: 1, button: Left }     ->   SelectTextAtMouseCursor(Cell)
        SHIFT          Down { streak: 1, button: Left }     ->   ExtendSelectionToMouseCursor(None)
        ALT            Down { streak: 1, button: Left }     ->   SelectTextAtMouseCursor(Block)
        ...

Lua Reference

This section documents the various lua functions and types that are provided to the configuration file. These are provided by the wezterm module that must be imported into your configuration file:

local wezterm = require 'wezterm';
return {
  font = wezterm.font("JetBrains Mono"),
}

Making your own Lua Modules

If you'd like to break apart your configuration into multiple files, you'll be interested in this information.

The package.path is configured with the following paths in this order:

  • On Windows: a wezterm_modules dir in the same directory as wezterm.exe
  • ~/.config/wezterm
  • ~/.wezterm
  • A system specific set of paths which may (or may not!) find locally installed lua modules

That means that if you wanted to break your config up into a helpers.lua file you would place it in ~/.config/wezterm/helpers.lua with contents like this:

-- I am helpers.lua and I should live in ~/.config/wezterm/helpers.lua

local wezterm = require 'wezterm';

-- This is the module table that we will export
local module = {}

-- This function is private to this module and is not visible
-- outside.
local function private_helper()
  wezterm.log_error("hello!")
end

-- define a function in the module table.
-- Only functions defined in `module` will be exported to
-- code that imports this module
function module.my_function()
  private_helper()
end

-- return our module table
return module

and then in your wezterm.lua you would use it like this:

local helpers = require 'helpers';
helpers.my_function()

require wezterm

The wezterm module is the primary module that exposes wezterm configuration and control to your config file.

You will typically place:

local wezterm = require 'wezterm';

at the top of your configuration file to enable it.

Available functions, constants

wezterm.GLOBAL

Since: 20220624-141144-bd1b7c5d

Provides global, in-process, in-memory, data storage for json-like variables that persists across config reloads.

wezterm's lua files may be re-loaded and re-evaluated multiple times in different contexts or in different threads. If you'd like to keep track of state that lasts for the lifetime of your wezterm process then you cannot simply use global variables in the lua script.

wezterm.GLOBAL is a special userdata value that acts like a table. Writing to keys will copy the data that you assign into a global in-memory table and allow it to be read back later.

Reads and writes from/to wezterm.GLOBAL are thread-safe but don't currently provide synchronization primitives for managing read-modify-write operations.

The following example shows the number of times that the config has been loaded in the right status bar. Watch it increase when you press the ReloadConfiguration key assignment (CTRL-SHIFT-R):

local wezterm = require 'wezterm'

-- Count how many times the lua config has been loaded
wezterm.GLOBAL.parse_count = (wezterm.GLOBAL.parse_count or 0) + 1

wezterm.on("update-right-status", function(window, pane)
  window:set_right_status("Reloads=" .. tostring(wezterm.GLOBAL.parse_count))
end)

return {}

Note that the reload counter goes up by more than 1 when you reload: that is because the config is evaluated multiple times in different threads as part of safely validating and setting up the configuration.

You may store values with the following types:

  • string
  • number
  • table
  • boolean

Attempting to assign other types will raise an error.

wezterm.action

Helper for defining key assignment actions in your configuration file. This is really just sugar for the underlying Lua -> Rust deserialation mapping that makes it a bit easier to identify where syntax errors may exist in your configuration file.

Constructor Syntax

Since: 20220624-141144-bd1b7c5d

wezterm.action is a special enum constructor type that makes it bit more ergonomic to express the various actions than in earlier releases. The older syntax is still supported, so you needn't scramble to update your configuration files.

Indexing wezterm.action with a valid KeyAssignment name will act as a constructor for that key assignment type. For example, the lua expression:

wezterm.action.QuickSelectArgs

is a constructor for QuickSelectArgs.

If the key assignment type is a unit variant (has no parameters) such as Copy, or can be constructed with default values such as QuickSelectArgs then you can reference the constructor directly to have it evaluate as that value without having to add any extra punctuation:

local wezterm = require 'wezterm'
return {
   keys = {
     {key=" ", mods="CTRL|SHIFT", action=wezterm.action.QuickSelectArgs},
   }
}

You may pass the optional parameters to QuickSelectArgs as you need them, like this:

local wezterm = require 'wezterm'
return {
   keys = {
     {key=" ", mods="CTRL|SHIFT", action=wezterm.action.QuickSelectArgs{
      alphabet="abc"
     }},
   }
}

If the key assignment type is a tuple variant (has positional parameters) such as ActivatePaneByIndex, then you can pass those by calling the constructor:

local wezterm = require 'wezterm'
-- shortcut to save typing below
local act = wezterm.action

return {
   keys = {
     {key="F1", mods="ALT", action=act.ActivatePaneByIndex(0)},
     {key="F2", mods="ALT", action=act.ActivatePaneByIndex(1)},
     {key="F3", mods="ALT", action=act.ActivatePaneByIndex(2)},
     {key="F4", mods="ALT", action=act.ActivatePaneByIndex(3)},
     {key="F5", mods="ALT", action=act.ActivatePaneByIndex(4)},
     {key="F6", mods="ALT", action=act.ActivatePaneByIndex(5)},
     {key="F7", mods="ALT", action=act.ActivatePaneByIndex(6)},
     {key="F8", mods="ALT", action=act.ActivatePaneByIndex(7)},
     {key="F9", mods="ALT", action=act.ActivatePaneByIndex(8)},
     {key="F10", mods="ALT", action=act.ActivatePaneByIndex(9)},

     -- Compare this with the older syntax shown in the section below
     {key="{", mods="CTRL", action=act.ActivateTabRelative(-1)},
     {key="}", mods="CTRL", action=act.ActivateTabRelative(1)},
   }
}

Older versions

For versions before 20220624-141144-bd1b7c5d, usage looks like this:

local wezterm = require 'wezterm';
return {
   keys = {
     {key="{", mods="CTRL", action=wezterm.action{ActivateTabRelative=-1}},
     {key="}", mods="CTRL", action=wezterm.action{ActivateTabRelative=1}},
   }
}

The parameter is a lua representation of the underlying KeyAssignment enum from the configuration code. These docs aim to spell out sufficient examples that you shouldn't need to learn to read Rust code, but there are occasions where newly developed features are not yet documented and an enterprising user may wish to go spelunking to figure them out!

You can find the reference for available KeyAssignment values here.

wezterm.action_callback(callback)

Since: 20211204-082213-a66c61ee9

This function is a helper to register a custom event and return an action triggering it.

It is helpful to write custom key bindings directly, without having to declare the event and use it in a different place.

The implementation is essentially the same as:

function wezterm.action_callback(callback)
  local event_id = "..." -- the function generates a unique event id
  wezterm.on(event_id, callback)
  return wezterm.action.EmitEvent(event_id)
end

See wezterm.on and wezterm.action for more info on what you can do with these.

Usage

local wezterm = require 'wezterm';

return {
  keys = {
    {
      mods = "CTRL|SHIFT",
      key = "i",
      action = wezterm.action_callback(function(win, pane)
        wezterm.log_info("Hello from callback!")
        wezterm.log_info("WindowID:", win:window_id(), "PaneID:", pane:pane_id())
      end)
    },
  }
}

wezterm.add_to_config_reload_watch_list(path)

Since: 20210814-124438-54e29167

Adds path to the list of files that are watched for config changes. If automatically_reload_config is enabled, then the config will be reloaded when any of the files that have been added to the watch list have changed.

Since: nightly builds only

This function is now called implicitly when you require a lua file.

wezterm.background_child_process(args)

Since: 20211204-082213-a66c61ee9

This function accepts an argument list; it will attempt to spawn that command in the background.

May generate an error if the command is not able to be spawned (eg: perhaps the executable doesn't exist), but not all operating systems/environments report all types of spawn failures immediately upon spawn.

This function doesn't return any value.

This example shows how you might set up a custom key assignment that opens the terminal background image in a separate image viewer process:

local wezterm = require 'wezterm'

return {
  window_background_image = "/home/wez/Downloads/sunset-american-fork-canyon.jpg",
  keys = {
    {mods="CTRL|SHIFT", key="m",
      action=wezterm.action_callback(function(win, pane)
        wezterm.background_child_process(
            {"xdg-open", win:effective_config().window_background_image})
      end)
    }
  }
}

See also run_child_process

wezterm.battery_info()

Since: 20210314-114017-04b7cedd

This function returns battery information for each of the installed batteries on the system. This is useful for example to assemble status information for the status bar.

The return value is an array of objects with the following fields:

  • state_of_charge - the battery level expressed as a number between 0.0 (empty) and 1.0 (full)
  • vendor - battery manufacturer name, or "unknown" if not known.
  • model - the battery model string, or "unknown" if not known.
  • serial - the battery serial number, or "unknown" if not known.
  • time_to_full - if charging, how long until the battery is full (in seconds). May be nil.
  • time_to_empty - if discharing, how long until the battery is empty (in seconds). May be nil.
  • state - "Charging", "Discharging", "Empty", "Full", "Unknown"

This example shows the battery status for each battery, along with the date and time in the status bar:

local wezterm = require 'wezterm';

wezterm.on("update-right-status", function(window, pane)
  -- "Wed Mar 3 08:14"
  local date = wezterm.strftime("%a %b %-d %H:%M ");

  local bat = ""
  for _, b in ipairs(wezterm.battery_info()) do
    bat = "🔋 " .. string.format("%.0f%%", b.state_of_charge * 100)
  end

  window:set_right_status(wezterm.format({
    {Text=bat .. "   "..date},
  }));
end)

wezterm.column_width(string)

Since: 20210502-130208-bff6815d

Given a string parameter, returns the number of columns that that text occupies in the terminal, which is useful together with format-tab-title and update-right-status to compute/layout tabs and status information.

This is different from string.len which returns the number of bytes that comprise the string.

wezterm.config_dir

This constant is set to the path to the directory in which your wezterm.lua configuration file was found.

local wezterm = require 'wezterm';
wezterm.log_error("Config Dir " .. wezterm.config_dir)

wezterm.config_file

Since: 20210502-130208-bff6815d

This constant is set to the path to the wezterm.lua that is in use.

local wezterm = require 'wezterm';
wezterm.log_info("Config file " .. wezterm.config_file)

wezterm.default_wsl_domains()

Since: 20220319-142410-0fcdea07

Computes a list of WslDomain objects, each one representing an installed WSL distribution on your system.

This list is the same as the default value for the wsl_domains configuration option, which is to make a WslDomain with the distribution field set to the name of WSL distro and the name field set to name of the distro but with "WSL:" prefixed to it.

For example, if:

; wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-18.04    Running         1

then this function will return:

{
  { name: "WSL:Ubuntu-18.04",
    distribution: "Ubuntu-18.04",
  },
}

The purpose of this function is to aid in situations where you might want set default_prog for the WSL distributions:

local wezterm = require 'wezterm'

local wsl_domains = wezterm.default_wsl_domains()

for idx, dom in ipairs(wsl_domains) do
  if dom.name == "WSL:Ubuntu-18.04" then
    dom.default_prog = {"fish"}
  end
end

return {
  wsl_domains = wsl_domains,
}

However, wez strongly recommends that you use chsh inside the WSL domain to make that the default shell if possible, so that you can avoid this additional configuration!

wezterm.emit(event_name, args...)

Since: 20201031-154415-9614e117

wezterm.emit resolves the registered callback(s) for the specified event name and calls each of them in turn, passing the additional arguments through to the callback.

If a callback returns false then it prevents later callbacks from being called for this particular call to wezterm.emit, and wezterm.emit will return false to indicate that no additional/default processing should take place.

If none of the callbacks returned false then wezterm.emit will itself return true to indicate that default processing should take place.

This function has no special knowledge of which events are defined by wezterm, or what their required arguments might be.

See wezterm.on for more information about event handling.

wezterm.enumerate_ssh_hosts([ssh_config_file_name, ...])

Since: 20220319-142410-0fcdea07

This function will parse your ssh configuration file(s) and extract from them the set of literal (non-pattern, non-negated) host names that are specified in Host and Match stanzas contained in those configuration files and return a mapping from the hostname to the effective ssh config options for that host.

You may optionally pass a list of ssh configuration files that should be read, in case you have a special configuration.

The files you specify (if any) will be parsed first, and then the default locations for your system will be parsed.

All files read by a call to this function, and any include statements processed from those ssh config files, will be added to the config reload watch list as though wezterm.add_to_config_reload_watch_list() was called on them. Note that only concrete path names are watched: if your config uses include to include glob patterns in a directory then, for example, newly created files in that directory will not cause a config reload event in wezterm.

This example shows how to use this function to automatically configure ssh multiplexing domains for the hosts configured in your ~/.ssh/config file:

local wezterm = require 'wezterm'

local ssh_domains = {}

for host, config in pairs(wezterm.enumerate_ssh_hosts()) do
  table.insert(ssh_domains, {
    -- the name can be anything you want; we're just using the hostname
    name = host,
    -- remote_address must be set to `host` for the ssh config to apply to it
    remote_address = host,

    -- if you don't have wezterm's mux server installed on the remote
    -- host, you may wish to set multiplexing = "None" to use a direct
    -- ssh connection that supports multiple panes/tabs which will close
    -- when the connection is dropped.

    -- multiplexing = "None",


    -- if you know that the remote host has a posix/unix environment,
    -- setting assume_shell = "Posix" will result in new panes respecting
    -- the remote current directory when multiplexing = "None".
    assume_shell = "Posix",
  })
end

return {
  ssh_domains = ssh_domains,
}

This shows the structure of the returned data, by evaluating the function in the debug overlay (CTRL-SHIFT-L):

> wezterm.enumerate_ssh_hosts()
{
    "aur.archlinux.org": {
        "hostname": "aur.archlinux.org",
        "identityagent": "/run/user/1000/keyring/ssh",
        "identityfile": "/home/wez/.ssh/aur",
        "port": "22",
        "user": "aur",
        "userknownhostsfile": "/home/wez/.ssh/known_hosts /home/wez/.ssh/known_hosts2",
    },
    "woot": {
        "hostname": "localhost",
        "identityagent": "/run/user/1000/keyring/ssh",
        "identityfile": "/home/wez/.ssh/id_dsa /home/wez/.ssh/id_ecdsa /home/wez/.ssh/id_ed25519 /home/wez/.ssh/id_rsa",
        "port": "22",
        "user": "someone",
        "userknownhostsfile": "/home/wez/.ssh/known_hosts /home/wez/.ssh/known_hosts2",
    },
}

the corresponding ~/.ssh/config file for the above is shown below: note host the Host group with a wildcard is not returned by the function because it doesn't have a concrete host name:

Host aur.archlinux.org
  IdentityFile ~/.ssh/aur
  User aur

Host 192.168.1.*
  ForwardAgent yes
  ForwardX11 yes

Host woot
  User someone
  Hostname localhost

wezterm.executable_dir

This constant is set to the directory containing the wezterm executable file.

local wezterm = require 'wezterm';
wezterm.log_error("Exe dir " .. wezterm.executable_dir)

wezterm.font(family [, attributes])

This function constructs a lua table that corresponds to the internal FontAttributes struct that is used to select a single named font:

local wezterm = require 'wezterm';

return {
  font = wezterm.font("JetBrains Mono"),
}

The first parameter is the name of the font; the name can be one of the following types of names:

  • The font family name, eg: "JetBrains Mono". The family name doesn't include any style information (such as weight, stretch or italic), which can be specified via the attributes parameter. This is the recommended name to use for the font, as it the most compatible way to resolve an installed font.
  • The computed full name, which is the family name with the sub-family (which incorporates style information) appended, eg: "JetBrains Mono Regular".
  • (Since 20210502-154244-3f7122cb) The postscript name, which is an ostensibly unique name identifying a given font and style that is encoded into the font by the font designer.

When specifying a font using its family name, the second attributes parameter is an optional table that can be used to specify style attributes; the following keys are allowed:

  • bold - whether to select a bold variant of the font (default: false)
  • italic - whether to select an italic variant of the font (default: false)

When attributes are specified, the font must match both the family name and attributes in order to be selected.

local wezterm = require 'wezterm';

return {
  font = wezterm.font("JetBrains Mono", {bold=true}),
}

Since: 20210502-130208-bff6815d

It is now possible to specify both font weight and font stretch when matching fonts:

  • stretch - specifies the font stretch to select. The default value is "Normal", and possible values are "UltraCondensed", "ExtraCondensed", "Condensed", "SemiCondensed", "Normal", "SemiExpanded", "Expanded", "ExtraExpanded", "UltraExpanded".
  • weight - specifies the weight of the font with more precision than bold. The default value is "Regular", and possible values are "Thin", "ExtraLight", "Light", "DemiLight", "Book", "Regular", "Medium", "DemiBold", "Bold", "ExtraBold", "Black", and "ExtraBlack".
  • bold - has been superseded by the new weight parameter and will be eventually removed. For compatibility purposes, specifying bold=true is equivalent to specifying weight="Bold".

These parameters are passed to the system font locator when resolving the font, which will apply system-specific rules to resolve the font.

When resolving fonts from font_dirs, wezterm follows CSS Fonts Level 3 compatible font matching, which tries to exactly match the specified attributes, but allows for locating a close match within the specified font family.

local wezterm = require 'wezterm';

return {
  font = wezterm.font('Iosevka Term', {stretch="Expanded", weight="Regular"}),
}

An alternative form of specifying the font can be used, where the family and the attributes are combined in the same lua table. This form is most useful when used together with wezterm.font_with_fallback when you want to specify precise weights for the different fallback fonts:

local wezterm = require 'wezterm';

return {
  font = wezterm.font({family='Iosevka Term', stretch="Expanded", weight="Regular"}),
}

Since: 20220101-133340-7edc5b5a

You can use the expanded form mentioned above to override freetype and harfbuzz settings just for the specified font; this examples shows how to disable the default ligature feature just for this particular font:

local wezterm = require 'wezterm'
return {
  font = wezterm.font({
    family="JetBrains Mono",
    harfbuzz_features={"calt=0", "clig=0", "liga=0"},
  })
}

The following options can be specified in the same way:

Since: 20220319-142410-0fcdea07

You may now specify style="Normal", style="Italic" or style="Oblique" instead of simply specifying a boolean italic value such as italic=true.

italic=false is equivalent to style="Normal", and italic=true is equivalent to style="Italic".

"Oblique" and "Italic" fonts are similar in the sense that the glyphs are presented at an angle. "Italic" fonts usually have a distinctive design difference from the "Normal" style in a given font family, whereas "Oblique" usually looks very similar to "Normal", but skewed at an angle.

wezterm.font_with_fallback(families [, attributes])

This function constructs a lua table that configures a font with fallback processing. Glyphs are looked up in the first font in the list but if missing the next font is checked and so on.

The first parameter is a table listing the fonts in their preferred order:

local wezterm = require 'wezterm';

return {
  font = wezterm.font_with_fallback({"JetBrains Mono", "Noto Color Emoji"}),
}

WezTerm implicitly adds its default fallback to the list that you specify.

The attributes parameter behaves the same as that of wezterm.font in that it allows you to specify font weight and style attributes that you want to match.

Since: 20210502-130208-bff6815d

The attributes can now be specified per fallback font using this alternative form where the family and attributes are specified as part of the same lua table:

local wezterm = require 'wezterm';

return {
  font = wezterm.font_with_fallback({
    {family="JetBrains Mono", weight="Medium"},
    {family="Terminus", weight="Bold"},
    "Noto Color Emoji",
  }),
}

Since: 20220101-133340-7edc5b5a

You can use the expanded form mentioned above to override freetype and harfbuzz settings just for the specified font; this examples shows how to disable the default ligature feature just for JetBrains Mono, but leave it on for the other fonts in the fallback:

local wezterm = require 'wezterm';

return {
  font = wezterm.font_with_fallback({
    {
      family="JetBrains Mono",
      harfbuzz_features={"calt=0", "clig=0", "liga=0"},
    },
    {family="Terminus", weight="Bold"},
    "Noto Color Emoji",
  }),
}

The following options can be specified in the same way:

Dealing with different fallback font heights

When mixing different font families there is a chance that glyphs from one font don't appear to be the same height as the glyphs from your primary font.

For "Roman" fonts there exists a font metric known as cap-height which indicates the nominal size of a capital (uppercase) letter that can be used to compute a scaling factor that can be used to make the fallback font appear to have the same size.

Setting use_cap_height_to_scale_fallback_fonts = true will cause wezterm to try to automatically scale using the cap-height metric (or to compute its own idea of the cap-height based on the size of glyph(s)).

Manual fallback scaling

Since: 20220408-101518-b908e2dd

CJK fonts typically won't have a useful cap-height metric so it may be desirable to manually configure the fallback scaling factor to boost the size of the CJK font so that the glyphs are more readable.

The example below shows how to boost the effective size of the "Microsoft YaHei" fallback font to 1.5 times the normal size. The boost cannot influence font metrics so it may be desirable to also specify line_height to produce a more pleasing display.

local wezterm = require 'wezterm'

return {
  line_height = 1.2,
  font = wezterm.font_with_fallback({
    "JetBrains Mono",
    {family="Microsoft YaHei", scale=1.5},
  }),
}

wezterm.format({})

Since: 20210314-114017-04b7cedd

wezterm.format can be used to produce a formatted string with terminal graphic attributes such as bold, italic and colors. The resultant string is rendered into a string with wezterm compatible escape sequences embedded.

wezterm.format accepts a single array argument, where each element is a FormatItem.

This example logs the text Hello, then the date/time, underlined, in purple text on a blue background to the stderr of the wezterm process:

local wezterm = require 'wezterm';

local success, date, stderr = wezterm.run_child_process({"date"});

wezterm.log_info(wezterm.format({
  {Attribute={Underline="Single"}},
  {Foreground={AnsiColor="Fuchsia"}},
  {Background={Color="blue"}},
  {Text="Hello " .. date},
}))

Possible values for the FormatItem elements are:

  • {Text="Hello"} - the text Hello. The string can be any string expression.
  • {Attribute={Underline="None"}} - disable underline
  • {Attribute={Underline="Single"}} - enable single underline
  • {Attribute={Underline="Double"}} - enable double underline
  • {Attribute={Underline="Curly"}} - enable curly underline
  • {Attribute={Underline="Dotted"}} - enable dotted underline
  • {Attribute={Underline="Dashed"}} - enable dashed underline
  • {Attribute={Intensity="Normal"}} - set normal intensity
  • {Attribute={Intensity="Bold"}} - set bold intensity
  • {Attribute={Intensity="Half"}} - set half intensity
  • {Attribute={Italic=true}} - enable italics
  • {Attribute={Italic=false}} - disable italics
  • {Foreground={AnsiColor="Black"}} - set foreground color to one of the ansi color palette values (index 0-15) using one of the names Black, Maroon, Green, Olive, Navy, Purple, Teal, Silver, Grey, Red, Lime, Yellow, Blue, Fuchsia, Aqua or White.
  • {Foreground={Color="yellow"}} - set foreground color to a named color or rgb value like #ffffff.
  • {Background={AnsiColor="Black"}} - set the background color to an ansi color as per Foreground above.
  • {Background={Color="blue"}} - set the background color to a named color or rgb value as per Foreground above.

wezterm.get_builtin_color_schemes()

Since: 20220101-133340-7edc5b5a

Returns a lua table keyed by color scheme name and whose values are the color scheme definition of the builtin color schemes.

This is useful for programmatically deciding things about the scheme to use based on its color, or for taking a scheme and overriding a couple of entries just from your wezterm.lua configuration file.

This example shows how to make wezterm pick a random color scheme for each newly created window:

local wezterm = require 'wezterm'

-- The set of schemes that we like and want to put in our rotation
local schemes = {}
for name, scheme in pairs(wezterm.get_builtin_color_schemes()) do
  table.insert(schemes, name)
end

wezterm.on("window-config-reloaded", function(window, pane)
  -- If there are no overrides, this is our first time seeing
  -- this window, so we can pick a random scheme.
  if not window:get_config_overrides() then
    -- Pick a random scheme name
    local scheme = schemes[math.random(#schemes)]
    window:set_config_overrides({
      color_scheme = scheme
    })
  end
end)

return {
}

This example shows how to take an existing scheme, modify a color, and then use that new scheme to override the default:

local wezterm = require 'wezterm'

local scheme = wezterm.get_builtin_color_schemes()["Gruvbox Light"]
scheme.background = "red"

return {
  color_schemes = {
    -- Override the builtin Gruvbox Light scheme with our modification.
    ["Gruvbox Light"] = scheme,

    -- We can also give it a different name if we don't want to override
    -- the default
    ["Gruvbox Red"] = scheme,
  },
  color_scheme = "Gruvbox Light",
}

wezterm.glob(pattern [, relative_to])

Since: 20200503-171512-b13ef15f

This function evalutes the glob pattern and returns an array containing the absolute file names of the matching results. Due to limitations in the lua bindings, all of the paths must be able to be represented as UTF-8 or this function will generate an error.

The optional relative_to parameter can be used to make the results relative to a path. If the results have the same prefix as relative_to then it will be removed from the returned path.

local wezterm = require 'wezterm';

-- logs the names of all of the conf files under `/etc`
for _, v in ipairs(wezterm.glob("/etc/*.conf")) do
  wezterm.log_error("entry: " .. v)
end

wezterm.gradient_colors(gradient, num_colors)

Since: 20210814-124438-54e29167

Given a gradient spec and a number of colors, returns a table holding that many colors spaced evenly across the range of the gradient.

This is useful for example to generate colors for tabs, or to do something fancy like interpolate colors across a gradient based on the time of the day.

gradient is any gradient allowed by the window_background_gradient option.

This example is what you'd see if you opened up the debug overlay to try this out in the repl:

> wezterm.gradient_colors({preset="Rainbow"}, 4)
["#6e40aa", "#ff8c38", "#5dea8d", "#6e40aa"]

wezterm.home_dir

This constant is set to the home directory of the user running wezterm.

local wezterm = require 'wezterm';
wezterm.log_error("Home " .. wezterm.home_dir)

wezterm.hostname()

This function returns the current hostname of the system that is running wezterm. This can be useful to adjust configuration based on the host.

Note that environments that use DHCP and have many clients and short leases may make it harder to rely on the hostname for this purpose.

local wezterm = require 'wezterm';
local hostname = wezterm.hostname();

local font_size;
if hostname == "pixelbookgo-localdomain" then
  -- Use a bigger font on the smaller screen of my PixelBook Go
  font_size = 12.0;
else
  font_size = 10.0;
end

return {
  font_size = font_size
}

wezterm.log_error(arg, ..)

This function logs the provided message string through wezterm's logging layer at 'ERROR' level. If you started wezterm from a terminal that text will print to the stdout of that terminal. If running as a daemon for the multiplexer server then it will be logged to the daemon output path.

local wezterm = require 'wezterm';
wezterm.log_error("Hello!");

Since: 20210814-124438-54e29167

Now accepts multiple arguments, and those arguments can be of any type.

See also log_info and log_warn.

wezterm.log_info(arg, ..)

Since: 20210314-114017-04b7cedd

This function logs the provided message string through wezterm's logging layer at 'INFO' level. If you started wezterm from a terminal that text will print to the stdout of that terminal. If running as a daemon for the multiplexer server then it will be logged to the daemon output path.

local wezterm = require 'wezterm';
wezterm.log_info("Hello!");

Since: 20210814-124438-54e29167

Now accepts multiple arguments, and those arguments can be of any type.

See also log_error and log_warn.

wezterm.log_warn(arg, ..)

Since: 20210314-114017-04b7cedd

This function logs the provided message string through wezterm's logging layer at 'WARN' level. If you started wezterm from a terminal that text will print to the stdout of that terminal. If running as a daemon for the multiplexer server then it will be logged to the daemon output path.

local wezterm = require 'wezterm';
wezterm.log_warn("Hello!");

Since: 20210814-124438-54e29167

Now accepts multiple arguments, and those arguments can be of any type.

See also log_info and log_error.

wezterm.nerdfonts

Since: 20220319-142410-0fcdea07

A special userdata value that can be used to resolve the symbolic name of a glyph from the Nerd Fonts font set into a string that can be used for example when formatting status lines and titles in your wezterm configuration.

WezTerm includes Nerd Font Symbols Font as a default font fallback which means that these special symbols are available even without requiring you to use a patched font.

This example shows how to lookup wezterm.nerdfonts.mdi_clock, the Material Design Icons glyph representing a clock, and use that together with the current date/time in the status area:

local wezterm = require 'wezterm';

wezterm.on("update-right-status", function(window, pane)
  -- "Wed Mar 3 08:14"
  local date = wezterm.strftime("%a %b %-d %H:%M ");

  window:set_right_status(wezterm.format({
    {Text=wezterm.nerdfonts.mdi_clock .. " "..date},
  }));
end)

The following symbols are defined:

custom_c
custom_cpp
custom_crystal
custom_electron
custom_elixir
custom_elm
custom_folder
custom_folder_config
custom_folder_git
custom_folder_git_branch
custom_folder_github
custom_folder_npm
custom_folder_open
custom_go
custom_msdos
custom_puppet
custom_purescript
custom_vim
custom_windows
dev_android
dev_angular
dev_appcelerator
dev_apple
dev_appstore
dev_aptana
dev_asterisk
dev_atlassian
dev_atom
dev_aws
dev_backbone
dev_bing_small
dev_bintray
dev_bitbucket
dev_blackberry
dev_bootstrap
dev_bower
dev_brackets
dev_bugsense
dev_celluloid
dev_chart
dev_chrome
dev_cisco
dev_clojure
dev_clojure_alt
dev_cloud9
dev_coda
dev_code
dev_code_badge
dev_codeigniter
dev_codepen
dev_codrops
dev_coffeescript
dev_compass
dev_composer
dev_creativecommons
dev_creativecommons_badge
dev_css3
dev_css3_full
dev_css_tricks
dev_cssdeck
dev_dart
dev_database
dev_debian
dev_digital_ocean
dev_django
dev_dlang
dev_docker
dev_doctrine
dev_dojo
dev_dotnet
dev_dreamweaver
dev_dropbox
dev_drupal
dev_eclipse
dev_ember
dev_envato
dev_erlang
dev_extjs
dev_firebase
dev_firefox
dev_fsharp
dev_ghost
dev_ghost_small
dev_git
dev_git_branch
dev_git_commit
dev_git_compare
dev_git_merge
dev_git_pull_request
dev_github
dev_github_alt
dev_github_badge
dev_github_full
dev_gnu
dev_go
dev_google_cloud_platform
dev_google_drive
dev_grails
dev_groovy
dev_grunt
dev_gulp
dev_hackernews
dev_haskell
dev_heroku
dev_html5
dev_html5_3d_effects
dev_html5_connectivity
dev_html5_device_access
dev_html5_multimedia
dev_ie
dev_illustrator
dev_intellij
dev_ionic
dev_java
dev_javascript
dev_javascript_badge
dev_javascript_shield
dev_jekyll_small
dev_jenkins
dev_jira
dev_joomla
dev_jquery
dev_jquery_ui
dev_komodo
dev_krakenjs
dev_krakenjs_badge
dev_laravel
dev_less
dev_linux
dev_magento
dev_mailchimp
dev_markdown
dev_materializecss
dev_meteor
dev_meteorfull
dev_mitlicence
dev_modernizr
dev_mongodb
dev_mootools
dev_mootools_badge
dev_mozilla
dev_msql_server
dev_mysql
dev_nancy
dev_netbeans
dev_netmagazine
dev_nginx
dev_nodejs
dev_nodejs_small
dev_npm
dev_onedrive
dev_openshift
dev_opensource
dev_opera
dev_perl
dev_phonegap
dev_photoshop
dev_php
dev_postgresql
dev_prolog
dev_python
dev_rackspace
dev_raphael
dev_rasberry_pi
dev_react
dev_redhat
dev_redis
dev_requirejs
dev_responsive
dev_ruby
dev_ruby_on_rails
dev_ruby_rough
dev_rust
dev_safari
dev_sass
dev_scala
dev_scriptcs
dev_scrum
dev_senchatouch
dev_sizzlejs
dev_smashing_magazine
dev_snap_svg
dev_sqllite
dev_stackoverflow
dev_streamline
dev_stylus
dev_sublime
dev_swift
dev_symfony
dev_symfony_badge
dev_techcrunch
dev_terminal
dev_terminal_badge
dev_travis
dev_trello
dev_typo3
dev_ubuntu
dev_uikit
dev_unity_small
dev_vim
dev_visualstudio
dev_w3c
dev_webplatform
dev_windows
dev_wordpress
dev_yahoo
dev_yahoo_small
dev_yeoman
dev_yii
dev_zend
fa_500px
fa_address_book
fa_address_book_o
fa_address_card
fa_address_card_o
fa_adjust
fa_adn
fa_align_center
fa_align_justify
fa_align_left
fa_align_right
fa_amazon
fa_ambulance
fa_american_sign_language_interpreting
fa_anchor
fa_android
fa_angellist
fa_angle_double_down
fa_angle_double_left
fa_angle_double_right
fa_angle_double_up
fa_angle_down
fa_angle_left
fa_angle_right
fa_angle_up
fa_apple
fa_archive
fa_area_chart
fa_arrow_circle_down
fa_arrow_circle_left
fa_arrow_circle_o_down
fa_arrow_circle_o_left
fa_arrow_circle_o_right
fa_arrow_circle_o_up
fa_arrow_circle_right
fa_arrow_circle_up
fa_arrow_down
fa_arrow_left
fa_arrow_right
fa_arrow_up
fa_arrows
fa_arrows_alt
fa_arrows_h
fa_arrows_v
fa_asl_interpreting
fa_assistive_listening_systems
fa_asterisk
fa_at
fa_audio_description
fa_automobile
fa_backward
fa_balance_scale
fa_ban
fa_bandcamp
fa_bank
fa_bar_chart
fa_bar_chart_o
fa_barcode
fa_bars
fa_bath
fa_bathtub
fa_battery
fa_battery_0
fa_battery_1
fa_battery_2
fa_battery_3
fa_battery_4
fa_battery_empty
fa_battery_full
fa_battery_half
fa_battery_quarter
fa_battery_three_quarters
fa_bed
fa_beer
fa_behance
fa_behance_square
fa_bell
fa_bell_o
fa_bell_slash
fa_bell_slash_o
fa_bicycle
fa_binoculars
fa_birthday_cake
fa_bitbucket
fa_bitbucket_square
fa_bitcoin
fa_black_tie
fa_blind
fa_bluetooth
fa_bluetooth_b
fa_bold
fa_bolt
fa_bomb
fa_book
fa_bookmark
fa_bookmark_o
fa_braille
fa_briefcase
fa_btc
fa_bug
fa_building
fa_building_o
fa_bullhorn
fa_bullseye
fa_bus
fa_buysellads
fa_cab
fa_calculator
fa_calendar
fa_calendar_check_o
fa_calendar_minus_o
fa_calendar_o
fa_calendar_plus_o
fa_calendar_times_o
fa_camera
fa_camera_retro
fa_car
fa_caret_down
fa_caret_left
fa_caret_right
fa_caret_square_o_down
fa_caret_square_o_left
fa_caret_square_o_right
fa_caret_square_o_up
fa_caret_up
fa_cart_arrow_down
fa_cart_plus
fa_cc
fa_cc_amex
fa_cc_diners_club
fa_cc_discover
fa_cc_jcb
fa_cc_mastercard
fa_cc_paypal
fa_cc_stripe
fa_cc_visa
fa_certificate
fa_chain
fa_chain_broken
fa_check
fa_check_circle
fa_check_circle_o
fa_check_square
fa_check_square_o
fa_chevron_circle_down
fa_chevron_circle_left
fa_chevron_circle_right
fa_chevron_circle_up
fa_chevron_down
fa_chevron_left
fa_chevron_right
fa_chevron_up
fa_child
fa_chrome
fa_circle
fa_circle_o
fa_circle_o_notch
fa_circle_thin
fa_clipboard
fa_clock_o
fa_clone
fa_close
fa_cloud
fa_cloud_download
fa_cloud_upload
fa_cny
fa_code
fa_code_fork
fa_codepen
fa_codiepie
fa_coffee
fa_cog
fa_cogs
fa_columns
fa_comment
fa_comment_o
fa_commenting
fa_commenting_o
fa_comments
fa_comments_o
fa_compass
fa_compress
fa_connectdevelop
fa_contao
fa_copy
fa_copyright
fa_creative_commons
fa_credit_card
fa_credit_card_alt
fa_crop
fa_crosshairs
fa_css3
fa_cube
fa_cubes
fa_cut
fa_cutlery
fa_dashboard
fa_dashcube
fa_database
fa_deaf
fa_deafness
fa_dedent
fa_delicious
fa_desktop
fa_deviantart
fa_diamond
fa_digg
fa_dollar
fa_dot_circle_o
fa_download
fa_dribbble
fa_drivers_license
fa_drivers_license_o
fa_dropbox
fa_drupal
fa_edge
fa_edit
fa_eercast
fa_eject
fa_ellipsis_h
fa_ellipsis_v
fa_empire
fa_envelope
fa_envelope_o
fa_envelope_open
fa_envelope_open_o
fa_envelope_square
fa_envira
fa_eraser
fa_etsy
fa_eur
fa_euro
fa_exchange
fa_exclamation
fa_exclamation_circle
fa_exclamation_triangle
fa_expand
fa_expeditedssl
fa_external_link
fa_external_link_square
fa_eye
fa_eye_slash
fa_eyedropper
fa_fa
fa_facebook
fa_facebook_f
fa_facebook_official
fa_facebook_square
fa_fast_backward
fa_fast_forward
fa_fax
fa_feed
fa_female
fa_fighter_jet
fa_file
fa_file_archive_o
fa_file_audio_o
fa_file_code_o
fa_file_excel_o
fa_file_image_o
fa_file_movie_o
fa_file_o
fa_file_pdf_o
fa_file_photo_o
fa_file_picture_o
fa_file_powerpoint_o
fa_file_sound_o
fa_file_text
fa_file_text_o
fa_file_video_o
fa_file_word_o
fa_file_zip_o
fa_files_o
fa_film
fa_filter
fa_fire
fa_fire_extinguisher
fa_firefox
fa_first_order
fa_flag
fa_flag_checkered
fa_flag_o
fa_flash
fa_flask
fa_flickr
fa_floppy_o
fa_folder
fa_folder_o
fa_folder_open
fa_folder_open_o
fa_font
fa_font_awesome
fa_fonticons
fa_fort_awesome
fa_forumbee
fa_forward
fa_foursquare
fa_free_code_camp
fa_frown_o
fa_futbol_o
fa_gamepad
fa_gavel
fa_gbp
fa_ge
fa_gear
fa_gears
fa_genderless
fa_get_pocket
fa_gg
fa_gg_circle
fa_gift
fa_git
fa_git_square
fa_github
fa_github_alt
fa_github_square
fa_gitlab
fa_gittip
fa_glass
fa_glide
fa_glide_g
fa_globe
fa_google
fa_google_plus
fa_google_plus_circle
fa_google_plus_official
fa_google_plus_square
fa_google_wallet
fa_graduation_cap
fa_gratipay
fa_grav
fa_group
fa_h_square
fa_hacker_news
fa_hand_grab_o
fa_hand_lizard_o
fa_hand_o_down
fa_hand_o_left
fa_hand_o_right
fa_hand_o_up
fa_hand_paper_o
fa_hand_peace_o
fa_hand_pointer_o
fa_hand_rock_o
fa_hand_scissors_o
fa_hand_spock_o
fa_hand_stop_o
fa_handshake_o
fa_hard_of_hearing
fa_hashtag
fa_hdd_o
fa_header
fa_headphones
fa_heart
fa_heart_o
fa_heartbeat
fa_history
fa_home
fa_hospital_o
fa_hotel
fa_hourglass
fa_hourglass_1
fa_hourglass_2
fa_hourglass_3
fa_hourglass_end
fa_hourglass_half
fa_hourglass_o
fa_hourglass_start
fa_houzz
fa_html5
fa_i_cursor
fa_id_badge
fa_id_card
fa_id_card_o
fa_ils
fa_image
fa_imdb
fa_inbox
fa_indent
fa_industry
fa_info
fa_info_circle
fa_inr
fa_instagram
fa_institution
fa_internet_explorer
fa_intersex
fa_ioxhost
fa_italic
fa_joomla
fa_jpy
fa_jsfiddle
fa_key
fa_keyboard_o
fa_krw
fa_language
fa_laptop
fa_lastfm
fa_lastfm_square
fa_leaf
fa_leanpub
fa_legal
fa_lemon_o
fa_level_down
fa_level_up
fa_life_bouy
fa_life_buoy
fa_life_ring
fa_life_saver
fa_lightbulb_o
fa_line_chart
fa_link
fa_linkedin
fa_linkedin_square
fa_linode
fa_linux
fa_list
fa_list_alt
fa_list_ol
fa_list_ul
fa_location_arrow
fa_lock
fa_long_arrow_down
fa_long_arrow_left
fa_long_arrow_right
fa_long_arrow_up
fa_low_vision
fa_magic
fa_magnet
fa_mail_forward
fa_mail_reply
fa_mail_reply_all
fa_male
fa_map
fa_map_marker
fa_map_o
fa_map_pin
fa_map_signs
fa_mars
fa_mars_double
fa_mars_stroke
fa_mars_stroke_h
fa_mars_stroke_v
fa_maxcdn
fa_meanpath
fa_medium
fa_medkit
fa_meetup
fa_meh_o
fa_mercury
fa_microchip
fa_microphone
fa_microphone_slash
fa_minus
fa_minus_circle
fa_minus_square
fa_minus_square_o
fa_mixcloud
fa_mobile
fa_mobile_phone
fa_modx
fa_money
fa_moon_o
fa_mortar_board
fa_motorcycle
fa_mouse_pointer
fa_music
fa_navicon
fa_neuter
fa_newspaper_o
fa_object_group
fa_object_ungroup
fa_odnoklassniki
fa_odnoklassniki_square
fa_opencart
fa_openid
fa_opera
fa_optin_monster
fa_outdent
fa_pagelines
fa_paint_brush
fa_paper_plane
fa_paper_plane_o
fa_paperclip
fa_paragraph
fa_paste
fa_pause
fa_pause_circle
fa_pause_circle_o
fa_paw
fa_paypal
fa_pencil
fa_pencil_square
fa_pencil_square_o
fa_percent
fa_phone
fa_phone_square
fa_photo
fa_picture_o
fa_pie_chart
fa_pied_piper
fa_pied_piper_alt
fa_pied_piper_pp
fa_pinterest
fa_pinterest_p
fa_pinterest_square
fa_plane
fa_play
fa_play_circle
fa_play_circle_o
fa_plug
fa_plus
fa_plus_circle
fa_plus_square
fa_plus_square_o
fa_podcast
fa_power_off
fa_print
fa_product_hunt
fa_puzzle_piece
fa_qq
fa_qrcode
fa_question
fa_question_circle
fa_question_circle_o
fa_quora
fa_quote_left
fa_quote_right
fa_ra
fa_random
fa_ravelry
fa_rebel
fa_recycle
fa_reddit
fa_reddit_alien
fa_reddit_square
fa_refresh
fa_registered
fa_remove
fa_renren
fa_reorder
fa_repeat
fa_reply
fa_reply_all
fa_resistance
fa_retweet
fa_rmb
fa_road
fa_rocket
fa_rotate_left
fa_rotate_right
fa_rouble
fa_rss
fa_rss_square
fa_rub
fa_ruble
fa_rupee
fa_s15
fa_safari
fa_save
fa_scissors
fa_scribd
fa_search
fa_search_minus
fa_search_plus
fa_sellsy
fa_send
fa_send_o
fa_server
fa_share
fa_share_alt
fa_share_alt_square
fa_share_square
fa_share_square_o
fa_shekel
fa_sheqel
fa_shield
fa_ship
fa_shirtsinbulk
fa_shopping_bag
fa_shopping_basket
fa_shopping_cart
fa_shower
fa_sign_in
fa_sign_language
fa_sign_out
fa_signal
fa_signing
fa_simplybuilt
fa_sitemap
fa_skyatlas
fa_skype
fa_slack
fa_sliders
fa_slideshare
fa_smile_o
fa_snapchat
fa_snapchat_ghost
fa_snapchat_square
fa_snowflake_o
fa_soccer_ball_o
fa_sort
fa_sort_alpha_asc
fa_sort_alpha_desc
fa_sort_amount_asc
fa_sort_amount_desc
fa_sort_asc
fa_sort_desc
fa_sort_down
fa_sort_numeric_asc
fa_sort_numeric_desc
fa_sort_up
fa_soundcloud
fa_space_shuttle
fa_spinner
fa_spoon
fa_spotify
fa_square
fa_square_o
fa_stack_exchange
fa_stack_overflow
fa_star
fa_star_half
fa_star_half_empty
fa_star_half_full
fa_star_half_o
fa_star_o
fa_steam
fa_steam_square
fa_step_backward
fa_step_forward
fa_stethoscope
fa_sticky_note
fa_sticky_note_o
fa_stop
fa_stop_circle
fa_stop_circle_o
fa_street_view
fa_strikethrough
fa_stumbleupon
fa_stumbleupon_circle
fa_subscript
fa_subway
fa_suitcase
fa_sun_o
fa_superpowers
fa_superscript
fa_support
fa_table
fa_tablet
fa_tachometer
fa_tag
fa_tags
fa_tasks
fa_taxi
fa_telegram
fa_television
fa_tencent_weibo
fa_terminal
fa_text_height
fa_text_width
fa_th
fa_th_large
fa_th_list
fa_themeisle
fa_thermometer
fa_thermometer_0
fa_thermometer_1
fa_thermometer_2
fa_thermometer_3
fa_thermometer_4
fa_thermometer_empty
fa_thermometer_full
fa_thermometer_half
fa_thermometer_quarter
fa_thermometer_three_quarters
fa_thumb_tack
fa_thumbs_down
fa_thumbs_o_down
fa_thumbs_o_up
fa_thumbs_up
fa_ticket
fa_times
fa_times_circle
fa_times_circle_o
fa_times_rectangle
fa_times_rectangle_o
fa_tint
fa_toggle_down
fa_toggle_left
fa_toggle_off
fa_toggle_on
fa_toggle_right
fa_toggle_up
fa_trademark
fa_train
fa_transgender
fa_transgender_alt
fa_trash
fa_trash_o
fa_tree
fa_trello
fa_tripadvisor
fa_trophy
fa_truck
fa_try
fa_tty
fa_tumblr
fa_tumblr_square
fa_turkish_lira
fa_tv
fa_twitch
fa_twitter
fa_twitter_square
fa_umbrella
fa_underline
fa_undo
fa_universal_access
fa_university
fa_unlink
fa_unlock
fa_unlock_alt
fa_unsorted
fa_upload
fa_usb
fa_usd
fa_user
fa_user_circle
fa_user_circle_o
fa_user_md
fa_user_o
fa_user_plus
fa_user_secret
fa_user_times
fa_users
fa_vcard
fa_vcard_o
fa_venus
fa_venus_double
fa_venus_mars
fa_viacoin
fa_viadeo
fa_viadeo_square
fa_video_camera
fa_vimeo
fa_vimeo_square
fa_vine
fa_vk
fa_volume_control_phone
fa_volume_down
fa_volume_off
fa_volume_up
fa_warning
fa_wechat
fa_weibo
fa_weixin
fa_whatsapp
fa_wheelchair
fa_wheelchair_alt
fa_wifi
fa_wikipedia_w
fa_window_close
fa_window_close_o
fa_window_maximize
fa_window_minimize
fa_window_restore
fa_windows
fa_won
fa_wordpress
fa_wpbeginner
fa_wpexplorer
fa_wpforms
fa_wrench
fa_xing
fa_xing_square
fa_y_combinator
fa_y_combinator_square
fa_yahoo
fa_yc
fa_yc_square
fa_yelp
fa_yen
fa_yoast
fa_youtube
fa_youtube_play
fa_youtube_square
fae_apple_fruit
fae_atom
fae_bacteria
fae_banana
fae_bath
fae_bed
fae_benzene
fae_bigger
fae_biohazard
fae_blogger_circle
fae_blogger_square
fae_bones
fae_book_open
fae_book_open_o
fae_brain
fae_bread
fae_butterfly
fae_carot
fae_cc_by
fae_cc_cc
fae_cc_nc
fae_cc_nc_eu
fae_cc_nc_jp
fae_cc_nd
fae_cc_remix
fae_cc_sa
fae_cc_share
fae_cc_zero
fae_checklist_o
fae_cheese
fae_cherry
fae_chess_bishop
fae_chess_horse
fae_chess_king
fae_chess_pawn
fae_chess_queen
fae_chess_tower
fae_chicken_thigh
fae_chilli
fae_chip
fae_cicling
fae_cloud
fae_cockroach
fae_coffe_beans
fae_coins
fae_comb
fae_comet
fae_crown
fae_cup_coffe
fae_dice
fae_disco
fae_dna
fae_donut
fae_dress
fae_drop
fae_ello
fae_envelope_open
fae_envelope_open_o
fae_equal
fae_equal_bigger
fae_feedly
fae_file_export
fae_file_import
fae_fingerprint
fae_floppy
fae_footprint
fae_freecodecamp
fae_galaxy
fae_galery
fae_gift_card
fae_glass
fae_google_drive
fae_google_play
fae_gps
fae_grav
fae_guitar
fae_gut
fae_halter
fae_hamburger
fae_hat
fae_hexagon
fae_high_heel
fae_hotdog
fae_ice_cream
fae_id_card
fae_imdb
fae_infinity
fae_injection
fae_isle
fae_java
fae_layers
fae_lips
fae_lipstick
fae_liver
fae_lollipop
fae_loyalty_card
fae_lung
fae_makeup_brushes
fae_maximize
fae_meat
fae_medicine
fae_microscope
fae_milk_bottle
fae_minimize
fae_molecule
fae_moon_cloud
fae_mountains
fae_mushroom
fae_mustache
fae_mysql
fae_nintendo
fae_orange
fae_palette_color
fae_peach
fae_pear
fae_pi
fae_pizza
fae_planet
fae_plant
fae_playstation
fae_poison
fae_popcorn
fae_popsicle
fae_pulse
fae_python
fae_quora_circle
fae_quora_square
fae_radioactive
fae_raining
fae_real_heart
fae_refrigerator
fae_restore
fae_ring
fae_ruby
fae_ruby_o
fae_ruler
fae_shirt
fae_slash
fae_smaller
fae_snowing
fae_soda
fae_sofa
fae_soup
fae_spermatozoon
fae_spin_double
fae_stomach
fae_storm
fae_sun_cloud
fae_sushi
fae_tacos
fae_telegram
fae_telegram_circle
fae_telescope
fae_thermometer
fae_thermometer_high
fae_thermometer_low
fae_thin_close
fae_toilet
fae_tools
fae_tooth
fae_tree
fae_triangle_ruler
fae_umbrella
fae_uterus
fae_virus
fae_w3c
fae_walking
fae_wallet
fae_wind
fae_xbox
iec_power
iec_power_off
iec_power_on
iec_sleep_mode
iec_toggle_power
indent_dotted_guide
indent_line
indentation_line
linux_alpine
linux_aosc
linux_apple
linux_archlabs
linux_archlinux
linux_artix
linux_budgie
linux_centos
linux_coreos
linux_debian
linux_deepin
linux_devuan
linux_docker
linux_elementary
linux_fedora
linux_fedora_inverse
linux_ferris
linux_flathub
linux_freebsd
linux_gentoo
linux_gnu_guix
linux_illumos
linux_kali_linux
linux_linuxmint
linux_linuxmint_inverse
linux_mageia
linux_mandriva
linux_manjaro
linux_nixos
linux_openbsd
linux_opensuse
linux_pop_os
linux_raspberry_pi
linux_redhat
linux_sabayon
linux_slackware
linux_slackware_inverse
linux_snappy
linux_solus
linux_tux
linux_ubuntu
linux_ubuntu_inverse
linux_void
linux_zorin
mdi_access_point
mdi_access_point_network
mdi_account
mdi_account_alert
mdi_account_box
mdi_account_box_outline
mdi_account_card_details
mdi_account_check
mdi_account_circle
mdi_account_convert
mdi_account_edit
mdi_account_key
mdi_account_location
mdi_account_minus
mdi_account_multiple
mdi_account_multiple_minus
mdi_account_multiple_outline
mdi_account_multiple_plus
mdi_account_multiple_plus_outline
mdi_account_network
mdi_account_off
mdi_account_outline
mdi_account_plus
ﳿmdi_account_plus_outline
mdi_account_remove
mdi_account_search
mdi_account_settings
mdi_account_settings_variant
mdi_account_star
mdi_account_switch
mdi_adjust
mdi_air_conditioner
mdi_airballoon
mdi_airplane
mdi_airplane_landing
mdi_airplane_off
mdi_airplane_takeoff
mdi_airplay
mdi_alarm
mdi_alarm_bell
mdi_alarm_check
mdi_alarm_light
mdi_alarm_multiple
mdi_alarm_off
mdi_alarm_plus
mdi_alarm_snooze
mdi_album
mdi_alert
mdi_alert_box
mdi_alert_circle
mdi_alert_circle_outline
mdi_alert_decagram
mdi_alert_octagon
mdi_alert_octagram
mdi_alert_outline
mdi_all_inclusive
mdi_allo
mdi_alpha
mdi_alphabetical
mdi_altimeter
mdi_amazon
mdi_amazon_clouddrive
mdi_ambulance
mdi_amplifier
mdi_anchor
mdi_android
mdi_android_debug_bridge
mdi_android_head
mdi_android_studio
mdi_angular
mdi_angularjs
mdi_animation
mdi_apple
mdi_apple_finder
mdi_apple_ios
mdi_apple_keyboard_caps
mdi_apple_keyboard_command
mdi_apple_keyboard_control
mdi_apple_keyboard_option
mdi_apple_keyboard_shift
mdi_apple_mobileme
mdi_apple_safari
mdi_application
mdi_approval
mdi_apps
mdi_archive
mdi_arrange_bring_forward
mdi_arrange_bring_to_front
mdi_arrange_send_backward
mdi_arrange_send_to_back
mdi_arrow_all
mdi_arrow_bottom_left
mdi_arrow_bottom_right
mdi_arrow_collapse
mdi_arrow_collapse_all
mdi_arrow_collapse_down
mdi_arrow_collapse_left
mdi_arrow_collapse_right
mdi_arrow_collapse_up
mdi_arrow_down
mdi_arrow_down_bold
mdi_arrow_down_bold_box
mdi_arrow_down_bold_box_outline
mdi_arrow_down_bold_circle
mdi_arrow_down_bold_circle_outline
mdi_arrow_down_bold_hexagon_outline
mdi_arrow_down_box
mdi_arrow_down_drop_circle
mdi_arrow_down_drop_circle_outline
mdi_arrow_down_thick
mdi_arrow_expand
mdi_arrow_expand_all
mdi_arrow_expand_down
mdi_arrow_expand_left
mdi_arrow_expand_right
mdi_arrow_expand_up
mdi_arrow_left
mdi_arrow_left_bold
mdi_arrow_left_bold_box
mdi_arrow_left_bold_box_outline
mdi_arrow_left_bold_circle
mdi_arrow_left_bold_circle_outline
mdi_arrow_left_bold_hexagon_outline
﮿mdi_arrow_left_box
mdi_arrow_left_drop_circle
mdi_arrow_left_drop_circle_outline
mdi_arrow_left_thick
mdi_arrow_right
mdi_arrow_right_bold
mdi_arrow_right_bold_box
mdi_arrow_right_bold_box_outline
mdi_arrow_right_bold_circle
mdi_arrow_right_bold_circle_outline
mdi_arrow_right_bold_hexagon_outline
mdi_arrow_right_box
mdi_arrow_right_drop_circle
mdi_arrow_right_drop_circle_outline
mdi_arrow_right_thick
mdi_arrow_top_left
mdi_arrow_top_right
mdi_arrow_up
mdi_arrow_up_bold
mdi_arrow_up_bold_box
mdi_arrow_up_bold_box_outline
mdi_arrow_up_bold_circle
mdi_arrow_up_bold_circle_outline
mdi_arrow_up_bold_hexagon_outline
mdi_arrow_up_box
mdi_arrow_up_drop_circle
mdi_arrow_up_drop_circle_outline
mdi_arrow_up_thick
mdi_artist
mdi_assistant
mdi_asterisk
mdi_at
mdi_atlassian
mdi_atom
mdi_attachment
mdi_audiobook
mdi_auto_fix
mdi_auto_upload
mdi_autorenew
mdi_av_timer
mdi_azure
mdi_baby
mdi_baby_buggy
mdi_backburger
mdi_backspace
mdi_backup_restore
mdi_bandcamp
mdi_bank
mdi_barcode
mdi_barcode_scan
mdi_barley
mdi_barrel
mdi_basecamp
mdi_basket
mdi_basket_fill
mdi_basket_unfill
mdi_basketball
mdi_battery
mdi_battery_10
mdi_battery_20
mdi_battery_30
mdi_battery_40
mdi_battery_50
mdi_battery_60
mdi_battery_70
mdi_battery_80
mdi_battery_90
mdi_battery_alert
mdi_battery_charging
mdi_battery_charging_20
mdi_battery_charging_30
mdi_battery_charging_40
mdi_battery_charging_60
mdi_battery_charging_80
mdi_battery_charging_90
mdi_battery_charging_100
mdi_battery_charging_wireless
mdi_battery_charging_wireless_10
mdi_battery_charging_wireless_20
mdi_battery_charging_wireless_30
mdi_battery_charging_wireless_40
mdi_battery_charging_wireless_50
mdi_battery_charging_wireless_60
mdi_battery_charging_wireless_70
mdi_battery_charging_wireless_80
mdi_battery_charging_wireless_90
mdi_battery_charging_wireless_alert
mdi_battery_charging_wireless_outline
mdi_battery_minus
mdi_battery_negative
mdi_battery_outline
mdi_battery_plus
mdi_battery_positive
mdi_battery_unknown
mdi_beach
mdi_beaker
mdi_beats
mdi_beer
mdi_behance
mdi_bell
mdi_bell_off
mdi_bell_outline
mdi_bell_plus
mdi_bell_ring
mdi_bell_ring_outline
mdi_bell_sleep
mdi_beta
mdi_bible
mdi_bike
mdi_bing
mdi_binoculars
mdi_bio
mdi_biohazard
mdi_bitbucket
mdi_bitcoin
mdi_black_mesa
mdi_blackberry
mdi_blender
mdi_blinds
mdi_block_helper
mdi_blogger
mdi_bluetooth
mdi_bluetooth_audio
mdi_bluetooth_connect
mdi_bluetooth_off
mdi_bluetooth_settings
mdi_bluetooth_transfer
mdi_blur
mdi_blur_linear
mdi_blur_off
mdi_blur_radial
mdi_bomb
mdi_bomb_off
mdi_bone
mdi_book
mdi_book_minus
mdi_book_multiple
mdi_book_multiple_variant
mdi_book_open
mdi_book_open_page_variant
mdi_book_open_variant
mdi_book_plus
mdi_book_secure
mdi_book_unsecure
mdi_book_variant
mdi_bookmark
mdi_bookmark_check
mdi_bookmark_music
mdi_bookmark_outline
mdi_bookmark_plus
mdi_bookmark_plus_outline
mdi_bookmark_remove
mdi_boombox
mdi_bootstrap
mdi_border_all
mdi_border_bottom
mdi_border_color
mdi_border_horizontal
mdi_border_inside
mdi_border_left
mdi_border_none
mdi_border_outside
mdi_border_right
mdi_border_style
mdi_border_top
mdi_border_vertical
mdi_bow_tie
mdi_bowl
mdi_bowling
mdi_box
mdi_box_cutter
mdi_box_shadow
mdi_bridge
mdi_briefcase
mdi_briefcase_check
mdi_briefcase_download
mdi_briefcase_outline
mdi_briefcase_upload
mdi_brightness_1
mdi_brightness_2
mdi_brightness_3
mdi_brightness_4
mdi_brightness_5
mdi_brightness_6
mdi_brightness_7
mdi_brightness_auto
mdi_broom
mdi_brush
mdi_buffer
mdi_bug
mdi_bulletin_board
mdi_bullhorn
mdi_bullseye
mdi_bus
mdi_bus_articulated_end
mdi_bus_articulated_front
mdi_bus_double_decker
mdi_bus_school
mdi_bus_side
mdi_cached
mdi_cake
mdi_cake_layered
mdi_cake_variant
mdi_calculator
mdi_calendar
mdi_calendar_blank
mdi_calendar_check
mdi_calendar_clock
mdi_calendar_multiple
mdi_calendar_multiple_check
mdi_calendar_plus
mdi_calendar_question
mdi_calendar_range
mdi_calendar_remove
mdi_calendar_text
mdi_calendar_today
mdi_call_made
mdi_call_merge
mdi_call_missed
mdi_call_received
mdi_call_split
mdi_camcorder
mdi_camcorder_box
mdi_camcorder_box_off
mdi_camcorder_off
mdi_camera
mdi_camera_burst
mdi_camera_enhance
mdi_camera_front
mdi_camera_front_variant
mdi_camera_gopro
mdi_camera_iris
mdi_camera_metering_center
mdi_camera_metering_matrix
mdi_camera_metering_partial
mdi_camera_metering_spot
mdi_camera_off
mdi_camera_party_mode
mdi_camera_rear
mdi_camera_rear_variant
mdi_camera_switch
mdi_camera_timer
mdi_cancel
mdi_candle
mdi_candycane
mdi_cannabis
mdi_car
mdi_car_battery
mdi_car_connected
mdi_car_convertible
mdi_car_estate
mdi_car_hatchback
mdi_car_pickup
mdi_car_side
mdi_car_sports
mdi_car_wash
mdi_caravan
mdi_cards
mdi_cards_outline
mdi_cards_playing_outline
mdi_cards_variant
mdi_carrot
mdi_cart
mdi_cart_off
mdi_cart_outline
mdi_cart_plus
mdi_case_sensitive_alt
mdi_cash
mdi_cash_100
mdi_cash_multiple
mdi_cash_usd
mdi_cast
mdi_cast_connected
mdi_cast_off
mdi_castle
mdi_cat
mdi_cctv
mdi_ceiling_light
mdi_cellphone
mdi_cellphone_android
mdi_cellphone_basic
mdi_cellphone_dock
mdi_cellphone_iphone
mdi_cellphone_link
mdi_cellphone_link_off
mdi_cellphone_settings
mdi_cellphone_wireless
mdi_certificate
mdi_chair_school
mdi_chart_arc
mdi_chart_areaspline
mdi_chart_bar
mdi_chart_bar_stacked
mdi_chart_bubble
mdi_chart_donut
mdi_chart_donut_variant
mdi_chart_gantt
mdi_chart_histogram
mdi_chart_line
mdi_chart_line_stacked
mdi_chart_line_variant
mdi_chart_pie
mdi_chart_scatterplot_hexbin
mdi_chart_timeline
mdi_check
mdi_check_all
mdi_check_circle
mdi_check_circle_outline
mdi_checkbox_blank
mdi_checkbox_blank_circle
mdi_checkbox_blank_circle_outline
mdi_checkbox_blank_outline
mdi_checkbox_marked
mdi_checkbox_marked_circle
mdi_checkbox_marked_circle_outline
mdi_checkbox_marked_outline
mdi_checkbox_multiple_blank
mdi_checkbox_multiple_blank_circle
mdi_checkbox_multiple_blank_circle_outline
mdi_checkbox_multiple_blank_outline
mdi_checkbox_multiple_marked
mdi_checkbox_multiple_marked_circle
mdi_checkbox_multiple_marked_circle_outline
mdi_checkbox_multiple_marked_outline
mdi_checkerboard
mdi_chemical_weapon
mdi_chevron_double_down
mdi_chevron_double_left
mdi_chevron_double_right
mdi_chevron_double_up
mdi_chevron_down
mdi_chevron_left
mdi_chevron_right
mdi_chevron_up
mdi_chili_hot
mdi_chili_medium
mdi_chili_mild
mdi_chip
mdi_church
mdi_circle
mdi_circle_outline
mdi_cisco_webex
mdi_city
mdi_clipboard
mdi_clipboard_account
mdi_clipboard_alert
mdi_clipboard_arrow_down
mdi_clipboard_arrow_left
mdi_clipboard_check
mdi_clipboard_flow
mdi_clipboard_outline
mdi_clipboard_plus
mdi_clipboard_text
mdi_clippy
mdi_clock
mdi_clock_alert
mdi_clock_end
mdi_clock_fast
mdi_clock_in
mdi_clock_out
mdi_clock_start
mdi_close
mdi_close_box
mdi_close_box_outline
mdi_close_circle
mdi_close_circle_outline
mdi_close_network
mdi_close_octagon
mdi_close_octagon_outline
mdi_close_outline
mdi_closed_caption
mdi_cloud
mdi_cloud_braces
mdi_cloud_check
mdi_cloud_circle
mdi_cloud_download
mdi_cloud_off_outline
mdi_cloud_outline
mdi_cloud_print
mdi_cloud_print_outline
mdi_cloud_sync
mdi_cloud_tags
mdi_cloud_upload
mdi_clover
mdi_code_array
mdi_code_braces
mdi_code_brackets
mdi_code_equal
mdi_code_greater_than
mdi_code_greater_than_or_equal
mdi_code_less_than
mdi_code_less_than_or_equal
mdi_code_not_equal
mdi_code_not_equal_variant
mdi_code_parentheses
mdi_code_string
mdi_code_tags
mdi_code_tags_check
mdi_codepen
mdi_coffee
mdi_coffee_outline
mdi_coffee_to_go
mdi_coin
mdi_coins
﬿mdi_collage
mdi_color_helper
mdi_comment
mdi_comment_account
mdi_comment_account_outline
mdi_comment_alert
mdi_comment_alert_outline
mdi_comment_check
mdi_comment_check_outline
mdi_comment_multiple_outline
mdi_comment_outline
mdi_comment_plus_outline
mdi_comment_processing
mdi_comment_processing_outline
mdi_comment_question
mdi_comment_question_outline
mdi_comment_remove
mdi_comment_remove_outline
mdi_comment_text
mdi_comment_text_outline
mdi_compare
mdi_compass
mdi_compass_outline
mdi_console
mdi_console_line
mdi_contact_mail
mdi_contacts
mdi_content_copy
mdi_content_cut
mdi_content_duplicate
mdi_content_paste
mdi_content_save
mdi_content_save_all
mdi_content_save_outline
mdi_content_save_settings
mdi_contrast
mdi_contrast_box
mdi_contrast_circle
mdi_cookie
mdi_copyright
mdi_corn
mdi_counter
mdi_cow
mdi_creation
mdi_credit_card
mdi_credit_card_multiple
mdi_credit_card_off
mdi_credit_card_plus
mdi_credit_card_scan
mdi_crop
mdi_crop_free
mdi_crop_landscape
mdi_crop_portrait
mdi_crop_rotate
mdi_crop_square
mdi_crosshairs
mdi_crosshairs_gps
mdi_crown
mdi_cube
mdi_cube_outline
mdi_cube_send
mdi_cube_unfolded
mdi_cup
mdi_cup_off
mdi_cup_water
mdi_currency_btc
mdi_currency_chf
mdi_currency_cny
mdi_currency_eth
mdi_currency_eur
mdi_currency_gbp
mdi_currency_inr
mdi_currency_jpy
mdi_currency_krw
mdi_currency_ngn
mdi_currency_rub
mdi_currency_sign
mdi_currency_try
mdi_currency_twd
mdi_currency_usd
mdi_currency_usd_off
mdi_cursor_default
mdi_cursor_default_outline
mdi_cursor_move
mdi_cursor_pointer
mdi_cursor_text
mdi_database
mdi_database_minus
mdi_database_plus
mdi_debug_step_into
mdi_debug_step_out
mdi_debug_step_over
mdi_decagram
mdi_decagram_outline
mdi_decimal_decrease
mdi_decimal_increase
mdi_delete
mdi_delete_circle
mdi_delete_empty
mdi_delete_forever
mdi_delete_restore
mdi_delete_sweep
mdi_delete_variant
mdi_delta
mdi_deskphone
mdi_desktop_classic
mdi_desktop_mac
mdi_desktop_tower
mdi_details
mdi_developer_board
mdi_deviantart
mdi_dialpad
mdi_diamond
mdi_dice_1
mdi_dice_2
mdi_dice_3
mdi_dice_4
mdi_dice_5
mdi_dice_6
mdi_dice_d4
mdi_dice_d6
mdi_dice_d8
mdi_dice_d10
mdi_dice_d20
mdi_dice_multiple
mdi_dictionary
ﲿmdi_dip_switch
mdi_directions
mdi_directions_fork
mdi_discord
mdi_disk
mdi_disk_alert
mdi_disqus
mdi_disqus_outline
mdi_division
mdi_division_box
mdi_dna
mdi_dns
mdi_do_not_disturb
mdi_do_not_disturb_off
mdi_dolby
mdi_domain
mdi_donkey
mdi_door
mdi_door_closed
mdi_door_open
mdi_dots_horizontal
mdi_dots_horizontal_circle
mdi_dots_vertical
mdi_dots_vertical_circle
mdi_douban
mdi_download
mdi_download_network
mdi_drag
mdi_drag_horizontal
mdi_drag_vertical
mdi_drawing
mdi_drawing_box
mdi_dribbble
mdi_dribbble_box
mdi_drone
mdi_dropbox
mdi_drupal
mdi_duck
mdi_dumbbell
mdi_ear_hearing
mdi_earth
mdi_earth_box
mdi_earth_box_off
mdi_earth_off
mdi_edge
mdi_eject
mdi_elephant
mdi_elevation_decline
mdi_elevation_rise
mdi_elevator
mdi_email
mdi_email_alert
mdi_email_open
mdi_email_open_outline
mdi_email_outline
mdi_email_secure
mdi_email_variant
mdi_emby
mdi_emoticon
mdi_emoticon_cool
mdi_emoticon_dead
mdi_emoticon_devil
mdi_emoticon_excited
mdi_emoticon_happy
mdi_emoticon_neutral
mdi_emoticon_poop
mdi_emoticon_sad
mdi_emoticon_tongue
mdi_engine
mdi_engine_outline
mdi_equal
mdi_equal_box
mdi_eraser
mdi_eraser_variant
mdi_escalator
mdi_ethernet
mdi_ethernet_cable
mdi_ethernet_cable_off
mdi_etsy
mdi_ev_station
mdi_eventbrite
mdi_evernote
mdi_exclamation
mdi_exit_to_app
mdi_export
mdi_eye
mdi_eye_off
mdi_eye_off_outline
mdi_eye_outline
mdi_eyedropper
mdi_eyedropper_variant
mdi_face
mdi_face_profile
mdi_facebook
mdi_facebook_box
mdi_facebook_messenger
mdi_factory
mdi_fan
mdi_fan_off
mdi_fast_forward
mdi_fast_forward_outline
mdi_fax
mdi_feather
mdi_ferry
mdi_file
mdi_file_account
mdi_file_chart
mdi_file_check
mdi_file_cloud
mdi_file_delimited
mdi_file_document
mdi_file_document_box
mdi_file_excel
mdi_file_excel_box
mdi_file_export
mdi_file_find
mdi_file_hidden
mdi_file_image
mdi_file_import
mdi_file_lock
mdi_file_multiple
mdi_file_music
mdi_file_outline
mdi_file_pdf
mdi_file_pdf_box
mdi_file_percent
mdi_file_plus
mdi_file_powerpoint
mdi_file_powerpoint_box
mdi_file_presentation_box
mdi_file_restore
mdi_file_send
mdi_file_tree
mdi_file_video
mdi_file_word
mdi_file_word_box
mdi_file_xml
mdi_film
mdi_filmstrip
mdi_filmstrip_off
mdi_filter
mdi_filter_outline
mdi_filter_remove
mdi_filter_remove_outline
mdi_filter_variant
mdi_finance
mdi_find_replace
mdi_fingerprint
mdi_fire
mdi_firefox
mdi_fish
mdi_flag
mdi_flag_checkered
mdi_flag_outline
mdi_flag_triangle
mdi_flag_variant
mdi_flag_variant_outline
mdi_flash
mdi_flash_auto
mdi_flash_circle
mdi_flash_off
mdi_flash_outline
mdi_flash_red_eye
mdi_flashlight
mdi_flashlight_off
mdi_flask
mdi_flask_empty
mdi_flask_empty_outline
mdi_flask_outline
mdi_flattr
mdi_flip_to_back
mdi_flip_to_front
mdi_floor_plan
mdi_floppy
mdi_flower
mdi_folder
mdi_folder_account
mdi_folder_download
mdi_folder_google_drive
mdi_folder_image
mdi_folder_lock
mdi_folder_lock_open
mdi_folder_move
mdi_folder_multiple
mdi_folder_multiple_image
mdi_folder_multiple_outline
mdi_folder_open
mdi_folder_outline
mdi_folder_plus
mdi_folder_remove
mdi_folder_star
mdi_folder_upload
mdi_font_awesome
mdi_food
mdi_food_apple
mdi_food_croissant
mdi_food_fork_drink
mdi_food_off
mdi_food_variant
mdi_football
mdi_football_australian
mdi_football_helmet
mdi_forklift
mdi_format_align_bottom
mdi_format_align_center
mdi_format_align_justify
mdi_format_align_left
mdi_format_align_middle
mdi_format_align_right
mdi_format_align_top
mdi_format_annotation_plus
mdi_format_bold
mdi_format_clear
mdi_format_color_fill
mdi_format_color_text
mdi_format_float_center
mdi_format_float_left
mdi_format_float_none
mdi_format_float_right
mdi_format_font
mdi_format_header_1
mdi_format_header_2
mdi_format_header_3
mdi_format_header_4
mdi_format_header_5
mdi_format_header_6
mdi_format_header_decrease
mdi_format_header_equal
mdi_format_header_increase
mdi_format_header_pound
mdi_format_horizontal_align_center
mdi_format_horizontal_align_left
mdi_format_horizontal_align_right
mdi_format_indent_decrease
mdi_format_indent_increase
mdi_format_italic
mdi_format_line_spacing
mdi_format_line_style
mdi_format_line_weight
mdi_format_list_bulleted
mdi_format_list_bulleted_type
mdi_format_list_checks
mdi_format_list_numbers
mdi_format_page_break
mdi_format_paint
mdi_format_paragraph
mdi_format_pilcrow
mdi_format_quote_close
mdi_format_quote_open
mdi_format_rotate_90
mdi_format_section
mdi_format_size
mdi_format_strikethrough
mdi_format_strikethrough_variant
mdi_format_subscript
mdi_format_superscript
mdi_format_text
mdi_format_textdirection_l_to_r
mdi_format_textdirection_r_to_l
mdi_format_title
mdi_format_underline
mdi_format_vertical_align_bottom
mdi_format_vertical_align_center
mdi_format_vertical_align_top
mdi_format_wrap_inline
mdi_format_wrap_square
mdi_format_wrap_tight
mdi_format_wrap_top_bottom
mdi_forum
mdi_forum_outline
mdi_forward
mdi_foursquare
mdi_fridge
mdi_fridge_filled
mdi_fridge_filled_bottom
mdi_fridge_filled_top
mdi_fuel
mdi_fullscreen
mdi_fullscreen_exit
mdi_function
mdi_gamepad
mdi_gamepad_variant
mdi_garage
mdi_garage_open
mdi_gas_cylinder
mdi_gas_station
mdi_gate
mdi_gauge
mdi_gavel
mdi_gender_female
mdi_gender_male
mdi_gender_male_female
mdi_gender_transgender
mdi_gesture
mdi_gesture_double_tap
mdi_gesture_swipe_down
mdi_gesture_swipe_left
mdi_gesture_swipe_right
mdi_gesture_swipe_up
ﰿmdi_gesture_tap
mdi_gesture_two_double_tap
mdi_gesture_two_tap
mdi_ghost
mdi_gift
mdi_git
mdi_github_box
mdi_github_circle
mdi_github_face
mdi_glass_flute
mdi_glass_mug
mdi_glass_stange
mdi_glass_tulip
mdi_glassdoor
mdi_glasses
mdi_gmail
mdi_gnome
mdi_golf
mdi_gondola
mdi_google
mdi_google_analytics
mdi_google_assistant
mdi_google_cardboard
mdi_google_chrome
mdi_google_circles
mdi_google_circles_communities
mdi_google_circles_extended
mdi_google_circles_group
mdi_google_controller
mdi_google_controller_off
mdi_google_drive
mdi_google_earth
mdi_google_glass
mdi_google_home
mdi_google_keep
mdi_google_maps
mdi_google_nearby
mdi_google_pages
mdi_google_photos
mdi_google_physical_web
mdi_google_play
mdi_google_plus
mdi_google_plus_box
mdi_google_translate
mdi_google_wallet
mdi_gradient
mdi_grease_pencil
mdi_grid
mdi_grid_large
mdi_grid_off
mdi_group
mdi_guitar_acoustic
mdi_guitar_electric
mdi_guitar_pick
mdi_guitar_pick_outline
mdi_guy_fawkes_mask
mdi_hackernews
mdi_hamburger
mdi_hand_pointing_right
mdi_hanger
mdi_hangouts
mdi_harddisk
mdi_headphones
mdi_headphones_box
mdi_headphones_off
mdi_headphones_settings
mdi_headset
mdi_headset_dock
mdi_headset_off
mdi_heart
mdi_heart_box
mdi_heart_box_outline
mdi_heart_broken
mdi_heart_half
mdi_heart_half_full
mdi_heart_half_outline
mdi_heart_off
mdi_heart_outline
mdi_heart_pulse
mdi_help
mdi_help_box
mdi_help_circle
mdi_help_circle_outline
mdi_help_network
mdi_hexagon
mdi_hexagon_multiple
mdi_hexagon_outline
mdi_high_definition
mdi_highway
mdi_history
mdi_hololens
mdi_home
mdi_home_account
mdi_home_assistant
mdi_home_automation
mdi_home_circle
mdi_home_heart
mdi_home_map_marker
mdi_home_modern
mdi_home_outline
mdi_home_variant
mdi_hook
mdi_hook_off
mdi_hops
mdi_hospital
mdi_hospital_building
mdi_hospital_marker
mdi_hot_tub
mdi_hotel
mdi_houzz
mdi_houzz_box
mdi_hulu
mdi_human
mdi_human_child
mdi_human_female
mdi_human_greeting
mdi_human_handsdown
mdi_human_handsup
mdi_human_male
mdi_human_male_female
mdi_human_pregnant
mdi_humble_bundle
mdi_ice_cream
mdi_image
mdi_image_album
mdi_image_area
mdi_image_area_close
mdi_image_broken
mdi_image_broken_variant
mdi_image_filter
mdi_image_filter_black_white
mdi_image_filter_center_focus
mdi_image_filter_center_focus_weak
mdi_image_filter_drama
mdi_image_filter_frames
mdi_image_filter_hdr
mdi_image_filter_none
mdi_image_filter_tilt_shift
mdi_image_filter_vintage
mdi_image_multiple
mdi_image_off
mdi_import
mdi_inbox
mdi_inbox_arrow_down
mdi_inbox_arrow_up
mdi_incognito
mdi_infinity
mdi_information
mdi_information_outline
mdi_information_variant
mdi_instagram
mdi_instapaper
mdi_internet_explorer
mdi_invert_colors
mdi_itunes
mdi_jeepney
mdi_jira
mdi_jsfiddle
mdi_json
mdi_karate
mdi_keg
mdi_kettle
mdi_key
mdi_key_change
mdi_key_minus
mdi_key_plus
mdi_key_remove
mdi_key_variant
mdi_keyboard
mdi_keyboard_backspace
mdi_keyboard_caps
mdi_keyboard_close
mdi_keyboard_off
mdi_keyboard_return
mdi_keyboard_tab
mdi_keyboard_variant
mdi_kickstarter
mdi_kodi
mdi_label
mdi_label_outline
mdi_ladybug
mdi_lambda
mdi_lamp
mdi_lan
mdi_lan_connect
mdi_lan_disconnect
mdi_lan_pending
mdi_language_c
mdi_language_cpp
mdi_language_csharp
mdi_language_css3
mdi_language_go
mdi_language_html5
mdi_language_javascript
mdi_language_php
mdi_language_python
mdi_language_python_text
mdi_language_r
mdi_language_swift
mdi_language_typescript
mdi_laptop
mdi_laptop_chromebook
mdi_laptop_mac
mdi_laptop_off
mdi_laptop_windows
mdi_lastfm
mdi_lastpass
mdi_launch
mdi_lava_lamp
mdi_layers
mdi_layers_off
mdi_lead_pencil
mdi_leaf
mdi_led_off
mdi_led_on
mdi_led_outline
mdi_led_strip
mdi_led_variant_off
mdi_led_variant_on
mdi_led_variant_outline
mdi_library
mdi_library_books
mdi_library_music
mdi_library_plus
mdi_lightbulb
mdi_lightbulb_on
mdi_lightbulb_on_outline
mdi_lightbulb_outline
mdi_link
mdi_link_off
mdi_link_variant
mdi_link_variant_off
mdi_linkedin
mdi_linkedin_box
mdi_linux
mdi_loading
mdi_lock
mdi_lock_open
mdi_lock_open_outline
mdi_lock_outline
mdi_lock_pattern
mdi_lock_plus
mdi_lock_reset
mdi_locker
mdi_locker_multiple
mdi_login
mdi_login_variant
mdi_logout
mdi_logout_variant
mdi_looks
mdi_loop
mdi_loupe
mdi_lumx
mdi_magnet
mdi_magnet_on
mdi_magnify
mdi_magnify_minus
mdi_magnify_minus_outline
mdi_magnify_plus
mdi_magnify_plus_outline
mdi_mail_ru
mdi_mailbox
mdi_map
mdi_map_marker
mdi_map_marker_circle
mdi_map_marker_minus
mdi_map_marker_multiple
mdi_map_marker_off
mdi_map_marker_outline
mdi_map_marker_plus
mdi_map_marker_radius
mdi_margin
mdi_markdown
mdi_marker
mdi_marker_check
mdi_martini
mdi_material_ui
mdi_math_compass
mdi_matrix
mdi_maxcdn
mdi_medical_bag
mdi_medium
mdi_memory
mdi_menu
mdi_menu_down
mdi_menu_down_outline
mdi_menu_left
mdi_menu_right
mdi_menu_up
mdi_menu_up_outline
mdi_message
mdi_message_alert
mdi_message_bulleted
mdi_message_bulleted_off
mdi_message_draw
mdi_message_image
mdi_message_outline
mdi_message_plus
mdi_message_processing
mdi_message_reply
mdi_message_reply_text
mdi_message_settings
mdi_message_settings_variant
mdi_message_text
mdi_message_text_outline
mdi_message_video
mdi_meteor
mdi_metronome
mdi_metronome_tick
mdi_micro_sd
mdi_microphone
mdi_microphone_off
mdi_microphone_outline
mdi_microphone_settings
mdi_microphone_variant
mdi_microphone_variant_off
mdi_microscope
mdi_microsoft
mdi_minecraft
mdi_minus
mdi_minus_box
mdi_minus_box_outline
mdi_minus_circle
mdi_minus_circle_outline
mdi_minus_network
mdi_mixcloud
mdi_mixer
mdi_monitor
mdi_monitor_multiple
mdi_more
mdi_motorbike
mdi_mouse
mdi_mouse_off
mdi_mouse_variant
mdi_mouse_variant_off
mdi_move_resize
mdi_move_resize_variant
mdi_movie
mdi_movie_roll
mdi_multiplication
mdi_multiplication_box
mdi_mushroom
mdi_mushroom_outline
mdi_music
mdi_music_box
mdi_music_box_outline
mdi_music_circle
mdi_music_note
mdi_music_note_bluetooth
mdi_music_note_bluetooth_off
mdi_music_note_eighth
mdi_music_note_half
mdi_music_note_off
mdi_music_note_quarter
mdi_music_note_sixteenth
mdi_music_note_whole
mdi_music_off
mdi_nature
mdi_nature_people
mdi_navigation
mdi_near_me
mdi_needle
mdi_nest_protect
mdi_nest_thermostat
mdi_netflix
mdi_network
mdi_new_box
mdi_newspaper
mdi_nfc
mdi_nfc_tap
mdi_nfc_variant
mdi_ninja
mdi_nintendo_switch
mdi_nodejs
mdi_note
mdi_note_multiple
mdi_note_multiple_outline
mdi_note_outline
mdi_note_plus
mdi_note_plus_outline
mdi_note_text
mdi_notebook
mdi_notification_clear_all
mdi_npm
mdi_nuke
mdi_null
mdi_numeric
mdi_numeric_0_box
mdi_numeric_0_box_multiple_outline
mdi_numeric_0_box_outline
mdi_numeric_1_box
mdi_numeric_1_box_multiple_outline
mdi_numeric_1_box_outline
mdi_numeric_2_box
mdi_numeric_2_box_multiple_outline
mdi_numeric_2_box_outline
mdi_numeric_3_box
mdi_numeric_3_box_multiple_outline
mdi_numeric_3_box_outline
mdi_numeric_4_box
mdi_numeric_4_box_multiple_outline
mdi_numeric_4_box_outline
mdi_numeric_5_box
mdi_numeric_5_box_multiple_outline
mdi_numeric_5_box_outline
mdi_numeric_6_box
mdi_numeric_6_box_multiple_outline
mdi_numeric_6_box_outline
mdi_numeric_7_box
mdi_numeric_7_box_multiple_outline
mdi_numeric_7_box_outline
mdi_numeric_8_box
mdi_numeric_8_box_multiple_outline
mdi_numeric_8_box_outline
mdi_numeric_9_box
mdi_numeric_9_box_multiple_outline
mdi_numeric_9_box_outline
mdi_numeric_9_plus_box
mdi_numeric_9_plus_box_multiple_outline
mdi_numeric_9_plus_box_outline
mdi_nut
mdi_nutrition
mdi_oar
mdi_octagon
mdi_octagon_outline
mdi_octagram
mdi_octagram_outline
mdi_odnoklassniki
mdi_office
mdi_oil
mdi_oil_temperature
mdi_omega
mdi_onedrive
mdi_onenote
mdi_opacity
mdi_open_in_app
mdi_open_in_new
mdi_openid
mdi_opera
mdi_orbit
mdi_ornament
mdi_ornament_variant
mdi_owl
mdi_package
mdi_package_down
mdi_package_up
mdi_package_variant
mdi_package_variant_closed
﫿mdi_page_first
mdi_page_last
mdi_page_layout_body
mdi_page_layout_footer
mdi_page_layout_header
mdi_page_layout_sidebar_left
mdi_page_layout_sidebar_right
mdi_palette
mdi_palette_advanced
mdi_panda
mdi_pandora
mdi_panorama
mdi_panorama_fisheye
mdi_panorama_horizontal
mdi_panorama_vertical
mdi_panorama_wide_angle
mdi_paper_cut_vertical
mdi_paperclip
mdi_parking
mdi_passport
mdi_pause
mdi_pause_circle
mdi_pause_circle_outline
mdi_pause_octagon
mdi_pause_octagon_outline
mdi_paw
mdi_paw_off
mdi_pen
mdi_pencil
mdi_pencil_box
mdi_pencil_box_outline
mdi_pencil_circle
mdi_pencil_circle_outline
mdi_pencil_lock
mdi_pencil_off
mdi_pentagon
ﯿmdi_pentagon_outline
mdi_percent
mdi_periodic_table_co2
mdi_periscope
mdi_pharmacy
mdi_phone
mdi_phone_bluetooth
mdi_phone_classic
mdi_phone_forward
mdi_phone_hangup
mdi_phone_in_talk
mdi_phone_incoming
mdi_phone_locked
mdi_phone_log
mdi_phone_minus
mdi_phone_missed
mdi_phone_outgoing
mdi_phone_paused
mdi_phone_plus
mdi_phone_return
mdi_phone_settings
mdi_phone_voip
mdi_pi
mdi_pi_box
mdi_piano
mdi_pig
mdi_pill
mdi_pillar
mdi_pin
mdi_pin_off
mdi_pine_tree
mdi_pine_tree_box
mdi_pinterest
mdi_pinterest_box
mdi_pipe
mdi_pipe_disconnected
mdi_pistol
mdi_pizza
mdi_plane_shield
mdi_play
mdi_play_box_outline
mdi_play_circle
mdi_play_circle_outline
mdi_play_pause
mdi_play_protected_content
mdi_playlist_check
mdi_playlist_minus
mdi_playlist_play
mdi_playlist_plus
mdi_playlist_remove
mdi_playstation
mdi_plex
mdi_plus
mdi_plus_box
mdi_plus_box_outline
mdi_plus_circle
mdi_plus_circle_multiple_outline
mdi_plus_circle_outline
mdi_plus_network
mdi_plus_one
mdi_plus_outline
mdi_pocket
mdi_pokeball
mdi_poker_chip
mdi_polaroid
mdi_poll
mdi_poll_box
mdi_polymer
mdi_pool
mdi_popcorn
mdi_pot
mdi_pot_mix
mdi_pound
mdi_pound_box
mdi_power
mdi_power_plug
mdi_power_plug_off
mdi_power_settings
mdi_power_socket
mdi_power_socket_eu
mdi_power_socket_uk
mdi_power_socket_us
mdi_prescription
mdi_presentation
mdi_presentation_play
mdi_printer
mdi_printer_3d
mdi_printer_alert
mdi_printer_settings
mdi_priority_high
mdi_priority_low
mdi_professional_hexagon
mdi_projector
mdi_projector_screen
mdi_publish
mdi_pulse
mdi_puzzle
mdi_qqchat
mdi_qrcode
mdi_qrcode_scan
mdi_quadcopter
mdi_quality_high
mdi_quicktime
mdi_radar
mdi_radiator
mdi_radio
mdi_radio_handheld
mdi_radio_tower
mdi_radioactive
mdi_radiobox_blank
mdi_radiobox_marked
mdi_raspberrypi
錄mdi_ray_end
mdi_ray_end_arrow
mdi_ray_start
mdi_ray_start_arrow
mdi_ray_start_end
mdi_ray_vertex
mdi_react
mdi_read
mdi_receipt
mdi_record
mdi_record_rec
mdi_recycle
mdi_reddit
mdi_redo
mdi_redo_variant
mdi_refresh
mdi_regex
mdi_relative_scale
mdi_reload
mdi_remote
mdi_rename_box
mdi_reorder_horizontal
mdi_reorder_vertical
mdi_repeat
mdi_repeat_off
mdi_repeat_once
mdi_replay
mdi_reply
mdi_reply_all
mdi_reproduction
mdi_resize_bottom_right
mdi_responsive
mdi_restart
mdi_restore
mdi_rewind
mdi_rewind_outline
mdi_rhombus
mdi_rhombus_outline
mdi_ribbon
mdi_rice
mdi_ring
mdi_road
mdi_road_variant
mdi_robot
mdi_rocket
mdi_roomba
mdi_rotate_3d
mdi_rotate_left
mdi_rotate_left_variant
mdi_rotate_right
mdi_rotate_right_variant
mdi_rounded_corner
mdi_router_wireless
mdi_routes
mdi_rowing
mdi_rss
mdi_rss_box
mdi_ruler
mdi_run
mdi_run_fast
mdi_sale
mdi_sass
mdi_satellite
mdi_satellite_variant
mdi_saxophone
mdi_scale
mdi_scale_balance
mdi_scale_bathroom
mdi_scanner
mdi_school
mdi_screen_rotation
mdi_screen_rotation_lock
mdi_screwdriver
mdi_script
mdi_sd
mdi_seal
mdi_search_web
mdi_seat_flat
mdi_seat_flat_angled
mdi_seat_individual_suite
mdi_seat_legroom_extra
mdi_seat_legroom_normal
勵mdi_seat_legroom_reduced
mdi_seat_recline_extra
mdi_seat_recline_normal
mdi_security
mdi_security_home
mdi_security_network
mdi_select
mdi_select_all
mdi_select_inverse
mdi_select_off
mdi_selection
mdi_selection_off
mdi_send
mdi_send_secure
mdi_serial_port
mdi_server
mdi_server_minus
mdi_server_network
mdi_server_network_off
mdi_server_off
mdi_server_plus
mdi_server_remove
mdi_server_security
mdi_set_all
mdi_set_center
mdi_set_center_right
mdi_set_left
mdi_set_left_center
mdi_set_left_right
mdi_set_none
mdi_set_right
mdi_settings
mdi_settings_box
mdi_shape
mdi_shape_circle_plus
mdi_shape_outline
mdi_shape_plus
mdi_shape_polygon_plus
mdi_shape_rectangle_plus
mdi_shape_square_plus
mdi_share
mdi_share_variant
mdi_shield
mdi_shield_half_full
mdi_shield_outline
mdi_ship_wheel
mdi_shopping
mdi_shopping_music
mdi_shovel
mdi_shovel_off
mdi_shredder
mdi_shuffle
mdi_shuffle_disabled
mdi_shuffle_variant
mdi_sigma
mdi_sigma_lower
mdi_sign_caution
ﱿmdi_sign_direction
mdi_sign_text
mdi_signal
mdi_signal_2g
mdi_signal_3g
mdi_signal_4g
mdi_signal_hspa
mdi_signal_hspa_plus
mdi_signal_off
mdi_signal_variant
mdi_silverware
mdi_silverware_fork
mdi_silverware_spoon
mdi_silverware_variant
mdi_sim
mdi_sim_alert
mdi_sim_off
mdi_sitemap
mdi_skip_backward
mdi_skip_forward
mdi_skip_next
mdi_skip_next_circle
mdi_skip_next_circle_outline
mdi_skip_previous
mdi_skip_previous_circle
mdi_skip_previous_circle_outline
mdi_skull
mdi_skype
mdi_skype_business
mdi_slack
mdi_sleep
mdi_sleep_off
mdi_smoking
mdi_smoking_off
mdi_snapchat
mdi_snowflake
mdi_snowman
mdi_soccer
mdi_soccer_field
mdi_sofa
mdi_solid
mdi_sort
mdi_sort_alphabetical
mdi_sort_ascending
mdi_sort_descending
mdi_sort_numeric
mdi_sort_variant
樂mdi_soundcloud
mdi_source_branch
mdi_source_commit
mdi_source_commit_end
mdi_source_commit_end_local
mdi_source_commit_local
mdi_source_commit_next_local
mdi_source_commit_start
mdi_source_commit_start_next_local
mdi_source_fork
mdi_source_merge
mdi_source_pull
mdi_soy_sauce
mdi_speaker
mdi_speaker_off
mdi_speaker_wireless
mdi_speedometer
mdi_spellcheck
mdi_spotify
mdi_spotlight
mdi_spotlight_beam
mdi_spray
mdi_square
mdi_square_inc
mdi_square_inc_cash
mdi_square_outline
mdi_square_root
mdi_stack_overflow
mdi_stackexchange
mdi_stadium
mdi_stairs
mdi_standard_definition
mdi_star
mdi_star_circle
mdi_star_half
mdi_star_off
mdi_star_outline
mdi_steam
mdi_steering
mdi_step_backward
mdi_step_backward_2
mdi_step_forward
mdi_step_forward_2
mdi_stethoscope
mdi_sticker
mdi_sticker_emoji
mdi_stocking
mdi_stop
mdi_stop_circle
mdi_stop_circle_outline
mdi_store
mdi_store_24_hour
mdi_stove
mdi_subdirectory_arrow_left
mdi_subdirectory_arrow_right
mdi_subway
mdi_subway_variant
mdi_summit
mdi_sunglasses
mdi_surround_sound
mdi_surround_sound_2_0
mdi_surround_sound_3_1
mdi_surround_sound_5_1
mdi_surround_sound_7_1
mdi_svg
mdi_swap_horizontal
mdi_swap_vertical
mdi_swim
mdi_switch
mdi_sword
mdi_sword_cross
mdi_sync
mdi_sync_alert
mdi_sync_off
mdi_tab
mdi_tab_plus
mdi_tab_unselected
mdi_table
mdi_table_column
mdi_table_column_plus_after
mdi_table_column_plus_before
mdi_table_column_remove
mdi_table_column_width
mdi_table_edit
mdi_table_large
mdi_table_of_contents
mdi_table_row
mdi_table_row_height
mdi_table_row_plus_after
mdi_table_row_plus_before
mdi_table_row_remove
mdi_table_settings
mdi_tablet
mdi_tablet_android
mdi_tablet_ipad
mdi_taco
mdi_tag
mdi_tag_faces
mdi_tag_heart
mdi_tag_multiple
mdi_tag_outline
mdi_tag_plus
mdi_tag_remove
mdi_tag_text_outline
mdi_target
mdi_taxi
刺mdi_teamviewer
mdi_telegram
mdi_television
mdi_television_box
mdi_television_classic
mdi_television_classic_off
mdi_television_guide
mdi_television_off
mdi_temperature_celsius
mdi_temperature_fahrenheit
mdi_temperature_kelvin
mdi_tennis
mdi_tent
mdi_terrain
mdi_test_tube
mdi_text_shadow
mdi_text_to_speech
mdi_text_to_speech_off
mdi_textbox
mdi_textbox_password
mdi_texture
mdi_theater
mdi_theme_light_dark
mdi_thermometer
mdi_thermometer_lines
mdi_thought_bubble
mdi_thought_bubble_outline
mdi_thumb_down
mdi_thumb_down_outline
mdi_thumb_up
mdi_thumb_up_outline
mdi_thumbs_up_down
mdi_ticket
mdi_ticket_account
mdi_ticket_confirmation
mdi_ticket_percent
mdi_tie
mdi_tilde
mdi_timelapse
mdi_timer
mdi_timer_3
mdi_timer_10
mdi_timer_off
mdi_timer_sand
mdi_timer_sand_empty
mdi_timer_sand_full
mdi_timetable
mdi_toggle_switch
mdi_toggle_switch_off
mdi_tooltip
mdi_tooltip_edit
mdi_tooltip_image
mdi_tooltip_outline
mdi_tooltip_outline_plus
mdi_tooltip_text
mdi_tooth
mdi_tor
ﭿmdi_tower_beach
mdi_tower_fire
mdi_towing
mdi_trackpad
mdi_traffic_light
mdi_train
mdi_tram
mdi_transcribe
mdi_transcribe_close
mdi_transfer
mdi_transit_transfer
mdi_translate
mdi_treasure_chest
mdi_tree
mdi_trello
mdi_trending_down
mdi_trending_neutral
mdi_trending_up
mdi_triangle
mdi_triangle_outline
mdi_trophy
mdi_trophy_award
mdi_trophy_outline
mdi_trophy_variant
mdi_trophy_variant_outline
mdi_truck
mdi_truck_delivery
mdi_truck_fast
mdi_truck_trailer
mdi_tshirt_crew
憎mdi_tshirt_v
mdi_tumblr
mdi_tumblr_reblog
mdi_tune
mdi_tune_vertical
mdi_twitch
mdi_twitter
mdi_twitter_box
mdi_twitter_circle
mdi_twitter_retweet
mdi_uber
mdi_ubuntu
mdi_ultra_high_definition
mdi_umbraco
mdi_umbrella
mdi_umbrella_outline
mdi_undo
mdi_undo_variant
mdi_unfold_less_horizontal
mdi_unfold_less_vertical
mdi_unfold_more_horizontal
mdi_unfold_more_vertical
mdi_ungroup
mdi_unity
mdi_untappd
mdi_update
mdi_upload
mdi_upload_multiple
mdi_upload_network
mdi_usb
mdi_van_passenger
mdi_van_utility
mdi_vanish
mdi_vector_arrange_above
mdi_vector_arrange_below
mdi_vector_circle
mdi_vector_circle_variant
mdi_vector_combine
mdi_vector_curve
mdi_vector_difference
mdi_vector_difference_ab
mdi_vector_difference_ba
mdi_vector_intersection
mdi_vector_line
mdi_vector_point
mdi_vector_polygon
mdi_vector_polyline
mdi_vector_radius
mdi_vector_rectangle
mdi_vector_selection
mdi_vector_square
mdi_vector_triangle
mdi_vector_union
mdi_venmo
mdi_verified
mdi_vibrate
mdi_video
mdi_video_3d
mdi_video_4k_box
mdi_video_input_antenna
mdi_video_input_component
﴿mdi_video_input_hdmi
mdi_video_input_svideo
mdi_video_off
mdi_video_switch
mdi_view_agenda
mdi_view_array
mdi_view_carousel
mdi_view_column
mdi_view_dashboard
mdi_view_dashboard_variant
mdi_view_day
mdi_view_grid
mdi_view_headline
mdi_view_list
mdi_view_module
mdi_view_parallel
mdi_view_quilt
mdi_view_sequential
mdi_view_stream
mdi_view_week
mdi_vimeo
mdi_violin
mdi_visualstudio
mdi_vk
mdi_vk_box
mdi_vk_circle
mdi_vlc
mdi_voice
mdi_voicemail
mdi_volume_high
mdi_volume_low
奔mdi_volume_medium
mdi_volume_minus
mdi_volume_mute
mdi_volume_off
mdi_volume_plus
mdi_vpn
mdi_vuejs
mdi_walk
mdi_wall
mdi_wallet
mdi_wallet_giftcard
mdi_wallet_membership
mdi_wallet_travel
mdi_wan
mdi_washing_machine
mdi_watch
mdi_watch_export
mdi_watch_import
mdi_watch_vibrate
mdi_water
mdi_water_off
mdi_water_percent
mdi_water_pump
mdi_watermark
mdi_waves
mdi_weather_cloudy
mdi_weather_fog
mdi_weather_hail
mdi_weather_lightning
mdi_weather_lightning_rainy
mdi_weather_night
mdi_weather_partlycloudy
mdi_weather_pouring
mdi_weather_rainy
mdi_weather_snowy
mdi_weather_snowy_rainy
mdi_weather_sunny
mdi_weather_sunset
mdi_weather_sunset_down
mdi_weather_sunset_up
mdi_weather_windy
mdi_weather_windy_variant
mdi_web
mdi_webcam
mdi_webhook
mdi_webpack
mdi_wechat
mdi_weight
mdi_weight_kilogram
mdi_whatsapp
mdi_wheelchair_accessibility
mdi_white_balance_auto
mdi_white_balance_incandescent
mdi_white_balance_iridescent
mdi_white_balance_sunny
mdi_widgets
mdi_wifi
mdi_wifi_off
mdi_wii
mdi_wiiu
mdi_wikipedia
mdi_window_close
mdi_window_closed
mdi_window_maximize
mdi_window_minimize
mdi_window_open
mdi_window_restore
mdi_windows
mdi_wordpress
mdi_worker
mdi_wrap
mdi_wrench
mdi_wunderlist
mdi_xamarin
mdi_xamarin_outline
mdi_xaml
mdi_xbox
mdi_xbox_controller
mdi_xbox_controller_battery_alert
mdi_xbox_controller_battery_empty
mdi_xbox_controller_battery_full
mdi_xbox_controller_battery_low
mdi_xbox_controller_battery_medium
mdi_xbox_controller_battery_unknown
mdi_xbox_controller_off
mdi_xda
mdi_xing
mdi_xing_box
mdi_xing_circle
謹mdi_xml
mdi_xmpp
mdi_yammer
mdi_yeast
mdi_yelp
mdi_yin_yang
mdi_youtube_creator_studio
mdi_youtube_gaming
mdi_youtube_play
mdi_youtube_tv
mdi_zip_box
oct_alert
oct_arrow_down
oct_arrow_left
oct_arrow_right
oct_arrow_small_down
oct_arrow_small_left
oct_arrow_small_right
oct_arrow_small_up
oct_arrow_up
oct_beaker
oct_bell
oct_bold
oct_book
oct_bookmark
oct_briefcase
oct_broadcast
oct_browser
oct_bug
oct_calendar
oct_check
oct_checklist
oct_chevron_down
oct_chevron_left
oct_chevron_right
oct_chevron_up
oct_circle_slash
oct_circuit_board
oct_clippy
oct_clock
oct_cloud_download
oct_cloud_upload
oct_code
oct_comment
oct_comment_discussion
oct_credit_card
oct_dash
oct_dashboard
oct_database
oct_desktop_download
oct_device_camera
oct_device_camera_video
oct_device_desktop
oct_device_mobile
oct_diff
oct_diff_added
oct_diff_ignored
oct_diff_modified
oct_diff_removed
oct_diff_renamed
oct_ellipses
oct_ellipsis
oct_eye
oct_file
oct_file_binary
oct_file_code
oct_file_directory
oct_file_media
oct_file_pdf
oct_file_submodule
oct_file_symlink_directory
oct_file_symlink_file
oct_file_text
oct_file_zip
oct_flame
oct_fold
oct_gear
oct_gift
oct_gist
oct_gist_secret
oct_git_branch
oct_git_commit
oct_git_compare
oct_git_merge
oct_git_pull_request
oct_globe
oct_grabber
oct_graph
oct_heart
oct_history
oct_home
oct_horizontal_rule
oct_hubot
oct_inbox
oct_info
oct_issue_closed
oct_issue_opened
oct_issue_reopened
oct_italic
oct_jersey
oct_key
oct_keyboard
oct_law
oct_light_bulb
oct_link
oct_link_external
oct_list_ordered
oct_list_unordered
oct_location
oct_lock
oct_logo_gist
oct_logo_github
oct_mail
oct_mail_read
oct_mail_reply
oct_mark_github
oct_markdown
oct_megaphone
oct_mention
oct_milestone
oct_mirror
oct_mortar_board
oct_mute
oct_no_newline
oct_octoface
oct_organization
oct_package
oct_paintcan
oct_pencil
oct_person
oct_pin
oct_plug
oct_plus
oct_plus_small
oct_primitive_dot
oct_primitive_square
oct_pulse
oct_question
oct_quote
oct_radio_tower
oct_reply
oct_repo
oct_repo_clone
oct_repo_force_push
oct_repo_forked
oct_repo_pull
oct_repo_push
oct_rocket
oct_rss
oct_ruby
oct_search
oct_server
oct_settings
oct_shield
oct_sign_in
oct_sign_out
oct_smiley
oct_squirrel
oct_star
oct_stop
oct_sync
oct_tag
oct_tasklist
oct_telescope
oct_terminal
oct_text_size
oct_three_bars
oct_thumbsdown
oct_thumbsup
oct_tools
oct_trashcan
oct_triangle_down
oct_triangle_left
oct_triangle_right
oct_triangle_up
oct_unfold
oct_unmute
oct_unverified
oct_verified
oct_versions
oct_watch
oct_x
oct_zap
pl_branch
pl_current_line
pl_hostname
pl_left_hard_divider
pl_left_soft_divider
pl_line_number
pl_readonly
pl_right_hard_divider
pl_right_soft_divider
ple_backslash_separator
ple_backslash_separator_redundant
ple_column_number
ple_current_column
ple_flame_thick
ple_flame_thick_mirrored
ple_flame_thin
ple_flame_thin_mirrored
ple_forwardslash_separator
ple_forwardslash_separator_redundant
ple_honeycomb
ple_honeycomb_outline
ple_ice_waveform
ple_ice_waveform_mirrored
ple_left_half_circle_thick
ple_left_half_circle_thin
ple_lego_block_facing
ple_lego_block_sideways
ple_lego_separator
ple_lego_separator_thin
ple_lower_left_triangle
ple_lower_right_triangle
ple_pixelated_squares_big
ple_pixelated_squares_big_mirrored
ple_pixelated_squares_small
ple_pixelated_squares_small_mirrored
ple_right_half_circle_thick
ple_right_half_circle_thin
ple_trapezoid_top_bottom
ple_trapezoid_top_bottom_mirrored
ple_upper_left_triangle
ple_upper_right_triangle
pom_away
pom_clean_code
pom_external_interruption
pom_internal_interruption
pom_long_pause
pom_pair_programming
pom_pomodoro_done
pom_pomodoro_estimated
pom_pomodoro_squashed
pom_pomodoro_ticking
pom_short_pause
seti_bower
seti_cjsx
seti_coffee
seti_config
seti_css
seti_default
seti_ejs
seti_favicon
seti_folder
seti_go
seti_grunt
seti_gulp
seti_haskell
seti_heroku
seti_home
seti_html
seti_image
seti_javascript
seti_json
seti_julia
seti_karma
seti_less
seti_license
seti_lua
seti_markdown
seti_mustache
seti_npm
seti_php
seti_play_arrow
seti_project
seti_python
seti_rails
seti_react
seti_ruby
seti_sass
seti_stylus
seti_text
seti_twig
seti_typescript
seti_xml
weather_alien
weather_aliens
weather_barometer
weather_celsius
weather_cloud
weather_cloud_down
weather_cloud_refresh
weather_cloud_up
weather_cloudy
weather_cloudy_gusts
weather_cloudy_windy
weather_day_cloudy
weather_day_cloudy_gusts
weather_day_cloudy_high
weather_day_cloudy_windy
weather_day_fog
weather_day_hail
weather_day_haze
weather_day_light_wind
weather_day_lightning
weather_day_rain
weather_day_rain_mix
weather_day_rain_wind
weather_day_showers
weather_day_sleet
weather_day_sleet_storm
weather_day_snow
weather_day_snow_thunderstorm
weather_day_snow_wind
weather_day_sprinkle
weather_day_storm_showers
weather_day_sunny
weather_day_sunny_overcast
weather_day_thunderstorm
weather_day_windy
weather_degrees
weather_direction_down
weather_direction_down_left
weather_direction_down_right
weather_direction_left
weather_direction_right
weather_direction_up
weather_direction_up_left
weather_direction_up_right
weather_dust
weather_earthquake
weather_fahrenheit
weather_fire
weather_flood
weather_fog
weather_gale_warning
weather_hail
weather_horizon
weather_horizon_alt
weather_hot
weather_humidity
weather_hurricane
weather_hurricane_warning
weather_lightning
weather_lunar_eclipse
weather_meteor
weather_moon_alt_first_quarter
weather_moon_alt_full
weather_moon_alt_new
weather_moon_alt_third_quarter
weather_moon_alt_waning_crescent_1
weather_moon_alt_waning_crescent_2
weather_moon_alt_waning_crescent_3
weather_moon_alt_waning_crescent_4
weather_moon_alt_waning_crescent_5
weather_moon_alt_waning_crescent_6
weather_moon_alt_waning_gibbous_1
weather_moon_alt_waning_gibbous_2
weather_moon_alt_waning_gibbous_3
weather_moon_alt_waning_gibbous_4
weather_moon_alt_waning_gibbous_5
weather_moon_alt_waning_gibbous_6
weather_moon_alt_waxing_crescent_1
weather_moon_alt_waxing_crescent_2
weather_moon_alt_waxing_crescent_3
weather_moon_alt_waxing_crescent_4
weather_moon_alt_waxing_crescent_5
weather_moon_alt_waxing_crescent_6
weather_moon_alt_waxing_gibbous_1
weather_moon_alt_waxing_gibbous_2
weather_moon_alt_waxing_gibbous_3
weather_moon_alt_waxing_gibbous_4
weather_moon_alt_waxing_gibbous_5
weather_moon_alt_waxing_gibbous_6
weather_moon_first_quarter
weather_moon_full
weather_moon_new
weather_moon_third_quarter
weather_moon_waning_crescent_1
weather_moon_waning_crescent_2
weather_moon_waning_crescent_3
weather_moon_waning_crescent_4
weather_moon_waning_crescent_5
weather_moon_waning_crescent_6
weather_moon_waning_gibbous_1
weather_moon_waning_gibbous_2
weather_moon_waning_gibbous_3
weather_moon_waning_gibbous_4
weather_moon_waning_gibbous_5
weather_moon_waning_gibbous_6
weather_moon_waxing_crescent_1
weather_moon_waxing_crescent_2
weather_moon_waxing_crescent_3
weather_moon_waxing_crescent_4
weather_moon_waxing_crescent_5
weather_moon_waxing_crescent_6
weather_moon_waxing_gibbous_1
weather_moon_waxing_gibbous_2
weather_moon_waxing_gibbous_3
weather_moon_waxing_gibbous_4
weather_moon_waxing_gibbous_5
weather_moon_waxing_gibbous_6
weather_moonrise
weather_moonset
weather_na
weather_night_alt_cloudy
weather_night_alt_cloudy_gusts
weather_night_alt_cloudy_high
weather_night_alt_cloudy_windy
weather_night_alt_hail
weather_night_alt_lightning
weather_night_alt_partly_cloudy
weather_night_alt_rain
weather_night_alt_rain_mix
weather_night_alt_rain_wind
weather_night_alt_sleet
weather_night_alt_sleet_storm
weather_night_alt_snow
weather_night_alt_snow_thunderstorm
weather_night_alt_snow_wind
weather_night_alt_sprinkle
weather_night_alt_storm_showers
weather_night_alt_thunderstorm
weather_night_clear
weather_night_cloudy
weather_night_cloudy_gusts
weather_night_cloudy_high
weather_night_cloudy_windy
weather_night_fog
weather_night_hail
weather_night_lightning
weather_night_partly_cloudy
weather_night_rain
weather_night_rain_mix
weather_night_rain_wind
weather_night_showers
weather_night_sleet
weather_night_sleet_storm
weather_night_snow
weather_night_snow_thunderstorm
weather_night_snow_wind
weather_night_sprinkle
weather_night_storm_showers
weather_night_thunderstorm
weather_rain
weather_rain_mix
weather_rain_wind
weather_raindrop
weather_raindrops
weather_refresh
weather_refresh_alt
weather_sandstorm
weather_showers
weather_sleet
weather_small_craft_advisory
weather_smog
weather_smoke
weather_snow
weather_snow_wind
weather_snowflake_cold
weather_solar_eclipse
weather_sprinkle
weather_stars
weather_storm_showers
weather_storm_warning
weather_strong_wind
weather_sunrise
weather_sunset
weather_thermometer
weather_thermometer_exterior
weather_thermometer_internal
weather_thunderstorm
weather_time_1
weather_time_2
weather_time_3
weather_time_4
weather_time_5
weather_time_6
weather_time_7
weather_time_8
weather_time_9
weather_time_10
weather_time_11
weather_time_12
weather_tornado
weather_train
weather_tsunami
weather_umbrella
weather_volcano
weather_wind_beaufort_0
weather_wind_beaufort_1
weather_wind_beaufort_2
weather_wind_beaufort_3
weather_wind_beaufort_4
weather_wind_beaufort_5
weather_wind_beaufort_6
weather_wind_beaufort_7
weather_wind_beaufort_8
weather_wind_beaufort_9
weather_wind_beaufort_10
weather_wind_beaufort_11
weather_wind_beaufort_12
weather_wind_direction
weather_wind_east
weather_wind_north
weather_wind_north_east
weather_wind_north_west
weather_wind_south
weather_wind_south_east
weather_wind_south_west
weather_wind_west
weather_windy

wezterm.on(event_name, callback)

Since: 20201031-154415-9614e117

This function follows the html/javascript naming for defining event handlers.

wezterm.on causes your specified callback to be called when event_name is emitted. Events can be emitted by wezterm itself, or through code/configuration that you specify.

wezterm.on can register multiple callbacks for the same event; internally an ordered list of callbacks is maintained for each event. When the event is emitted, each of the registered callbacks is called in the order that they were registered.

The callback will receive the following parameters:

If a callback returns false it will prevent any callbacks that were registered after it from being triggered for the current event. Some events have a defined default action; returning false will prevent that default action from being taken for the current event.

There is no way to de-register an event handler. However, since the Lua state is built from scratch when the configuration is reloaded, simply reloading the configuration will clear any existing event handlers.

See wezterm.action_callback for a helper to define a custom action callback.

Predefined Events

See Window Events for a list of pre-defined events.

Custom Events

You may register handlers for arbitrary events for which wezterm itself has no special knowledge. It is recommended that you avoid event names that are likely to be used future versions of wezterm in order to avoid unexpected behavior if/when those names might be used in future.

The wezterm.emit function and the EmitEvent key assignment can be used to emit events.


In the following example, a key is assigned to capture the visible content of the active pane, write it to a file and then open that file in the vim editor:

local wezterm = require "wezterm"
local io = require "io"
local os = require "os"
local act = wezterm.action

wezterm.on("trigger-vim-with-visible-text", function(window, pane)
  -- Retrieve the current viewport's text.
  --
  -- Note: You could also pass an optional number of lines (eg: 2000) to
  -- retrieve that number of lines starting from the bottom of the viewport.
  local viewport_text = pane:get_lines_as_text()

  -- Create a temporary file to pass to vim
  local name = os.tmpname()
  local f = io.open(name, "w+")
  f:write(viewport_text)
  f:flush()
  f:close()

  -- Open a new window running vim and tell it to open the file
  window:perform_action(act.SpawnCommandInNewWindow{
    args={"vim", name}
  }, pane)

  -- Wait "enough" time for vim to read the file before we remove it.
  -- The window creation and process spawn are asynchronous wrt. running
  -- this script and are not awaitable, so we just pick a number.
  --
  -- Note: We don't strictly need to remove this file, but it is nice
  -- to avoid cluttering up the temporary directory.
  wezterm.sleep_ms(1000)
  os.remove(name)
end)

return {
  keys = {
    {key="E", mods="CTRL",
      action=act.EmitEvent("trigger-vim-with-visible-text")},
  }
}

wezterm.open_with(path_or_url [, application])

Since: 20220101-133340-7edc5b5a

This function opens the specified path_or_url with either the specified application or uses the default application if application was not passed in.

-- Opens a URL in your default browser
wezterm.open_with("http://example.com")

-- Opens a URL specifically in firefox
wezterm.open_with("http://example.com", "firefox")

wezterm.pad_left(string, min_width)

Since: 20210502-130208-bff6815d

Returns a copy of string that is at least min_width columns (as measured by wezterm.column_width).

If the string is shorter than min_width, spaces are added to the left end of the string.

For example, wezterm.pad_left("o", 3) returns " o".

See also: wezterm.truncate_left, wezterm.pad_right.

wezterm.pad_right(string, min_width)

Since: 20210502-130208-bff6815d

Returns a copy of string that is at least min_width columns (as measured by wezterm.column_width).

If the string is shorter than min_width, spaces are added to the right end of the string.

For example, wezterm.pad_right("o", 3) returns "o ".

See also: wezterm.truncate_left, wezterm.pad_left.

wezterm.permute_any_mods(table)

Since: 20201031-154415-9614e117

This function is intended to help with generating key or mouse binding entries that should apply regardless of the combination of modifier keys pressed.

For each combination of modifiers CTRL, ALT, SHIFT and SUPER, the supplied table value is copied and has mods = <value> set into the copy.

An entry for NONE is NOT generated (this is the only difference between permute_any_mods and permute_any_or_no_mods).

An array holding all of those combinations is returned.

If this is your only binding, or it is the last binding, the resulting array can be unpacked into a lua table initializer and used like this:

local wezterm = require 'wezterm';

return {
  mouse_bindings = {
    table.unpack(wezterm.permute_any_mods({
      event={Down={streak=1, button="Middle"}},
      action="PastePrimarySelection"
    }))
  }
}

(and if you have other bindings before and/or after, use a for loop to iterate and add each binding to your bindings table)

This is equivalent to writing this out, but is much less verbose:

return {
  mouse_bindings = {
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "CTRL | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT | CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT | CTRL | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | CTRL | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT | CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT | CTRL | SUPER",
        },
  }
}

wezterm.permute_any_or_no_mods(table)

Since: 20201031-154415-9614e117

This function is intended to help with generating key or mouse binding entries that should apply regardless of the combination of modifier keys pressed.

For each combination of modifiers CTRL, ALT, SHIFT and SUPER, the supplied table value is copied and has mods = <value> set into the copy.

In addition, an entry for NONE is generated (this is the only difference between permute_any_mods and permute_any_or_no_mods).

An array holding all of those combinations is returned.

If this is your only binding, or it is the last binding, the resulting array can be unpacked into a lua table initializer and used like this:

local wezterm = require 'wezterm';

return {
  mouse_bindings = {
    table.unpack(wezterm.permute_any_or_no_mods({
      event={Down={streak=1, button="Middle"}},
      action="PastePrimarySelection"
    }))
  }
}

(and if you have other bindings before and/or after, use a for loop to iterate and add each binding to your bindings table)

This is equivalent to writing this out, but is much less verbose:

return {
  mouse_bindings = {
        {
            action= "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "NONE",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "CTRL | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT | CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "ALT | CTRL | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | CTRL | SUPER",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT | CTRL",
        },
        {
            action = "PastePrimarySelection",
            event = {
                Down = {
                    button = "Middle",
                    streak = 1,
                },
            },
            mods = "SHIFT | ALT | CTRL | SUPER",
        },
  }
}

wezterm.read_dir(path)

Since: 20200503-171512-b13ef15f

This function returns an array containing the absolute file names of the directory specified. Due to limitations in the lua bindings, all of the paths must be able to be represented as UTF-8 or this function will generate an error.

local wezterm = require 'wezterm';

-- logs the names of all of the entries under `/etc`
for _, v in ipairs(wezterm.read_dir("/etc")) do
  wezterm.log_error("entry: " .. v)
end

wezterm.run_child_process(args)

Since: 20200503-171512-b13ef15f

This function accepts an argument list; it will attempt to spawn that command and will return a tuple consisting of the boolean success of the invocation, the stdout data and the stderr data.

local wezterm = require 'wezterm';

local success, stdout, stderr = wezterm.run_child_process({"ls", "-l"})

See also background_child_process

wezterm.running_under_wsl()

This function returns a boolean indicating whether we believe that we are running in a Windows Services for Linux (WSL) container. In such an environment the wezterm.target_triple will indicate that we are running in Linux but there will be some slight differences in system behavior (such as filesystem capabilities) that you may wish to probe for in the configuration.

local wezterm = require 'wezterm';
wezterm.log_error("System " .. wezterm.target_triple .. " " ..
  tostring(wezterm.running_under_wsl()))

wezterm.sleep_ms(milliseconds)

Since: 20201031-154415-9614e117

wezterm.sleep_ms suspends execution of the script for the specified number of milliseconds. After that time period has elapsed, the script continues running at the next statement.

wezterm.split_by_newlines(str)

Since: 20200503-171512-b13ef15f

This function takes the input string and splits it by newlines (both \n and \r\n are recognized as newlines) and returns the result as an array of strings that have the newlines removed.

local wezterm = require 'wezterm';

local example = "hello\nthere\n";

for _, line in ipairs(wezterm.split_by_newlines(example)) do
  wezterm.log_error(line)
end

wezterm.strftime(format)

Since: 20210314-114017-04b7cedd

Formats the current local date/time into a string using the Rust chrono strftime syntax.

local wezterm = require 'wezterm';

local date_and_time = wezterm.strftime("%Y-%m-%d %H:%M:%S");
wezterm.log_info(date_and_time);

See also strftime_utc.

wezterm.strftime_utc(format)

Since: 20220624-141144-bd1b7c5d

Formats the current UTC date/time into a string using the Rust chrono strftime syntax.

local wezterm = require 'wezterm';

local date_and_time = wezterm.strftime_utc("%Y-%m-%d %H:%M:%S");
wezterm.log_info(date_and_time);

See also strftime.

wezterm.target_triple

This constant is set to the Rust target triple for the platform on which wezterm was built. This can be useful when you wish to conditionally adjust your configuration based on the platform.

local wezterm = require 'wezterm';

if wezterm.target_triple == "x86_64-pc-windows-msvc" then
  -- We are running on Windows; maybe we emit different
  -- key assignments here?
end

The most common triples are:

  • x86_64-pc-windows-msvc - Windows
  • x86_64-apple-darwin - macOS
  • x86_64-unknown-linux-gnu - Linux

wezterm.truncate_left(string, max_width)

Since: 20210502-130208-bff6815d

Returns a copy of string that is no longer than max_width columns (as measured by wezterm.column_width).

Truncation occurs by removing excess characters from the left end of the string.

For example, wezterm.truncate_left("hello", 3) returns "llo".

See also: wezterm.truncate_right, wezterm.pad_right.

wezterm.truncate_right(string, max_width)

Since: 20210502-130208-bff6815d

Returns a copy of string that is no longer than max_width columns (as measured by wezterm.column_width).

Truncation occurs by reemoving excess characters from the right end of the string.

For example, wezterm.truncate_right("hello", 3) returns "hel",

See also: wezterm.truncate_left, wezterm.pad_left.

wezterm.utf16_to_utf8(str)

Since: 20200503-171512-b13ef15f

This function is overly specific and exists primarily to workaround this wsl.exe issue.

It takes as input a string and attempts to convert it from utf16 to utf8.

local wezterm = require 'wezterm';

local success, wsl_list, wsl_err = wezterm.run_child_process({"wsl.exe", "-l"})
wsl_list = wezterm.utf16_to_utf8(wsl_list)

wezterm.version

This constant is set to the wezterm version string that is also reported by running wezterm -V. This can potentially be used to adjust configuration according to the installed version.

The version string looks like 20200406-151651-5b700e4. You can compare the strings lexicographically if you wish to test whether a given version is newer than another; the first component is the date on which the release was made, the second component is the time and the final component is a git hash.

local wezterm = require 'wezterm';
wezterm.log_error("Version " .. wezterm.version)

Since: nightly builds only

The wezterm.gui module exposes functions that operate on the gui layer.

The multiplexer may not be connected to a GUI, so attempting to resolve this module from the mux server will return nil.

You will typically use something like:

local wezterm = require 'wezterm'
local gui = wezterm.gui
if gui then
  -- do something that depends on the gui layer
end

Available functions, constants

wezterm.gui.gui_window_for_mux_window(window_id)

Since: nightly builds only

Attempts to resolve a mux window to its corresponding Gui Window.

This may not succeed for a couple of reasons:

  • If called by the multiplexer daemon, there is no gui, so this will never succeed
  • If the mux window is part of a workspace that is not the active workspace

wezterm.gui.screens()

Since: nightly builds only

Returns information about the screens connected to the system.

The follow example was typed into the Debug Overlay (by default: press CTRL-SHIFT-L) on a macbook:

> wezterm.gui.screens()
{
    "active": {
        "height": 1800,
        "name": "Built-in Retina Display",
        "width": 2880,
        "x": 0,
        "y": 0,
    },
    "by_name": {
        "Built-in Retina Display": {
            "height": 1800,
            "name": "Built-in Retina Display",
            "width": 2880,
            "x": 0,
            "y": 0,
        },
    },
    "main": {
        "height": 1800,
        "name": "Built-in Retina Display",
        "width": 2880,
        "x": 0,
        "y": 0,
    },
    "origin_x": 0,
    "origin_y": 0,
    "virtual_height": 1800,
    "virtual_width": 2880,
}

The return value is a table with the following keys:

  • active - contains information about the active screen. The active screen is the one which has input focus. On some systems, wezterm will return the same information as the main screen screen.
  • main - contains information about the main screen. The main screen is the primary screen: the one that has the menu bar or task bar.
  • by_name - a table containing information about each screen, indexed by their name
  • origin_x, origin_y, virtual_height, virtual_width - the bounds of the combined desktop geometry spanning all connected screens

The screen information is a table with the following keys:

  • name - the name of the screen.
  • x, y, width, height - the bounds of this screen

Since: 20220624-141144-bd1b7c5d

The wezterm.mux module exposes functions that operate on the multiplexer layer.

The multiplexer manages the set of running programs into panes, tabs, windows and workspaces.

The multiplexer may not be connected to a GUI so certain operations that require a running Window management system are not present in the interface exposed by this module.

You will typically use something like:

local wezterm = require 'wezterm'
local mux = wezterm.mux

at the top of your configuration file to access it.

Important Note!

You should avoid using, at the file scope in your config, mux functions that cause new splits, tabs or windows to be created. The configuration file can be evaluated multiple times in various contexts. If you want to spawn new programs when wezterm starts up, look at the gui-startup and mux-startup events.

Available functions, constants

wezterm.mux.all_windows()

Since: nightly builds only

Returns an array table holding all of the known MuxWindow objects.

wezterm.mux.get_active_workspace()

Since: 20220624-141144-bd1b7c5d

Returns the name of the active workspace.

wezterm.mux.get_pane(PANE_ID)

Since: 20220624-141144-bd1b7c5d

Given a pane ID, verifies that the ID is a valid pane known to the mux and returns a MuxPane object that can be used to operate on the pane.

This is useful for situations where you have obtained a pane id from some other source and want to use the various MuxPane methods with it.

wezterm.mux.get_tab(WINDOW_ID)

Since: 20220624-141144-bd1b7c5d

Given a tab ID, verifies that the ID is a valid tab known to the mux and returns a MuxTab object that can be used to operate on the tab.

This is useful for situations where you have obtained a tab id from some other source and want to use the various MuxTab methods with it.

wezterm.mux.get_window(WINDOW_ID)

Since: 20220624-141144-bd1b7c5d

Given a window ID, verifies that the ID is a valid window known to the mux and returns a MuxWindow object that can be used to operate on the window.

This is useful for situations where you have obtained a window id from some other source and want to use the various MuxWindow methods with it.

wezterm.mux.get_workspace_names()

Since: 20220624-141144-bd1b7c5d

Returns a table containing the names of the workspaces known to the mux.

wezterm.mux.set_active_workspace(WORKSPACE)

Since: 20220624-141144-bd1b7c5d

Sets the active workspace name.

If the requested name doesn't correspond to an existing workspace, then an error is raised.

wezterm.mux.spawn_window{}

Since: 20220624-141144-bd1b7c5d

Spawns a program into a new window, returning the MuxTab, MuxPane and MuxWindow objects associated with it:

local tab, pane, window = wezterm.mux.spawn_window{}

When no arguments are passed, the default program is spawned.

The following parameters are supported:

args

Specifies the argument array for the command that should be spawned. If omitted the default program for the domain will be spawned.

wezterm.mux.spawn_window{args={"top"}}

cwd

Specify the current working directory that should be used for the program.

If unspecified, follows the rules from default_cwd

wezterm.mux.spawn_window{cwd="/tmp"}

set_environment_variables

Sets additional environment variables in the environment for this command invocation.

wezterm.mux.spawn_window{set_environment_variables={"FOO"="BAR"}}

domain

Specifies the multiplexer domain into which the program should be spawned. The default value is assumed to be "DefaultDomain", which causes the default domain to be used.

You may specify the name of one of the multiplexer domains defined in your configuration using the following:

wezterm.mux.spawn_window{domain={DomainName="my.name"}}

width and height

Only valid when width and height are used together, allows specifying the number of column and row cells that the window should have.

wezterm.mux.spawn_window{width=60, height=30}

workspace

Specifies the name of the workspace that the newly created window will be associated with. If omitted, the currently active workspace name will be used.

wezterm.mux.spawn_window{workspace={"coding"}}

Config struct

The return statement at the end of your wezterm.lua file returns a table that is interpreted as the internal Config struct type.

This section documents the various available fields in the config struct.

At the time of writing, it is not a complete list!

adjust_window_size_when_changing_font_size = true

Since 20210203-095643-70a364eb

Control whether changing the font size adjusts the dimensions of the window (true) or adjusts the number of terminal rows/columns (false). The default is true.

If you use a tiling window manager then you may wish to set this to false.

allow_square_glyphs_to_overflow_width = "Never"

Since: 20210203-095643-70a364eb

Configures how square symbol glyph's cell is rendered:

  • "WhenFollowedBySpace" - deliberately overflow the cell width when the next cell is a space.
  • "Always" - overflow the cell regardless of the next cell being a space.
  • "Never" (the default) - strictly respect the cell width.

Since: 20210404-112810-b63a949d

This setting now applies to any glyph with an aspect ratio larger than 0.9, which covers more symbol glyphs than in earlier releases.

The default value for this setting has changed to WhenFollowedBySpace.

allow_win32_input_mode

Since: 20220319-142410-0fcdea07

When set to true, wezterm will honor an escape sequence generated by the Windows ConPTY layer to switch the keyboard encoding to a proprietary scheme that has maximum compatibility with win32 console applications.

See also Improved Keyboard Handling in ConPTY.

Since: 20220624-141144-bd1b7c5d

The default for allow_win32_input_mode is now true.

alternate_buffer_wheel_scroll_speed = 3

Since: 20210203-095643-70a364eb

Normally the vertical mouse wheel will scroll the terminal viewport so that different sections of the scrollback are visible.

When an application activates the Alternate Screen Buffer (this is common for "full screen" terminal programs such as pagers and editors), the alternate screen doesn't have a scrollback.

In this mode, if the application hasn't enabled mouse reporting, wezterm will generate Arrow Up/Down key events when the vertical mouse wheel is scrolled.

The alternate_buffer_wheel_scroll_speed specifies how many arrow key presses are generated by a single scroll wheel "tick".

The default for this value is 3, which means that a single wheel up tick will appear to the application as though the user pressed arrow up three times in quick succession.

In versions of wezterm prior to this configuration option being available, the behavior was the same except that the effective value of this option was always 1.

animation_fps = 10

Since: 20220319-142410-0fcdea07

This setting controls the maximum frame rate used when rendering easing effects for blinking cursors, blinking text and visual bell.

Setting it larger will result in smoother easing effects but will increase GPU utilization.

If you are running with a CPU renderer (eg: you have front_end = "Software", or your system doesn't have a GPU), then setting animation_fps = 1 is recommended, as doing so will disable easing effects and use transitions:

return {
  animation_fps = 1,
  cursor_blink_ease_in = "Constant",
  cursor_blink_ease_out = "Constant",
}

audible_bell

Since: 20211204-082213-a66c61ee9

When the BEL ascii sequence is sent to a pane, the bell is "rung" in that pane.

You may choose to configure the audible_bell option to change the sound that wezterm makes when the bell rings.

The follow are possible values:

  • "SystemBeep" - perform the system beep or alert sound. This is the default. On Wayland systems, which have no system beep function, it does not produce a sound.
  • "Disabled" - don't make a sound

See also visual_bell and bell event

automatically_reload_config

Since: 20201031-154415-9614e117

When true (the default), watch the config file and reload it automatically when it is detected as changing. When false, you will need to manually trigger a config reload with a key bound to the action ReloadConfiguration.

For example, to disable auto config reload:

return {
  automatically_reload_config = false
}

background

Since: 20220624-141144-bd1b7c5d

The background config option allows you to compose a number of layers to produce the background content in the terminal.

Layers can be image files, gradients or solid blocks of color. Layers composite over each other based on their alpha channel. Images in layers can be made to fill the viewport or to tile, and also to scroll with optional parallax as the viewport is scrolled.

This video demonstrates the use of multiple layers to produce a rich video game style parallax background; the configuration used for this is shown as an example at the bottom of this page:

The background option is a table that lists the desired layers starting with the deepest/back-most layer. Subsequent layers are composited over the top of preceding layers.

Layer Definition

A layer is a lua table with the following fields:

  • source - defines the source of the layer texture data. See below for source definitions
  • attachment - controls whether the layer is fixed to the viewport or moves as it scrolls. Can be:
    • "Fixed" (the default) to not move as the window scrolls,
    • "Scroll" to scroll 1:1 with the number of pixels scrolled in the viewport,
    • {Parallax=0.1} to scroll 1:10 with the number of pixels scrolled in the viewport.
  • repeat_x - controls whether the image is repeated in the x-direction. Can be one of:
    • "Repeat" - Repeat as much as possible to cover the area. The last image will be clipped if it doesn't fit. This is the default.
    • "Mirror" - Like "Repeat" except that the image is alternately mirrored which can make images that don't tile seamlessly look a bit better when repeated
    • "NoRepeat" - the image is not repeated.
  • repeat_x_size - Normally, when repeating, the image is tiled based on its width such that each copy of the image is immediately adjacent to the preceding instance. You may set repeat_x_size to a different value to increase or decrease the space between the repeated instances. Accepts:
    • number values in pixels,
    • string values like "100%" to specify a size relative to the viewport,
    • "10cell" to specify a size based on the terminal cell metrics.
  • repeat_y - like repeat_x but affects the y-direction.
  • repeat_y_size - like repeat_x_size but affects the y-direction.
  • vertical_align - controls the initial vertical position of the layer, relative to the viewport:
    • "Top" (the default),
    • "Middle",
    • "Bottom"
  • vertical_offset - specify an offset from the initial vertical position. Accepts:
    • number values in pixels,
    • string values like "100%" to specify a size relative to the viewport,
    • "10cell" to specify a size based on terminal cell metrics.
  • horizontal_align - controls the initial horizontal position of the layer, relative to the viewport:
    • "Left" (the default),
    • "Center"
    • "Right"
  • horizontal_offset - like vertical_offset but applies to the x-direction.
  • opacity - a number in the range 0 through 1.0 inclusive that is multiplied with the alpha channel of the source to adjust the opacity of the layer. The default is 1.0 to use the source alpha channel as-is. Using a smaller value makes the layer less opaque/more transparent.
  • hsb - a hue, saturation, brightness tranformation that can be used to adjust those attributes of the layer. See foreground_text_hsb for more information about this kind of transform.
  • height - controls the height of the image. The following values are accepted:
    • "Cover" (this is the default) - Scales the image, preserving aspect ratio, to the smallest possible size to fill the viewport, leaving no empty space. If the aspect ratio of the viewport differs from the image, the image is cropped.
    • "Contain" - Scales the image as large as possible without cropping or stretching. If the viewport is larger than the image, tiles the image unless repeat_y is set to "NoRepeat".
    • 123 - specifies a height of 123 pixels
    • "50%" - specifies a size of 50% of the viewport height
    • "2cell" - specifies a size equivalent to 2 rows
  • width - controls the width of the image. Same details as height but applies to the x-direction.

Source Definition

A source can be one of the following:

  • {File="/path/to/file.png"} - load the specified image file. PNG, JPEG, GIF, BMP, ICO, TIFF, PNM, DDS, TGA and farbfeld files can be loaded. Animated GIF and PNG files will animate while the window has focus.
  • {File={path="/path/to/anim.gif", speed=0.2}} - load the specified image file, which is an animated gif, and adjust the animation speed to 0.2 times its normal speed.
  • {Gradient={preset="Warm"}} - generate a gradient. The gradient definitions are the same as those allowed for window_background_gradient.
  • {Color="black"} - generate an image with the specified color.

Relationship with other config options

Specifying the following options:

  • window_background_gradient
  • window_background_image
  • window_background_opacity
  • window_background_image_hsb

will implicitly prepend a layer to the background configuration with width and height set to 100%.

It is recommended that you migrate to the newer background rather than mixing both the older and the newer configuration options.

Parallax Example

This example uses these Alien Space Ship Background - Parallax - Repeatable (Vertical) assets to demonstrate most of the available features of background. That asset pack includes a background layer and a number of overlays. The overlays are positioned at varying offsets with differing parallax to provide a greater sense of depth.

The video at the top of this page demonstrate this configuration in action.

-- The art is a bit too bright and colorful to be useful as a backdrop
-- for text, so we're going to dim it down to 10% of its normal brightness
local dimmer = {brightness=0.1}

return {
  enable_scroll_bar = true,
  min_scroll_bar_height = "2cell",
  colors = {
    scrollbar_thumb = "white",
  },
  background = {
    -- This is the deepest/back-most layer. It will be rendered first
    {
      source = {File="/Alien_Ship_bg_vert_images/Backgrounds/spaceship_bg_1.png"},
      -- The texture tiles vertically but not horizontally.
      -- When we repeat it, mirror it so that it appears "more seamless".
      -- An alternative to this is to set `width = "100%"` and have
      -- it stretch across the display
      repeat_x = "Mirror",
      hsb = dimmer,
      -- When the viewport scrolls, move this layer 10% of the number of
      -- pixels moved by the main viewport. This makes it appear to be
      -- further behind the text.
      attachment = {Parallax=0.1},
    },
    -- Subsequent layers are rendered over the top of each other
    {
      source = {File="/Alien_Ship_bg_vert_images/Overlays/overlay_1_spines.png"},
      width = "100%",
      repeat_x = "NoRepeat",

      -- position the spins starting at the bottom, and repeating every
      -- two screens.
      vertical_align = "Bottom",
      repeat_y_size = "200%",
      hsb = dimmer,

      -- The parallax factor is higher than the background layer, so this
      -- one will appear to be closer when we scroll
      attachment = {Parallax=0.2},
    },
    {
      source = {File="/Alien_Ship_bg_vert_images/Overlays/overlay_2_alienball.png"},
      width = "100%",
      repeat_x = "NoRepeat",

      -- start at 10% of the screen and repeat every 2 screens
      vertical_offset = "10%",
      repeat_y_size = "200%",
      hsb = dimmer,
      attachment = {Parallax=0.3},
    },
    {
      source = {File="/Alien_Ship_bg_vert_images/Overlays/overlay_3_lobster.png"},
      width = "100%",
      repeat_x = "NoRepeat",

      vertical_offset = "30%",
      repeat_y_size = "200%",
      hsb = dimmer,
      attachment = {Parallax=0.4},
    },
    {
      source = {File="/Alien_Ship_bg_vert_images/Overlays/overlay_4_spiderlegs.png"},
      width = "100%",
      repeat_x = "NoRepeat",

      vertical_offset = "50%",
      repeat_y_size = "150%",
      hsb = dimmer,
      attachment = {Parallax=0.5},
    },
  },
}

bold_brightens_ansi_colors = true

When true (the default), PaletteIndex 0-7 are shifted to bright when the font intensity is bold.

This brightening effect doesn't occur when the text is set to the default foreground color!

This defaults to true for better compatibility with a wide range of mature software; for instance, a lot of software assumes that Black+Bold renders as a Dark Grey which is legible on a Black background, but if this option is set to false, it would render as Black on Black.

bypass_mouse_reporting_modifiers = "SHIFT"

Since: 20210814-124438-54e29167

If an application has enabled mouse reporting mode, mouse events are sent directly to the application, and do not get routed through the mouse assignment logic.

Holding down the bypass_mouse_reporting_modifiers modifier key(s) will prevent the event from being passed to the application.

The default value for bypass_mouse_reporting_modifiers is SHIFT, which means that holding down shift while clicking will not send the mouse event to eg: vim running in mouse mode and will instead treat the event as though SHIFT was not pressed and then match it against the mouse assignments.

return {
  -- Use ALT instead of SHIFT to bypass application mouse reporting
  bypass_mouse_reporting_modifiers = "ALT"
}

canonicalize_pasted_newlines

Since: 20211204-082213-a66c61ee9

Controls whether pasted text will have newlines normalized.

If bracketed paste mode is enabled by the application, the effective value of this configuration option is "None".

The following values are accepted:

valuemeaningversion
truesame as "CarriageReturnAndLineFeed"Since: 20211204-082213-a66c61ee9
falsesame as "None"Since: 20211204-082213-a66c61ee9
"None"The text is passed through unchangedSince: 20220319-142410-0fcdea07
"LineFeed"Newlines of any style are rewritten as LFSince: 20220319-142410-0fcdea07
"CarriageReturn"Newlines of any style are rewritten as CRSince: 20220319-142410-0fcdea07
"CarriageReturnAndLineFeed"Newlines of any style are rewritten as CRLFSince: 20220319-142410-0fcdea07

Note that the string forms of these values are accepted in 20220319-142410-0fcdea07, however, true in all prior versions behaves the same way as "CarriageReturnAndLineFeed" behaves in the nightly build.

The default value has changed in different versions of wezterm:

versionplatformdefault
20211204-082213-a66c61ee9Windows"CarriageReturnAndLineFeed"
20211204-082213-a66c61ee9NOT Windows"None"
20220319-142410-0fcdea07NOT Windows"CarriageReturn"

On Windows we're in a bit of a frustrating situation: pasting into Windows console programs requires CRLF otherwise there is no newline at all, but when in WSL, pasting with CRLF gives excess blank lines.

In practice, the default setting means that unix shells and vim will get the unix newlines in their pastes (which is the UX most users will want) and cmd.exe will get CRLF.

cell_width = 1.0

Since: 20220624-141144-bd1b7c5d

Scales the computed cell width to adjust the spacing between successive cells of text.

If possible, you should prefer to specify the stretch parameter when selecting a font using wezterm.font or wezterm.font_with_fallback as that will generally look better and have fewer undesirable side effects.

If your preferred font doesn't have variations with different stretches, or if the font spacing still doesn't look right to you, then cell_width gives you a simple way to influence the spacing.

The default cell width is indirectly controlled by the font and font_size configuration options; the selected font and font size controls the height of the font, while the font designer controls the aspect ratio of the glyphs in the font. The base font (the first font resolved from your font configuration) defines the cell metrics for the terminal display grid, and those metrics are then used to place glyphs, regardless of which fallback font might be resolved for a given glyph.

If you feel that your chosen font feels too horizontally cramped then you can set cell_width = 1.2 to increase the horizontal spacing by 20%. Conversely, setting cell_width = 0.9 will decrease the horizontal spacing by 10%.

This option doesn't adjust the rasterized width of glyphs, it just changes what wezterm considers to be the cell boundaries. When rendering monospace, wezterm advances by the cell width to place successive glyphs.

If you set the scale less than 1.0 then the glyphs won't be truncated or squished, but will render over the top of each other. Conversely, if you set the scale to greater than 1.0, the glyphs won't be stretched but will render further apart from each other.

Changing cell_width doesn't adjust the positioning of the glyph within the cell: it remains at its usual x-position. It is not centered within the adjusted space.

Changing cell_width may have undesirable consequences, especially for fonts that use ligatures: depending on the font, you may find that some ligatured sequences are misaligned or render strangely. This is not a bug: the font is designed to be rendered with a cell_width = 1.0, so running with a different value will have this sort of side effect.

See also: line_height

check_for_updates & check_for_updates_interval_seconds

Wezterm checks regularly if there is a new stable version available on github, and shows a simple UI to let you know about the update (See show_update_window to control this UI).

By default it is checked once every 24 hours.

NOTE that it doesn't automatically download the release. No data are collected for the wezterm project as part of this.

Set check_for_updates to false to disable this completely or set check_for_updates_interval_seconds for an alternative update interval.

return {
  check_for_updates = true,
  check_for_updates_interval_seconds = 86400,
}

clean_exit_codes = { 0 }

Since: 20220624-141144-bd1b7c5d

Defines the set of exit codes that are considered to be a "clean" exit by exit_behavior when the program running in the terminal completes.

Acceptable values are an array of integer exit codes that you wish to treat as successful.

For example, if you often CTRL-C a program and then CTRL-D, bash will typically exit with status 130 to indicate that a program was terminated with SIGINT, but that bash itself wasn't. In that situation you may wish to set this config to treat 130 as OK:

return {
  clean_exit_codes = {130},
}

Note that 0 is always treated as a clean exit code and can be omitted from the list.

color_schemes

Specifies various named color schemes in your configuration file.

Described in more detail in Colors & Appearance

colors

Specifies the color palette.

Described in more detail in Colors & Appearance

cursor_blink_ease_in = "Linear"

Since: 20220319-142410-0fcdea07

Specifies the easing function to use when computing the color for the text cursor when it is set to a blinking style.

See visual_bell for more information about easing functions.

cursor_blink_ease_out = "Linear"

Since: 20220319-142410-0fcdea07

Specifies the easing function to use when computing the color for the text cursor when it is set to a blinking style.

See visual_bell for more information about easing functions.

cursor_blink_rate

Specifies how often a blinking cursor transitions between visible and invisible, expressed in milliseconds. Setting this to 0 disables blinking.

Note that this value is approximate due to the way that the system event loop schedulers manage timers; non-zero values will be at least the interval specified with some degree of slop.

It is recommended to avoid blinking cursors when on battery power, as it is relatively costly to keep re-rendering for the blink!

return {
  cursor_blink_rate = 800,
}

Since: 20220319-142410-0fcdea07

The cursor blink is controlled by the easing functions specified by the cursor_blink_ease_in and cursor_blink_ease_out.

custom_block_glyphs = true

Since: 20210314-114017-04b7cedd

When set to true (the default), WezTerm will compute its own idea of what the glyphs in the following unicode ranges should be, instead of using glyphs resolved from a font.

Ideally this option wouldn't exist, but it is present to work around a hinting issue in freetype.

BlockWhatSince
U2500Box Drawing20210814-124438-54e29167
U2580unicode block elements20210314-114017-04b7cedd
U1FB00Symbols for Legacy Computing (Sextants and Smooth mosaic graphics)20210814-124438-54e29167
U2800Braille Patterns20210814-124438-54e29167
PowerlinePowerline triangle, curve and diagonal glyphs20210814-124438-54e29167

You can set this to false to use the block characters provided by your font selection.

daemon_options

Allows configuring the multiplexer (mux) server and how it places itself into the background to run as a daemon process.

You should not normally need to configure this setting; the defaults should be sufficient in most cases.

There are three fields supported:

  • pid_file - specify the location of the pid and lock file. The default location is $XDG_RUNTIME_DIR/wezterm/pid on X11/Wayland systems, or $HOME/.local/share/wezterm/pid
  • stdout - specifies where a log of the stdout stream from the daemon will be placed. The default is $XDG_RUNTIME_DIR/wezterm/stdout on X11/Wayland systems, or $HOME/.local/share/wezterm/stdout.
  • stderr - specifies where a log of the stderr stream from the daemon will be placed. The default is $XDG_RUNTIME_DIR/wezterm/stderr on X11/Wayland systems, or $HOME/.local/share/wezterm/stderr.
return {
  daemon_options = {
    stdout = "/some/where/stdout",
    stderr = "/some/where/stderr",
    pid_file = "/some/where/pid_file",
  }
}

debug_key_events = false

When set to true, each key event will be logged by the GUI layer as an INFO level log message on the stderr stream from wezterm. You will typically need to launch wezterm directly from another terminal to see this logging.

This can be helpful in figuring out how keys are being decoded on your system, or for discovering the system-dependent "raw" key code values.

return {
  debug_key_events = true,
}

Produces logs like the following when typing ls: (artificially wrapped to make these docs more readable):

 2021-02-20T17:04:28.149Z INFO  wezterm_gui::gui::termwindow   > key_event 
   KeyEvent { key: Char('l'), modifiers: NONE, raw_key: None,
   raw_modifiers: NONE, raw_code: Some(46), repeat_count: 1, key_is_down: true }
 2021-02-20T17:04:28.605Z INFO  wezterm_gui::gui::termwindow   > key_event
   KeyEvent { key: Char('s'), modifiers: NONE, raw_key: None, raw_modifiers: NONE,
   raw_code: Some(39), repeat_count: 1, key_is_down: true }

The key event has a number of fields:

  • key is the decoded key after keymapping and composition effects. For example Char('l') occurs when typing the l key and Char('L') occurs when doing the same but with SHIFT held down. It could also be one of the keycode identifiers listed in the Configuring Key Assignments section.
  • modifiers indicates which modifiers are active after keymapping and composition effects. For example, typing l with SHIFT held down produces key: Char('L'), modifiers: NONE because the SHIFT key composed to produce the uppercase L.
  • raw_key represents the key press prior to any keymapping/composition events. If raw_key would be the same as key then raw_key will be printed as NONE.
  • raw_modifiers represents the state of the modifier keys prior to any keymapping or composition effects. For example, typeing l with SHIFT held down produces raw_modifiers: SHIFT.
  • raw_code is the hardware-and-or-windowing-system-dependent raw keycode value associated with the key press. This generally represents the physical location of the key independent of keymapping.
  • repeat_count is usually 1 but on some systems may be larger number to indicate that the key is being held down and that the system is synthesizing multiple key-presses based on the system key repeat settings.
  • key_is_down indicates whether the key is being pressed or released. This will always be true when debug logging, as logging and key press handling is only triggered on key press events in wezterm.

default_cursor_style = "SteadyBlock"

Specifies the default cursor style. Various escape sequences can override the default style in different situations (eg: an editor can change it depending on the mode), but this value controls how the cursor appears when it is reset to default. The default is SteadyBlock.

Acceptable values are SteadyBlock, BlinkingBlock, SteadyUnderline, BlinkingUnderline, SteadyBar, and BlinkingBar.

return {
  default_cursor_style = "SteadyBlock",
}

Using a blinking style puts more load on the graphics subsystem. animation_fps can be used to tune the frame rate used for easing in the blink animation.

default_cwd

Since: 20210203-095643-70a364eb

Sets the default current working directory used by the initial window. If wezterm start --cwd /some/path is used to specify the current working directory, that will take precedence.

Commands launched using SpawnCommand will use the cwd specified in the SpawnCommand, if any.

Panes/Tabs/Windows created after the first will generally try to resolve the current working directory of the current Pane, preferring a value set by OSC 7 and falling back to attempting to lookup the cwd of the current process group leader attached to a local Pane. If no cwd can be resolved, then the default_cwd will be used. If default_cwd is not specified, then the home directory of the user will be used.

graph TD
    X[Determine current working directory for new pane] --> A{{Is initial window?}}
    A -->|Yes| B[Opened with CLI and --cwd flag?]
    A -->|No| C[New pane, tab or window.]
    C --> D{{Opened with a SpawnCommand<br/> that includes cwd?}}
    D -->|No| J{{Does current pane have same domain<br/>and have a value set by OSC 7?}}
    B -->|Yes| E[Use --cwd]
    B -->|No| F{{Is default_cwd defined?}}
    F -->|Yes| G[Use default_cwd]
    F -->|No| H[Use home directory]
    D -->|Yes| I[Use cwd specified<br/> by `SpawnCommand`]
    J -->|Yes| K[Use that OSC 7 value]
    J -->|No| L{{Can cwd be resolved via<br/> the process group leader?}}
    L -->|Yes| M[Use resolved cwd]
    L -->|No| F

On macOS and Linux, wezterm can attempt to resolve the process group leader and then attempt to resolve its current working directory. This is not guaranteed to succeed, and there are a number of potential edge cases (which is another reason for configuring your shell to use OSC 7 sequences).

On Windows, there isn't a process group leader concept, but wezterm will examine the process tree of the program that it started in the current pane and use some heuristics to determine an approximate equivalent.

default_domain = "local"

Since: 20220319-142410-0fcdea07

When starting the GUI (not using the serial or connect subcommands), by default wezterm will set the built-in "local" domain as the default multiplexing domain.

The "local" domain represents processes that are spawned directly on the local system.

Windows users, particularly those who use WSL, may wish to override the default domain to instead use a particular WSL distribution so that wezterm launches directly into a Linux shell rather than having to manually invoke wsl.exe. Using a WslDomain for this has the advantage that wezterm can then use shell integration to track the current directory inside WSL and use it when splitting new panes or spawning new tabs.

For example, if:

; wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-18.04    Running         1

then wezterm will by default create a WslDomain with the name "WSL:Ubuntu-18.04" and if I set my config like this:

return {
  default_domain = "WSL:Ubuntu-18.04",
}

then when wezterm starts up, it will open with a shell running inside that Ubuntu distribution rather than using the default cmd or powershell.

While these examples are WSL-centric, default_domain will accept the name of any of the available multiplexing domains.

default_gui_startup_args = {"start"}

Since: 20220101-133340-7edc5b5a

When launching the GUI using either wezterm or wezterm-gui (with no subcommand explicitly specified), wezterm will use the value of default_gui_startup_args to pick a default mode for running the GUI.

The default for this config is {"start"} which makes wezterm with no additional subcommand arguments equivalent to wezterm start.

If you know that you always want to use wezterm's ssh client to login to a particular host, then you might consider using this configuration:

return {
  default_gui_startup_args = {"ssh", "some-host"},
}

which will cause wezterm with no additional subcommand arguments to be equivalent to running wezterm ssh some-host.

Specifying subcommand arguments on the command line is NOT additive with this config; the command line arguments always take precedence.

Depending on your desktop environment, you may find it simpler to use your operating system shortcut or alias function to set up a shortcut that runs the subcommand you desire.

default_prog

If no prog is specified on the command line, use this instead of running the user's shell.

For example, to have wezterm always run top by default, you'd use this:

return {
  default_prog = {"top"}
}

default_prog is implemented as an array where the 0th element is the command to run and the rest of the elements are passed as the positional arguments to that command.

See also: Launching Programs

default_workspace = "default"

Since: 20220319-142410-0fcdea07

Specifies the name of the default workspace. The default is "default".

disable_default_quick_select_patterns

Since: 20210502-130208-bff6815d

When set to true, the default set of quick select patterns are omitted, and your quick_select_patterns config specifies the total set of patterns used for quick select mode.

dpi

Override the detected DPI (dots per inch) for the display.

This can be useful if the detected DPI is inaccurate and the text appears either blurry or too small (especially if you are using a 4K display on X11 or Wayland).

The default value is system specific:

OSStandard DensityHigh Density
macOS72.0144.0
WindowsProbed from the displayProbed from the display
X1196.096.0
X11 (version 20210314-114017-04b7cedd and later)Probed from Xft.dpi, fallback to 96.0Probed from Xft.dpi, fallback to 96.0
X11 (version 20210814-124438-54e29167 and later)Reads Xft/DPI via xsettings, fallback to Xft.dpi, then fallback to 96.0same as standard density
Wayland96.0192.0

In macOS and Wayland environments there isn't strictly a system DPI value that can be queried; instead standard density has a fixed value and the system will inform WezTerm when the display is high density by communicating a scaling factor for the display.

The Wayland protocol only allows for integer scaling factors, but some compositors support fractional scaling. That fractional scaling can result in blurry text and you may wish to specify a DPI value to compensate.

On macOS the scaling factor changes based on the monitor on which the window is displayed; dragging the window from a retina laptop display to an external standard DPI display causes the window to automatically adjust to the DPI scaling.

Microsoft Windows reports the true DPI for the monitor on which the window is displayed, and will similarly adjust as the window is dragged between monitors.

DPI is poorly supported by X11 itself; while it is possible to query the displays to determine their dimensions, the results are generally inaccurate. It is common for X11 environments to publish an Xft.dpi value as a property of the root window as a hint for the DPI of the display. While that is a reasonable workaround for a single-monitor system, it isn't ideal for a multi-monitor setup where the monitors have varying DPIs.

enable_csi_u_key_encoding = false

When set to true, the keyboard encoding will be changed to use the scheme that is described here.

It is not recommended to enable this option as it does change the behavior of some keys in backwards incompatible ways and there isn't a way for applications to detect or request this behavior.

The default for this option is false.

Note that allow_win32_input_mode takes precedence over this option.

enable_kitty_keyboard = false

Since: 20220624-141144-bd1b7c5d

When set to true, wezterm will honor kitty keyboard protocol escape sequences that modify the keyboard encoding.

enable_scroll_bar

Enable the scrollbar. This is currently disabled by default. It will occupy the right window padding space.

If right padding is set to 0 then it will be increased to a single cell width.

return {
  enable_scroll_bar = true,
}

enable_tab_bar = true

Controls whether the tab bar is enabled. Set to false to disable it.

See also hide_tab_bar_if_only_one_tab

enable_wayland

If false, do not try to use a Wayland protocol connection when starting the gui frontend, and instead use X11.

This option is only considered on X11/Wayland systems and has no effect on macOS or Windows.

The default is false.

return {
  enable_wayland = true,
}

Since: 20220624-141144-bd1b7c5d

The default is now true.

exit_behavior = "CloseOnCleanExit"

Since: 20210314-114017-04b7cedd

Controls the behavior when the shell program spawned by the terminal exits. There are three possible values:

  • "Close" - close the corresponding pane as soon as the program exits.
  • "Hold" - keep the pane open after the program exits. The pane must be manually closed via CloseCurrentPane, CloseCurrentTab or closing the window.
  • "CloseOnCleanExit" - if the shell program exited with a successful status, behave like "Close", otherwise, behave like "Hold". This is the default setting.
return {
  exit_behavior = "Hold",
}

Note that most unix shells will exit with the status of the last command that it ran if you don't specify an exit status.

For example, if you interrupt a command and then use exit (with no arguments), or CTRL-D to send EOF to the shell, the shell will return an unsuccessful exit status. The same thing holds if you were to run:

false
exit

With the default exit_behavior="CloseOnCleanExit" setting, that will cause the pane to remain open.

See also: clean_exit_codes for fine tuning what is considered to be a clean exit status.

Since: 20220624-141144-bd1b7c5d

The default is now "Close".

font

Configures the font to use by default. The font setting can specify a set of fallbacks and other options, and is described in more detail in the Fonts section.

You will typically use wezterm.font or wezterm.font_with_fallback to specify the font.

font_antialias = "Greyscale"

Deprecated starting in version 20210314-114017-04b7cedd; this option no longer does anything and will be removed in a future release. Use freetype_load_target instead

Adjusts the anti-aliasing portion of the font rasterizer.

Possible values are None, Greyscale, Subpixel.

The default value is Greyscale.

font_dirs

By default, wezterm will use an appropriate system-specific method for locating the fonts that you specify using the options below. In addition, if you configure the font_dirs option, wezterm will load fonts from that set of directories:

return {
  -- This tells wezterm to look first for fonts in the directory named
  -- `fonts` that is found alongside your `wezterm.lua` file.
  -- As this option is an array, you may list multiple locations if
  -- you wish.
  font_dirs = {"fonts"},
}

wezterm will scan the font_dirs to build a database of available fonts. When resolving a font, wezterm will first use the configured font_locator which is typically the system specific font resolver. If the system doesn't resolve the requested font, the fonts from font_dirs are searched for a match.

If you want to only find fonts from your font_dirs, perhaps because you have a self-contained wezterm config that you carry around with you between multiple systems and don't want to install those fonts on every system that you use, then you can set:

return {
  font_locator = "ConfigDirsOnly"`
}

font_hinting = "Full"

Deprecated starting in version 20210314-114017-04b7cedd; this option no longer does anything and will be removed in a future release. Use freetype_load_target instead

Adjust the hinting portion of the font rasterizer.

Possible values are None, Vertical, VerticalSubpixel, Full.

font_locator

specifies the method by which system fonts are located and loaded. You may specify ConfigDirsOnly to disable loading system fonts and use only the fonts found in the directories that you specify in your font_dirs configuration option.

Otherwise, it is recommended to omit this setting.

font_rasterizer

Specifies the method by which fonts are rendered on screen. The only available implementation is FreeType.

font_rules

You may optionally specify rules that apply different font styling based on the attributes of the text rendered in the terminal. Most users won't need to do this; these rules are useful when you have some unusual fonts or mixtures of fonts that you'd like to use. The default is to auto-generate reasonable italic and bold styling based on the font configuration.

If you do specify font_rules, they are applied in the order that they are specified in the configuration file, stopping with the first matching rule:

local wezterm = require 'wezterm';
return {
  font_rules = {
    -- Define a rule that matches when italic text is shown
    {
      -- If specified, this rule matches when a cell's italic value exactly
      -- matches this.  If unspecified, the attribute value is irrelevant
      -- with respect to matching.
      italic = true,

      -- Match based on intensity: "Bold", "Normal" and "Half" are supported
      -- intensity = "Normal",

      -- Match based on underline: "None", "Single", and "Double" are supported
      -- underline = "None",

      -- Match based on the blink attribute: "None", "Slow", "Rapid"
      -- blink = "None",

      -- Match based on reverse video
      -- reverse = false,

      -- Match based on strikethrough
      -- strikethrough = false,

      -- Match based on the invisible attribute
      -- invisible = false,

      -- When the above attributes match, apply this font styling
      font = wezterm.font("Operator Mono SSm Lig Medium", {italic=true}),
    }
  }
}

Here's an example from my configuration file;

local wezterm = require 'wezterm';

-- A helper function for my fallback fonts
function font_with_fallback(name, params)
  local names = {name, "Noto Color Emoji", "JetBrains Mono"}
  return wezterm.font_with_fallback(names, params)
end

return {
  font = font_with_fallback("Operator Mono SSm Lig Medium"),
  font_rules= {
    -- Select a fancy italic font for italic text
    {
      italic = true,
      font = font_with_fallback("Operator Mono SSm Lig Medium Italic"),
    },

    -- Similarly, a fancy bold+italic font
    {
      italic = true,
      intensity = "Bold",
      font = font_with_fallback("Operator Mono SSm Lig Book Italic"),
    },

    -- Make regular bold text a different color to make it stand out even more
    {
      intensity = "Bold",
      font = font_with_fallback("Operator Mono SSm Lig Bold", {foreground = "tomato"}),
    },

    -- For half-intensity text, use a lighter weight font
    {
      intensity = "Half",
      font = font_with_fallback("Operator Mono SSm Lig Light"),
    },
  },
}

Since: 20210502-130208-bff6815d

The default font_rules generated by wezterm are now always appended to the rules that you've supplied (rather than used only if you didn't specify any), and now also include rules for selecting lighter weight fonts when half-bright text is rendered to the terminal.

That means that you shouldn't need to specify as many rules as in previously releases.

You can run wezterm ls-fonts to summarize the font rules and the fonts that match them:

$ wezterm ls-fonts
Primary font:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- /home/wez/.fonts/NotoColorEmoji.ttf, FontConfig
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Half Italic=true:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  {family="JetBrains Mono", weight="ExtraLight", italic=true},

  -- /home/wez/.fonts/NotoColorEmoji.ttf, FontConfig
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Half Italic=false:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  {family="JetBrains Mono", weight="ExtraLight"},

  -- /home/wez/.fonts/NotoColorEmoji.ttf, FontConfig
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=false:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  {family="JetBrains Mono", weight="Bold"},

  -- /home/wez/.fonts/NotoColorEmoji.ttf, FontConfig
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Bold Italic=true:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  {family="JetBrains Mono", weight="Bold", italic=true},

  -- /home/wez/.fonts/NotoColorEmoji.ttf, FontConfig
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})


When Intensity=Normal Italic=true:
wezterm.font_with_fallback({
  -- <built-in>, BuiltIn
  {family="JetBrains Mono", italic=true},

  -- /home/wez/.fonts/NotoColorEmoji.ttf, FontConfig
  "Noto Color Emoji",

  -- <built-in>, BuiltIn
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  "Last Resort High-Efficiency",

})

font_shaper

specifies the method by which text is mapped to glyphs in the available fonts. The shaper is responsible for handling kerning, ligatures and emoji composition. The default is Harfbuzz and we have very preliminary support for Allsorts.

It is strongly recommended that you use the default Harfbuzz shaper.

Since: 20211204-082213-a66c61ee9

The incomplete Allsorts shaper was removed.

font_size = 10.0

Specifies the size of the font, measured in points.

You may use fractional point sizes, such as 13.3, to fine tune the size.

The default font size is 10.0 points.

Since: 20210314-114017-04b7cedd

The default font size is now 12.0 points.

force_reverse_video_cursor = false

Since: 20210502-130208-bff6815d

When force_reverse_video_cursor = true, override the cursor_fg, cursor_bg, cursor_border settings from the color scheme and force the cursor to use reverse video colors based on the foreground and background colors.

When force_reverse_video_cursor = false (the default), cursor_fg, cursor_bg and cursor_border color scheme settings are applied as normal.

Since: 20220319-142410-0fcdea07

If escape sequences are used to change the cursor color, they will take precedence over force_reverse_video_cursor. In earlier releases, setting force_reverse_video_cursor = true always ignored the configured cursor color.

foreground_text_hsb

Since: 20210314-114017-04b7cedd

Configures a Hue, Saturation, Brightness transformation that is applied to monochrome glyphs.

The transform works by converting the RGB colors to HSV values and then multiplying the HSV by the numbers specified in foreground_text_hsb.

Modifying the hue changes the hue of the color by rotating it through the color wheel. It is not as useful as the other components, but is available "for free" as part of the colorspace conversion.

Modifying the saturation can add or reduce the amount of "colorfulness". Making the value smaller can make it appear more washed out.

Modifying the brightness can be used to dim or increase the perceived amount of light.

The range of these values is 0.0 and up; they are used to multiply the existing values, so the default of 1.0 preserves the existing component, whilst 0.5 will reduce it by half, and 2.0 will double the value.

return {
  -- This increases color saturation by 50%
  foreground_text_hsb = {
    hue = 1.0,
    saturation = 1.5,
    brightness = 1.0,
  }
}

demonstrating the appearance of the default value demonstrating setting saturating to 1.5 demonstrating setting brightness to 1.5 demonstrating setting hue to 1.5

freetype_interpreter_version

Selects the freetype interpret version to use. Possible values are 35, 38 and 40 which have different characteristics with respective to subpixel hinting. See https://freetype.org/freetype2/docs/subpixel-hinting.html

freetype_load_flags = "DEFAULT"

Since: 20210314-114017-04b7cedd

An advanced option to fine tune the freetype rasterizer. This is a bitfield, so you can combine one or more of these options together, separated by the | character, although not many of the available options necessarily make sense to be combined.

Available flags are:

  • DEFAULT - This is the default!
  • NO_HINTING - Disable hinting. This generally generates ‘blurrier’ bitmap glyph when the glyph is rendered in any of the anti-aliased modes.
  • NO_BITMAP - don't load any pre-rendered bitmap strikes
  • FORCE_AUTOHINT - Use the freetype auto-hinter rather than the font's native hinter.
  • MONOCHROME - instructs renderer to use 1-bit monochrome rendering. This option doesn't impact the hinter.
  • NO_AUTOHINT - don't use the freetype auto-hinter
return {
  -- You probably don't want to do this, but this demonstrates
  -- that the flags can be combined
  freetype_load_flags = "NO_HINTING|MONOCHROME"
}

freetype_load_target = "Normal"

Since: 20210314-114017-04b7cedd

Configures the hinting and (potentially) the rendering mode used with the freetype rasterizer. The following values are possible:

  • "Normal" - This corresponds to the default hinting algorithm, optimized for standard gray-level rendering. This is the default setting.
  • "Light" - A lighter hinting algorithm for non-monochrome modes. Many generated glyphs are more fuzzy but better resemble its original shape. A bit like rendering on Mac OS X.
  • "Mono" - Strong hinting algorithm that should only be used for monochrome output. The result is probably unpleasant if the glyph is rendered in non-monochrome modes.
  • "HorizontalLcd" - A subpixel-rendering variant of Normal optimized for horizontally decimated LCD displays.

See also freetype_render_target and freetype_load_flags for more advanced flags that can be primarily used to influence font hinting.

freetype_pcf_long_family_names = false

Since: 20220624-141144-bd1b7c5d

This option provides control over the no-long-family-names FreeType PCF font driver property.

The default is for this configuration to be false which sets the PCF driver to use the un-decorated font name. This corresponds to the default mode of operation of the freetype library.

Some Linux distributions build the freetype library in a way that causes the PCF driver to report font names differently; instead of reporting just Terminus it will prefix the font name with the foundry (xos4 in the case of Terminus) and potentially append Wide to the name if the font has wide glyphs. The purpose of that configuration option is to disambiguate fonts, as there are a number of fonts from different foundries that all have the name Fixed, and being presented with multiple items with the same Fixed label is a very ambiguous user experience.

When two different applications have differing values for this long family names property, they will face inconsistencies in resolving fonts by name as they will disagree on what the name of a given PCF font is.

When should you set this option to true?

If all of the following are true, then you should set this option to true:

  • You need to use PCF fonts and you need to use fontconfig to resolve their names to font files.
  • You are using a Linux distribution that builds their FreeType library with PCF_CONFIG_OPTION_LONG_FAMILY_NAMES defined.

Note that PCF fonts are a legacy font format and you will be better served by OTF, TTF or OTB (open type binary) file formats.

Why doesn't wezterm use the distro FreeType or match its configuration?

For the sake of consistency, wezterm vendors in its own copy of the latest version FreeType and builds that same version on all platforms. The result is that font-related behaviors in a given version of wezterm are the same on all platforms regardless of what (potentially old) version of FreeType may be provided by the distribution.

Not only does this provide consistency at runtime, but it is much simpler to reason about at build time, making it simpler to build wezterm on all systems.

freetype_render_target = "Normal"

Since: 20210502-130208-bff6815d

Configures the rendering mode used with the freetype rasterizer.

The default is to use the value of freetype_load_target.

You may wish to override that value if you want very fine control over how freetype hints and then renders glyphs.

For example, this configuration uses light hinting but produces subpixel-antialiased glyph bitmaps:

return {
  freetype_load_target = "Light",
  freetype_render_target = "HorizontalLcd",
}

front_end = "OpenGL"

Specifies which render front-end to use. This option used to have more scope in earlier versions of wezterm, but today it allows two possible values:

  • OpenGL - use GPU accelerated rasterization (this is the default)
  • Software - use CPU-based rasterization.

You may wish (or need!) to select Software if there are issues with your GPU/OpenGL drivers.

WezTerm will automatically select Software if it detects that it is being started in a Remote Desktop environment on Windows.

harfbuzz_features

When font_shaper = "Harfbuzz", this setting affects how font shaping takes place.

See Font Shaping for more information and examples.

hide_tab_bar_if_only_one_tab = false

If set to true, when there is only a single tab, the tab bar is hidden from the display. If a second tab is created, the tab will be shown.

See also enable_tab_bar

hyperlink_rules

Defines rules to match text from the terminal output and generate clickable links.

See Hyperlinks for more information and examples.

ime_preedit_rendering

Since: 20220624-141144-bd1b7c5d

Control IME preedit rendering. IME preedit is an area that is used to display the string being preedited in IME. WezTerm supports the following IME preedit rendering.

  • "Builtin" - (Default) IME preedit is rendered by WezTerm itself

    "Builtin" rendering provides good look and feel for many IMEs, rendering the text using the same font as the terminal and works in concert with features like window:composition_status().

  • "System" - IME preedit is rendered by system

    "Builtin" rendering may truncate displaying of IME preedit at the end of window if IME preedit is very long because the rendering does not allow the IME preedit to overflow the window and does not wrap IME preedit to the next line. "System" rendering can be useful to avoid the truncated displaying of IME preedit but has a worse look and feel compared to "Builtin" rendering.

You can control IME preedit rendering in your configuraiton file:

return {
  ime_preedit_rendering = "System",
}

Otherwise, the default is "Builtin".

Note:

  • Changing ime_preedit_rendering usually requires re-launching WezTerm to take full effect.
  • In macOS, ime_preedit_rendering has effected nothing yet. IME preedit is always rendered by WezTerm itself.

initial_cols = 80

Together with initial_rows, configures the window size (window width) for newly created windows.

Specifies the width of a new window, expressed in character cells.

initial_rows = 24

Together with initial_cols, configures the window size (window height) for newly created windows.

Specifies the height of a new window, expressed in character cells.

key_map_preference = "Mapped"

Since: 20220408-101518-b908e2dd

Controls how keys without an explicit phys: or mapped: prefix are treated.

If key_map_preference = "Mapped" (the default), then mapped: is assumed. If key_map_preference = "Physical" then phys: is assumed.

Default key assignments also respect key_map_preference.

key_tables = {}

See the main Key Tables docs!

launch_menu

Since 20200503-171512-b13ef15f

You can define your own entries for the Launcher Menu using this configuration setting. The snippet below adds two new entries to the menu; one that runs the top program to monitor process activity and a second one that explicitly launches the bash shell.

Each entry in launch_menu is an instance of a SpawnCommand object.

return {
  launch_menu = {
    {
      args = {"top"},
    },
    {
      -- Optional label to show in the launcher. If omitted, a label
      -- is derived from the `args`
      label = "Bash",
      -- The argument array to spawn.  If omitted the default program
      -- will be used as described in the documentation above
      args = {"bash", "-l"},

      -- You can specify an alternative current working directory;
      -- if you don't specify one then a default based on the OSC 7
      -- escape sequence will be used (see the Shell Integration
      -- docs), falling back to the home directory.
      -- cwd = "/some/path"

      -- You can override environment variables just for this command
      -- by setting this here.  It has the same semantics as the main
      -- set_environment_variables configuration option described above
      -- set_environment_variables = { FOO = "bar" },
    },
  }
}

line_height = 1.0

Scales the computed line height to adjust the spacing between successive rows of text. The default line height is controlled by the font_size configuration option. If you feel that your chosen font feels too vertically cramped then you can set line_height = 1.2 to increase the vertical spacing by 20%. Conversely, setting line_height = 0.9 will decrease the vertical spacing by 10%.

See also: cell_width

min_scroll_bar_height = "0.5cell"

Since: 20220624-141144-bd1b7c5d

Controls the minimum size of the scroll bar "thumb".

The value can be a number to specify the number of pixels, or a string with a unit suffix:

  • "1px" - the px suffix indicates pixels, so this represents a 1 pixel value
  • "1pt" - the pt suffix indicates points. There are 72 points in 1 inch. The actual size this occupies on screen depends on the dpi of the display device.
  • "1cell" - the cell suffix indicates the height of the terminal cell, which in turn depends on the font size, font scaling and dpi.
  • "1%" - the % suffix indicates the size of the terminal portion of the display, which is computed based on the number of rows and the size of the cell.

You may use a fractional number such as "0.5cell" or numbers large than one such as "72pt".

mux_env_remove

Since: 20211204-082213-a66c61ee9

Specifies a list of environment variables that should be removed from the environment in the multiplexer server.

The intent is to clean up environment variables that might give the wrong impression of their operating environment to the various terminal sessions spawned by the multiplexer server.

The default value for this is:

return {
  mux_env_remove = {
    "SSH_AUTH_SOCK",
    "SSH_CLIENT",
    "SSH_CONNECTION",
  }
}

native_macos_fullscreen_mode = false

Specifies whether the ToggleFullScreen key assignment uses the native macOS full-screen application support or not.

The default is false which will simply (and very quickly!) toggle between a full screen window with no decorations and a regularly size window.

When true, transitioning to full screen will slowly animate the window moving to a full screen space on the monitor.

This option only has an effect when running on macOS.

pane_focus_follows_mouse = false

Since: 20210502-130208-bff6815d

When pane_focus_follows_mouse = true, moving the mouse pointer over an inactive pane will cause that pane to activate; this behavior is known as "focus follows mouse".

When pane_focus_follows_mouse = false (the default), you need to click on an inactive pane to activate it.

prefer_egl = true

Depending on the OS and windowing environment, there are a number of different ways to access the GPU.

This option controls whether wezterm should attempt to use EGL to configure the GPU.

Environmentprefer_egl=trueprefer_egl=false
Waylanduse wayland-eglNo effect: EGL is the only way to use the GPU
X11Use libEGL.soNo effect: EGL is the only way to use the GPU
macOSUse MetalANGLE libEGL.dylib if installed alongside the wezterm-gui executable. Some versions of wezterm shipped with this configuration which translated OpenGL calls to MetalUse Core OpenGL API (CGL). Since BigSur, CGL uses Metal APIs.
WindowsUse ANGLE to translate OpenGL calls to Direct3D, which makes wezterm more robust if you upgrade your graphics card drivers.Use the OpenGL implementation provided by your graphics card vendor

The default is true.

quick_select_alphabet

Since: 20210502-130208-bff6815d

Specify the alphabet used to produce labels for the items matched in quick select mode.

The default alphabet is "asdfqwerzxcvjklmiuopghtybn" which means that the first matching item from the bottom is labelled with an a, the second with s and so forth; these are easily accessible characters in a qwerty keyboard layout.

Keyboard LayoutSuggested Alphabet
qwerty"asdfqwerzxcvjklmiuopghtybn" (this is the default)
qwertz"asdfqweryxcvjkluiopmghtzbn"
azerty"qsdfazerwxcvjklmuiopghtybn"
dvorak"aoeuqjkxpyhtnsgcrlmwvzfidb"
colemak"arstqwfpzxcvneioluymdhgjbk"

quick_select_patterns

Since: 20210502-130208-bff6815d

Specify additional patterns to match when in quick select mode. This setting is a table listing out a set of regular expressions.

return {
  quick_select_patterns = {
    -- match things that look like sha1 hashes
    -- (this is actually one of the default patterns)
    "[0-9a-f]{7,40}",
  }
}

quote_dropped_files = "SpacesOnly"

Since: 20220624-141144-bd1b7c5d

Controls how file names are quoted (or not) when dragging and dropping. There are five possible values:

  • "None" - no quoting is performed, the file name is passed through as-is.
  • "SpacesOnly" - backslash-escape only spaces, leaving all other characters as-is. This is the default for non-Windows platforms.
  • "Posix" - use POSIX style shell word escaping.
  • "Windows" - use Windows style shell word escaping: double-quote filename with space characters in it, and leaving others as-is. This is the default on Windows.
  • "WindowsAlwaysQuoted" - like "Windows", while always double-quote the filename.

For example:

quote_dropped_filesfile namequoted result
"None"hello ($world)hello ($world)
"SpacesOnly"hello ($world)hello\ ($world)
"Posix"hello ($world)"hello (\$world)"
"Windows"hello ($world)"hello ($world)"
"WindowsAlwaysQuoted"hello ($world)"hello ($world)"

Drag and drop support for files is a platform dependent feature

PlatformSupported since
macOS20220624-141144-bd1b7c5d
Windows20220624-141144-bd1b7c5d
X11Not yet
Wayland20220624-141144-bd1b7c5d

scroll_to_bottom_on_input

When true (the default), the viewport will automatically scroll to the bottom of the scrollback when there is input to the terminal so that you can see what you are typing.

scrollback_lines = 3500

How many lines of scrollback you want to retain.

Learn more about scrollback

selection_word_boundary

Since: 20210203-095643-70a364eb

Configures the boundaries of a word, thus what is selected when doing a word selection with the mouse. (See mouse actions SelectTextAtMouseCursor & ExtendSelectionToMouseCursor with the mode argument set to Word)

Defaults to " \t\n{}[]()\"'`".

For example, to always include spaces and newline when selecting a word, but stop on punctuations:

return {
  selection_word_boundary = "{}[]()\"'`.,;:"
}

set_environment_variables

Specifies a map of environment variables that should be set when spawning new commands in the "local" domain. This configuration is consulted at the time that a program is launched. It is not possible to update the environment of a running program on any Operating System.

This is not used when working with remote domains.

See also: Launching Programs

show_tab_index_in_tab_bar = true

When set to true (the default), tab titles show their tab number (tab index) with a prefix such as 1:. When false, no numeric prefix is shown.

The tab_and_split_indices_are_zero_based setting controls whether numbering starts with 0 or 1.

show_update_window

When Wezterm checks for an update and detects a new version, this option controls whether a window is shown with information about the new available version and links to download/install it.

See check_for_updates for more information on the automatic update checks.

return {
  show_update_window = false,
}

skip_close_confirmation_for_processes_named

Since: 20210404-112810-b63a949d

This configuration specifies a list of process names that are considered to be "stateless" and that are safe to close without prompting when closing windows, panes or tabs.

When closing a pane wezterm will try to determine the processes that were spawned by the program that was started in the pane. If all of those process names match one of the names in the skip_close_confirmation_for_processes_named list then it will not prompt for closing that particular pane.

The default value for this setting is shown below:

return {
  skip_close_confirmation_for_processes_named = {
    "bash", "sh", "zsh", "fish", "tmux"
  }
}

Since: 20210814-124438-54e29167:

This option now also works on Windows (prior versions only worked on Linux and macOS), and the default value for this setting now includes some windows shell processes:

return {
  skip_close_confirmation_for_processes_named = {
        "bash",
        "sh",
        "zsh",
        "fish",
        "tmux",
        "nu",
        "cmd.exe",
        "pwsh.exe",
        "powershell.exe"
  }
}

Since: 20220101-133340-7edc5b5a

More advanced control over this behavior can be achieved by defining a mux-is-process-stateful event handler.

ssh_backend = "libssh"

Since: 20211204-082213-a66c61ee9

Sets which ssh backend should be used by default for the integrated ssh client.

Possible values are:

  • "Ssh2" - use libssh2
  • "LibSsh" - use libssh

Despite the naming, libssh2 is not a newer version of libssh, they are completely separate ssh implementations.

In prior releases, "Ssh2" was the only option. "LibSsh" is the default as it has broader support for newer keys and cryptography, and has clearer feedback about authentication events that require entering a passphrase.

ssh_domains

Configures SSH multiplexing domains. Read more about SSH Domains.

This option accepts a list of SshDomain objects.

status_update_interval = 1000

Since: 20210314-114017-04b7cedd

Specifies the number of milliseconds that need to elapse between triggering the update-right-status hook.

swallow_mouse_click_on_pane_focus = false

Since: 20210502-130208-bff6815d

When set to true, clicking on a pane will focus it.

When set to false (the default), clicking on a pane will focus it and then pass the click through to the application in the terminal.

swallow_mouse_click_on_window_focus

Since: 20220319-142410-0fcdea07

When set to true, clicking on a wezterm window will focus it.

When set to false,clickong on a wezterm window will focus it and then pass through the click to the pane where the swallow_mouse_click_on_pane_focus option will further modify mouse event processing.

The default is true on macOS but false on other systems.

swap_backspace_and_delete = false

When set to true, switch the interpretation of the Backspace and Delete keys such that Backspace generates Delete and vice versa.

tab_and_split_indices_are_zero_based = false

If true, show_tab_index_in_tab_bar uses a zero-based index. The default is false and the tab shows a one-based index.

tab_bar_at_bottom = false

Since: 20210502-130208-bff6815d

When tab_bar_at_bottom = true, the tab bar will be rendered at the bottom of the window rather than the top of the window.

The default is false.

tab_bar_style

Since: 20210814-124438-54e29167

new_tab_left, new_tab_right, new_tab_hover_left, new_tab_hover_right have been removed and replaced by the more flexible new_tab and new_tab_hover elements.

Since: 20210502-154244-3f7122cb

active_tab_left, active_tab_right, inactive_tab_left, inactive_tab_right, inactive_tab_hover_left, inactive_tab_hover_right have been removed and replaced by the more flexible format-tab-title event.

Since: 20210314-114017-04b7cedd

This config option allows styling the elements that appear in the tab bar. This configuration supplements the tab bar color options.

Styling in this context refers to how the edges of the tabs and the new tab button are rendered. The default is simply a space character but you can use any sequence of formatted text produced by the wezterm.format function.

The defaults for each of these styles is simply a space. For each element, the foreground and background colors are set as per the tab bar colors you've configured.

The available elements are:

  • active_tab_left, active_tab_right - the left and right sides of the active tab
  • inactive_tab_left, inactive_tab_right - the left and right sides of inactive tabs
  • inactive_tab_hover_left, inactive_tab_hover_right - the left and right sides of inactive tabs in the hover state
  • new_tab_left, new_tab_right - the left and right sides of the new tab + button
  • new_tab_hover_left, new_tab_hover_right - the left and right sides of the new tab + button in the hover state.

This example changes the tab edges to the PowerLine arrow symbols:

Demonstrating setting the styling of the left and right tab edges

local wezterm = require 'wezterm';

-- The filled in variant of the < symbol
local SOLID_LEFT_ARROW = utf8.char(0xe0b2)

-- The filled in variant of the > symbol
local SOLID_RIGHT_ARROW = utf8.char(0xe0b0)

return {
  tab_bar_style = {
    active_tab_left = wezterm.format({
      {Background={Color="#0b0022"}},
      {Foreground={Color="#2b2042"}},
      {Text=SOLID_LEFT_ARROW},
    }),
    active_tab_right = wezterm.format({
      {Background={Color="#0b0022"}},
      {Foreground={Color="#2b2042"}},
      {Text=SOLID_RIGHT_ARROW},
    }),
    inactive_tab_left = wezterm.format({
      {Background={Color="#0b0022"}},
      {Foreground={Color="#1b1032"}},
      {Text=SOLID_LEFT_ARROW},
    }),
    inactive_tab_right = wezterm.format({
      {Background={Color="#0b0022"}},
      {Foreground={Color="#1b1032"}},
      {Text=SOLID_RIGHT_ARROW},
    }),
  }
}

tab_max_width

Specifies the maximum width that a tab can have in the tab bar when using retro tab mode. It is ignored when using fancy tab mode.

Defaults to 16 glyphs in width.

return {
  tab_max_width = 16,
}

term = "xterm-256color"

What to set the TERM environment variable to. The default is xterm-256color, which should provide a good level of feature support without requiring the installation of additional terminfo data.

If you want to get the most application support out of wezterm, then you may wish to install a copy of the wezterm TERM definition:

tempfile=$(mktemp) \
  && curl -o $tempfile https://raw.githubusercontent.com/wez/wezterm/main/termwiz/data/wezterm.terminfo \
  && tic -x -o ~/.terminfo $tempfile \
  && rm $tempfile

You can then set term = "wezterm" in your .wezterm.lua config file.

Doing this will inform some software of newer, more advanced features such as colored underlines, styled underlines (eg: undercurl). If the system you are using has a relatively outdated ncurses installation, the wezterm terminfo will also enable italics and true color support.

If you are using WSL, wezterm will automatically populate WSLENV to properly set TERM, COLORTERM, TERM_PROGRAM and TERM_PROGRAM_VERSION in the environment when crossing between win32 and WSL environments. See this Microsoft blog post for more information on how WSLENV works.

If your package manager installed the terminfo data in a non-standard location, which will likely be the case if your are using nixpkgs/home-manager/NixOS, then you need to set TERMINFO_DIRS in the environment in order for applications to find it. The following snippet works if you installed wezterm.terminfo with nix into your user profile. Update the path to TERMINFO_DIRS to match the location on your system.

  set_environment_variables={
    TERMINFO_DIRS='/home/user/.nix-profile/share/terminfo',
    WSLENV='TERMINFO_DIRS'
  },
  term = "wezterm",

text_blink_ease_in = "Linear"

Since: 20220319-142410-0fcdea07

Specifies the easing function to use when computing the color for text that has the blinking attribute in the fading-in phase--when the text is fading from the background color to the foreground color.

See visual_bell for more information about easing functions.

See cursor_blink_rate to control the rate at which the cursor blinks.

text_blink_ease_out = "Linear"

Since: 20220319-142410-0fcdea07

Specifies the easing function to use when computing the color for text that has the blinking attribute in the fading-out phase--when the text is fading from the foreground color to the background color.

See visual_bell for more information about easing functions.

text_blink_rapid_ease_in = "Linear"

Since: 20220319-142410-0fcdea07

Specifies the easing function to use when computing the color for text that has the rapid blinking attribute in the fading-in phase--when the text is fading from the background color to the foreground color.

See visual_bell for more information about easing functions.

text_blink_rapid_ease_out = "Linear"

Since: 20220319-142410-0fcdea07

Specifies the easing function to use when computing the color for text that has the rapid blinking attribute in the fading-out phase--when the text is fading from the foreground color to the background color.

See visual_bell for more information about easing functions.

text_blink_rate

Since: 20210814-124438-54e29167

Specifies how often blinking text (normal speed) transitions between visible and invisible, expressed in milliseconds. Setting this to 0 disables slow text blinking. Note that this value is approximate due to the way that the system event loop schedulers manage timers; non-zero values will be at least the interval specified with some degree of slop.

return {
  text_blink_rate = 500
}

Since: 20220319-142410-0fcdea07

Blinking is no longer a binary blink, but interpolates between invisible and visible text using an easing function. See text_blink_ease_in and text_blink_ease_out for more information.

text_blink_rate_rapid

Since: 20210814-124438-54e29167

Specifies how often blinking text (rapid speed) transitions between visible and invisible, expressed in milliseconds. Setting this to 0 disables rapid text blinking. Note that this value is approximate due to the way that the system event loop schedulers manage timers; non-zero values will be at least the interval specified with some degree of slop.

return {
  text_blink_rate_rapid = 250
}

Since: 20220319-142410-0fcdea07

Blinking is no longer a binary blink, but interpolates between invisible and visible text using an easing function. See text_blink_rapid_ease_in and text_blink_rapid_ease_out for more information.

tls_clients

Configures TLS multiplexing domains. Read more about TLS Domains.

This option accepts a list of TlsDomainClient objects.

tls_servers

Configures TLS multiplexing domains. Read more about TLS Domains.

This option accepts a list of TlsDomainServer objects.

treat_east_asian_ambiguous_width_as_wide = false

Since: 20220624-141144-bd1b7c5d

Unicode defines a number of codepoints as having Ambiguous Width. These are characters whose width resolves differently according to context that is typically absent from the monospaced world of the terminal.

WezTerm will by default treat ambiguous width as occupying a single cell.

When treat_east_asian_ambiguous_width_as_wide = true WezTerm will treat them as being two cells wide.

Note that changing this setting may have consequences for layout in text UI applications if their expectation of width differs from your choice of configuration.

treat_left_ctrlalt_as_altgr = false

since: 20210314-114017-04b7cedd

If you are using a layout with an AltGr key, you may experience issues when running inside a VNC session, because VNC emulates the AltGr keypresses by sending plain Ctrl-Alt keys, which won't be understood as AltGr.

To fix this behavior you can tell WezTerm to treat left Ctrl-Alt keys as AltGr with the option treat_left_ctrlalt_as_altgr. Note that the key bindings using separate Ctrl and Alt won't be triggered anymore.

return {
  treat_left_ctrlalt_as_altgr = true
}

unicode_version = 9

Since: 20211204-082213-a66c61ee9

Specifies the version of unicode that will be used when interpreting the width/presentation of text.

This option exists because Unicode is an evolving specification that introduces new features and that occasionally adjusts how existing features should be handled.

For example, there were a number of unicode code points that had their width changed between Unicode version 8 and version 9. This wouldn't be an issue if all software was simultaneously aware of the change, but the reality is that there is a lot of older software out there, and that even if your local system is fully up to date, you might connect to a remote system vis SSH that is running applications that use a different version of unicode than your local system.

The impact of mismatching expectations of unicode width for a terminal emulator is that text columns may no longer line up as the application author expected, and/or that the cursor may appear to be in the wrong place when editing lines or text in shells or text editors.

The unicode_version option defaults to unicode version 9 as that is the most widely used version (from the perspective of width) at the time of writing, which means that the default experience has the lowest chance of mismatched expectations.

Unicode VersionImpact
8 (or lower)Some characters will be narrower than later versions
9-13Some characters will be wider than in Unicode 8
14 (or higher)Explicit Emoji or Text presentation selectors will be respected and make some characters wider or narrower than earlier versions, depending on the context

If you aggressively maintain all of your software to the latest possible versions then you may wish to set unicode_version = 14 to match the current (at the time of writing) version of Unicode. This will enable Emoji Presentation selectors to affect the presentation of certain emoji characters and alter their width in the terminal display.

If you'd like to use a higher default version but switch to a lower version when launching an older application, or when SSH'ing into a remote host, then you may be pleased to learn that wezterm also provides an escape sequence that allows the unicode version to be changed on the fly.

Unicode Version Escape sequence

This escape sequence is was originally defined by iTerm2. It supports setting the value as well as pushing and popping the value on a stack, which is helpful when temporarily adjusting the value.

OSC 1337 ; UnicodeVersion=N ST

The above sets the unicode version to N, where N is the integer version number.

OSC 1337 ; UnicodeVersion=push ST

Pushes the current version onto a stack.

OSC 1337 ; UnicodeVersion=pop ST

Pops the last-pushed version from the stack and sets the unicode version to that value. If there were no entries on the stack, the unicode version is left unchanged.

OSC 1337 ; UnicodeVersion=push LABEL ST

Pushes the current version onto a stack, labeling it with LABEL.

OSC 1337 ; UnicodeVersion=pop LABEL ST

Pops entries from the stack stopping after an entry labelled with LABEL is popped.

The labels are helpful when writing a wrapper alias, for example:

function run_with_unicode_version_9() {
  local label=$(uuidgen)
  printf "\e]1337;UnicodeVersion=push %s\e\\" $label
  printf "\e]1337;UnicodeVersion=9\e\\"
  eval $@
  local result=${PIPESTATUS[0]}
  printf "\e]1337;UnicodeVersion=pop %s\e\\" $label
  return $result
}

# Connect to a remote machine with an older version of unicode
run_with_unicode_version_9 ssh remote.machine

Will save the current version on the stack with a unique label, then set the version to 9 and spawn the requested command. When the command returns it will restore the saved version, even if the command itself set or pushed other values.

unix_domains

Defines a list of multiplexer domains for both the multiplexer server and multiplexer client.

Read more about multiplexing

unzoom_on_switch_pane = true

Since: 20211204-082213-a66c61ee9

If set to false, the ActivatePaneDirection command will have no effect if the active pane is zoomed.

If true, the active pane will be unzoomed first and then switched.

See also: TogglePaneZoomState

use_cap_height_to_scale_fallback_fonts = false

Since: 20210502-130208-bff6815d

When set to true, use the cap-height font metrics of the base and the current font to adjust the size of secondary fonts (such as bold or italic faces) to visually match the size of the base font.

The default is false.

use_fancy_tab_bar = true

Since: 20220101-133340-7edc5b5a

When set to true (the default), the tab bar is rendered in a native style with proportional fonts.

When set to false, the tab bar is rendered using a retro aesthetic using the main terminal font.

use_ime

Controls whether the Input Method Editor (IME) will be used to process keyboard input. The IME is useful for inputting kanji or other text that is not natively supported by the attached keyboard hardware.

IME support is a platform dependent feature

PlatformSupported sinceNotes
WindowsForeverAlways enabled, cannot be disabled
macOS20200113-214446-bb6251fdefaults to enabled starting in 20220319-142410-0fcdea07. Earlier versions had problems with key repeat when enabled
X1120211204-082213-a66c61ee9XIM based. Your system needs to have a running input method engine (such as ibus or fcitx) that support the XIM protocol in order for wezterm to use it.
WaylandNot yet#1772 is tracking IME support

You can control whether the IME is enabled in your configuration file:

return {
  use_ime = false,
}

Changing use_ime usually requires re-launching WezTerm to take full effect.

Since: 20200620-160318-e00b076c

The default for use_ime is false. The default in earlier releases was true.

Since: 20220101-133340-7edc5b5a

The default for X11 systems is now true. Please ensure that the XMODIFIERS environment variable or the new xim_im_name configuration option is set appropriately before wezterm is launched! For example, Gnome users will probably want to set XMODIFIERS=@im=ibus.

Since: 20220319-142410-0fcdea07

The default for all systems is now true

use_resize_increments = false

Since: 20211204-082213-a66c61ee9

When set to true, prefer to snap the window size to a multiple of the terminal cell size. The default is false, which allows sizing the window to an arbitrary size.

This option is only respected on X11, Wayland and macOS systems.

Note that if you have configured window_padding then the resize increments don't take the padding into account.

visual_bell

Since: 20211204-082213-a66c61ee9

When the BEL ascii sequence is sent to a pane, the bell is "rung" in that pane.

You may choose to configure the visual_bell option so show a visible representation of the bell event, by having the background color of the pane briefly change color.

There are four fields to the visual_bell config option:

  • fade_in_duration_ms - how long it should take for the bell color to fade in, in milliseconds. The default is 0.
  • fade_out_duration_ms - how long it should take for the bell color to fade out, in milliseconds. The default is 0.
  • fade_in_function - an easing function, similar to CSS easing functions, that affects how the bell color is faded in.
  • fade_out_function - an easing function that affects how the bell color is faded out.
  • target - can be "BackgroundColor" (the default) to have the background color of the terminal change when the bell is rung, or "CursorColor" to have the cursor color change when the bell is rung.

If the total fade in and out durations are 0, then there will be no visual bell indication.

The bell color is itself specified in your color settings; if not specified, the text foreground color will be used.

The following easing functions are supported:

  • Linear - the fade happens at a constant rate.
  • Ease - The fade starts slowly, accelerates sharply, and then slows gradually towards the end. This is the default.
  • EaseIn - The fade starts slowly, and then progressively speeds up until the end, at which point it stops abruptly.
  • EaseInOut - The fade starts slowly, speeds up, and then slows down towards the end.
  • EaseOut - The fade starts abruptly, and then progressively slows down towards the end.
  • {CubicBezier={0.0, 0.0, 0.58, 1.0}} - an arbitrary cubic bezier with the specified parameters.
  • Constant - Evaluates as 0 regardless of time. Useful to implement a step transition at the end of the duration. (Since: 20220408-101518-b908e2dd)

The following configuration enables a low intensity visual bell that takes a total of 300ms to "flash" the screen:

return {
  visual_bell = {
    fade_in_function = "EaseIn",
    fade_in_duration_ms = 150,
    fade_out_function = "EaseOut",
    fade_out_duration_ms = 150,
  },
  colors = {
    visual_bell = "#202020"
  },
}

The follow configuration make the cursor briefly flare when the bell is run:

return {
  visual_bell = {
    fade_in_duration_ms = 75,
    fade_out_duration_ms = 75,
    target = "CursorColor",
  },
}

See also audible_bell and bell event.

warn_about_missing_glyphs = true

Since: 20210502-130208-bff6815d

When set to true, if a glyph cannot be found for a given codepoint, then the configuration error window will be shown with a pointer to the font configuration docs.

You can set warn_about_missing_glyphs = false to prevent the configuration error window from being displayed.

The default is warn_about_missing_glyphs = true.

window_background_gradient

Since: 20210814-124438-54e29167

Dynamically generates a window_background_image from the provided gradient specification. When window_background_gradient is configured, the value for window_background_image is ignored.

Linear gradients with vertical or horizontal orientation are supported:

return {
  window_background_gradient = {
    -- Can be "Vertical" or "Horizontal".  Specifies the direction
    -- in which the color gradient varies.  The default is "Horizontal",
    -- with the gradient going from left-to-right.
    -- Linear and Radial gradients are also supported; see the other
    -- examples below
    orientation = "Vertical",

    -- Specifies the set of colors that are interpolated in the gradient.
    -- Accepts CSS style color specs, from named colors, through rgb
    -- strings and more
    colors = {
      "#0f0c29",
      "#302b63",
      "#24243e"
    },

    -- Instead of specifying `colors`, you can use one of a number of
    -- predefined, preset gradients.
    -- A list of presets is shown in a section below.
    -- preset = "Warm",

    -- Specifies the interpolation style to be used.
    -- "Linear", "Basis" and "CatmullRom" as supported.
    -- The default is "Linear".
    interpolation = "Linear",

    -- How the colors are blended in the gradient.
    -- "Rgb", "LinearRgb", "Hsv" and "Oklab" are supported.
    -- The default is "Rgb".
    blend = "Rgb",

    -- To avoid vertical color banding for horizontal gradients, the
    -- gradient position is randomly shifted by up to the `noise` value
    -- for each pixel.
    -- Smaller values, or 0, will make bands more prominent.
    -- The default value is 64 which gives decent looking results
    -- on a retina macbook pro display.
    -- noise = 64,

    -- By default, the gradient smoothly transitions between the colors.
    -- You can adjust the sharpness by specifying the segment_size and
    -- segment_smoothness parameters.
    -- segment_size configures how many segments are present.
    -- segment_smoothness is how hard the edge is; 0.0 is a hard edge,
    -- 1.0 is a soft edge.

    -- segment_size = 11,
    -- segment_smoothness = 0.0,
  },
}

Gradients are implemented using the colorgrad crate. Take a look at https://github.com/mazznoer/colorgrad-rs#using-web-color-format for some usage examples and additional information about gradients.

Linear gradient:

Since: 20220624-141144-bd1b7c5d

A linear gradient follows a linear path across the window. It can be rotated around the window center. The angle is described in degrees and moves counter clockwise in the positive direction.

So 0 degrees is equivalent to Horizontal with the gradient moving from left to right. 90 degrees is equivalent to Vertical with the gradient moving from bottom to top. 180 degrees is equivalent to Horizontal but with the gradient moving from right to left. 270 degrees is equivalent to Vertical but with the gradient going from top to bottom. Negative degrees are equivalent to going clockwise, so -45 is equivalent to 315 degrees and results in a gradient that is moving from the top left corner down to the bottom right corner.

return {
  window_background_gradient = {
    colors = { "#EEBD89", "#D13ABD" },
    -- Specifices a Linear gradient starting in the top left corner.
    orientation = { Linear = { angle = -45.0 } },
  }
}

Radial gradient:

Radial gradients are implemented using a notional perfect circle that is subsequently stretched to fill the dimensions of the window.

return {
  color_scheme = "Github",
  window_background_gradient = {
     colors = {"deeppink", "gold"},
     orientation = {
       Radial={
         -- Specifies the x coordinate of the center of the circle,
         -- in the range 0.0 through 1.0.  The default is 0.5 which
         -- is centered in the X dimension.
         cx = 0.75,

         -- Specifies the y coordinate of the center of the circle,
         -- in the range 0.0 through 1.0.  The default is 0.5 which
         -- is centered in the Y dimension.
         cy = 0.75,

         -- Specifies the radius of the notional circle.
         -- The default is 0.5, which combined with the default cx
         -- and cy values places the circle in the center of the
         -- window, with the edges touching the window edges.
         -- Values larger than 1 are possible.
         radius = 1.25,
       }
     },
  }
}

Presets

The following presets are available:

PresetGradient
Blues
BrBg
BuGn
BuPu
Cividis
Cool
CubeHelixDefault
GnBu
Greens
Greys
Inferno
Magma
OrRd
Oranges
PiYg
Plasma
PrGn
PuBu