|
| 1 | +---`opencode.nvim` public API. |
1 | 2 | local M = {} |
2 | 3 |
|
3 | | ----@param callback fun(port: number) |
4 | | -local function get_port(callback) |
5 | | - require("opencode.cli.server").get_port(function(ok, result) |
6 | | - if ok then |
7 | | - callback(result) |
8 | | - else |
9 | | - vim.notify(result, vim.log.levels.ERROR, { title = "opencode" }) |
10 | | - end |
11 | | - end) |
12 | | -end |
| 4 | +M.ask = require("opencode.ui.ask").ask |
| 5 | +M.select = require("opencode.ui.select").select |
13 | 6 |
|
14 | | ----@class opencode.prompt.Opts |
15 | | ----@field clear? boolean Clear the TUI input before. |
16 | | ----@field submit? boolean Submit the TUI input after. |
17 | | ----@field context? opencode.Context The context the prompt was written or selected in, if any. |
| 7 | +M.prompt = require("opencode.api.prompt").prompt |
| 8 | +M.command = require("opencode.api.command").command |
18 | 9 |
|
19 | | ----Prompt `opencode`. |
20 | | ---- |
21 | | ----1. Resolves `prompt` if it's a prompt name from `opts.prompts`. |
22 | | ----2. Clears the TUI input if `opts.clear`. |
23 | | ----3. Injects `opts.contexts` into `prompt`. |
24 | | ----4. Appends `prompt` to the TUI input. |
25 | | ----5. Submits the TUI input if `opts.submit`. |
26 | | ----6. Listens for Server-Sent-Events to forward as `OpencodeEvent` autocmd. |
27 | | ----7. Calls `callback` if provided. |
28 | | ---- |
29 | | ----@param prompt string The prompt to send to `opencode`, or a prompt name from `opts.prompts`. |
30 | | ----@param opts? opencode.prompt.Opts |
31 | | ----@param callback? fun() |
32 | | -function M.prompt(prompt, opts, callback) |
33 | | - local referenced_prompt = require("opencode.config").opts.prompts[prompt] |
34 | | - prompt = referenced_prompt and referenced_prompt.prompt or prompt |
35 | | - opts = { |
36 | | - clear = opts and opts.clear or false, |
37 | | - submit = opts and opts.submit or false, |
38 | | - context = opts and opts.context or require("opencode.context").new(), |
39 | | - } |
40 | | - |
41 | | - get_port(function(port) |
42 | | - require("opencode.provider").show() |
43 | | - |
44 | | - require("opencode.util").chain({ |
45 | | - function(next) |
46 | | - if opts.clear then |
47 | | - require("opencode.cli.client").tui_clear_prompt(port, next) |
48 | | - else |
49 | | - next() |
50 | | - end |
51 | | - end, |
52 | | - function(next) |
53 | | - local rendered = opts.context:render(prompt) |
54 | | - local plaintext = opts.context.plaintext(rendered.output) |
55 | | - require("opencode.cli.client").tui_append_prompt(plaintext, port, next) |
56 | | - end, |
57 | | - function(next) |
58 | | - if opts.submit then |
59 | | - -- WARNING: If user never prompts opencode via the plugin, we'll never receive SSEs. |
60 | | - -- Could register in `/plugin` and even periodically check, but is it worth the complexity and performance hit? |
61 | | - require("opencode.cli.client").listen_to_sse(port, function(response) |
62 | | - vim.api.nvim_exec_autocmds("User", { |
63 | | - pattern = "OpencodeEvent", |
64 | | - data = { |
65 | | - event = response, |
66 | | - port = port, |
67 | | - }, |
68 | | - }) |
69 | | - end) |
70 | | - |
71 | | - require("opencode.cli.client").tui_submit_prompt(port, next) |
72 | | - else |
73 | | - next() |
74 | | - end |
75 | | - end, |
76 | | - function() |
77 | | - if callback then |
78 | | - callback() |
79 | | - end |
80 | | - end, |
81 | | - }) |
82 | | - end) |
83 | | -end |
84 | | - |
85 | | ----@alias opencode.Command |
86 | | ----| 'session_new' |
87 | | ----| 'session_share' |
88 | | ----| 'session_interrupt' |
89 | | ----| 'session_compact' |
90 | | ----| 'messages_page_up' |
91 | | ----| 'messages_page_down' |
92 | | ----| 'messages_half_page_up' |
93 | | ----| 'messages_half_page_down' |
94 | | ----| 'messages_first' |
95 | | ----| 'messages_last' |
96 | | ----| 'messages_copy' |
97 | | ----| 'messages_undo' |
98 | | ----| 'messages_redo' |
99 | | ----| 'input_clear' |
100 | | ----| 'agent_cycle' |
101 | | - |
102 | | ----Send a [command](https://opencode.ai/docs/keybinds) to `opencode`. |
103 | | ---- |
104 | | ----@param command opencode.Command|string The command to send to `opencode`. |
105 | | ----@param callback fun(response: table)|nil |
106 | | -function M.command(command, callback) |
107 | | - get_port(function(port) |
108 | | - -- No need to register SSE here - commands don't trigger any. |
109 | | - -- (except maybe the `input_*` commands? but no reason for user to use those). |
110 | | - |
111 | | - require("opencode.provider").show() |
112 | | - |
113 | | - ---@cast command opencode.Command|string |
114 | | - require("opencode.cli.client").tui_execute_command(command, port, callback) |
115 | | - end) |
116 | | -end |
117 | | - |
118 | | ----Input a prompt to send to `opencode`. |
119 | | ----Press the up arrow to browse recent prompts. |
120 | | ---- |
121 | | ---- - Highlights `opts.contexts` placeholders. |
122 | | ---- - Completes `opts.contexts` placeholders. |
123 | | ---- - Press `<Tab>` to trigger built-in completion. |
124 | | ---- - When using `blink.cmp` and `snacks.input`, registers `opts.auto_register_cmp_sources`. |
125 | | ---- |
126 | | ----@param default? string Text to prefill the input with. |
127 | | ----@param opts? opencode.prompt.Opts Options for `prompt()`. |
128 | | -function M.ask(default, opts) |
129 | | - opts = opts or {} |
130 | | - opts.context = opts.context or require("opencode.context").new() |
131 | | - |
132 | | - require("opencode.ui.ask").input(default, opts.context, function(value) |
133 | | - if value and value ~= "" then |
134 | | - M.prompt(value, opts) |
135 | | - end |
136 | | - end) |
137 | | -end |
138 | | - |
139 | | ----Select a prompt, command, or provider function. |
140 | | ----Includes previews when using `snacks.picker`. |
141 | | ----@param opts? opencode.select.Opts Control what's shown in the select menu. |
142 | | -function M.select(opts) |
143 | | - local context = require("opencode.context").new() |
144 | | - opts = opts or { |
145 | | - prompts = true, |
146 | | - commands = true, |
147 | | - provider = true, |
148 | | - } |
149 | | - |
150 | | - require("opencode.ui.select").select(opts, context, function(choice) |
151 | | - if not choice then |
152 | | - return |
153 | | - elseif choice.__type == "prompt" then |
154 | | - ---@type opencode.Prompt |
155 | | - local prompt = require("opencode.config").opts.prompts[choice.name] |
156 | | - prompt.context = context |
157 | | - if prompt.ask then |
158 | | - require("opencode").ask(prompt.prompt, prompt) |
159 | | - else |
160 | | - require("opencode").prompt(prompt.prompt, prompt) |
161 | | - end |
162 | | - elseif choice.__type == "command" then |
163 | | - require("opencode").command(choice.name) |
164 | | - elseif choice.__type == "provider" then |
165 | | - local provider = require("opencode.provider") |
166 | | - if choice.name == "toggle" then |
167 | | - provider.toggle() |
168 | | - elseif choice.name == "start" then |
169 | | - provider.start() |
170 | | - elseif choice.name == "show" then |
171 | | - provider.show() |
172 | | - end |
173 | | - end |
174 | | - end) |
175 | | -end |
176 | | - |
177 | | ----Toggle `opencode` via `opts.provider`. |
178 | | -function M.toggle() |
179 | | - require("opencode.provider").toggle() |
180 | | -end |
| 10 | +M.toggle = require("opencode.provider").toggle |
| 11 | +M.start = require("opencode.provider").start |
| 12 | +M.show = require("opencode.provider").show |
181 | 13 |
|
182 | 14 | return M |
0 commit comments