diff --git a/README.md b/README.md index 95921586..966205a5 100644 --- a/README.md +++ b/README.md @@ -79,17 +79,17 @@ programs.nixvim = { `opencode.nvim` replaces placeholders in prompts with the corresponding context: -| Placeholder | Context | -| -------------- | ------------------------------------------------------------- | -| `@this` | Operator range or visual selection if any, else cursor position | -| `@buffer` | Current buffer | -| `@buffers` | Open buffers | -| `@visible` | Visible text | -| `@diagnostics` | Current buffer diagnostics | -| `@quickfix` | Quickfix list | -| `@diff` | Git diff | -| `@marks` | Global marks | -| `@grapple` | [grapple.nvim](https://github.com/cbochs/grapple.nvim) tags | +| Placeholder | Context | +| -------------- | --------------------------------------------------------------- | +| `@this` | Operator range or visual selection if any, else cursor position | +| `@buffer` | Current buffer | +| `@buffers` | Open buffers | +| `@visible` | Visible text | +| `@diagnostics` | Current buffer diagnostics | +| `@quickfix` | Quickfix list | +| `@diff` | Git diff | +| `@marks` | Global marks | +| `@grapple` | [grapple.nvim](https://github.com/cbochs/grapple.nvim) tags | ### Prompts @@ -244,6 +244,19 @@ vim.g.opencode_opts = { Please submit PRs adding new providers! 🙂 +#### Keymaps + +`opencode.nvim` sets these buffer-local keymaps in provider terminals for Neovim-like message navigation: + +| Keymap | Command | Description | +| ------- | ------------------------ | ---------------------------- | +| `` | `session.half.page.up` | Scroll up half page | +| `` | `session.half.page.down` | Scroll down half page | +| `` | `session.interrupt` | Interrupt | +| `gg` | `session.first` | Go to first message | +| `G` | `session.last` | Go to last message | + + ## 🚀 Usage ### ✍️ Ask — `require("opencode").ask()` diff --git a/lua/opencode/config.lua b/lua/opencode/config.lua index 2b1a3d78..58569704 100644 --- a/lua/opencode/config.lua +++ b/lua/opencode/config.lua @@ -134,6 +134,9 @@ local defaults = { win = { position = "right", enter = false, -- Stay in the editor after opening the terminal + on_buf = function(win) + require("opencode.keymaps").apply(win.buf) + end, wo = { winbar = "", -- Title is unnecessary - `opencode` TUI has its own footer }, diff --git a/lua/opencode/keymaps.lua b/lua/opencode/keymaps.lua new file mode 100644 index 00000000..e3971528 --- /dev/null +++ b/lua/opencode/keymaps.lua @@ -0,0 +1,29 @@ +local M = {} + +---Apply buffer-local keymaps to the given buffer. +---@param bufnr integer The buffer number to apply keymaps to. +function M.apply(bufnr) + local opts = { buffer = bufnr } + + vim.keymap.set("n", "", function() + require("opencode.api.command").command("session.half.page.up") + end, vim.tbl_extend("force", opts, { desc = "Scroll up half page" })) + + vim.keymap.set("n", "", function() + require("opencode.api.command").command("session.half.page.down") + end, vim.tbl_extend("force", opts, { desc = "Scroll down half page" })) + + vim.keymap.set("n", "gg", function() + require("opencode.api.command").command("session.first") + end, vim.tbl_extend("force", opts, { desc = "Go to first message" })) + + vim.keymap.set("n", "G", function() + require("opencode.api.command").command("session.last") + end, vim.tbl_extend("force", opts, { desc = "Go to last message" })) + + vim.keymap.set("n", "", function() + require("opencode.api.command").command("session.interrupt") + end, vim.tbl_extend("force", opts, { desc = "Interrupt current session (esc)" })) +end + +return M diff --git a/lua/opencode/provider/snacks.lua b/lua/opencode/provider/snacks.lua index af356a52..f8ab8e66 100644 --- a/lua/opencode/provider/snacks.lua +++ b/lua/opencode/provider/snacks.lua @@ -25,7 +25,7 @@ function Snacks.health() return "`snacks.nvim` is not available.", { "Install `snacks.nvim` and enable `snacks.terminal.`", } - elseif not snacks.config.get("terminal", {}).enabled then + elseif not snacks and snacks.config.get("terminal", {}).enabled then return "`snacks.terminal` is not enabled.", { "Enable `snacks.terminal` in your `snacks.nvim` configuration.", diff --git a/lua/opencode/provider/terminal.lua b/lua/opencode/provider/terminal.lua index dab7acdd..8b1b61c6 100644 --- a/lua/opencode/provider/terminal.lua +++ b/lua/opencode/provider/terminal.lua @@ -63,6 +63,17 @@ function Terminal:start() end, }) + -- because jobsttart runs with term=true neovim converts the created buffer + -- into a terminal buffer which resets the keymap so we have to wait until the buffer + -- will become a terminal to apply our local keymaps + vim.api.nvim_create_autocmd("TermOpen", { + buffer = self.bufnr, + once = true, + callback = function(event) + require("opencode.keymaps").apply(event.buf) + end, + }) + vim.fn.jobstart(self.cmd, { term = true, on_exit = function()