效率神器 活跃维护

sesh

joshmedeski/sesh

智能 tmux 会话管理器

2862
Stars 标星
130
Forks 分支
7
Watchers 关注
50
Open Issues
Go
主要语言
MIT
开源协议
9.9 MB
仓库大小
3 天前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:joshmedeski/sesh
git clone https://github.com/joshmedeski/sesh.git
git clone git@github.com:joshmedeski/sesh.git
README.md main

机器翻译正文由机器翻译自项目原始文档(英文),排版经程序统一处理,可能存在偏差,请以原项目仓库为准。

Sesh,智能 tmux 会话管理器

Sesh 是一个命令行工具(CLI),帮助你使用 zoxide 快速轻松地创建和管理 tmux 会话。

  • 智能会话创建 - 根据 git 仓库、git 远程或目录自动命名会话
  • Zoxide 集成 - 即刻跳转到你最常使用的项目
  • 会话配置 - 在 sesh.toml 中为每个项目定义启动命令、窗口和预览命令
  • 通配符配置 - 将设置应用于所有匹配 glob 模式的项目
  • 内置选择器 - 交互式会话选择器,或与 fzf、television 或 gum 集成
  • 克隆并连接 - 克隆 git 仓库并一步启动会话
  • 创建目录并连接 - 创建新目录(相对或绝对路径)并一步启动会话
  • 上次会话切换 - 无缝在最近的两个会话之间切换
  • 根会话导航 - 跳转到 git 工作树或仓库根目录
  • Nerd 字体图标 - 在选择器中显示会话类型图标
  • Shell 自动补全 - Bash、Zsh、Fish 和 PowerShell 的 Tab 补全

[!注意]
⭐ 如果你觉得 sesh 有用,请给仓库加星——这有助于项目发展并触及更多开发者!

[!提示]
想看到更多功能并帮助 sesh 成长?可以考虑 赞助该项目 支持持续开发。

视频

由 Josh Medeski(sesh 的创作者)介绍

来自 DevOps 工具箱的评论

如何安装

自制

要安装 sesh,请运行以下 homebrew 命令:

使用 Homebrew 安装 sesh
Arch Linux AUR

要安装 sesh,请运行以下 yay 命令:

yay -S sesh-bin
Fedora (Copr)

Sesh 可从 buckaroogeek/Tmux_sesh Copr 仓库(适用于 Fedora 和 EPEL 10)获取:

sudo dnf copr enable buckaroogeek/Tmux_sesh
sudo dnf 安装 tmux-sesh
Go

或者,你可以使用 Go 的 go install 命令来安装 Sesh:

安装 github.com/joshmedeski/sesh/v2@latest

这将下载并安装 Sesh 的最新版本。确保你的 Go 环境已正确配置。

Conda

要安装 sesh,请根据您的设置运行以下 其中一条命令:

  • Conda/(micro)mamba 用户
# 如有需要,可替换为 mamba/micromamba
conda -c conda-forge 安装 sesh
  • Pixi 用户
pixi 全局安装会话
尼克斯

请参阅 Nix 软件包目录,了解如何通过 Nix 平台安装 sesh 的说明。

注意: 你希望在另一个包管理器上使用吗?创建一个问题并告诉我!

Shell 补全

Sesh 支持 Bash、Zsh、Fish 和 PowerShell 的 Shell 补全(Tab 补全)。这可以帮助你通过按 Tab 键来发现命令、选项和参数。

Bash
# 生成补全脚本
sesh 完成 bash > sesh-completion.bash

# 安装到系统范围(推荐)
sudo cp sesh-completion.bash /etc/bash_completion.d/

# 或者仅安装到用户目录
mkdir -p ~/.local/share/bash-completion/completions
cp sesh-completion.bash ~/.local/share/bash-completion/completions/sesh

# 重新加载你的 shell
source ~/.bashrc
Zsh
# 生成补全脚本
sesh 完成 zsh    >    _sesh

# 安装系统范围(推荐)
sudo mkdir -p /usr/local/share/zsh/site-functions
sudo cp _sesh /usr/local/share/zsh/site-functions/

# 或者仅安装用户
mkdir -p ~/.zsh/completions
cp _sesh ~/.zsh/completions/
echo 'fpath=(~/.zsh/completions $fpath)' >> ~/.zshrc
echo 'autoload -U compinit && compinit' >> ~/.zshrc

# 重新加载你的 shell
source ~/.zshrc
鱼
# 生成并安装补全
sesh 完成 fish              >              ~/.config/fish/completions/sesh.fish

# 重新加载 fish 配置
source ~/.config/fish/config.fish
PowerShell
# 生成补全脚本
sesh 完成 powershell  >  sesh.ps1

# 如果不存在则创建 PowerShell 配置目录
mkdir -p (Split-Path $PROFILE)

# 添加到 PowerShell 配置文件
Add-Content $PROFILE ". /path/to/sesh.ps1"

# 重新加载 PowerShell
& $PROFILE

设置完成后,你可以在输入 sesh 时按 Tab 键查看可用的命令、标志和参数。

扩展

Raycast 扩展

sesh 伴侣扩展 对于 Raycast 来说,使得在终端外使用 sesh 变得容易。

需要注意以下限制:

  • tmux 必须先运行,才能使用该扩展
  • 该扩展会缓存几秒钟的结果,因此它可能并不总是最新的

Ulauncher 扩展

对于使用 Ulauncher 的 Linux 用户,有两个扩展可以在终端外使用 sesh:

以下是使用 Sesh 会话管理器时需要注意的限制:

  • tmux 必须先运行才能使用该扩展

Walker 启动器使用方法(Linux)

直接在 $XDG_CONFIG_HOME/config.toml 上创建操作

[[plugins]]
name = "sesh"
prefix = ";s "
src_once = "sesh list -d -c -t -T"
cmd = "sesh connect --switch %RESULT%"
keep_sort = false
recalculate_score = true
show_icon_when_single = true
switcher_only = true

对于 dmenu 模式,您可以使用:

Fish shell:

设置 ssession $(sesh l -t -T -d -H | walker -d -f -k -p "Sesh 会话"); sesh cn --switch $ssession

Bash/Zsh:

ssession=$(sesh l -t -T -d -H | walker -d -f -k -p "Sesh 会话"); sesh cn --switch $ssession

对于 dmenu 启动器,将 walker -dfk 替换为 dmenu 或 rofi

代理技能

Sesh 搭载了一个 agent skill,它教会编码代理通过 sesh 开始工作,而不是调用 tmux new-session、tmux new-window 和 tmux send-keys。拥有该技能的代理会根据工作是否属于已打开的内容选择会话或窗口,解决 tmux、zoxide、配置和 tmuxinator 中的名称及目录,重用已经运行的内容而不是重复它,并在工作是后台步骤时将您停留在当前位置。

通过 skills CLI 安装它:

# globally, for every project
npx skills add joshmedeski/sesh -g

