Xuz 5b6eee0b71 新增设置:外观(界面语言、应用外观)与终端字体配置,最近连接支持右键菜单
- 会话列表底部新增「设置」按钮(⌘, / Ctrl+,),在中间区打开单例的「设置」标签页
- 设置页用 gpui-kit 的 Settings 组件分两栏:左边分类(外观、终端,可搜索),右边设置分组
- 设置写穿到数据目录的 settings.json,写失败或读不出时弹通知;由工作区统一应用到窗口
- 外观 → 常规:界面语言(跟随系统 / 简体中文 / English,目前只切换 gpui-kit 自带文案)、应用外观(深色 / 浅色 / 跟随系统,随系统切换);标题栏主题按钮改为写这一项
- 终端 → 字体配置:字体(仅列出已安装的等宽字体,后台扫描)、字号、行高,默认值与原来一致,立即作用于已打开的终端;下方按终端排法预览数字、符号和中文
- 最近连接列表的主机支持右键菜单,与会话树共用同一个会话菜单
2026-09-25 10:00:20 +08:00
2026-09-12 09:33:59 +08:00
2026-09-12 09:33:59 +08:00
2026-09-11 20:41:07 +08:00
2026-09-11 20:41:07 +08:00
2026-09-12 09:33:59 +08:00

shellr

基于 GPUI Kit 的中文 SSH 会话管理工具,提供持久化会话与分组、本地终端、SSH 多终端和对标 WinSCP 的 SFTP 双栏浏览器。

会话列表

右键主机可连接、打开 SFTP、编辑、复制或删除。没有打开任何标签时,中间区显示「最近连接」列表,双击或回车连接;右键其中的主机弹出同一个菜单,并选中该主机。

拖动分组或主机到同类项目的上侧 / 下侧可调整同级顺序;主机拖到分组会移入该分组,分组拖到另一个分组的中部会成为子分组。拖到列表空白处可移回根层级。分组始终排在同级主机之前,顺序与分组的展开状态会保存到本地数据库。搜索时暂停拖动排序。

设置

会话列表最下方的「设置」按钮(或 ⌘,,其他平台 Ctrl+,)在中间区打开「设置」标签页;已经打开时切换到该标签,不会重复打开。设置页分两栏:左边是分类(外观、终端),上方可搜索,栏宽可拖动;右边是所选分类的设置。设置改动立即生效并保存在数据目录的 settings.json 里。

  • 外观 → 常规 → 界面语言:跟随系统、简体中文、English,默认简体中文。英文界面尚在翻译中,目前只有 GPUI Kit 组件自带的文字(如搜索框提示)会切换。
  • 外观 → 常规 → 应用外观:深色、浅色、跟随系统,默认跟随系统;选「跟随系统」时随系统的深浅色切换。标题栏的主题按钮也会改写这一项。
  • 终端 → 字体配置:字体(只列出本机安装的等宽字体,默认是系统的等宽字体,macOS 上为 Menlo)、字号(8–32 像素,默认 13)、行高(字号的 1.0–2.0 倍,默认 1.54,即原来的 20 像素行高)。改动立即作用于所有已打开的终端。下方的预览按终端的排法显示字母、数字、易混字符、符号、中文、制表符和一行命令。设置文件里的字体在本机没有安装时,使用默认字体。

标签页

远程终端标签和 SFTP 标签都以主机系统徽章为图标(与会话列表相同)。右键标签可重命名(仅本次运行有效,留空恢复为会话名称,用于区分同一台主机的多个连接)、在新标签页中连接、打开 SFTP、复制 IP 地址 / 主机名、重新连接、编辑会话,以及关闭当前、左侧、右侧、其他或全部标签。SFTP 标签的菜单是「重命名标签…」(留空恢复为「会话名称 · SFTP」)加关闭命令,本地终端标签是「重新启动」加关闭命令。标签栏右侧「…」按钮的菜单与当前标签的右键菜单相同。远程终端运行时,标签栏右侧显示这条 SSH 连接的往返延迟,每 5 秒更新一次:低于 100 ms 为绿色,100–200 ms 为黄色,高于 200 ms 或超时为红色。批量关闭时,正在上传的 SFTP 标签仍会先确认。

