A simple project switcher for Kakoune
A simple project switcher for Kakoune
为 Kakoune 开发一个简单的项目切换器
Posted on 31st May 2026 in Editing, Kakoune 发布于 2026 年 5 月 31 日,归类于 Editing, Kakoune
I always appreciate a project-switching interface in my editor. I didn’t expect Kakoune, a barebones terminal editor, to have a built-in project switcher. But, after executing cd $project_dir; kak for the nth time, I started looking for a solution.
我一直很欣赏编辑器中自带的项目切换界面。我本没指望 Kakoune 这种极简的终端编辑器会内置项目切换器。但在第 N 次执行 cd $project_dir; kak 后,我开始寻找解决方案。
How other editors implement a project switcher
其他编辑器如何实现项目切换器
VS Code provides a project switcher through “Open Recent” action, bound to Ctrl + R on Linux. In my experience, any file or folder opened with VS Code’s “Open File” or “Open Folder” dialogs show up here. So it’s a bit of a stretch to call it a project switcher if you frequently open files directly.
VS Code 通过“打开最近项目”(Open Recent)功能提供项目切换,在 Linux 上绑定为 Ctrl + R。根据我的经验,任何通过 VS Code 的“打开文件”或“打开文件夹”对话框打开的内容都会出现在这里。因此,如果你经常直接打开单个文件,将其称为“项目切换器”其实有些牵强。
JetBrains IDEs offer an unbounded “Open Recent Project” action, which opens the switcher at the tip of the cursor, though I use a FrameSwitcher plugin which performs the job better. JetBrains 系列 IDE 提供了一个无限制的“打开最近项目”操作,它会在光标处打开切换器,不过我更喜欢使用 FrameSwitcher 插件,它的表现更好。
Elements of a project switcher
项目切换器的要素
I identify two essential elements of a project switcher interface: 我认为项目切换器界面有两个核心要素:
-
Display a list of projects already registered with the interface, through which one can fuzzy find and switch to a project. Once switched, the selected project’s directory becomes the current directory within the editor’s context, so that editor actions happen in the selected project directory’s context. So, for instance, a file finder would now look for a file within the selected project’s directory. And so on.
-
显示已注册的项目列表:用户可以通过该列表进行模糊搜索并切换到特定项目。切换后,所选项目的目录将成为编辑器上下文中的当前目录,从而确保后续的编辑器操作都在该项目目录下进行。例如,文件查找器现在会在所选项目目录内搜索文件,以此类推。
-
Add a new project to the interface. Usually this is automatic. When user opens a new project in JetBrains IDEs or VS Code, the editor automatically registers the project to the switcher interface.
-
向界面添加新项目:通常这是自动完成的。当用户在 JetBrains IDE 或 VS Code 中打开新项目时,编辑器会自动将该项目注册到切换器界面中。
How I manifested the elements in Kakoune
我如何在 Kakoune 中实现这些要素
Kakoune’s scripting primitives, combined with its philosophy to use shell scripting to extend itself, were adequate tools to build a simple project switcher. I needed a place to persistently register opened project directories in Kakoune. I chose a plaintext projects file that sits besides kakoune’s config file ~/.config/kak/kakrc. Each line in projects stores a path to a project dir.
Kakoune 的脚本原语,结合其利用 Shell 脚本进行扩展的哲学,为构建简单的项目切换器提供了充足的工具。我需要一个地方来持久化存储已打开的项目目录。我选择在 Kakoune 的配置文件 ~/.config/kak/kakrc 旁边创建一个纯文本的 projects 文件,每一行存储一个项目目录的路径。
Registering a new project with the interface
向界面注册新项目
I wrote a Kakoune command :project-add that:
我编写了一个 Kakoune 命令 :project-add,它可以:
- lets user choose a directory from their filesystem, using Kakoune’s path completion interface
- appends the path of the chosen directory in
projectsfile - uses Kakoune’s
:change-directoryprimitive to set the chosen directory as Kakoune’s working directory - 允许用户使用 Kakoune 的路径补全界面从文件系统中选择目录
- 将所选目录的路径追加到
projects文件中 - 使用 Kakoune 的
:change-directory原语将所选目录设置为当前工作目录
Here is the implementation: 实现如下:
define-command project-add \
-docstring "Add a project" \
-params 1 %{
nop %sh{ printf "%s\n" "$1" >> ~/.config/kak/projects }
change-directory %arg{1}
exec ":file-picker "
}
complete-command project-add file
Switching to a registered project
切换到已注册的项目
I implemented a Kakoune command :project-pick that:
我实现了一个 Kakoune 命令 :project-pick,它可以:
- lists the paths stored in
projectsfile using Kakoune’s completion interface. The completion interface also sorts and excludes duplicate entries. - sets the working directory of Kakoune to the selected path using its
:change-directoryprimitive - 使用 Kakoune 的补全界面列出
projects文件中存储的路径(补全界面会自动排序并排除重复项) - 使用
:change-directory原语将 Kakoune 的工作目录设置为所选路径
Here is the implementation: 实现如下:
define-command project-pick \
-docstring "Pick a project" \
-params 1 %{
change-directory %arg{1}
exec ":file-picker "
}
complete-command project-pick \
shell-script-candidates \
%{ cat ~/.config/kak/projects | sort | uniq }
Bonus - file picker
额外福利 - 文件选择器
Both :project-add and :project-pick commands land the user on a file picker interface, which again builds on top of Kakoune’s completion interface, so that they can start working right away on their project.
:project-add 和 :project-pick 命令执行后都会进入文件选择界面,该界面同样基于 Kakoune 的补全功能构建,让用户可以立即开始项目工作。
define-command file-picker \
-docstring "Pick a file from current directory" \
-params 1 %{
edit %arg{1}
}
complete-command file-picker \
shell-script-candidates \
%{ git ls-files -c -o --exclude-standard }
Bonus - keybindings
额外福利 - 快捷键
Both the commands received their own keybindings for quick execution. Kakoune offers custom user modes which can act as namespaces to neatly tuck away related keybindings. I created a project user mode to do just that for my project switcher.
这两个命令都分配了快捷键以便快速执行。Kakoune 提供了自定义用户模式(user modes),可以作为命名空间来整齐地组织相关快捷键。我为此创建了一个 project 用户模式。
# Define project user mode
# 定义 project 用户模式
declare-user-mode project
map global project p ":project-pick " -docstring "Pick a project"
map global project a ":project-add " -docstring "Add a project"
# Now tie up project mode to the global user mode
# so that project mode becomes a submode to the
# global user mode
# 将 project 模式绑定到全局用户模式,使其成为子模式
map global user p ":enter-user-mode project<ret>" -docstring "Project commands"
Now, Space + p + a triggers :project-add, while Space + p + p triggers :project-pick.
现在,Space + p + a 触发 :project-add,而 Space + p + p 触发 :project-pick。
In closing
结语
The video snippet below showcases the final result. I apologise for a cropped Kakoune’s modeline in the video. I don’t know why that happened, and I can’t be bothered with making another video since the cropped modeline is still comprehensible. I could implement guardrails like checking for existence of the projects file, or add a :project-delete command, but I’m satisfied with the current state. Any comments are welcome.
下方的视频片段展示了最终效果。视频中 Kakoune 的状态栏(modeline)被裁剪了,对此我深表歉意。我不知道原因,也不想重录视频,因为被裁剪的状态栏依然清晰可辨。我本可以实现一些保护措施,比如检查 projects 文件是否存在,或者添加 :project-delete 命令,但我对目前的状态很满意。欢迎提出任何建议。
Written by Jayesh Bhoot 作者:Jayesh Bhoot