# or into the current project only
npx skills add joshmedeski/sesh

它可以与 Claude Code、Codex、Cursor、OpenCode 以及其他数十个代理一起使用 — skills add 会询问要安装到哪些代理,或者使用 -a claude-code 来选择。

该技能位于 skills/sesh/SKILL.md,并随 CLI 版本更新,因此 npx skills update sesh 会获取更新。要手动安装,请将该文件复制或创建符号链接到 ~/.claude/skills/sesh/SKILL.md(或你的代理对应的技能目录)。

使用方法

tmux 用于会话

tmux 是一个强大的终端复用器,允许你创建和管理多个终端会话。Sesh 旨在使 tmux 会话管理更简单。

zoxide 用于目录

zoxide 是 cd 的极速替代方案,它会跟踪你最常使用的目录。Sesh 使用 zoxide 来管理你的项目。你需要先设置 zoxide,但设置完成后,你就可以快速跳转到最常用的目录。

基本用法

一旦 tmux 和 zoxide 设置好,sesh list 会列出所有 tmux 会话和 zoxide 结果,而 sesh connect {session} 会连接到一个会话(如果不存在会自动创建)。最佳使用方式是将其集成到你的 shell 和 tmux 中。

fzf

将 sesh 集成到工作流程中最简单的方式是使用 fzf。你可以用它来选择要连接的会话:

sesh connect $(sesh list | fzf)

tmux fzf

为了与 tmux 集成,你可以在你的 tmux 配置文件(tmux.conf)中添加一个绑定。例如,下面的示例将绑定 ctrl-a T 以在 tmux 弹出窗口中打开 fzf 提示(使用 fzf-tmux),并使用不同的命令列出活动会话(sesh list -t)、已配置会话(sesh list -c)、zoxide 目录(sesh list -z)以及查找目录(fd...)。

bind-key "T" run-shell "sesh connect \"$(
  sesh list --icons | fzf-tmux -p 80%,70% \
    --no-sort --ansi --border-label ' sesh ' --prompt '⚡  ' \
    --header '  ^a all ^t tmux ^g configs ^x zoxide ^d tmux kill ^f find' \
    --bind 'tab:down,btab:up' \
    --bind 'ctrl-a:change-prompt(⚡  )+reload(sesh list --icons)' \
    --bind 'ctrl-t:change-prompt(🪟  )+reload(sesh list -t --icons)' \
    --bind 'ctrl-g:change-prompt(⚙️  )+reload(sesh list -c --icons)' \
    --bind 'ctrl-x:change-prompt(📁  )+reload(sesh list -z --icons)' \
    --bind 'ctrl-f:change-prompt(🔎  )+reload(fd -H -d 2 -t d -E .Trash . ~)' \
    --bind 'ctrl-d:execute(tmux kill-session -t {2..})+change-prompt(⚡  )+reload(sesh list --icons)' \
    --preview-window 'right:55%' \
    --preview 'sesh preview {}'
)\""

您可以按照自己的意愿自定义此设置,更多不同选项的信息请参阅 man fzf。

要持续刷新活动的 tmux 会话预览,请在预览命令中添加 --watch:

--preview 'sesh preview --watch {}'

监视模式仅轮询活动的 tmux 会话;目录和已配置的会话预览仍会渲染一次。默认间隔为 500 毫秒,可通过 --interval 100ms 修改。

自定义列表格式

--format 允许外部选择器控制每个 sesh list 行的渲染,而不改变默认输出。可用的占位符如下:

占位符 值
{name} 常规显示名称,包括在设置 --icons 时的源图标
{session} 原始会话名称
{source} 会话来源(tmux、config、zoxide 等)
{path} 会话路径
{active_window_name} 活动 tmux 窗口名称;非 tmux 会话则为空
{active_window_name_prefix} 活动窗口名称后跟一个空格,如果没有则为空

例如,可与 tmux 插件 tmux-nerd-font-window-name 一起使用

sesh list --icons --format '{active_window_name_prefix}{name}'
  neovim-config
  sesh
 dotfiles

要使用活动窗口图标 而不是 普通的 tmux 源图标,同时保留配置/zoxide 等的源图标,只排除 tmux 源图标:

sesh list --icons --icons-exclude tmux --format '{active_window_name_prefix}{name}'

前景颜色可以直接在格式中使用 {fg:COLOR} 和 {/fg} 来设置。这使得展示保留在格式中,而不是将颜色绑定到特定的占位符上:

sesh list --icons --icons-exclude tmux \
  --format '{fg:yellow}{active_window_name_prefix}{/fg}{name}'

颜色可以应用到行的任何部分,例如:

sesh list --format '{fg:gray}{source}{/fg} {fg:bright-cyan}{active_window_name}{/fg} {name}'

支持的颜色有 black、red、green、yellow、blue、magenta、cyan、white 及它们的 bright-* 变体。gray/grey 是 bright-black 的别名。--no-color 会移除格式颜色标记以及内置的源图标颜色。

活动窗口名称会在一次 tmux 调用中实时获取,并且仅在格式使用了 active-window-name 占位符时获取。tmux 查找失败时会简单地将 active-window-name 占位符留空。--format 不能与 --json 一起使用。

sesh list --json 会报告连接时实际使用的内容:每个会话解析后的 Icon(与选择器显示的相同)、其 Alias、AliasAutoConnect 和 Tmuxp、匹配的 Wildcard 模式,以及 StartupCommand、PreviewCommand、WindowNames 和 WindowConfigs(应用了 [[wildcard]] 及 [default_session] 回退)。tmux 会话会包括其实时的 TmuxWindows(Name、Index、Path、Active),无论 [tui] show_windows 是否设置。在 [[worktree]] 根下的会话会包含 Worktree(Repo、Number、Title、State),其中 Title 和 State 从 sesh worktree list 填充的 issue 缓存中读取;其他会话为 null。

任意格式化的行都是显示输出,不会被 sesh connect 解析回去。在使用 fzf 时,将原始会话名保存在隐藏字段中,只显示格式化字段:

selected="$(
  sesh list --icons --format $'{session}\t{active_window_name_prefix}{name}' |
    fzf --delimiter=$'\t' --with-nth=2
)"
sesh connect "${selected%%$'\t'*}"

tmux television

如果你更喜欢使用 television 而不是 fzf,你可以在你的 tmux 配置中添加一个绑定,在 tmux 弹出窗口中打开 sesh 频道。

bind-key "T" display-popup -E -w 80% -h 70% -d '#{pane_current_path}' -T 'Sesh' tv sesh

使用 Ctrl-s 循环浏览资源,使用 Ctrl-d 结束高亮的会话。

窗口管理

sesh window(别名 w)允许你在会话中列出、切换和创建 tmux 窗口——类似于 sesh list 和 sesh connect 对会话的操作。它是一组子命令:

sesh window list      # list the windows of a session
sesh window connect   # select a window, creating it if it doesn't exist

