Skip to content

Commit a847e5e

Browse files
feat(provider): normal mode keymaps for navigating messages (#151)
Co-authored-by: Nick van Dyke <nickjvandyke15@gmail.com>
1 parent 5ef1395 commit a847e5e

5 files changed

Lines changed: 68 additions & 12 deletions

File tree

README.md

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,17 @@ programs.nixvim = {
7979

8080
`opencode.nvim` replaces placeholders in prompts with the corresponding context:
8181

82-
| Placeholder | Context |
83-
| -------------- | ------------------------------------------------------------- |
84-
| `@this` | Operator range or visual selection if any, else cursor position |
85-
| `@buffer` | Current buffer |
86-
| `@buffers` | Open buffers |
87-
| `@visible` | Visible text |
88-
| `@diagnostics` | Current buffer diagnostics |
89-
| `@quickfix` | Quickfix list |
90-
| `@diff` | Git diff |
91-
| `@marks` | Global marks |
92-
| `@grapple` | [grapple.nvim](https://github.com/cbochs/grapple.nvim) tags |
82+
| Placeholder | Context |
83+
| -------------- | --------------------------------------------------------------- |
84+
| `@this` | Operator range or visual selection if any, else cursor position |
85+
| `@buffer` | Current buffer |
86+
| `@buffers` | Open buffers |
87+
| `@visible` | Visible text |
88+
| `@diagnostics` | Current buffer diagnostics |
89+
| `@quickfix` | Quickfix list |
90+
| `@diff` | Git diff |
91+
| `@marks` | Global marks |
92+
| `@grapple` | [grapple.nvim](https://github.com/cbochs/grapple.nvim) tags |
9393

9494
### Prompts
9595

@@ -244,6 +244,19 @@ vim.g.opencode_opts = {
244244

245245
Please submit PRs adding new providers! 🙂
246246

247+
#### Keymaps
248+
249+
`opencode.nvim` sets these buffer-local keymaps in provider terminals for Neovim-like message navigation:
250+
251+
| Keymap | Command | Description |
252+
| ------- | ------------------------ | ---------------------------- |
253+
| `<C-u>` | `session.half.page.up` | Scroll up half page |
254+
| `<C-d>` | `session.half.page.down` | Scroll down half page |
255+
| `<Esc>` | `session.interrupt` | Interrupt |
256+
| `gg` | `session.first` | Go to first message |
257+
| `G` | `session.last` | Go to last message |
258+
259+
247260
## 🚀 Usage
248261

249262
### ✍️ Ask — `require("opencode").ask()`

lua/opencode/config.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ local defaults = {
135135
win = {
136136
position = "right",
137137
enter = false, -- Stay in the editor after opening the terminal
138+
on_buf = function(win)
139+
require("opencode.keymaps").apply(win.buf)
140+
end,
138141
wo = {
139142
winbar = "", -- Title is unnecessary - `opencode` TUI has its own footer
140143
},

lua/opencode/keymaps.lua

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
local M = {}
2+
3+
---Apply buffer-local keymaps to the given buffer.
4+
---@param bufnr integer The buffer number to apply keymaps to.
5+
function M.apply(bufnr)
6+
local opts = { buffer = bufnr }
7+
8+
vim.keymap.set("n", "<C-u>", function()
9+
require("opencode.api.command").command("session.half.page.up")
10+
end, vim.tbl_extend("force", opts, { desc = "Scroll up half page" }))
11+
12+
vim.keymap.set("n", "<C-d>", function()
13+
require("opencode.api.command").command("session.half.page.down")
14+
end, vim.tbl_extend("force", opts, { desc = "Scroll down half page" }))
15+
16+
vim.keymap.set("n", "gg", function()
17+
require("opencode.api.command").command("session.first")
18+
end, vim.tbl_extend("force", opts, { desc = "Go to first message" }))
19+
20+
vim.keymap.set("n", "G", function()
21+
require("opencode.api.command").command("session.last")
22+
end, vim.tbl_extend("force", opts, { desc = "Go to last message" }))
23+
24+
vim.keymap.set("n", "<Esc>", function()
25+
require("opencode.api.command").command("session.interrupt")
26+
end, vim.tbl_extend("force", opts, { desc = "Interrupt current session (esc)" }))
27+
end
28+
29+
return M

lua/opencode/provider/snacks.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function Snacks.health()
2525
return "`snacks.nvim` is not available.", {
2626
"Install `snacks.nvim` and enable `snacks.terminal.`",
2727
}
28-
elseif not snacks.config.get("terminal", {}).enabled then
28+
elseif not snacks and snacks.config.get("terminal", {}).enabled then
2929
return "`snacks.terminal` is not enabled.",
3030
{
3131
"Enable `snacks.terminal` in your `snacks.nvim` configuration.",

lua/opencode/provider/terminal.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ function Terminal:start()
6363
end,
6464
})
6565

66+
-- because jobsttart runs with term=true neovim converts the created buffer
67+
-- into a terminal buffer which resets the keymap so we have to wait until the buffer
68+
-- will become a terminal to apply our local keymaps
69+
vim.api.nvim_create_autocmd("TermOpen", {
70+
buffer = self.bufnr,
71+
once = true,
72+
callback = function(event)
73+
require("opencode.keymaps").apply(event.buf)
74+
end,
75+
})
76+
6677
vim.fn.jobstart(self.cmd, {
6778
term = true,
6879
on_exit = function()

0 commit comments

Comments
 (0)