Skip to content

Commit e2ceb24

Browse files
committed
feat(nvim): add Neovim integration for Diffium
1 parent 90acf2f commit e2ceb24

3 files changed

Lines changed: 227 additions & 0 deletions

File tree

nvim-plugin/README.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Diffium Neovim Plugin
2+
3+
A Neovim plugin that integrates [Diffium](https://github.com/interpretive-systems/diffium), a diff-first TUI for git changes, directly into your editor via a floating terminal window.
4+
5+
## ✨ Features
6+
7+
- Launch Diffium's interactive TUI in a floating window without leaving Neovim
8+
- Default `:Diffium` command to start watching git changes
9+
- Customizable keymap (default: `<C-d>`) for quick access
10+
- Pass arguments to the `diffium` command for advanced usage
11+
- Lightweight Lua-based plugin with minimal dependencies
12+
- Automatic error handling and notifications
13+
14+
## 📋 Prerequisites
15+
16+
- **Neovim** >= 0.5.0 (with Lua support)
17+
- **Diffium** binary installed and available in your `PATH`
18+
- **Git** repository (Diffium requires a git repo to function)
19+
20+
### Installing Diffium
21+
22+
Before using this plugin, you need to install the Diffium CLI tool:
23+
24+
1. Clone the main repository: `git clone https://github.com/interpretive-systems/diffium`
25+
2. Build and install: `cd diffium && go build -o diffium ./cmd/diffium && sudo mv diffium /usr/local/bin/` (or add to your PATH)
26+
27+
For detailed installation instructions, see the [main Diffium README](https://github.com/interpretive-systems/diffium).
28+
29+
## 🧩 Installation
30+
31+
### Manual Installation
32+
33+
Since this plugin is part of the main Diffium repository, install it manually:
34+
35+
1. Clone the Diffium repository: `git clone https://github.com/interpretive-systems/diffium`
36+
2. Copy the plugin files to your Neovim config:
37+
```bash
38+
cp -r diffium/nvim-plugin/lua ~/.config/nvim/lua/
39+
cp -r diffium/nvim-plugin/plugin ~/.config/nvim/plugin/
40+
```
41+
3. Alternatively, create symlinks:
42+
```bash
43+
ln -s $(pwd)/diffium/nvim-plugin/lua ~/.config/nvim/lua/diffium
44+
ln -s $(pwd)/diffium/nvim-plugin/plugin/diffium.vim ~/.config/nvim/plugin/diffium.vim
45+
```
46+
4. Restart Neovim or run `:source ~/.config/nvim/init.lua`
47+
48+
### Plugin Managers
49+
50+
This plugin is not currently published as a separate package. For plugin manager support, you would need to host it as a separate repository. The manual installation above is the recommended approach.
51+
52+
## 🧠 Usage
53+
54+
### Basic Usage
55+
56+
1. Open Neovim in a git repository
57+
2. Run `:Diffium` to launch the Diffium TUI in a floating window
58+
3. Use Diffium's keyboard shortcuts to navigate and interact with your git changes
59+
4. Press `q` in the floating window to close Diffium and return to Neovim
60+
61+
### Command Reference
62+
63+
- `:Diffium` - Launch Diffium with default `watch` command
64+
- `:Diffium <args>` - Launch Diffium with custom arguments (e.g., `:Diffium --repo /path/to/repo`)
65+
66+
### Keybindings
67+
68+
- `<C-d>` - Quick launch Diffium (customizable)
69+
70+
### Diffium TUI Controls
71+
72+
Once launched, use these keys in the floating window:
73+
74+
- `j/k` or arrows: Navigate file list
75+
- `s`: Toggle side-by-side vs inline diff view
76+
- `c`: Open commit flow
77+
- `r`: Refresh changes
78+
- `q`: Quit Diffium
79+
80+
For complete controls, see the [main Diffium documentation](https://github.com/interpretive-systems/diffium).
81+
82+
## ⚙️ Configuration
83+
84+
The plugin can be configured during setup. Add this to your `init.lua`:
85+
86+
```lua
87+
require('diffium').setup({
88+
command = "Diffium", -- Custom command name (default: "Diffium")
89+
keymap = "<C-d>", -- Custom keymap (default: "<C-d>", set to "" to disable)
90+
})
91+
```
92+
93+
Example with custom settings:
94+
95+
```lua
96+
require('diffium').setup({
97+
command = "MyDiff",
98+
keymap = "<leader>d",
99+
})
100+
```
101+
102+
## ❓ FAQ
103+
104+
### Q: "diffium binary not found in PATH" error
105+
106+
**A:** The Diffium CLI tool must be installed and accessible in your system's PATH. Follow these steps:
107+
108+
1. Ensure you have Go installed (`go version`)
109+
2. Clone the Diffium repository: `git clone https://github.com/interpretive-systems/diffium`
110+
3. Build the binary: `cd diffium && go build -o diffium ./cmd/diffium`
111+
4. Move to a directory in your PATH: `sudo mv diffium /usr/local/bin/` (or `~/bin/` if you have it in PATH)
112+
5. Verify: `diffium --help` should work in your terminal
113+
6. Restart Neovim and try again
114+
115+
### Q: The floating window doesn't appear
116+
117+
**A:** Ensure you're in a git repository. Diffium requires a valid git repo to function. Check with `git status` in the directory.
118+
119+
### Q: How do I change the floating window size?
120+
121+
**A:** The window size is calculated as 90% of your Neovim's dimensions. This is currently not configurable but may be added in future versions.
122+
123+
### Q: Can I use this with non-git repositories?
124+
125+
**A:** No, Diffium is specifically designed for git repositories and will not work in non-git directories.
126+
127+
## 🤝 Contributing
128+
129+
Contributions are welcome! Please see the [main Diffium repository](https://github.com/interpretive-systems/diffium) for contribution guidelines.
130+
131+
## 📄 License
132+
133+
This plugin is part of the Diffium project and follows the same license. See [LICENSE](https://github.com/interpretive-systems/diffium/blob/main/LICENSE) in the main repository.

nvim-plugin/lua/diffium.lua

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
-- Neovim plugin integration for Diffium CLI
2+
local M = {}
3+
4+
-- Find diffium binary in PATH
5+
local function find_diffium()
6+
local path = vim.fn.exepath("diffium")
7+
if path == "" then
8+
vim.notify("[Diffium.nvim] diffium binary not found in PATH.", vim.log.levels.ERROR)
9+
return nil
10+
end
11+
return path
12+
end
13+
14+
-- Create floating terminal for Diffium
15+
local function open_floating_term(cmd)
16+
local buf = vim.api.nvim_create_buf(false, true)
17+
local width = math.floor(vim.o.columns * 0.9)
18+
local height = math.floor(vim.o.lines * 0.9)
19+
local row = math.floor((vim.o.lines - height) / 2)
20+
local col = math.floor((vim.o.columns - width) / 2)
21+
22+
local win = vim.api.nvim_open_win(buf, true, {
23+
relative = "editor",
24+
width = width,
25+
height = height,
26+
row = row,
27+
col = col,
28+
style = "minimal",
29+
border = "rounded",
30+
})
31+
32+
vim.fn.termopen(cmd, {
33+
on_exit = function(_, code)
34+
if code ~= 0 then
35+
vim.notify(string.format("[Diffium.nvim] exited with code %d", code), vim.log.levels.WARN)
36+
end
37+
if vim.api.nvim_buf_is_valid(buf) then
38+
vim.api.nvim_buf_delete(buf, { force = true })
39+
end
40+
end,
41+
})
42+
43+
vim.cmd("startinsert")
44+
return win
45+
end
46+
47+
--- Public entrypoint: open Diffium inside Neovim
48+
-- @param args table|nil Optional CLI args for Diffium
49+
function M.open(args)
50+
local diffium = find_diffium()
51+
if not diffium then return end
52+
53+
local cmd = { diffium }
54+
if args and #args > 0 then
55+
vim.list_extend(cmd, args)
56+
else
57+
table.insert(cmd, "watch") -- default subcommand
58+
end
59+
60+
local joined_cmd = table.concat(cmd, " ")
61+
open_floating_term(joined_cmd)
62+
end
63+
64+
--- Setup function for configuration
65+
-- @param opts table { command="Diffium", keymap="<C-d>" }
66+
function M.setup(opts)
67+
opts = opts or {}
68+
local cmd_name = opts.command or "Diffium"
69+
local keymap = opts.keymap or "<C-d>"
70+
71+
vim.api.nvim_create_user_command(cmd_name, function(params)
72+
M.open(params.fargs)
73+
end, { nargs = "*" })
74+
75+
if keymap and keymap ~= "" then
76+
vim.keymap.set("n", keymap, string.format(":%s<CR>", cmd_name),
77+
{ noremap = true, silent = true, desc = "Open Diffium" })
78+
end
79+
end
80+
81+
return M

nvim-plugin/plugin/diffium.vim

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
" Initializes Diffium Neovim integration
2+
3+
if exists('g:loaded_diffium_plugin')
4+
finish
5+
endif
6+
let g:loaded_diffium_plugin = 1
7+
8+
lua << EOF
9+
require('diffium').setup({
10+
command = "Diffium",
11+
keymap = "<C-d>", -- customize if desired
12+
})
13+
EOF

0 commit comments

Comments
 (0)