列出窗口

sesh window list           # the session you're attached to
sesh window list -t work   # another session
sesh window list -j        # as json

按名称切换到现有窗口

sesh window connect editor

如果目标会话中存在名为 editor 的窗口,sesh 会选择它。如果不存在,sesh 会创建它。

在某个目录下创建一个新窗口

sesh window connect ~/projects/my-app

目录参数会以其基本名称(my-app)命名窗口,并将其固定在该位置。再次运行它会选择第一次运行创建的窗口,而不是打开一个重复窗口。

在窗口中运行命令

sesh window connect claude -t 'second brain' -c 'claude "summarize my notes"'

在一个新建的窗口中,命令会成为该窗口的进程,因此窗口在命令退出时关闭。在一个已有的窗口中,它会在已有的程序中输入命令。每次调用都想获得一个全新的窗口而不是复用名称时,请传递 --new。

定位到特定会话

使用 --target / -t 来管理你未附加的其他会话中的窗口:

sesh window list -t work
sesh window connect ~/projects/my-app -t work

目标的解析方式与 sesh connect 解析会话的方式相同——通过 tmux、zoxide、配置和 tmuxinator——并在其尚未运行时启动,而不会将你移出当前会话。使用 -b / --background 可以在不切换到该窗口的情况下创建窗口,使用 -s / --switch 在从终端外触发 sesh 时使用。

[!注意]
sesh window <name> 和 sesh window -s <session> 已被 sesh window connect <name> 和 sesh window list -t <session> 替代。--session 仍然作为 --target 的已弃用别名可用,而 -s 现在在 sesh window connect 中表示 --switch,与 sesh connect 保持一致。

fzf 集成

你可以将这两个子命令与 fzf 结合,交互式切换窗口:

sesh window connect "$(sesh window list | fzf)"

或者作为 tmux 快捷键:

bind-key "W" run-shell "sesh window connect \"$(sesh window list | fzf-tmux -p 60%,50% --prompt '🪟  ')\""

创建一个目录并连接

sesh mkdir(别名 md)将 mkdir 和 sesh connect 合并为一步操作:如果目录尚不存在,它会创建该目录,然后将其作为会话连接——无需先 cd 进入目录或等待 zoxide 识别它。

sesh mkdir my-new-project

<path> 可以接受 相对 路径(相对于您当前的工作目录解析)和 绝对 路径,也可以使用 ~ 表示您的主目录:

sesh mkdir my-new-project        # relative to the current directory
sesh mkdir ~/projects/my-app     # relative to your home directory
sesh mkdir /Users/josh/dev/api   # absolute path

口香糖 tmux

如果您更喜欢使用 charmbracelet 的 gum,那么您可以使用以下命令连接到会话:

bind-key "K" display-popup -E -w 40% "sesh connect \"$(
 sesh list -i | gum filter --limit 1 --no-sort --fuzzy --placeholder 'Pick a sesh' --height 50 --prompt='⚡'
)\""

注意: 与 fzf 相比,gum 的功能较少,但我发现它的匹配算法更快,而且使用起来感觉更现代。

[!警告]
从 gum v0.15.0 起,你必须添加 --no-strip-ansi 才能正确显示图标。

请查看我的视频,Top 4 Fuzzy CLIs,获取更多可与 sesh 集成的工具灵感。

sesh 选择器

Sesh 有一个内置的选择器,可用作 tmux 弹出窗口:

bind-key "K" display-popup -h 90% -w 50% -E "sesh picker -i"

zsh 快捷键绑定

如果你使用 zsh,你可以将以下快捷键绑定添加到你的 .zshrc 中以连接到会话:

function sesh-sessions() {
  {
    exec </dev/tty
    exec <&1
    local session
    session=$(sesh list -t -c | fzf --height 40% --reverse --border-label ' sesh ' --border --prompt '⚡  ')
    zle reset-prompt > /dev/null 2>&1 || true
    [[ -z "$session" ]] && return
    sesh connect $session
  }
}

zle     -N             sesh-sessions
bindkey -M emacs '\es' sesh-sessions
bindkey -M vicmd '\es' sesh-sessions
bindkey -M viins '\es' sesh-sessions

在将此添加到你的 .zshrc 后,你可以按 Alt-s 打开 fzf 提示以连接到一个会话。

推荐的 tmux 设置

我建议你将这些设置添加到你的 tmux.conf 中,以便更好地使用这个插件。

bind-key x kill-pane # skip "kill-pane 1? (y/n)" prompt
set -g detach-on-destroy off  # don't exit from tmux when closing a session

奖励

上一个

默认的 <prefix>+L 命令将“将附加的客户端切换回上一个会话。”然而,如果在设置了 detach-on-destroy off 时关闭会话,将无法找到上一个会话。为了解决这个问题,我有一个 sesh last 命令,它将始终把客户端切换到最近附加的倒数第二个会话。

在你的 tmux.conf 中添加以下内容以覆盖默认的 last-session 命令:

bind -N "last-session (via sesh) " L run-shell "sesh last"

使用 GitHub 问题标题丰富会话名称

sesh 可以重命名会话以包含其分支的 GitHub 问题标题,例如 400-status → 400-status — warm the status cache。它从分支名称中解析问题编号,并使用 gh CLI(必须已安装并认证)进行查找。

添加一个可选择的 tmux 钩子,以便每个新会话在后台被丰富:

set-hook -g session-created 'run-shell -b "sesh rename --enrich"'

当分支没有可解析的问题时,该命令不会执行任何操作(会话保持其原始名称),并且它会自我修复:切换到没有问题的分支会将会话重命名回基础名称。重新连接到目录会重新附加到已扩展的会话,而不是创建重复会话。

连接到根目录

在嵌套会话中工作时,你可能希望连接到 git 工作树或 git 仓库的根会话。为此,你可以在 sesh connect 命令中使用 --root 标志。

我建议将此添加到你的 tmux.conf:

bind -N "switch to root session (via sesh) " 9 run-shell "sesh connect --root $(pwd)"

按根目录过滤

如果您想按活动项目的根目录来过滤搜索,可以使用 sesh root 命令来修改您的选择器:

bind-key "R" display-popup -E -w 40% "sesh connect \"$(
  sesh list -i -H | gum filter --value \"$(sesh root)\" --limit 1 --fuzzy --no-sort --placeholder 'Pick a sesh' --prompt='⚡'readme
)\""

我已经把这个绑定到 <prefix>+R,这样我就可以使用一个备用绑定。

注意: 只有在你位于 git worktree 或 git 仓库中时,这才会起作用。目前,git worktrees 期望有一个 .bare 文件夹。

配置

你可以通过在 $XDG_CONFIG_HOME/sesh 或 $HOME/.config/sesh 目录中创建一个 sesh.toml 文件来配置 sesh。

mkdir -p ~/.config/sesh && touch ~/.config/sesh/sesh.toml

自定义配置路径

