From 98024ccb88beabbdbe093b3b1bcd2c694aa134e6 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 21 Mar 2024 18:41:11 +0100 Subject: [PATCH 1/4] feat: Add start and end line number as line range to active selection Closes #214 --- lua/CopilotChat/copilot.lua | 18 +++++++++++++++--- lua/CopilotChat/init.lua | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/lua/CopilotChat/copilot.lua b/lua/CopilotChat/copilot.lua index fdceaa3e..7a9bef0a 100644 --- a/lua/CopilotChat/copilot.lua +++ b/lua/CopilotChat/copilot.lua @@ -9,6 +9,8 @@ ---@field embeddings table? ---@field filename string? ---@field filetype string? +---@field start_row number? +---@field end_row number? ---@field system_prompt string? ---@field model string? ---@field temperature number? @@ -91,12 +93,19 @@ local function get_cached_token() return userdata['github.com'].oauth_token end -local function generate_selection_message(filename, filetype, selection) +local function generate_selection_message(filename, filetype, start_row, end_row, selection) if not selection or selection == '' then return '' end - return string.format('Active selection: `%s`\n```%s\n%s\n```', filename, filetype, selection) + return string.format( + 'Active selection: `%s` (lines %s-%s)\n```%s\n%s\n```', + filename, + start_row, + end_row, + filetype, + selection + ) end local function generate_embeddings_message(embeddings) @@ -300,6 +309,8 @@ function Copilot:ask(prompt, opts) local filename = opts.filename or '' local filetype = opts.filetype or '' local selection = opts.selection or '' + local start_row = opts.start_row + local end_row = opts.end_row local system_prompt = opts.system_prompt or prompts.COPILOT_INSTRUCTIONS local model = opts.model or 'gpt-4' local temperature = opts.temperature or 0.1 @@ -325,7 +336,8 @@ function Copilot:ask(prompt, opts) self:stop() end - local selection_message = generate_selection_message(filename, filetype, selection) + local selection_message = + generate_selection_message(filename, filetype, start_row, end_row, selection) local embeddings_message = generate_embeddings_message(embeddings) -- Count tokens diff --git a/lua/CopilotChat/init.lua b/lua/CopilotChat/init.lua index 88f6c0b4..d7c18edf 100644 --- a/lua/CopilotChat/init.lua +++ b/lua/CopilotChat/init.lua @@ -397,6 +397,8 @@ function M.ask(prompt, config, source) embeddings = embeddings, filename = filename, filetype = filetype, + start_row = selection.start_row, + end_row = selection.end_row, system_prompt = system_prompt, model = config.model, temperature = config.temperature, From 9327353358118d06909cbd965c4ffe86682b7f52 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 21 Mar 2024 19:09:16 +0100 Subject: [PATCH 2/4] Try to pass lines as prefix to active selection Signed-off-by: Tomas Slusny --- lua/CopilotChat/copilot.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lua/CopilotChat/copilot.lua b/lua/CopilotChat/copilot.lua index 7a9bef0a..4d99594a 100644 --- a/lua/CopilotChat/copilot.lua +++ b/lua/CopilotChat/copilot.lua @@ -98,13 +98,17 @@ local function generate_selection_message(filename, filetype, start_row, end_row return '' end + local lines = vim.split(selection, '\n') + + for i, line in ipairs(lines) do + lines[i] = (i + start_row) .. ': ' .. line + end + return string.format( - 'Active selection: `%s` (lines %s-%s)\n```%s\n%s\n```', + 'Active selection: `%s`\n```%s\n%s\n```', filename, - start_row, - end_row, filetype, - selection + table.concat(lines, '\n') ) end From b7aeb10bfb8424cd02cbd344eb7e63390f884b96 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 21 Mar 2024 19:12:26 +0100 Subject: [PATCH 3/4] Fix missing start/end row Signed-off-by: Tomas Slusny --- lua/CopilotChat/copilot.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lua/CopilotChat/copilot.lua b/lua/CopilotChat/copilot.lua index 4d99594a..09900f40 100644 --- a/lua/CopilotChat/copilot.lua +++ b/lua/CopilotChat/copilot.lua @@ -99,7 +99,6 @@ local function generate_selection_message(filename, filetype, start_row, end_row end local lines = vim.split(selection, '\n') - for i, line in ipairs(lines) do lines[i] = (i + start_row) .. ': ' .. line end @@ -313,8 +312,8 @@ function Copilot:ask(prompt, opts) local filename = opts.filename or '' local filetype = opts.filetype or '' local selection = opts.selection or '' - local start_row = opts.start_row - local end_row = opts.end_row + local start_row = opts.start_row or 0 + local end_row = opts.end_row or 0 local system_prompt = opts.system_prompt or prompts.COPILOT_INSTRUCTIONS local model = opts.model or 'gpt-4' local temperature = opts.temperature or 0.1 From 29cd46e8b141ed2f9e67accae5d171ee52adaf0f Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Thu, 21 Mar 2024 20:07:08 +0100 Subject: [PATCH 4/4] Use proper line numbering and adjust prompt Signed-off-by: Tomas Slusny --- lua/CopilotChat/copilot.lua | 21 +++++++++++---------- lua/CopilotChat/prompts.lua | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/lua/CopilotChat/copilot.lua b/lua/CopilotChat/copilot.lua index 09900f40..a8074525 100644 --- a/lua/CopilotChat/copilot.lua +++ b/lua/CopilotChat/copilot.lua @@ -98,17 +98,19 @@ local function generate_selection_message(filename, filetype, start_row, end_row return '' end - local lines = vim.split(selection, '\n') - for i, line in ipairs(lines) do - lines[i] = (i + start_row) .. ': ' .. line + local content = selection + if start_row > 0 then + local lines = vim.split(selection, '\n') + local total_lines = #lines + local max_length = #tostring(total_lines) + for i, line in ipairs(lines) do + local formatted_line_number = string.format('%' .. max_length .. 'd', i - 1 + start_row) + lines[i] = formatted_line_number .. ': ' .. line + end + content = table.concat(lines, '\n') end - return string.format( - 'Active selection: `%s`\n```%s\n%s\n```', - filename, - filetype, - table.concat(lines, '\n') - ) + return string.format('Active selection: `%s`\n```%s\n%s\n```', filename, filetype, content) end local function generate_embeddings_message(embeddings) @@ -168,7 +170,6 @@ local function generate_ask_request( end if embeddings and #embeddings.files > 0 then - -- FIXME: Is this really supposed to be sent like this? Maybe just send it with query, not sure table.insert(messages, { content = embeddings.header .. table.concat(embeddings.files, ''), role = 'system', diff --git a/lua/CopilotChat/prompts.lua b/lua/CopilotChat/prompts.lua index bc2737a3..2cd385c9 100644 --- a/lua/CopilotChat/prompts.lua +++ b/lua/CopilotChat/prompts.lua @@ -23,7 +23,7 @@ Copilot MUST decline to respond if the question is against Microsoft content pol Copilot MUST decline to answer if the question is not related to a developer. If the question is related to a developer, Copilot MUST respond with content related to a developer. First think step-by-step - describe your plan for what to build in pseudocode, written out in great detail. -Then output the code in a single code block. +Then output the code in a single code block. This code block should not contain line numbers (line numbers are not necessary for the code to be understood, they are in format number: at beginning of lines). Minimize any other prose. Keep your answers short and impersonal. Use Markdown formatting in your answers.