Skip to content

Commit 7e027df

Browse files
authored
fix(chat): correct block selection logic by cursor (#1301)
Refactored Chat:get_block to properly select the closest block to the cursor, considering the role filter and ensuring correct fallback to the last matching block. This improves accuracy when interacting with chat blocks in the UI.
1 parent 92777fb commit 7e027df

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

lua/CopilotChat/ui/chat.lua

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,27 +124,40 @@ end
124124
---@param cursor boolean? If true, returns the block closest to the cursor position
125125
---@return CopilotChat.ui.chat.Block?
126126
function Chat:get_block(role, cursor)
127-
if not self:visible() then
128-
return nil
129-
end
127+
if cursor then
128+
if not self:visible() then
129+
return nil
130+
end
130131

131-
self:render()
132-
local cursor_pos = vim.api.nvim_win_get_cursor(self.winnr)
133-
local cursor_line = cursor_pos[1]
134-
local closest_block = nil
135-
local max_line_below_cursor = -1
136-
137-
for _, message in pairs(self.messages) do
138-
local section = message.section
139-
for _, block in ipairs(section.blocks) do
140-
if block.start_line <= cursor_line and block.start_line > max_line_below_cursor then
141-
max_line_below_cursor = block.start_line
142-
closest_block = block
132+
self:render()
133+
local cursor_pos = vim.api.nvim_win_get_cursor(self.winnr)
134+
local cursor_line = cursor_pos[1]
135+
local closest_block = nil
136+
local max_line_below_cursor = -1
137+
138+
for _, message in ipairs(self.messages) do
139+
local section = message.section
140+
local matches_role = not role or message.role == role
141+
if matches_role and section and section.blocks then
142+
for _, block in ipairs(section.blocks) do
143+
if block.start_line <= cursor_line and block.start_line > max_line_below_cursor then
144+
max_line_below_cursor = block.start_line
145+
closest_block = block
146+
end
147+
end
143148
end
144149
end
150+
151+
return closest_block
145152
end
146153

147-
return closest_block
154+
for i = #self.messages, 1, -1 do
155+
local message = self.messages[i]
156+
local matches_role = not role or message.role == role
157+
if matches_role and message.section and message.section.blocks and #message.section.blocks > 0 then
158+
return message.section.blocks[#message.section.blocks]
159+
end
160+
end
148161
end
149162

150163
--- Get last message by role in the chat window.

0 commit comments

Comments
 (0)