您可以使用 --config(或 -C)标志指定自定义配置文件路径。这对于 NixOS 包装器、维护独立的工作/私人配置或进行测试非常有用。

sesh -C /path/to/custom/sesh.toml list
sesh --config /path/to/custom/sesh.toml connect my-session

该标志适用于任何子命令。指定时,文件必须存在,否则 sesh 会返回错误。没有该标志时,sesh 使用默认配置路径。

自定义多路复用器 (psmux)

Sesh 默认使用 tmux 作为终端多路复用器,但你可以通过在 sesh.toml 中设置 tmux_command 来配置使用任何兼容 tmux 的多路复用器,例如 psmux :

tmux_command = "psmux"

这会替换 sesh 运行的所有命令中的 tmux 二进制文件(会话创建、切换、附加等)。配置的多路复用器必须支持 tmux 的 CLI 接口。

自定义频繁使用(Frecency)后台(fasd、autojump 等)。

Sesh 使用 zoxide 作为默认的频繁使用目录跳转后台,但你可以通过在 [frecency] 表中重写命令,将其指向替代工具,如 fasd、fasder、autojump 或 memy。这对于跟踪文件和目录的工具很有用,而 zoxide 仅跟踪目录。

[frecency]
list_command  = "fasd -d -l -R"  # list all tracked entries
query_command = "fasd -d {}"     # resolve one input to a path
add_command   = "fasd -A {}"     # record a path after connecting
remove_command = "fasd -D {}"    # remove a path (picker ctrl+x)
  • {} 占位符会被查询字符串 (query_command) 或路径 (add_command, remove_command) 替换,这与 preview_command 使用的替换方式相同。
  • list_command 的输出按每行一个路径解析,最近使用的排在最前。如果存在前导数字分数(如 zoxide 的 --score),会自动检测;否则分数为 0。
  • 任何命令都会作为单个二进制程序运行(不经过 shell),因此不支持管道/重定向。
  • 任何你省略的字段都会回退到 zoxide 默认值(zoxide query --list --score、zoxide query {}、zoxide add {}、zoxide remove {}),因此缺少 [frecency] 表时行为保持不变。
  • sesh list 输出中的源标签保持为 zoxide,因此读取 --json 输出的现有集成程序仍然可以正常工作。

架构(编辑器自动补全)

Sesh 为 sesh.toml 提供了一个 JSON Schema,可在编辑器中启用自动补全、验证和文档功能。这适用于支持 taplo TOML 语言服务器的任何编辑器。

快速设置

在你的 sesh.toml 顶部添加以下行:

#:schema https://github.com/joshmedeski/sesh/raw/main/sesh.schema.json

就是这样!Taplo 会读取指令并自动应用模式。

Neovim

确保你已经安装了 taplo:

brew install taplo

如果你正在使用 nvim-lspconfig,使用上面的 #:schema 指令,taplo 应该可以开箱即用。或者,你也可以直接配置模式关联:

require("lspconfig").taplo.setup({
  settings = {
    taplo = {
      schema = {
        associations = {
          [".*sesh\\.toml$"] = "https://github.com/joshmedeski/sesh/raw/main/sesh.schema.json",
        },
      },
    },
  },
})

黑名单

您可能希望将某些 tmux 会话加入黑名单,以避免它们出现在结果中。例如,您可能希望将 scratch 目录排除在结果之外。

blacklist = ["scratch"]

要显示以供管理的黑名单会话,请将 -b(或 --blacklisted)传递给 sesh list。它可以与源标志组合使用,所以 sesh list -b -t 只列出被列入黑名单的 tmux 会话。

目录长度

控制用于会话名称的目录组件数量。默认值是 1(仅目录的基本名称)。

dir_length = 2  # Uses last 2 directories: "projects/sesh" instead of just "sesh"

[!注意]
与 tmux-floax 配合使用效果很好

会话名称替换

一些目录会生成很长且重复的会话名称——~/c/dotfiles/.config 下的所有内容都会显示完整前缀。name_substitution 规则可以重写名称来源的路径,以便你缩短或重新命名它。

[[name_substitution]]
find = "~/c/dotfiles/.config/"
replace = ""

按照该规则,连接到 ~/c/dotfiles/.config/nvim 会创建一个名为 nvim 的会话,而不是使用完整路径。规则会针对每个路径来源(zoxide、目录和通配符)的折叠主目录路径(以 ~ 开头)进行匹配。现有的 tmux 会话会保留它们的名称,如果没有规则匹配,则命名会回退到常规的 git 和目录策略,所以添加规则不会改变其他任何东西的命名。

规则按顺序应用,每个规则看到的是前一个规则的结果,因此它们可以组合使用。find 默认按字面意思匹配;设置 regex = true 可将其视为 Go 正则表达式,这允许 replace 使用 $1、$2 等引用捕获组。

[[name_substitution]]
find = ".*/workspace/[0-9]+_(.*)"
replace = "ws-$1"
regex = true

[!注意]
tmux 会话名称不能包含 . 或 :,并且空格会被替换为 _,因此 replace 中的这些字符在最终名称中会被规范化。

排序

如果您想更改显示会话的顺序,可以在您的 sesh.toml 文件中配置 sort_order

sort_order = [
    "tmuxinator", # show first
    "config",
    "tmux",
    "zoxide", # show last
]

默认顺序是 tmux、config、tmuxinator,然后是 zoxide。

如果你只关心特定类型的顺序,可以省略会话类型。

sort_order = [
  "config", # resulting order: config, tmux, tmuxinator, zoxide
]

将多个来源合并为一个按分数排序的组

默认情况下,每个来源都是它自己独立的块,因此你每天打开的配置会话仍然会位于几周未访问的 zoxide 路径下。将来源嵌套在 sort_order 中,可以将它们合并为一个按 zoxide 分数排序的单一块,分数最高的放在最前:

sort_order = [
  "tmux",                # live sessions stay pinned on top
  ["config", "zoxide"],  # merged, ordered by zoxide score
]

来自没有自身分数的来源的会话——例如 [[session]] 块——会借用 zoxide 为其路径分配的分数,因此它们会根据该目录实际访问的频率进行排序。zoxide 从未见过的路径分数为 0,并排在组的后面。

组仍按列出的顺序显示,平铺的 sort_order 的行为与以往完全相同:合并是可选的。

组分隔符

一旦来源交错,活跃 tmux 会话与其他所有内容之间的边界仅凭位置就不再明显。group_separator 会在选择器中的 sort_order 组之间绘制一条淡淡的分隔线:

[tui]
group_separator = true

该规则永远不可选择,光标会直接跳过它。在过滤时它会被抑制,此时结果按匹配质量重新排序,组不再与连续范围对齐。

缓存

[!警告]
此功能属于实验性,可能无法按预期工作。

