diff --git a/nvim-plugin/README.md b/nvim-plugin/README.md new file mode 100644 index 0000000..57f0285 --- /dev/null +++ b/nvim-plugin/README.md @@ -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: ``) 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 ` - Launch Diffium with custom arguments (e.g., `:Diffium --repo /path/to/repo`) + +### Keybindings + +- `` - 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 = "", -- Custom keymap (default: "", set to "" to disable) +}) +``` + +Example with custom settings: + +```lua +require('diffium').setup({ + command = "MyDiff", + keymap = "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. diff --git a/nvim-plugin/lua/diffium.lua b/nvim-plugin/lua/diffium.lua new file mode 100644 index 0000000..06b566a --- /dev/null +++ b/nvim-plugin/lua/diffium.lua @@ -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="", 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 "" + + 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", cmd_name), + { noremap = true, silent = true, desc = "Open Diffium" }) + end +end + +return M diff --git a/nvim-plugin/plugin/diffium.vim b/nvim-plugin/plugin/diffium.vim new file mode 100644 index 0000000..fdbf0fe --- /dev/null +++ b/nvim-plugin/plugin/diffium.vim @@ -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 = "", -- customize if desired +}) +EOF