Skip to content

Commit 044c54b

Browse files
committed
fix: range transformation for selection
1 parent 6deb4f1 commit 044c54b

File tree

3 files changed

+32
-34
lines changed

3 files changed

+32
-34
lines changed

lua/opencode/api.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ function M.quick_chat(message, range)
114114
local visual_range = util.get_visual_range()
115115
if visual_range then
116116
range = {
117-
start_line = visual_range.start_line,
118-
end_line = visual_range.end_line,
117+
start = visual_range.start_line,
118+
stop = visual_range.end_line,
119119
}
120120
end
121121
end

lua/opencode/context.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,6 @@ M.format_message_quick_chat = Promise.async(function(prompt, context_instance)
779779
end
780780

781781
local diff_text = context_instance:get_git_diff():await()
782-
vim.print('⭕ ❱ context.lua:781 ❱ ƒ(diff_text) ❱ diff_text =', diff_text)
783782
if diff_text and diff_text ~= '' then
784783
table.insert(parts, format_git_diff_part(diff_text))
785784
end

lua/opencode/quick_chat.lua

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@ local Timer = require('opencode.ui.timer')
99

1010
local M = {}
1111

12-
local active_sessions = {}
12+
---@class OpencodeQuickChatRunningSession
13+
---@field buf integer Buffer handle
14+
---@field row integer Row position for spinner
15+
---@field col integer Column position for spinner
16+
---@field spinner CursorSpinner Spinner instance
17+
---@field timestamp integer Timestamp when session started
18+
19+
---@type table<string, OpencodeQuickChatRunningSession>
20+
local running_sessions = {}
1321

1422
--- Simple cursor spinner using the same animation logic as loading_animation.lua
1523
local CursorSpinner = {}
@@ -126,7 +134,7 @@ local function cleanup_session(session_info, session_id, message)
126134
if session_info and session_info.spinner then
127135
session_info.spinner:stop()
128136
end
129-
active_sessions[session_id] = nil
137+
running_sessions[session_id] = nil
130138
if message then
131139
vim.notify(message, vim.log.levels.WARN)
132140
end
@@ -150,15 +158,12 @@ end
150158
---@param response_text string Response text that may contain JSON in code blocks
151159
---@return table|nil replacement_data Parsed replacement data or nil if invalid
152160
local function parse_replacement_json(response_text)
153-
-- Try to extract JSON from response text (handle cases where JSON is in code blocks)
154161
local json_text = response_text
155-
-- Look for JSON in code blocks
156162
local json_match = response_text:match('```json\n(.-)\n```') or response_text:match('```\n(.-)\n```')
157163
if json_match then
158164
json_text = json_match
159165
end
160166

161-
-- Try to parse JSON format
162167
local ok, replacement_data = pcall(vim.json.decode, json_text)
163168
if not ok then
164169
return nil
@@ -176,6 +181,7 @@ local function parse_replacement_json(response_text)
176181
end
177182

178183
--- Converts object format like {"1": "line1", "2": "line2"} to array
184+
--- Some LLMs may return line replacements in this format instead of an array
179185
---@param obj_lines table Object with string keys representing line numbers
180186
---@return string[] lines_array Array of lines in correct order
181187
local function convert_object_to_lines_array(obj_lines)
@@ -236,7 +242,6 @@ local function apply_line_replacements(buf, replacement_data)
236242
end
237243
end
238244

239-
-- Apply replacement if valid
240245
if start_line and start_line >= 1 and start_line <= buf_line_count and new_lines and #new_lines > 0 then
241246
local start_idx = math.floor(math.max(0, start_line - 1))
242247
local end_idx = math.floor(math.min(end_line, buf_line_count))
@@ -274,28 +279,28 @@ local function process_response(session_info, messages)
274279
end
275280

276281
--- Hook function called when a session is done thinking (no more pending messages)
277-
---@param session_obj Session The session object
278-
local on_done = Promise.async(function(session_obj)
279-
if not (session_obj.title and vim.startswith(session_obj.title, '[QuickChat]')) then
282+
---@param active_session Session The session object
283+
local on_done = Promise.async(function(active_session)
284+
if not (active_session.title and vim.startswith(active_session.title, '[QuickChat]')) then
280285
return
281286
end
282287

283-
local session_info = active_sessions[session_obj.id]
284-
if not session_info then
288+
local running_session = running_sessions[active_session.id]
289+
if not running_session then
285290
return
286291
end
287292

288-
local messages = session.get_messages(session_obj):await() --[[@as OpencodeMessage[] ]]
293+
local messages = session.get_messages(active_session):await() --[[@as OpencodeMessage[] ]]
289294
if not messages then
290-
cleanup_session(session_info, session_obj.id, 'Failed to update file with quick chat response')
295+
cleanup_session(running_session, active_session.id, 'Failed to update file with quick chat response')
291296
return
292297
end
293298

294-
local success = process_response(session_info, messages)
299+
local success = process_response(running_session, messages)
295300
if success then
296-
cleanup_session(session_info, session_obj.id) -- Success cleanup (no error message)
301+
cleanup_session(running_session, active_session.id)
297302
else
298-
cleanup_session(session_info, session_obj.id, 'Failed to update file with quick chat response') -- Error cleanup
303+
cleanup_session(running_session, active_session.id, 'Failed to update file with quick chat response')
299304
end
300305

301306
--@TODO: enable session deletion after testing
@@ -305,7 +310,6 @@ local on_done = Promise.async(function(session_obj)
305310
-- end)
306311
end)
307312

308-
--- Validates quick chat prerequisites
309313
---@param message string|nil The message to validate
310314
---@return boolean valid
311315
---@return string|nil error_message
@@ -329,7 +333,7 @@ end
329333
---@param context_config OpencodeContextConfig Context configuration
330334
---@param range table|nil Range information
331335
---@return table context_instance
332-
local function setup_quick_chat_context(buf, context_config, range)
336+
local function init_context(buf, context_config, range)
333337
local context_instance = context.new_instance(context_config)
334338

335339
if range and range.start and range.stop then
@@ -383,7 +387,6 @@ local create_message = Promise.async(function(message, context_instance, options
383387
local parts = context.format_message_quick_chat(message, context_instance):await()
384388
local params = { parts = parts, system = table.concat(instructions, '\n'), synthetic = true }
385389

386-
-- Set model if specified
387390
local current_model = core.initialize_current_model():await()
388391
local target_model = options.model or quick_chat_config.default_model or current_model
389392
if target_model then
@@ -413,7 +416,6 @@ end)
413416
M.quick_chat = Promise.async(function(message, options, range)
414417
options = options or {}
415418

416-
-- Validate prerequisites
417419
local valid, error_msg = validate_quick_chat_prerequisites(message)
418420
if not valid then
419421
vim.notify(error_msg or 'Unknown error', vim.log.levels.ERROR)
@@ -426,17 +428,15 @@ M.quick_chat = Promise.async(function(message, options, range)
426428
local row, col = cursor_pos[1] - 1, cursor_pos[2] -- Convert to 0-indexed
427429
local spinner = CursorSpinner.new(buf, row, col)
428430

429-
-- Setup context
430431
local context_config = vim.tbl_deep_extend('force', create_context_config(range ~= nil), options.context_config or {})
431-
local context_instance = setup_quick_chat_context(buf, context_config, range)
432-
-- Check prompt guard
432+
local context_instance = init_context(buf, context_config, range)
433+
433434
local allowed, err_msg = util.check_prompt_allowed(config.values.prompt_guard, context_instance:get_mentioned_files())
434435
if not allowed then
435436
spinner:stop()
436437
return Promise.new():reject(err_msg or 'Prompt denied by prompt_guard')
437438
end
438439

439-
-- Create session
440440
local title = create_session_title(buf)
441441
local quick_chat_session = core.create_new_session(title):await()
442442
if not quick_chat_session then
@@ -447,15 +447,14 @@ M.quick_chat = Promise.async(function(message, options, range)
447447
--TODO only for debug
448448
state.active_session = quick_chat_session
449449

450-
active_sessions[quick_chat_session.id] = {
450+
running_sessions[quick_chat_session.id] = {
451451
buf = buf,
452452
row = row,
453453
col = col,
454454
spinner = spinner,
455455
timestamp = vim.uv.now(),
456456
}
457457

458-
-- Create and send message
459458
local params = create_message(message, context_instance, options):await()
460459
spinner:stop()
461460

@@ -466,7 +465,7 @@ M.quick_chat = Promise.async(function(message, options, range)
466465

467466
if not success then
468467
spinner:stop()
469-
active_sessions[quick_chat_session.id] = nil
468+
running_sessions[quick_chat_session.id] = nil
470469
vim.notify('Error in quick chat: ' .. vim.inspect(err), vim.log.levels.ERROR)
471470
end
472471
end)
@@ -479,12 +478,12 @@ function M.setup()
479478
group = augroup,
480479
callback = function(ev)
481480
local buf = ev.buf
482-
for session_id, session_info in pairs(active_sessions) do
481+
for session_id, session_info in pairs(running_sessions) do
483482
if session_info.buf == buf then
484483
if session_info.spinner then
485484
session_info.spinner:stop()
486485
end
487-
active_sessions[session_id] = nil
486+
running_sessions[session_id] = nil
488487
end
489488
end
490489
end,
@@ -493,12 +492,12 @@ function M.setup()
493492
vim.api.nvim_create_autocmd('VimLeavePre', {
494493
group = augroup,
495494
callback = function()
496-
for _session_id, session_info in pairs(active_sessions) do
495+
for _session_id, session_info in pairs(running_sessions) do
497496
if session_info.spinner then
498497
session_info.spinner:stop()
499498
end
500499
end
501-
active_sessions = {}
500+
running_sessions = {}
502501
end,
503502
})
504503
end

0 commit comments

Comments
 (0)