Sesh 可以缓存会话列表以加速重复调用。缓存是可选的,默认情况下禁用。启用后,sesh 会将结果存储在 $XDG_CACHE_HOME/sesh/sessions.gob(默认 ~/.cache/sesh/sessions.gob),并使用 5 秒 TTL 的 stale-while-revalidate 策略:

  • 冷启动:缓存不存在,获取实时数据并写入缓存
  • 新鲜命中(5 秒内):立即返回缓存数据
  • 陈旧命中(5 秒后):立即返回缓存数据,同时在后台刷新缓存

缓存也会在 sesh connect 后自动刷新。

cache = true

在 sesh connect 之外创建或关闭的会话(例如普通的 tmux new-session,关闭会话的最后一个窗口)在下一次过期刷新之前不会出现在缓存中。为了保持缓存的最新,请在这些事件发生时运行 sesh cache refresh —— 它会获取实时数据并重写缓存,当缓存被禁用时不会执行任何操作。使用 tmux 钩子可以覆盖这两种事件:

set-hook -g session-created 'run-shell -b "sesh cache refresh"'
set-hook -g session-closed  'run-shell -b "sesh cache refresh"'

如果你在 fzf 选择器中使用终止绑定(例如上面示例中的 ctrl-d),在重新加载列表之前刷新缓存,以便被终止的会话立即消失:

--bind 'ctrl-d:execute(tmux kill-session -t {2..}; sesh cache refresh)+change-prompt(⚡  )+reload(sesh list --icons)' \

选择器 TUI

选择器 TUI 可以使用一些选项进行配置,这些选项可以帮助您自定义其行为,这个选择器是外部模糊选择器的一个有用替代品。

[tui]
prompt = "> "
placeholder = "Filter sessions... "
show_icons = false
show_windows = false
group_separator = false
window_name_format = "#{window_name}"
alias_auto_connect_delay = "150ms"
alias_filter_prefix = "/"
preview = false
preview_width = 60
preview_min_width = 100
preview_border = "line"

使用 show_windows = true,每一行还列出了该会话内窗口的名称,显示在会话名称之后并呈暗色。无法显示的窗口名称会被汇总为 +N:

>  sesh editor server logs
   dotfiles nvim shell
   my-project code server db +2
   scratch

窗口名称仅用于显示:选择一行仍然只返回会话名称,输入窗口名称不会匹配其会话。活动 tmux 会话的名称是在单次 tmux 调用中获取的,因此无论你有多少会话,该选项的成本都是相同的。

window_name_format 接受任何 tmux 格式。tmux 会解释条件语句、回退变量和 #() 命令。例如,该格式在存在窗格标题时使用窗格标题,否则使用窗口名称:

window_name_format = "#{?#{pane_title},#{pane_title},#{window_name}}"

alias_auto_connect_delay 和 alias_filter_prefix 用于调整别名 — 参见 Session Aliases。

自定义图标

使用 show_icons = true 时,每一行会显示一个表示会话来源的图标 — tmux、config、zoxide、tmuxinator。这个图标表示会话的来源,而不是它的类型,因此 [[session]] 和 [[wildcard]] 块可以使用自己的图标。它可以是任意字符串:一个极客字体图标或一个表情符号。

[[session]]
name = "sesh"
path = "~/c/sesh"
icon = ""

[[session]]
name = "notes"
path = "~/second-brain"
icon = "📓"

[[wildcard]]
pattern = "~/c/work/*"
icon = "🏠"
>  sesh
  📓 notes
  🏠 work-api
   dotfiles

最具体的匹配获胜:先精确匹配 [[session]] 名称,然后匹配其 path —— 因此即使同一目录在 zoxide 下以派生名称列出,仍然会获得图标 —— 然后匹配 [[wildcard]] 模式。如果有多个模式匹配,配置顺序中第一个获胜,就像 startup_command 一样。任何没有自己图标的都会保留其源字符,而 icon = "" 被视为未设置。

自定义图标渲染时不带样式:表情符号自带颜色,而 nerd 字体字符使用默认前景色。图标列会根据你配置的最宽图标进行填充,所以某一行的双宽表情符号不会使它的名称与其他行错位。

如果仍有某个图标偏离一列,请在其后添加一个空格:

[[session]]
name = "update"
path = "~/c/update"
icon = "⬆️ "   # note the trailing space

终端对表情符号的宽度有不同意见,并且在 TUI 中没有任何方法可以询问你的终端是怎么显示的。带有变体选择器的表情符号——⬆️ 是 U+2B06 加上 U+FE0F,🖼️ 和 🖥️ 也是如此——测量为两个单元格,但在 WezTerm 和其他终端中绘制为一个单元格,这会使该行显得短。尾随空格会被计入行,但不计入列宽度,因此它修复了单个图标而不移动其他任何内容。

这仅限于选择器使用。sesh list --icons 保留源字形,因为解析其输出的脚本和外部选择器会截取已知宽度的字形——参见 #246。如果设置 show_icons = false,自定义图标也会完全被禁止。

从过滤器开始

--query(-q)会打开选择器并预先填写好过滤器,这在 tmux 快捷键中非常方便,可以将会话列表限定到其中的一部分:

bind-key "P" display-popup -h 90% -w 50% -E "sesh picker -q work/"

查询的输入方式与直接键入时完全相同,因此在会话加载时列表会立即缩小,而按退格键则会再次扩大。符号也有效 —— -q '#' 直接进入 按编号跳转,而 -q / 进入 别名模式。

匹配单个会话的查询不会自动连接;选择器会打开那一行并高亮显示,等待 enter。拼写出别名并开启 alias_auto_connect 的查询也不会自动连接 —— 自动连接只有在你实际键入时才会触发,因此脚本化的 --query 永远不会连接到你没有查看的地方。

这仅适用于每次调用,没有 [tui] 的对应选项:默认查询会在每次启动时静默隐藏会话。

按编号跳转

输入 # 作为首字符会对行进行编号,并将下一个数字作为跳转 —— 达到前几会话中某一个的最快方式,而无需阅读它们的名称:

filter: #

> 1 sesh
  2 dotfiles
  3 my-project

按 3 会立即连接到 my-project。只有 1–9 可以跳转,而且只有前九行有编号。

数字会按照可见列表顺序,因此在符号后输入的任何内容会先缩小范围,然后重新编号剩下的项目——#a 然后 2 会跳到 a 的第二个匹配项。该位置没有行号的数字不会起作用,而不是进行过滤。

只有开头的 # 才算数,所以 feat#123 会正常过滤。如果你配置了 alias_filter_prefix = "#",别名模式优先,那么此模式将无法访问。

移除一行

ctrl x 会移除高亮的那一行,具体意味着什么取决于该行的来源:一个实时的 TMMUX 会话被终止,Zoxide 条目从更新后端被修剪。无论哪种情况,这都是在确认之后发生的。

你删除或重命名的目录会一直出现在拣选器里,直到 zoxide 被告知它,所以在 zoxide 行上按 ctrl x 修剪它,就在你注意到的地方:

