Skip to content
Merged
23 changes: 23 additions & 0 deletions lua/opencode/state/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ local store = require('opencode.state.store')
---@field output_buf integer|nil
---@field output_was_at_bottom boolean|nil
---@field position 'right'|'left'|'current'|'float'|nil
---@field output_folds { ranges: {from: integer, to: integer}[] }|nil

---@class OpencodeUiStateMutations
local M = {}
Expand All @@ -40,6 +41,28 @@ function M.clear_windows()
return store.set('windows', nil)
end

---@param folds { ranges: {from: integer, to: integer}[] }|nil
function M.set_output_folds(folds)
return store.mutate('windows', function(win)
if win then
win.output_folds = folds
end
end)
end

---@return { ranges: {from: integer, to: integer}[] }
function M.get_output_folds()
local win = store.get('windows')
if win and win.output_folds then
return win.output_folds
end
return { ranges = {} }
end

function M.clear_output_folds()
return M.set_output_folds(nil)
end

---@param is_opening boolean
function M.set_opening(is_opening)
return store.set('is_opening', is_opening)
Expand Down
54 changes: 22 additions & 32 deletions lua/opencode/ui/output_window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,6 @@ local function build_fold_state(folds)
return fold_state
end

---@param buf integer
---@return { ranges: table<{from: integer, to: integer}> }
local function get_fold_state(buf)
local ok, fold_state = pcall(vim.api.nvim_buf_get_var, buf, 'opencode_folds')
if not ok or type(fold_state) ~= 'table' then
return { ranges = {} }
end
if type(fold_state.ranges) == 'table' then
return fold_state
end
return build_fold_state(fold_state)
end

local _update_depth = 0
local _update_buf = nil

Expand Down Expand Up @@ -87,7 +74,7 @@ end
function M.create_buf()
local output_buf = vim.api.nvim_create_buf(false, true)

vim.api.nvim_buf_set_var(output_buf, 'opencode_folds', build_fold_state({}))
state.ui.set_output_folds(build_fold_state({}))

local buffixwin = require('opencode.ui.buf_fix_win')
buffixwin.fix_to_win(output_buf, function()
Expand Down Expand Up @@ -354,7 +341,7 @@ function M.fold_text()
return vim.fn.foldtext()
end

local folds = get_fold_state(output_buf).ranges
local folds = state.ui.get_output_folds().ranges

local line_count = 0
for _, range in ipairs(folds) do
Expand All @@ -380,7 +367,7 @@ function M.get_open_fold_starts(win, buf)
return {}
end

local prev_folds = get_fold_state(buf).ranges
local prev_folds = state.ui.get_output_folds().ranges

local was_open = {}
vim.api.nvim_win_call(win, function()
Expand All @@ -395,7 +382,7 @@ function M.get_open_fold_starts(win, buf)
end

---Set the folds for the output buffer
---@param fold_ranges table<{from: number, to: number}>
---@param fold_ranges {from: number, to: number}[]
function M.set_folds(fold_ranges)
local windows = state.windows
if not M.mounted() then
Expand All @@ -406,31 +393,39 @@ function M.set_folds(fold_ranges)
local buf = windows.output_buf
local win = windows.output_win
local folds = build_fold_state(fold_ranges or {})
local prev_folds = get_fold_state(buf)
local prev_folds = state.ui.get_output_folds()

if vim.deep_equal(prev_folds.ranges, folds.ranges) then
return
end

local was_open = M.get_open_fold_starts(win, buf)
local preserve_view = not M.is_at_bottom(win)
vim.api.nvim_buf_set_var(buf, 'opencode_folds', folds)
state.ui.set_output_folds(folds)

vim.api.nvim_win_call(win, function()
local view = preserve_view and vim.fn.winsaveview() or nil

local line_count = vim.api.nvim_buf_line_count(buf)
local fold_commands = {}
for _, range in ipairs(folds.ranges) do
if range.from <= line_count and range.to <= line_count then
vim.cmd(range.from .. ',' .. range.to .. 'fold')
fold_commands[#fold_commands + 1] = range.from .. ',' .. range.to .. 'fold'
end
end
if #fold_commands > 0 then
vim.api.nvim_exec2(table.concat(fold_commands, ' | '), { output = false })
end

local open_commands = {}
for _, range in ipairs(folds.ranges) do
if was_open[range.from] then
vim.cmd(range.from .. ',' .. range.to .. 'foldopen!')
if was_open[range.from] and range.from <= line_count and range.to <= line_count then
open_commands[#open_commands + 1] = range.from .. ',' .. range.to .. 'foldopen!'
end
end
if #open_commands > 0 then
vim.api.nvim_exec2(table.concat(open_commands, ' | '), { output = false })
end

if view then
vim.fn.winrestview(view)
Expand All @@ -446,8 +441,7 @@ function M.shift_folds(start_line, delta)
if not windows or not windows.output_buf then
return
end
local buf = windows.output_buf
local fold_state = get_fold_state(buf)
local fold_state = state.ui.get_output_folds()
local folds = fold_state.ranges

for _, range in ipairs(folds) do
Expand All @@ -471,11 +465,6 @@ function M.shift_folds(start_line, delta)
table.sort(folds, function(a, b)
return a.from < b.from
end)

fold_state.starts = {}
for _, range in ipairs(folds) do
fold_state.starts[#fold_state.starts + 1] = range.from
end
end

---@return integer
Expand Down Expand Up @@ -610,11 +599,12 @@ end
---@param start_line integer
---@param end_line integer
function M.highlight_changed_lines(start_line, end_line)
local windows = state.windows
if not windows or not windows.output_buf or not vim.api.nvim_buf_is_valid(windows.output_buf) then
if not config.debug.highlight_changed_lines then
return
end
if not config.debug.highlight_changed_lines then

local windows = state.windows
if not windows or not windows.output_buf or not vim.api.nvim_buf_is_valid(windows.output_buf) then
return
end

Expand Down
43 changes: 0 additions & 43 deletions lua/opencode/ui/renderer/append.lua

This file was deleted.

Loading
Loading