Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ require('copilot').setup({
print_log_level = vim.log.levels.WARN,
trace_lsp = "off", -- "off" | "messages" | "verbose"
trace_lsp_progress = false,
log_lsp_messages = false,
},
copilot_node_command = 'node', -- Node.js version must be > 18.x
workspace_folders = {},
Expand Down Expand Up @@ -194,8 +195,8 @@ require("copilot").setup {

### logger

When `log_to_file` is true, logs will be written to the `file` for anything of `file_log_level` or higher.
When `print_log` is true, logs will be printed to NeoVim (using `notify`) for anything of `print_log_level` or higher.
Logs will be written to the `file` for anything of `file_log_level` or higher.
Logs will be printed to NeoVim (using `notify`) for anything of `print_log_level` or higher.
File logging is done asynchronously to minimize performance impacts, however there is still some overhead.

Log levels used are the ones defined in `vim.log`:
Expand All @@ -213,8 +214,14 @@ vim.log = {
}
```

`trace_lsp` can either be `off`, `messages` which will output the LSP messages, or `verbose` which adds additonal information to the message.
When `trace_lsp_progress` is true, LSP progress messages will also be logged.
`trace_lsp` controls logging of LSP trace messages (`$/logTrace`) can either be:

- `off`
- `messages` which will output the LSP messages
- `verbose` which adds additonal information to the message.

When `trace_lsp_progress` is true, LSP progress messages (`$/progress`) will also be logged.
When `log_lsp_messages` is true, LSP log messages (`window/logMessage`) events will be logged.

Careful turning on all logging features as the log files may get very large over time, and are not pruned by the application.

Expand Down
63 changes: 32 additions & 31 deletions lua/copilot/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,37 @@ function M.use_client(callback)
)
end

local function get_handlers()
local handlers = {
PanelSolution = api.handlers.PanelSolution,
PanelSolutionsDone = api.handlers.PanelSolutionsDone,
statusNotification = api.handlers.statusNotification,
["copilot/openURL"] = api.handlers["copilot/openURL"],
}

-- optional handlers
local logger_conf = config.get("logger") --[[@as copilot_config_logging]]
if logger_conf.trace_lsp ~= "off" then
handlers = vim.tbl_extend("force", handlers, {
["$/logTrace"] = logger.handle_lsp_trace,
})
end

if logger_conf.trace_lsp_progress then
handlers = vim.tbl_extend("force", handlers, {
["$/progress"] = logger.handle_lsp_progress,
})
end

if logger_conf.log_lsp_messages then
handlers = vim.tbl_extend("force", handlers, {
["window/logMessage"] = logger.handle_log_lsp_messages,
})
end

return handlers
end

local function prepare_client_config(overrides)
local node = config.get("copilot_node_command")

Expand Down Expand Up @@ -217,36 +248,6 @@ local function prepare_client_config(overrides)
workspaceFolders = true,
}

local handlers = {
PanelSolution = api.handlers.PanelSolution,
PanelSolutionsDone = api.handlers.PanelSolutionsDone,
statusNotification = api.handlers.statusNotification,
["copilot/openURL"] = api.handlers["copilot/openURL"],
-- set up "window/logMessage" handler here instead of in `logger.lua`, since some other lsp servers don't support this method, such as jsonlsp
["window/logMessage"] = function(_, result, _)
if not result then
return
end

local message = string.format("LSP message: %s", result.message)
local message_type = result.type --[[@as integer]]

if message_type == 1 then
logger.error(message)
elseif message_type == 2 then
logger.warn(message)
elseif message_type == 3 then
logger.info(message)
elseif message_type == 4 then
logger.info(message)
elseif message_type == 5 then
logger.debug(message)
else
logger.trace(message)
end
end,
}

local root_dir = config.get_root_dir()
local workspace_folders = {
--- @type workspace_folder
Expand Down Expand Up @@ -325,7 +326,7 @@ local function prepare_client_config(overrides)
end)
end
end,
handlers = handlers,
handlers = get_handlers(),
init_options = {
copilotIntegrationId = "vscode-chat",
-- Fix LSP warning: editorInfo and editorPluginInfo will soon be required in initializationOptions
Expand Down
5 changes: 2 additions & 3 deletions lua/copilot/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,13 @@ local default_config = {
},
---@class copilot_config_logging
logger = {
log_to_file = false,
file = vim.fn.stdpath("log") .. "/copilot-lua.log",
file_log_level = vim.log.levels.WARN,
print_log = true,
file_log_level = vim.log.levels.OFF,
print_log_level = vim.log.levels.WARN,
---@type string<'off'|'messages'|'verbose'>
trace_lsp = "off",
trace_lsp_progress = false,
log_lsp_messages = false,
},
---@deprecated
ft_disable = nil,
Expand Down
57 changes: 36 additions & 21 deletions lua/copilot/logger.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ local uv = vim.uv

---@class logger
local mod = {
log_to_file = false,
log_file = vim.fn.stdpath("log") .. "/copilot-lua.log",
file_log_level = vim.log.levels.WARN,
print_log = true,
file_log_level = vim.log.levels.OFF,
print_log_level = vim.log.levels.WARN,
}

Expand Down Expand Up @@ -75,11 +73,11 @@ end
---@param data any
---@param force_print boolean
function mod.log(log_level, msg, data, force_print)
if mod.log_to_file and (mod.file_log_level <= log_level) then
if mod.file_log_level <= log_level then
write_log(log_level, mod.log_file, msg, data)
end

if force_print or (mod.print_log and (mod.print_log_level <= log_level)) then
if force_print or (mod.print_log_level <= log_level) then
notify_log(log_level, msg, data)
end
end
Expand Down Expand Up @@ -125,27 +123,44 @@ function mod.setup(conf)
mod.log_file = conf.file
mod.file_log_level = conf.file_log_level
mod.print_log_level = conf.print_log_level
mod.log_to_file = conf.log_to_file
mod.print_log = conf.print_log
end

if conf.trace_lsp ~= "off" then
vim.lsp.handlers["$/logTrace"] = function(_, result, _)
if not result then
return
end
function mod.handle_lsp_trace(_, result, _)
if not result then
return
end

mod.trace(string.format("LSP trace - %s", result.message), result.verbose)
end
mod.trace(string.format("LSP trace - %s", result.message), result.verbose)
end

function mod.handle_lsp_progress(_, result, _)
if not result then
return
end

if conf.trace_lsp_progress then
vim.lsp.handlers["$/progress"] = function(_, result, _)
if not result then
return
end
mod.trace(string.format("LSP progress - token %s", result.token), result.value)
end

mod.trace(string.format("LSP progress - token %s", result.token), result.value)
end
function mod.handle_log_lsp_messages(_, result, _)
if not result then
return
end

local message = string.format("LSP message: %s", result.message)
local message_type = result.type --[[@as integer]]

if message_type == 1 then
mod.error(message)
elseif message_type == 2 then
mod.warn(message)
elseif message_type == 3 then
mod.info(message)
elseif message_type == 4 then
mod.info(message)
elseif message_type == 5 then
mod.debug(message)
else
mod.trace(message)
end
end

Expand Down