Shell Integration
On this page
wakterm supports integrating with the shell through the following means:
OSC 7Escape sequences to advise the terminal of the working directoryOSC 133Escape sequence to define Input, Output and Prompt zonesOSC 1337Escape sequences to set user vars for tracking additional shell state
OSC is escape sequence jargon for Operating System Command.
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 wakterm repo.
Wakterm loads its integration automatically into bash, zsh and fish shells started in local panes, without changes to their startup files; see shell_integration. Sourcing the file yourself as well is harmless: it installs its hooks once per shell.
To set it up yourself instead, for example on a remote host, copy the file to your computer and source it via . /path/to/file.sh in your .bashrc
or .zshrc, or install it at /etc/profile.d on most unix systems.
Wsh's bundled Zsh emits OSC 7 and OSC 133 natively. When Wsh marks itself as their owner, this script keeps its separate OSC 1337 user variables but skips its prompt, output, and working-directory hooks so each standard sequence has one owner.
Xonsh is supported via a term-integrations plugin.
Starting with version 20210314-114017-04b7cedd, the Fedora and Debian packages automatically activate shell integration for Bash and Zsh. Starting with version 20230320.124340.559cb7b0, the Arch Linux package also automatically activate it.
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.
Pane-local history#
Wakterm sets WAKTERM_PANE_TOKEN in every local pane. It is an opaque identifier for the logical pane: it stays the same when the shell in that pane restarts, is replaced with exec, or is restored after the mux server restarts, and a split or new tab gets a new one. Unlike WAKTERM_PANE, it is not reused as a numeric index.
When the Bash and Zsh integration script is loaded, it uses the token to keep each pane's command history:
- Up and Down recall the commands entered in this pane first, then the shared history from
HISTFILE. - Commands entered in a shell collect in a pane file while it runs. When the shell exits they are also appended to
HISTFILE, so the shared history still contains every pane's commands. - If a shell is killed before it can exit normally, the next shell started in the same pane merges its commands.
- Live history sharing (
setopt SHARE_HISTORY) is turned off in these shells, because it would import other panes' commands while you work. - A nested interactive shell started inside the pane uses the shared history as usual.
Pane history is stored in ${XDG_STATE_HOME:-$HOME/.local/state}/wakterm/pane-history/. Set WAKTERM_SHELL_SKIP_PANE_HISTORY=1 before sourcing the script to keep the shell's usual history behavior.
With automatic integration, fish gets the same pane history. A pane's history starts as a copy of the shared history and then uses its own fish history session, and its new commands are appended to the shared history on exit.
Wsh implements pane history natively and marks it with WSH_NATIVE_PANE_HISTORY=1, which this script respects. Other shells can build the same behavior on WAKTERM_PANE_TOKEN by selecting a per-token history file at startup.
User Vars#
OSC 1337 provides a means for setting user vars, which are somewhat similar
to environment variables, except that they are variables associated with a
given pane rather than a process.
Installing the wakterm shell integration will define the following user vars by default:
WAKTERM_PROG- the command line being executed by the shellWAKTERM_USER- holds the output fromid -un; the current user nameWAKTERM_HOST- holds the output fromhostname; the hostname that the shell is running onWAKTERM_IN_TMUX- holds1if the shell is running inside tmux,0otherwise
If you are a tmux user, you must ensure that you have set -g allow-passthrough on set
in your tmux.conf for user vars to work.
Those vars will be updated each time the prompt is shown and just prior to executing a command.
The shell integration provides a shell function named __wakterm_set_user_var which can be
used to set your own user vars.
Setting a user var will generate events in the window that contains the corresponding pane:
- user-var-changed, which allows you to directly take action when a var is set/changed.
- update-status which allows you to update left/right status items
- the title and tab bar area will then update and trigger any associated events as part of that update
You can access the complete set of user vars in a given pane by calling
pane:get_user_vars(), or by accessing
the user_vars field in a PaneInformation
struct.
You may wish to use this information to adjust what is shown in your tab titles or in the status area.
OSC 7 Escape sequence to set the working directory#
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 .wakterm.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:
config.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)) ";
}
OSC 7 on Windows with powershell (with starship)#
When using Starship, since it has taken control of the prompt, hooking in to set OSC 7 can be achieved this way instead:
$prompt = ""
function Invoke-Starship-PreCommand {
$current_location = $executionContext.SessionState.Path.CurrentLocation
if ($current_location.Provider.Name -eq "FileSystem") {
$ansi_escape = [char]27
$provider_path = $current_location.ProviderPath -replace "\\", "/"
$prompt = "$ansi_escape]7;file://${env:COMPUTERNAME}/${provider_path}$ansi_escape\"
}
$host.ui.Write($prompt)
}
Using Clink on Windows Systems#
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 wakterm to launch clink by setting the default_prog configuration
in your .wakterm.lua; for example, if you have extracted clink to c:\clink
you might configure this:
local wakterm = require 'wakterm'
local config = {}
config.set_environment_variables = {}
if wakterm.target_triple == 'x86_64-pc-windows-msvc' then
-- Use OSC 7 as per the above example
config.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
config.set_environment_variables['DIRCMD'] = '/d'
-- And inject clink into the command prompt
config.default_prog =
{ 'cmd.exe', '/s', '/k', 'c:/clink/clink_x64.exe', 'inject', '-q' }
end
return config
Now, rather than just running cmd.exe on its own, this will cause cmd.exe
to self-inject the clink line editor.