╭────────────────────────────────────────────────────────╮
│                                                        │
│    Do you want to remove this directory from zoxide?   │
│                                                        │
│                    ~/c/some-old-project                │
│                                                        │
│                      Yes      No                       │
│                                                        │
╰────────────────────────────────────────────────────────╯

在 tmux 行上,它改为运行 tmux kill-session,这是内置启动器中相当于 fzf 设置 中 ctrl d 绑定的操作:

╭────────────────────────────────────────────────────────╮
│                                                        │
│          Do you want to kill this tmux session?        │
│                                                        │
│                       my-project                       │
│                                                        │
│                      Yes      No                       │
│                                                        │
╰────────────────────────────────────────────────────────╯

y 或 enter 确认,n、q 或 esc 取消,←/→ 或 tab 在按钮间移动。当对话框打开时输入的内容不会传递给过滤器,所以列表保持原样,不会受到影响。

只有 tmux 和 zoxide 的行可以被移除 —— 一个 [[session]] 块或 tmuxinator 配置描述了可能存在的会话,删除它们中的任何一个都需要编辑文件,所以 ctrl x 会提示并且不做任何操作。只有当命令实际成功时,该行才会消失;如果后端拒绝操作,会报告错误并保留该行。

允许终止正在连接的会话:tmux 会将你的客户端移到另一个会话,或者如果这是最后一个会话则退出。选择器也会随之关闭,因为它在该会话中运行。

zoxide 的移除操作默认运行 zoxide remove {},或你设置的任何 remove_command —— 参见 自定义频繁访问后端。如果 cache = true,无论哪种操作都会重写缓存,这样下次启动时不会列出刚刚删除的内容。

预览窗格

当 preview = true 时,列表旁会预览高亮的会话,使用的输出与 sesh preview 完全相同 —— 通过 capture-pane 获取实时 tmux 窗格,对于配置的会话使用你的 preview_command,否则显示目录列表。

> sesh                │ $ eza --icons
  dotfiles            │  README.md    main.go
  my-project          │  picker/      previewer/

该窗格默认是关闭的,ctrl+o 可以随时切换它。

preview_width 是终端中保证给窗格的百分比。会话列表最多显示 60 列,因此在宽终端上,超过此上限的部分会显示在顶部的预览中;在窄终端上,列表永远不会被压缩到 40 列以下。

preview_border 选择两个窗格之间的分隔线:line(默认)、thick、double,或者 none 表示没有分隔线。关闭它会将分隔线的列空间分配给预览文本:

[tui]
preview_border = "none"
> sesh                 $ eza --icons
  dotfiles              README.md    main.go
  my-project            picker/      previewer/

preview_min_width(默认值 100)是最窄仍会出现分屏的终端宽度。低于此宽度时,选择器只会渲染列表,而当窗口有足够空间时,窗格会自行出现——在小型 tmux 弹出窗口中非常方便。预览命令会在光标移动时后台运行,因此慢速命令不会阻塞列表,失败的命令会在窗格中报告,而不会导致选择器崩溃。

默认会话

默认会话可以配置在连接到会话时运行命令。这对于运行开发服务器或启动 tmux 插件非常有用。

此外,您可以定义在预览会话目录时运行的预览命令。这对于使用像 eza 或 lsd 这样的工具显示文件非常方便。

注意:{} 会被自动替换为会话的路径。

[default_session]
startup_command = "nvim -c ':Telescope find_files'"
preview_command = "eza --all --git --icons --color=always {}"

如果你想在特定会话中禁用默认启动命令,你可以设置 disable_startup_command = true。

会话配置

启动命令是在会话创建时运行的命令。它对于为特定项目设置环境非常有用。例如,你可能想运行 npm run dev 来自动启动开发服务器。

注意: 如果你使用 --command/-c 标志,则启动脚本将不会被运行。

我喜欢在会话启动时使用一个打开 nvim 的命令。

你还可以定义一个预览命令,使用 bat 或你选择的任何其他文件预览器来显示特定文件的内容。

[[session]]
name = "Downloads 📥"
path = "~/Downloads"
startup_command = "ls"

[[session]]
name = "tmux config"
path = "~/c/dotfiles/.config/tmux"
startup_command = "nvim tmux.conf"
preview_command = "bat --color=always ~/c/dotfiles/.config/tmux/tmux.conf"

会话还可以设置 icon 来替换它在选择器中获取的源图标 — 参见 自定义图标。

会话别名

模糊匹配非常适合发现内容,但 wp 的首个结果会随着会话的增减而变化,因此肌肉记忆永远无法形成。别名为会话提供一个简短的固定名称,你可以始终依赖它:

[[session]]
name = "wallpaper"
path = "~/c/wallpaper"
alias = "wp"
alias_auto_connect = true

[[session]]
name = "dotfiles"
path = "~/.config"
alias = "dot"

别名必须是唯一的(不区分大小写)——如果两个会话共享一个别名,sesh 在启动时会报告错误。

在命令行中,sesh connect wp 的行为与 sesh connect wallpaper 完全相同。在选择器中,别名会话会标记一个标签,以便它们保持可发现性:

>  wp wallpaper
   dot dotfiles
   my-project

输入别名准确地对应到该会话,而不会对应到其他任何内容,无论模糊匹配的排名如何——其重点是结果永远不会改变:

filter: wp

>  wp wallpaper

除了完全匹配的别名外,其他都像往常一样进行模糊匹配,所以 w 和 wpx 的行为就像任何其他查询一样。即使别名所在的会话不在当前列表中,它也会被解析 —— 比如你正在运行 sesh picker --tmux,而它尚未启动。

使用 alias_auto_connect = true 时,输入完整别名会立即连接——无需按 Enter。它是按会话选择加入的,因为只有对于那些你经常跳转的少数别名才值得启用。

允许使用共享前缀的别名(w 和 wp)。[tui] alias_auto_connect_delay(默认 150ms)是在自动连接触发前的宽限期,这样可以有时间输入更长的别名。如果你打字较慢,可以增加该值;或者将其降低为 "0s",以在别名完成时立即触发。

要在一次性调用中继续输入别名,请使用 --no-alias-auto 运行选择器。

浏览别名

将 / 作为第一个字符输入会将选择器缩小到仅别名会话,这就是你从“我知道我为此设置了快捷方式”到无需记住快捷方式即可进入会话的方式:

filter: /

>  wp  wallpaper
   dot dotfiles
   tc  tmux config

你接下来输入的内容会进一步缩小范围,通过前缀匹配别名(/t 会找到 tc),然后回退到会话名称(/config 也会找到 tc,因为别名优先,而且名称可以在任何位置匹配)。即使别名对应的会话未运行,它们仍会显示。

在这种模式下完成别名会立即连接,无论是否设置了 alias_auto_connect —— 输入 / 表示接下来输入的是一个跳转的快捷方式。alias_auto_connect_delay 仍然适用,所以 /w 可以扩展为 /wp,而 --no-alias-auto 仍会阻止自动连接。

