Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions nvim-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Diffium Neovim Plugin

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.

## ✨ Features

- Launch Diffium's interactive TUI in a floating window without leaving Neovim
- Default `:Diffium` command to start watching git changes
- Customizable keymap (default: `<C-d>`) for quick access
- Pass arguments to the `diffium` command for advanced usage
- Lightweight Lua-based plugin with minimal dependencies
- Automatic error handling and notifications

## 📋 Prerequisites

- **Neovim** >= 0.5.0 (with Lua support)
- **Diffium** binary installed and available in your `PATH`
- **Git** repository (Diffium requires a git repo to function)

### Installing Diffium

Before using this plugin, you need to install the Diffium CLI tool:

1. Clone the main repository: `git clone https://github.com/interpretive-systems/diffium`
2. Build and install: `cd diffium && go build -o diffium ./cmd/diffium && sudo mv diffium /usr/local/bin/` (or add to your PATH)

For detailed installation instructions, see the [main Diffium README](https://github.com/interpretive-systems/diffium).

## 🧩 Installation

### Manual Installation

Since this plugin is part of the main Diffium repository, install it manually:

1. Clone the Diffium repository: `git clone https://github.com/interpretive-systems/diffium`
2. Copy the plugin files to your Neovim config:
```bash
cp -r diffium/nvim-plugin/lua ~/.config/nvim/lua/
cp -r diffium/nvim-plugin/plugin ~/.config/nvim/plugin/
```
3. Alternatively, create symlinks:
```bash
ln -s $(pwd)/diffium/nvim-plugin/lua ~/.config/nvim/lua/diffium
ln -s $(pwd)/diffium/nvim-plugin/plugin/diffium.vim ~/.config/nvim/plugin/diffium.vim
```
4. Restart Neovim or run `:source ~/.config/nvim/init.lua`

### Plugin Managers

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.

## 🧠 Usage

### Basic Usage

1. Open Neovim in a git repository
2. Run `:Diffium` to launch the Diffium TUI in a floating window
3. Use Diffium's keyboard shortcuts to navigate and interact with your git changes
4. Press `q` in the floating window to close Diffium and return to Neovim

### Command Reference

- `:Diffium` - Launch Diffium with default `watch` command
- `:Diffium <args>` - Launch Diffium with custom arguments (e.g., `:Diffium --repo /path/to/repo`)

### Keybindings

- `<C-d>` - Quick launch Diffium (customizable)

### Diffium TUI Controls

Once launched, use these keys in the floating window:

- `j/k` or arrows: Navigate file list
- `s`: Toggle side-by-side vs inline diff view
- `c`: Open commit flow
- `r`: Refresh changes
- `q`: Quit Diffium

For complete controls, see the [main Diffium documentation](https://github.com/interpretive-systems/diffium).

## ⚙️ Configuration

The plugin can be configured during setup. Add this to your `init.lua`:

```lua
require('diffium').setup({
command = "Diffium", -- Custom command name (default: "Diffium")
keymap = "<C-d>", -- Custom keymap (default: "<C-d>", set to "" to disable)
})
```

Example with custom settings:

```lua
require('diffium').setup({
command = "MyDiff",
keymap = "<leader>d",
})
```

## ❓ FAQ

### Q: "diffium binary not found in PATH" error

**A:** The Diffium CLI tool must be installed and accessible in your system's PATH. Follow these steps:

1. Ensure you have Go installed (`go version`)
2. Clone the Diffium repository: `git clone https://github.com/interpretive-systems/diffium`
3. Build the binary: `cd diffium && go build -o diffium ./cmd/diffium`
4. Move to a directory in your PATH: `sudo mv diffium /usr/local/bin/` (or `~/bin/` if you have it in PATH)
5. Verify: `diffium --help` should work in your terminal
6. Restart Neovim and try again

### Q: The floating window doesn't appear

**A:** Ensure you're in a git repository. Diffium requires a valid git repo to function. Check with `git status` in the directory.

### Q: How do I change the floating window size?

**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.

### Q: Can I use this with non-git repositories?

**A:** No, Diffium is specifically designed for git repositories and will not work in non-git directories.

## 🤝 Contributing

Contributions are welcome! Please see the [main Diffium repository](https://github.com/interpretive-systems/diffium) for contribution guidelines.

## 📄 License

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.
94 changes: 94 additions & 0 deletions nvim-plugin/lua/diffium.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
-- Neovim plugin integration for Diffium CLI
local M = {}

-- Find diffium binary in PATH
local function find_diffium()
local path = vim.fn.exepath("diffium")
if path == "" then
vim.notify("[Diffium.nvim] diffium binary not found in PATH.", vim.log.levels.ERROR)
return nil
end
return path
end

-- Create floating terminal for Diffium
local function open_floating_term(cmd, opts)
local buf = vim.api.nvim_create_buf(false, true)
local width = math.floor(vim.o.columns * 0.9)
local height = math.floor(vim.o.lines * 0.9)
local row = math.floor((vim.o.lines - height) / 2)
local col = math.floor((vim.o.columns - width) / 2)

local ok, win = pcall(vim.api.nvim_open_win, buf, true, {
relative = "editor",
width = width,
height = height,
row = row,
col = col,
style = "minimal",
border = "rounded",
})

if not ok then
vim.cmd("terminal " .. cmd)
vim.notify("[Diffium.nvim] Floating windows not supported, opened in split.", vim.log.levels.INFO)
return
end

vim.fn.termopen(cmd, {
on_exit = function(_, code)
vim.schedule(function()
if code ~= 0 then
vim.notify(string.format("[Diffium.nvim] exited with code %d", code), vim.log.levels.WARN)
end
if opts.auto_close ~= false then
if vim.api.nvim_buf_is_valid(buf) then
vim.api.nvim_buf_delete(buf, { force = true })
end
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_win_close(win, true)
end
end
vim.cmd("stopinsert")
end)
end,
})

vim.cmd("startinsert")
end

--- Public entrypoint: open Diffium inside Neovim
-- @param args table|nil Optional CLI args for Diffium
function M.open(args)
local diffium = find_diffium()
if not diffium then return end

local cmd = { diffium }
if args and #args > 0 then
vim.list_extend(cmd, args)
else
table.insert(cmd, "watch") -- default subcommand
end

local joined_cmd = vim.fn.join(cmd, " ")
open_floating_term(joined_cmd, M.opts or {})
end

--- Setup function for configuration
-- @param opts table { command="Diffium", keymap="<C-d>", auto_close=true }
function M.setup(opts)
M.opts = opts or {}
local cmd_name = M.opts.command or "Diffium"
local keymap = M.opts.keymap or "<C-d>"

vim.api.nvim_create_user_command(cmd_name, function(params)
M.open(params.fargs)
end, { nargs = "*" })

if keymap and keymap ~= "" then
vim.keymap.set("n", keymap, string.format(":%s<CR>", cmd_name),
{ noremap = true, silent = true, desc = "Open Diffium" })
end
end

return M
13 changes: 13 additions & 0 deletions nvim-plugin/plugin/diffium.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
" Initializes Diffium Neovim integration

if exists('g:loaded_diffium_plugin')
finish
endif
let g:loaded_diffium_plugin = 1

lua << EOF
require('diffium').setup({
command = "Diffium",
keymap = "<C-d>", -- customize if desired
})
EOF