终端

右键终端内容区可复制、粘贴、查找、清屏;远程终端另有打开 SFTP、重新连接和断开连接。断开连接只断开这一个标签,标签保留,可随时重新连接,同一会话的其他标签和 SFTP 不受影响。

  • 查找(⌘F,其他平台 Ctrl+Shift+F):在终端右上角打开查找条,按字面量搜索屏幕和回滚历史。查询全为小写时不区分大小写,含大写字母时区分。所有匹配高亮显示,当前项颜色更深,查找条显示「当前项/总数」。回车或 ⌘G(F3)跳到下一项(更新的输出),Shift+回车或 ⌘⇧G(Shift+F3)跳到上一项(更早的输出),到头后循环。Esc 关闭。打开时如有选中文字,会作为查询词。
  • 清屏(⌘K,其他平台 Ctrl+Shift+K;焦点不在终端时 ⌘K 仍是聚焦会话搜索):清掉屏幕和回滚历史,只留下光标所在的提示符行,包括已输入但未回车的内容。清屏只在本地进行,不向服务器发送任何内容。vim、top 等全屏程序运行时不可用。

SFTP

打开会话的「SFTP」标签即可浏览本地与远程目录;和终端一样,每次「打开 SFTP」都新开一个标签,同一会话可以开多个,各自独立连接、各看各的目录。操作方式对标 WinSCP Commander。SFTP 使用独立 SSH 连接,仅请求 SFTP 子系统,不要求服务器提供 Shell;关闭终端不会中止传输。

工具栏

每一侧面板都有两行工具栏,下方是路径标签:

  • 第一行(导航):
    • 「目录列表」:列出从根到当前目录的每一级,本地另有主目录、桌面、文稿、下载,选中即前往。
    • 书签:点按钮打开「打开目录/书签」(见下);旁边的下拉箭头列出本会话这一侧的书签,点击即前往,也可添加或移除当前路径。书签保存在本地数据库,删除会话时一并删除。
    • 上级目录、根目录、主目录、刷新、后退、前进。
  • 第二行(文件):
    • 远程是「下载…」,本地是「上传…」,下拉里还有「选择文件上传…」。
    • 删除、重命名…、属性…、新建(文件夹… / 文件…)。

路径标签

与 WinSCP 的路径标签相同:

  • 显示当前目录的完整路径,例如 /home/tester/。
  • 每一级都可以点:悬停时从根到该级高亮,单击即前往。
  • 当前使用的一侧(最近点过的一侧)底部有一条深蓝色线。
  • 路径放不下时保留根目录和末尾几级,中间折成 …,点 … 前往被折叠的最后一级。
  • 单击当前目录、双击路径右侧空白处打开「打开目录/书签」。
  • 右键:前往、刷新、添加路径到书签、复制路径、打开目录/书签…。

打开目录/书签

与 WinSCP 的「打开目录」对话框相同,可以从路径标签、书签按钮、⌘O(其他平台 Ctrl+O;macOS 另有 ⌘⇧G)或路径标签的右键菜单打开:

  • 「目录」预填当前目录并已选中,直接输入即可替换。~ 表示主目录,相对路径从当前目录算起。本地侧另有「浏览…」。
  • 下方是本会话这一侧的书签。与目录相同的书签处于选中状态;单击书签把它填入目录,双击直接打开。
  • 「添加」把目录加入书签,「删除」(或在列表中按 Delete)删除选中的书签并选中相邻的一个,「上移」「下移」调整顺序。
  • 书签的改动立即保存,按「取消」也不会撤销,与 WinSCP 相同。
  • 回车或「打开」前往目录;Esc 或「取消」关闭。

远程侧断开时,原因显示在路径标签下方,旁边有「重新连接」。连接中和读取目录超过 0.3 秒时,列表下方的状态栏显示「正在连接 SFTP…」或「正在读取目录…」,列表本身不会移动。

