From 514fa8d11ee7019c45e62c1cc5d482d361ba7e82 Mon Sep 17 00:00:00 2001 From: disrupted Date: Sun, 1 Feb 2026 23:15:15 +0100 Subject: [PATCH] fix(context): deduplicate selection ranges --- lua/opencode/context/chat_context.lua | 7 ++++++ tests/unit/context_spec.lua | 36 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/lua/opencode/context/chat_context.lua b/lua/opencode/context/chat_context.lua index fc547641..20a78782 100644 --- a/lua/opencode/context/chat_context.lua +++ b/lua/opencode/context/chat_context.lua @@ -167,6 +167,13 @@ function M.add_selection(selection) M.context.selections = {} end + -- prevent duplicate selection (same exact line range) from being added + for _, sel in ipairs(M.context.selections) do + if sel.file.path == selection.file.path and sel.lines == selection.lines then + return + end + end + table.insert(M.context.selections, selection) state.context_updated_at = vim.uv.now() end diff --git a/tests/unit/context_spec.lua b/tests/unit/context_spec.lua index c12d33a3..bbedadd7 100644 --- a/tests/unit/context_spec.lua +++ b/tests/unit/context_spec.lua @@ -193,6 +193,42 @@ describe('add_file/add_selection/add_subagent', function() context.add_selection({ foo = 'bar' }) assert.same({ { foo = 'bar' } }, context.get_context().selections) end) + it('does not add duplicate selections with same range', function() + local selection1 = { file = { path = '/tmp/foo.lua' }, lines = '1-2', content = 'one' } + local selection2 = { file = { path = '/tmp/foo.lua' }, lines = '1-2', content = 'two' } + + context.add_selection(selection1) + context.add_selection(selection2) + + assert.same({ selection1 }, context.get_context().selections) + end) + it('allows non-overlapping selections in same file', function() + local selection1 = { file = { path = '/tmp/foo.lua' }, lines = '1-2', content = 'one' } + local selection2 = { file = { path = '/tmp/foo.lua' }, lines = '4-6', content = 'two' } + + context.add_selection(selection1) + context.add_selection(selection2) + + assert.same({ selection1, selection2 }, context.get_context().selections) + end) + it('allows overlapping selections in same file', function() + local selection1 = { file = { path = '/tmp/foo.lua' }, lines = '1-4', content = 'one' } + local selection2 = { file = { path = '/tmp/foo.lua' }, lines = '3-6', content = 'two' } + + context.add_selection(selection1) + context.add_selection(selection2) + + assert.same({ selection1, selection2 }, context.get_context().selections) + end) + it('allows same line range in different files', function() + local selection1 = { file = { path = '/tmp/foo.lua' }, lines = '1-2', content = 'one' } + local selection2 = { file = { path = '/tmp/bar.lua' }, lines = '1-2', content = 'two' } + + context.add_selection(selection1) + context.add_selection(selection2) + + assert.same({ selection1, selection2 }, context.get_context().selections) + end) it('adds a subagent', function() context.add_subagent('agentX') assert.same({ 'agentX' }, context.get_context().mentioned_subagents)