https://github.com/karshPrime/switchboard.nvim
same keybinds, different commands depending on file type or project
https://github.com/karshPrime/switchboard.nvim
build-tools neovim neovim-plugin tmux
Last synced: 28 days ago
JSON representation
same keybinds, different commands depending on file type or project
- Host: GitHub
- URL: https://github.com/karshPrime/switchboard.nvim
- Owner: karshPrime
- License: apache-2.0
- Created: 2024-05-19T14:31:19.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2026-06-07T03:12:53.000Z (about 1 month ago)
- Last Synced: 2026-06-07T05:06:31.193Z (about 1 month ago)
- Topics: build-tools, neovim, neovim-plugin, tmux
- Language: Lua
- Homepage:
- Size: 9.05 MB
- Stars: 30
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-neovim - karshPrime/switchboard.nvim - Define "run", "build", or any custom command/bind per language or project, then use the same keybinds everywhere. (Project / Assembly)
README
# switchboard.nvim
Switchboard lets you run project commands without leaving Neovim. It picks the right command based on the file or project and runs it in a split, floating window, or tmux.
It’s designed so the same keybinds work across different languages and projects.
### What it does
* Runs commands in splits, floating windows, or tmux
* Supports project-aware editor actions (dynamic vim keybinds)
* Chooses commands based on file type or project
* Falls back to `:term` if tmux isn’t available
* Lets you define your own commands (build, run, or anything else)
* Supports local project-specific overrides
## Installation
Using the built-in package manager (Neovim 0.12+):
```lua
vim.pack.add({
'https://github.com/karshPrime/switchboard.nvim',
})
```
## Basic idea
You define what “run”, “build”, or any editor action means per language or project:
```lua
require('switchboard').setup({
commands = {
lazygit = "lazygit",
},
build_run_config = {{
extension = {'py'},
commands = {
run = 'uv run main',
build = 'uv run pyinstaller bin ./*/__main__.py',
},
binds = {
divide = 'I#79A=o',
import = 'Iimport ',
}
},{
extension = {'c', 'cpp', 'h'},
cd_root = true,
commands = {
run = 'make run',
build = 'make',
debug = 'gdb ./bin',
},
binds = {
divide = 'I//78A=o',
import = 'I#include ',
}
}}
})
```
Then you bind keys once, and reuse them everywhere:
```lua
-- Commands:
vim.keymap.set('n', '', ':Switchboard split run', { silent = true })
vim.keymap.set('n', '', ':Switchboard vsplit debug', { silent = true }) -- works only for C/C++ projects
vim.keymap.set('n', '', ':Switchboard quickfix build', { silent = true }) -- :make extended
vim.keymap.set('n', 'g', ':Switchboard overlay lazygit', { silent = true }) -- works for all projects
-- Keybinds:
vim.keymap.set('n', 'id', ':Switchboard bind divide', { silent = true })
vim.keymap.set({'n','i'}, 'ii', ':Switchboard bind import', { silent = true })
-- Append before :Switchboard for insert mode maps
```
Switchboard handles the rest.
## Usage
### Commands
```vim
:Switchboard
```
Modes:
* `overlay` – floating window overlay
* `split` – opens a horizontal split
* `vsplit` – opens a vertical split
* `background` – background tmux window (or background term buffer)
* `quickfix` - run the command in quickfix mode and `:copen`
Commands come from:
* global neovim config
* file type config - in neovim config
* project overrides - in project root
So `run` in a Python project can mean something completely different from `run` in Rust.
### Binds
```vim
:Switchboard bind
```
Binds run configured editor actions. For example, divide can insert a Python-style divider in Python files and a C-style divider in C files.
## Example config
```lua
require('switchboard').setup({
-- General settings (optional)
save_session = false, -- Save files before executing
build_run_window_title = "build", -- Tmux window name
notify_missing_project_config = false,
local_config = ".switchboard-config",
-- Window sizing (optional)
new_pane_everytime = false,
side_width_percent = 50,
bottom_height_percent = 30,
overlay_width_percent = 80,
overlay_height_percent = 80,
overlay_sleep = -1, -- -1 = no auto-close
build_run_config = {{
...
}},
-- Override individual projects configs
-- Example: for zephyr projects, use zephyr to build instead of set C/C++ configs
project_override_config = {{
project_base_dir = '~/Projects/MyProject',
commands = {
build = 'west build',
}
}}
})
```
Alternatively, have a look at [my personal config](https://github.com/karshPrime/dotfiles/blob/main/nvim/lua/plugins/tmux.lua).
## Project-specific config
You can override commands per project by adding a file at the root:
```lua
-- .switchboard-config
return {
cd_root = true,
commands = {
run = 'npm start',
build = 'npm run build',
test = 'npm test',
},
binds = {
import = 'ggOimport ',
}
}
```
**In short:** define commands and editor actions once, use the same keybinds everywhere, and let Switchboard adapt to the project you’re in.