只有开头的 / 才算作前缀,所以 code/app 可以正常过滤。但如果查询以路径开头 —— /Users/you/code —— 则会进入别名模式,因此如果那样过滤,请选择不同的符号开头:

[tui]
alias_filter_prefix = "@"   # or "" to turn the mode off

路径替换

如果您希望在启动或预览命令中使用所选会话的路径,可以使用 {} 占位符。该占位符在命令执行时将被替换为会话的路径。

一个使用示例如下,其中 tmuxinator 的 default_project 使用路径作为键/值对,使用 ERB 语法:

[default_session]
startup_command = "tmuxinator start default_project path={}"
preview_command = "eza --all --git --icons --color=always {}"

多窗口

如果您希望您的会话有多个窗口,您可以在配置中定义窗口。然后,您可以在会话中使用这些窗口布局。这些窗口可以重复使用任意次数,并且您可以在每个会话中添加任意数量的窗口。

注意:如果您在窗口中未指定路径,它将使用会话的路径。

[[session]]
name = "Downloads 📥"
path = "~/Downloads"
startup_command = "ls"

[[session]]
name = "tmux config"
path = "~/c/dotfiles/.config/tmux"
startup_command = "nvim tmux.conf"
preview_command = "bat --color=always ~/c/dotfiles/.config/tmux/tmux.conf"
windows = [ "git" ]

[[window]]
name = "git"
startup_script = "git pull"

万用卡配置

通配符配置允许您定义适用于与通配符模式匹配的任何目录的会话设置,而无需为每个项目创建一个 [[session]] 条目。当您有一个包含多个项目的目录,并且这些项目都应该使用相同的启动命令时,这非常有用。

[[wildcard]]
pattern = "~/projects/*"
startup_command = "nvim"

[[wildcard]]
pattern = "~/work/*"
startup_command = "make dev"
preview_command = "ls -la"

[[wildcard]]
pattern = "~/repos/**"
startup_command = "git status"

当你运行 sesh connect ~/projects/myapp 时,sesh 会将路径与通配符模式进行匹配,并自动创建一个以目录命名的会话(使用 git 远程或文件夹名称),运行已配置的启动命令,并将路径添加到 zoxide。

可用字段:

字段 描述
pattern 用于匹配目录的通配符模式(例如 ~/projects/*)
startup_command 创建会话时运行的命令(支持 {} 代表路径)
preview_command 预览会话时运行的命令
disable_startup_command 设置为 true 以禁止启动命令
windows 使用的窗口布局(来自 [[window]] 配置的窗口名称数组)
icon 在选择器中匹配会话时显示的图标 — 参见 自定义图标

注意: 模式使用 Go 的 filepath.Match 语法,支持 *(任意序列)、?(单个字符)和 [...](字符类)。你还可以在模式末尾使用 /** 进行递归匹配 —— ~/projects/** 会匹配 ~/projects/foo、~/projects/foo/bar 及任何更深的嵌套。单个 * 仅匹配一级:~/projects/* 匹配 ~/projects/foo,但不匹配 ~/projects/foo/bar。显式的 [[session]] 配置总是优先于通配符匹配。如果多个通配符匹配,则按配置顺序第一个生效。

工作树

sesh worktree connect <number> 连接到 GitHub 问题或拉取请求的 git 工作树作为 tmux 会话,如果工作树尚不存在则先创建 —— 与 sesh connect 相同的创建或附加约定。为每个仓库配置一个 [[worktree]] 块:

# macOS: activate this terminal app after connecting from outside tmux
terminal = "wezterm"

[[worktree]]
repo = "nutiliti/nutiliti"          # GitHub org/repo
path = "~/c/nu"                      # local repo root
worktree_dir = "w"                   # worktrees go here (relative to path, or absolute); default ".wk"
branch_template = "jam/{number}-1"   # {number} is the issue/PR number; default "{number}"
base_branch = "origin/main"          # branch new worktrees from this; default "origin/main"
fetch = true                         # git fetch before creating; default true
create_command = "pnpm i"            # runs once, on the connect that creates the worktree
startup_command = "nu_setup"         # runs when connecting to a worktree that already existed

[[worktree]]
repo = "joshmedeski/joshmedeski.com"
path = "~/c/joshmedeski_com"
worktree_dir = "w"
create_command = "pnpm i"

[[worktree]]
repo = "joshmedeski/sesh"
path = "~/c/sesh"
worktree_dir = "w"

用法:

sesh worktree connect 2345                       # detect repo from cwd, connect to worktree for issue/PR 2345
sesh worktree connect 2345 --repo joshmedeski/sesh   # target a repo explicitly (no cwd needed)
sesh worktree connect 2345 --pr                  # force the pull-request path
sesh worktree connect 2345 --switch              # switch (not attach) — for invocation outside tmux

每个标记也有一个简短形式:--repo/-r、--pr/-p、--switch/-s。

sesh 通过 gh 自动检测 <number> 是问题还是 PR。对于你自己的 PR,它会解决关闭的问题(回退到 PR 标题或正文中的第一个 #N 引用);对于他人的 PR,它会创建一个独立的 worktree 并运行 gh pr checkout。在 tmux 外使用 --switch 调用时,sesh 会将活动的 tmux 客户端切换到新会话,并在 macOS 上激活 terminal 应用。

create_command 与 startup_command

两者互斥,运行哪一个取决于 connect 是否创建了 worktree:

由此 connect 创建的 worktree worktree 已存在
create_command 运行 —
startup_command — 运行

create_command 是新工作树一次性设置所需的命令 — pnpm i、初始化 .env、生成客户端 — 每次重新连接时执行这些会浪费工作。startup_command 是每次返回工作树时想要运行的命令,比如打开编辑器。创建时刻意不运行 startup_command,所以 create_command 包含了创建时发生的所有操作;如果你想两者都运行,可以将它们串联:create_command = "pnpm i && nvim"。

无论哪种方式,该命令仅在tmux 会话是新的时候发送,所以重新连接到仍然活跃的会话时不会运行任何内容。

从浏览器连接工作树(macOS)

配置 [browser] 后,使用 sesh worktree connect --browser 会读取浏览器活动标签页的 URL,提取 GitHub org/repo 和 issue/PR 编号,并连接到匹配的工作树 — 无需输入编号或在仓库内部。

[browser]
application = "Helium"
# url_command = "URL of active tab of front window"  # optional; Safari uses "URL of current tab of front window"
# With github.com/joshmedeski/sesh/issues/409 open in the front tab:
sesh worktree connect --browser   # or: sesh wt c -b

URL 的 org/repo 会通过 repo 与你的 [[worktree]] 条目进行匹配。支持 /issues/N 和 /pull/N URL。仅限 macOS。

在浏览器中打开 worktree 的 issue 或 PR

sesh worktree browse 的方向相反:从你正在关注的 tmux 会话出发,它会打开该 worktree 所属的 issue。在 tmux 内部,它使用调用会话;从外部(Leader Key 或 Raycast 绑定)它使用 client sesh 解析的会话。

sesh worktree browse           # open https://github.com/<repo>/issues/<n>
sesh worktree browse --pr      # open the PR for the worktree's branch (via gh)
sesh worktree browse --print   # print the URL instead of opening it

当设置了 [browser].application(macOS)时,URL 会在该应用中打开,否则在系统默认浏览器中打开。GitHub 会将 /issues/<n> 重定向到 /pull/<n>,当数字是 PR 时,因此外部 PR 检出无需使用 --pr。

列出工作树及其问题标题

sesh worktree list 会显示仓库的每个工作树,并在其编号旁显示问题标题,这样你可以一眼区分 409 和 411:

sesh worktree list --path ~/c/nu/w          # or: sesh wt ls --path ~/c/nu/w
sesh worktree list --repo nutiliti/nutiliti # select the repo by name instead
sesh worktree list                          # detect the repo from the current directory
sesh worktree list --json                   # machine-readable output
sesh worktree list --refresh                # refetch every title, ignoring the cache
89   Tmuxifier Support
409  Add git worktree support: `sesh worktree create <number>`
411  Add Windows and psmux compatibility

--path 和 --repo 是选择同一个 [[worktree]] 块的两种方式。只有数字命名的目录才算作工作树,这是 sesh worktree connect 创建的。

标题被缓存到 $XDG_CACHE_HOME/sesh/github-issues.v1.json(回退到 ~/.cache/sesh),所以列出通常是即时的。只有新的编号或超过 24 小时 TTL 的编号才会产生请求,这些编号会在单个批量 GraphQL 查询中获取,而不是每个工作树一次 gh 调用。如果刷新失败 —— 离线或被限流 —— 缓存的标题仍然会显示,而不会导致列表失败。

--refresh 会重新获取每个标题和状态,而不管缓存的内容有多新,用于自上次列出后被编辑的标题或已关闭的问题,并将获取到的内容写回缓存。无论哪种方式,缓存都是一次性使用的:删除该文件的效果与使用一次 --refresh 相同。

交互式选择工作树

sesh worktree picker 将相同的列表放入选择器中,并连接到你选择的工作树。每一行显示问题编号、颜色编码的状态徽章以及标题:

sesh worktree picker                          # or: sesh wt p
sesh worktree picker --repo nutiliti/nutiliti # select the repo by name
sesh worktree picker --path ~/c/nu/w          # or by worktree root
sesh worktree picker --query 409              # prefill the filter
sesh worktree picker --icons                  # pill-shaped badges (needs a nerd font)
sesh worktree picker --switch                 # switch, for invocation outside tmux
sesh worktree picker --refresh                # refetch titles on the way in
>  89   OPEN    Tmuxifier Support
  409   MERGED  Add git worktree support: `sesh worktree connect <number>`
  411   CLOSED  Add Windows and psmux compatibility
  412

徽章遵循 GitHub 自身的编码——绿色表示开放,紫色表示已合并,红色表示已关闭。一个问题从未解决的工作树(已删除,或从未是问题的编号)显示它的裸编号。

启用 show_icons(或 --icons)时,徽章使用极客字体半圆形成胶囊状——OPEN——而不是填充方块。两种形式宽度相同,因此标题会对齐。

在号码和标题上一起输入筛选器,所以 409、worktree support 和 409 worktree 都会找到同一行。enter 连接,esc 未连接就退出,ctrl+j / ctrl+k 移动——与会话选择器使用相同的键。

选择器打开时显示缓存的标题,然后在屏幕上已有行的背后重新获取它们:自上次列表后重命名或关闭的问题在选择器打开片刻后自动更新,无需你操作。行在整个过程中仍可使用——你的查询和所在行被保留——由于没人要求刷新,刷新失败时会静默跳过,仍保留缓存的标题。

ctrl+r 可以在任何时间请求相同的重新获取,并会报告失败,因为你要求它这样做。--refresh 则是在进入时进行,而是在绘制第一行之前,这是获取相同标题的较慢方式。

连接通过 sesh worktree connect 实现,因此选择的工作树会正好落在该命令会创建的会话中,包括 startup_command。

列出配置

如果未提供标志,会话配置默认加载(在 tmux 会话和 zoxide 结果之间回车)。如果你想明确列出它们,可以使用 -c 标志。

sesh list -c

贡献

想要贡献?查看我们的 贡献指南 开始入手。

背景(“t”脚本)

Sesh 是我受欢迎的 t-smart-tmux-session-manager tmux 插件的继任者。经过一年的开发和超过 250 个星标,很明显大家喜欢智能会话管理器的想法。然而,我一直觉得 tmux 插件有点像一个临时解决方案。它是一个在后台运行并解析 tmux 命令输出的 bash 脚本。它可以工作,但并不理想,灵活性不足,无法支持其他终端复用器。

我决定从头开始构建一个会话管理器。这一次,我使用一种更适合此任务的语言:Go。Go 是一种编译型语言,运行快速,类型静态,并拥有出色的标准库。它非常适合像这样的项目。我还决定让这个会话管理器对复用器保持中立。它将能够与任何终端复用器一起工作,包括 tmux、zellij、Wezterm 等。

第一步是构建一个能够与 tmux 交互的 CLI,并能作为我之前 tmux 插件的直接替代。一旦完成,我将扩展它以支持其他终端复用器。

星图仪

星际历史

本站来源与版权声明
  • 本文标题:sesh - 智能 tmux 会话管理器
  • 本文链接:https://cn121.com/productivity/joshmedeski-sesh.html
  • 原项目:joshmedeski/sesh 版权归原作者 joshmedeski 及贡献者所有
  • 收录信息:本站于 2026-10-10 收录本项目,本页所列协议与仓库指标均为收录当时的状态;该日期之后原项目的版本更新与协议变更,本页不作同步。
  • 开源协议:收录时本项目采用 MIT(查看 LICENSE 原文),本站译文为其衍生内容;使用、修改、分发请以该仓库 LICENSE 原文为准。
  • 站点出处:本文首发于 OneTwoOne,收录自 GitHub 开源项目 joshmedeski/sesh。
  • 翻译说明:本页正文为人工智能生成内容——由机器翻译对原项目 README 初译、经程序校验排版,可能存在错漏,请以原项目文档为准。
  • 引用声明:商业转载、第三方聚合或 AI 检索训练引用时,请务必保留以上来源出处、本文永久链接,以及原项目的版权声明与许可信息。
  • 下架通道:若原项目此后变更或收紧了许可协议、或作者/权利人认为本站的收录方式(译文、排版适配、简介翻译等)超出其授权范围,请通过 xyd3302001@163.com 发送下架通知,并附上项目地址与本页链接。本站核实后将第一时间删除本页内容,或改为不复制原文的目录性收录;署名更正等其他要求可一并提出。