列与 WinSCP 相同:本地为名称、大小、类型、修改时间,远程为名称、大小、修改时间、权限、所有者。

  • 大小以 KB 显示(4,008,960 KB)。
  • 时间形如 2026/4/22 12:44:53。
  • 权限形如 rwxr-xr-x。
  • 所有者来自服务器的 ls -l 行。
  • 链接到目录的符号链接显示为带箭头的文件夹,可以双击进入。

选择与右键菜单

  • 鼠标:单击选中,⌘ 单击(其他平台 Ctrl 单击)增减,Shift 单击选取范围。
  • 键盘:↑↓、Home、End、PageUp、PageDown 移动,加 Shift 扩展;空格或 Insert 切换当前行;⌘A 全选;Tab 切到另一侧。
  • 右键未选中的行会先选中它。
    • 行上的菜单:打开、上传… / 下载…、删除、重命名…、属性…。
    • 空白处的菜单:前往(上级 / 根 / 主目录 / 后退 / 前进)、刷新、添加路径到书签、新建。

快捷键

命令 快捷键
上传 / 下载(按所在面板) F5
重命名 F2
新建文件夹 F7
删除 F8、Delete;macOS 另有 ⌘⌫
属性 F9;macOS 另有 ⌘I
刷新 ⌘R / Ctrl+R
上级目录 Backspace;macOS 另有 ⌘↑
根目录 ⌘\ / Ctrl+\
主目录 macOS ⌘⇧H,其他平台 Ctrl+H
后退 / 前进 ⌥← / ⌥→;macOS 另有 ⌘[ / ⌘]
添加路径到书签 ⌘D / Ctrl+D
打开目录 Enter;macOS 另有 ⌘↓
打开目录/书签 ⌘O / Ctrl+O;macOS 另有 ⌘⇧G

文件操作

  • 删除前会确认,并写明对象和后果:
    • 本地项目移到废纸篓。
    • 远程项目永久删除,目录连同其中全部内容。
    • 删除符号链接只删除链接本身。
  • 重命名和新建:
    • 按当前列表检查名称;不能为空,不能是 . 或 ..,不能与已有项目同名。
    • 重命名不会覆盖已有项目。
  • 属性:
    • 显示位置、大小、修改时间,远程另有所有者和组。
    • 权限用 3×3 复选框和八进制数字编辑,两者同步。
    • 多选时,项目之间不一致的权限位保持原样,除非你改动它。
    • 含目录时可以递归应用;递归时默认「为目录添加执行权限(X)」,避免目录无法进入。
    • 符号链接不参与修改权限。

上传与下载

  • 入口:
    • 上传:「上传…」、本地列表中的 F5、「选择文件上传…」,或把本地项目 / Finder 中的文件拖到远程列表。
    • 下载:「下载…」、远程列表中的 F5,或把远程项目拖到本地列表。
    • 拖到目录行时放进该目录,拖到其余区域时放进当前目录。
  • 所有入口都显示确认框,可以修改目标目录;下载可以用「浏览…」选择本机目录。
  • 确认后来源、会话端点和目标即固定。每个 SFTP 标签同时运行一个批次(上传和下载共用),批内依次处理;其他 SFTP 标签、会话和终端可以继续操作。
  • 递归传输包含空目录。符号链接原样创建,不跟随。默认二进制传输,保留普通文件的修改时间。
  • 新建项使用目标一侧的默认权限,覆盖时保留目标原有的基本权限。不复制所有者、ACL 或扩展属性。
  • 同名目录合并。文件或链接冲突时询问覆盖、跳过或取消,可以应用于本批剩余冲突;目录与非目录冲突不会自动删除。
  • 出错时可以重试、跳过或取消,完成后的汇总分别列出成功、跳过和失败。

断点续传和替换

文件先写入 <目标文件名>.filepart。写入请求采用有界流水线,收到每个写入确认并关闭成功后才发布正式文件;服务器支持时先调用 fsync@openssh.com。支持 posix-rename@openssh.com 的服务器使用原子替换;其他服务器先将旧文件移到 .shellr-<UUID>.backup,再发布新文件,此兼容路径不保证原子性。发布响应丢失时根据受管理临时路径、阶段、类型和大小恢复,无法安全判断则保留恢复文件并报告。

