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
30 changes: 15 additions & 15 deletions lua/opencode/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ end

function M.close()
if state.display_route then
state.display_route = nil
state.ui.clear_display_route()
ui.clear_output()
-- need to trigger a re-render here to re-display the session
ui.render_output()
Expand All @@ -61,7 +61,7 @@ end

---@return {status: 'closed'|'hidden'|'visible', position: string, windows: OpencodeWindowState|nil, cursor_positions: {input: integer[]|nil, output: integer[]|nil}}
function M.get_window_state()
return state.get_window_state()
return state.ui.get_window_state()
end

---@param hidden OpencodeHiddenBuffers|nil
Expand All @@ -82,7 +82,7 @@ end
---@return {focus: 'input'|'output', open_action: 'reuse_visible'|'restore_hidden'|'create_fresh'}
local function build_toggle_open_context(restore_hidden)
if restore_hidden then
local hidden = state.inspect_hidden_buffers()
local hidden = state.ui.inspect_hidden_buffers()
return {
focus = resolve_hidden_focus(hidden),
open_action = 'restore_hidden',
Expand All @@ -98,7 +98,7 @@ local function build_toggle_open_context(restore_hidden)
end

M.toggle = Promise.async(function(new_session)
local decision = state.resolve_toggle_decision(config.ui.persist_state, state.display_route ~= nil)
local decision = state.ui.resolve_toggle_decision(config.ui.persist_state, state.display_route ~= nil)
local action = decision.action
local is_new_session = new_session == true

Expand Down Expand Up @@ -329,7 +329,7 @@ function M.set_review_breakpoint()
end

function M.prev_history()
if not state.is_visible() then
if not state.ui.is_visible() then
return
end
local prev_prompt = history.prev()
Expand All @@ -340,7 +340,7 @@ function M.prev_history()
end

function M.next_history()
if not state.is_visible() then
if not state.ui.is_visible() then
return
end
local next_prompt = history.next()
Expand Down Expand Up @@ -390,7 +390,7 @@ M.submit_input_prompt = Promise.async(function()
if state.display_route then
-- we're displaying /help or something similar, need to clear that and refresh
-- the session data before sending the command
state.display_route = nil
state.ui.clear_display_route()
ui.render_output(true)
end

Expand Down Expand Up @@ -485,7 +485,7 @@ M.initialize = Promise.async(function()
vim.notify('Invalid model format: ' .. tostring(state.current_model), vim.log.levels.ERROR)
return
end
state.active_session = new_session
state.session.set_active(new_session)
M.open_input()
state.api_client:init_session(state.active_session.id, {
providerID = providerId,
Expand Down Expand Up @@ -533,7 +533,7 @@ end)

function M.with_header(lines, show_welcome)
show_welcome = show_welcome or false
state.display_route = '/header'
state.ui.set_display_route('/header')

local msg = {
'## Opencode.nvim',
Expand All @@ -558,7 +558,7 @@ function M.with_header(lines, show_welcome)
end

function M.help()
state.display_route = '/help'
state.ui.set_display_route('/help')
M.open_input()
local msg = M.with_header({
'### Available Commands',
Expand All @@ -575,7 +575,7 @@ function M.help()
'|--------------|-------------|',
}, false)

if not state.is_visible() or not state.windows.output_win then
if not state.ui.is_visible() or not state.windows.output_win then
return
end

Expand Down Expand Up @@ -611,7 +611,7 @@ M.commands_list = Promise.async(function()
return
end

state.display_route = '/commands'
state.ui.set_display_route('/commands')
M.open_input()

local msg = M.with_header({
Expand Down Expand Up @@ -859,7 +859,7 @@ M.rename_session = Promise.async(function(current_session, new_title)
local session_obj = session.get_by_id(current_session.id):await()
if session_obj then
session_obj.title = title
state.active_session = vim.deepcopy(session_obj)
state.session.set_active(vim.deepcopy(session_obj))
end
end
promise:resolve(current_session)
Expand Down Expand Up @@ -1056,7 +1056,7 @@ M.review = Promise.async(function(args)
vim.notify('Invalid model format: ' .. tostring(state.current_model), vim.log.levels.ERROR)
return
end
state.active_session = new_session
state.session.set_active(new_session)
M.open_input():await()
state.api_client
:send_command(state.active_session.id, {
Expand Down Expand Up @@ -1181,7 +1181,7 @@ M.commands = {
vim.notify('Failed to create new session', vim.log.levels.ERROR)
return
end
state.active_session = new_session
state.session.set_active(new_session)
M.open_input()
else
M.open_input_new_session()
Expand Down
4 changes: 2 additions & 2 deletions lua/opencode/api_client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function OpencodeApiClient:_ensure_base_url()

if not state.opencode_server then
-- this is last resort - try to start the server and could be blocking
state.opencode_server = server_job.ensure_server():wait() --[[@as OpencodeServer]]
state.jobs.set_server(server_job.ensure_server():wait() --[[@as OpencodeServer]])
-- shouldn't normally happen but prevents error in replay tester
if not state.opencode_server then
return false
Expand Down Expand Up @@ -532,7 +532,7 @@ local function create_client(base_url)
end
end

state.subscribe('opencode_server', on_server_change)
state.store.subscribe('opencode_server', on_server_change)

return api_client
end
Expand Down
27 changes: 15 additions & 12 deletions lua/opencode/context.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ local toggleable_context_keys = {
---@param context_key OpencodeToggleableContextKey
---@return table
local function ensure_context_state(context_key)
state.current_context_config = state.current_context_config or {}
local current = state.current_context_config[context_key]
local current_config = state.current_context_config or {}
local current = current_config[context_key]
local new_config = vim.deepcopy(current_config)
local defaults = vim.tbl_get(config, 'context', context_key) or {}
state.current_context_config[context_key] = vim.tbl_deep_extend('force', {}, defaults, current or {})
return state.current_context_config[context_key]

new_config[context_key] = vim.tbl_deep_extend('force', {}, defaults, current or {})
state.context.set_current_context_config(new_config)
return new_config[context_key]
end

M.ChatContext = ChatContext
Expand Down Expand Up @@ -117,12 +120,12 @@ end
-- Delegate global state management to ChatContext
function M.add_selection(selection)
ChatContext.add_selection(selection)
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.remove_selection(selection)
ChatContext.remove_selection(selection)
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.clear_selections()
Expand Down Expand Up @@ -180,13 +183,13 @@ function M.add_file(file)

file = vim.fn.fnamemodify(file, ':p')
ChatContext.add_file(file)
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.remove_file(file)
file = vim.fn.fnamemodify(file, ':p')
ChatContext.remove_file(file)
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.clear_files()
Expand All @@ -195,12 +198,12 @@ end

function M.add_subagent(subagent)
ChatContext.add_subagent(subagent)
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.remove_subagent(subagent)
ChatContext.remove_subagent(subagent)
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.clear_subagents()
Expand All @@ -213,7 +216,7 @@ end

function M.load()
ChatContext.load()
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

-- Context creation with delta logic (delegates to ChatContext)
Expand Down Expand Up @@ -312,7 +315,7 @@ function M.setup()
M.load()
end, 200)

state.subscribe({ 'current_code_buf', 'current_context_config', 'is_opencode_focused' }, function()
state.store.subscribe({ 'current_code_buf', 'current_context_config', 'is_opencode_focused' }, function()
debounced_load()
end)

Expand Down
24 changes: 12 additions & 12 deletions lua/opencode/context/chat_context.lua
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ function M.add_selection(selection)
end

table.insert(M.context.selections, selection)
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.remove_selection(selection)
Expand All @@ -190,12 +190,12 @@ function M.remove_selection(selection)
break
end
end
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.clear_selections()
M.context.selections = {}
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.add_file(file)
Expand All @@ -210,7 +210,7 @@ function M.add_file(file)
if not vim.tbl_contains(M.context.mentioned_files, file) then
table.insert(M.context.mentioned_files, file)
end
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.remove_file(file)
Expand All @@ -226,12 +226,12 @@ function M.remove_file(file)
break
end
end
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.clear_files()
M.context.mentioned_files = {}
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.add_subagent(subagent)
Expand All @@ -243,7 +243,7 @@ function M.add_subagent(subagent)
if not vim.tbl_contains(M.context.mentioned_subagents, subagent) then
table.insert(M.context.mentioned_subagents, subagent)
end
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.remove_subagent(subagent)
Expand All @@ -258,18 +258,18 @@ function M.remove_subagent(subagent)
break
end
end
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.clear_subagents()
M.context.mentioned_subagents = {}
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.unload_attachments()
M.context.mentioned_files = {}
M.context.selections = {}
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

function M.get_mentioned_files()
Expand Down Expand Up @@ -402,7 +402,7 @@ function M.load()
or not vim.deep_equal(prev_cursor_data, M.context.cursor_data)
or not vim.deep_equal(prev_linter_errors, M.context.linter_errors)
then
state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
end

-- Handle current selection
Expand Down Expand Up @@ -471,7 +471,7 @@ function M.delta_context(opts)
end
end

state.context_updated_at = vim.uv.now()
state.context.set_context_updated_at(vim.uv.now())
return ctx
end

Expand Down
Loading
Loading