续传记录保存在应用数据目录的 upload-resume/,采用版本化 JSON 和原子写入,不写入密码、口令或私钥,不改变会话数据库结构。记录用于绑定端点、主机指纹、来源、目标和安全替换阶段。续传方式与 WinSCP 相同:读取远端 .filepart 的当前大小,在本地文件中跳过相同长度并继续传输;使用者需确保来源仍是同一版本。上传过程不会为了校验而回读远端文件内容。

下载同样先写入本机的 <目标文件名>.filepart,完成后设置远程的修改时间、fsync,再在同一文件系统内重命名为正式文件(原子替换)。并发的读取请求可能乱序、短读返回,但临时文件严格按顺序写入,因为续传只信它的长度。下载续传记录保存在 download-resume/,绑定端点、主机指纹、远程来源及其大小与修改时间、本地目标;远程文件变化后不能续传,只能重新下载或跳过。

网络故障每批最多自动重连三次,间隔 1、3、10 秒。耗尽后使用「继续上传」或「继续下载」,手动恢复会重置次数。认证失败、主机密钥变化和主动取消需要用户处理。重连沿用原连接配置,会话编辑不会改变正在传输的目标。

取消、关闭标签、断开会话或退出时保留续传记录;关闭正在传输的标签会先确认。重启后不会自动继续,再次选择相同来源和目标时会询问续传。停止状态下可使用「丢弃续传进度」清理该批受管理的临时文件;存在无法判断的恢复备份时会保留文件并说明原因。成功发布的项目自动清理记录和备份。

文件名不能准确表示时会明确报错。当前 russh-sftp 3.0.0 的远端字符串解码会替换无效 UTF-8,浏览器因此拒绝包含替换字符 U+FFFD 的远端名称,避免访问错误路径。符号链接沿用 OpenSSH 的 SFTP v3 参数顺序。

尚未实现:目录同步、传输队列、过滤、查找文件、目录树和 Dock 布局持久化。

运行和验证

工具链固定 Rust 1.98.1,russh-sftp 固定 3.0.0;保持仓库锁定的 GPUI 与 russh 版本。

cargo run
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --check

数据目录默认是系统应用数据目录中的 shellr,可通过 SHELLR_DATA_DIR 覆盖。会话保存在 shellr.db,主机信任记录保存在该目录的 known_hosts,凭据使用系统钥匙串。

src/sftp/tests.rs 使用临时目录与故障注入覆盖上传和下载的文件内容、空目录、链接、覆盖、权限、取消、源文件变化、乱序与短读、续传及替换各阶段恢复,以及删除、重命名、新建和递归改权限不跟随链接。Unix 协议测试使用本机 OpenSSH sftp-server(macOS /usr/libexec/sftp-server,Linux /usr/lib/openssh/sftp-server);工作线程测试仅监听 127.0.0.1 的随机端口,使用测试凭据。限制本地套接字的沙箱会跳过该部分,需要在允许回环套接字的环境运行。

tests/ui.rs 驱动真实 Workspace,通过 Workspace::new_with_services 注入 SFTP、本地目录和终端服务,不连接用户服务器或真实钥匙串。Finder 的系统原生拖放仍需在真实 macOS 窗口中补充人工验收;无头测试覆盖原生文件拖入事件和面板内部拖放。

上传交互参考 WinSCP 上传流程,协议适配参考 russh-sftp 请求接口 与 OpenSSH 扩展规范。

S
Description
High-performance native SSH client in Rust, GPU-rendered with GPUI: host manager, terminal, WinSCP-style SFTP and port forwarding. Rust 编写、GPU 渲染的原生 SSH 客户端。
https://shellrs.com
Readme GPL-3.0
14 MiB
0 Stars 1 Watchers 0 Forks
ShellRS 0.1.8
Latest
2026-10-11 08:40:38 +00:00
Languages
Rust 99.8%
Shell 0.1%