Skip to content

Commit c15f65e

Browse files
authored
perf(core): do not require calling setup(), add lazy initialization (#1413)
Refactored plugin initialization to use lazy loading via metatable, setting an `initialized` flag and moving setup logic to `init()`. Replaced `add_providers` with `set_providers` for clarity. Improved health check to verify initialization. Cleaned up chat state handling and logging logic for better reliability and maintainability. Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
1 parent 0514e7d commit c15f65e

4 files changed

Lines changed: 87 additions & 67 deletions

File tree

lua/CopilotChat/client.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ end
211211

212212
--- Set a provider resolver on the client
213213
---@param resolver function: A function that returns a table of providers
214-
function Client:add_providers(resolver)
214+
function Client:set_providers(resolver)
215215
self.provider_resolver = resolver
216216
end
217217

lua/CopilotChat/health.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ function M.check()
5757
error('nvim: unsupported, please upgrade to 0.10.0 or later. See "https://neovim.io/".')
5858
end
5959

60-
local setup_called = require('CopilotChat').config ~= nil
61-
if setup_called then
62-
ok('setup: called')
60+
local initialized = require('CopilotChat').initialized
61+
if initialized then
62+
ok('initialized: true')
6363
else
64-
error('setup: not called, required for plugin to work. See `:h CopilotChat-installation`.')
64+
error('initialized: false, something went wrong. See `:h CopilotChat-installation`.')
6565
end
6666

6767
local testfile = os.tmpname()

lua/CopilotChat/init.lua

Lines changed: 82 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ local M = setmetatable({}, {
2323
if key == 'config' then
2424
return require('CopilotChat.config')
2525
end
26+
27+
-- Lazy initialize
28+
local initialized = rawget(t, 'initialized')
29+
if not initialized then
30+
rawset(t, 'initialized', true)
31+
rawget(t, 'init')()
32+
end
33+
2634
return rawget(t, key)
2735
end,
2836
})
@@ -33,8 +41,8 @@ local M = setmetatable({}, {
3341
--- @field cwd fun():string
3442

3543
--- @class CopilotChat.state
36-
--- @field source CopilotChat.source?
37-
--- @field sticky string[]?
44+
--- @field source CopilotChat.source
45+
--- @field sticky string[]
3846
local state = {
3947
source = {
4048
bufnr = nil,
@@ -44,7 +52,7 @@ local state = {
4452
end,
4553
},
4654

47-
sticky = nil,
55+
sticky = {},
4856
}
4957

5058
--- Insert sticky values from config into prompt
@@ -1023,28 +1031,32 @@ function M.log_level(level)
10231031
M.config.log_level = level
10241032
M.config.debug = level == 'debug'
10251033

1026-
log.new({
1027-
plugin = constants.PLUGIN_NAME,
1028-
level = level,
1029-
outfile = M.config.log_path,
1030-
fmt_msg = function(is_console, mode_name, src_path, src_line, msg)
1031-
local nameupper = mode_name:upper()
1032-
if is_console then
1033-
return string.format('[%s] %s', nameupper, msg)
1034-
else
1035-
local lineinfo = src_path .. ':' .. src_line
1036-
return string.format('[%-6s%s] %s: %s\n', nameupper, os.date(), lineinfo, msg)
1037-
end
1038-
end,
1039-
}, true)
1034+
if level ~= log.level then
1035+
log.new({
1036+
plugin = constants.PLUGIN_NAME,
1037+
level = level,
1038+
outfile = M.config.log_path,
1039+
fmt_msg = function(is_console, mode_name, src_path, src_line, msg)
1040+
local nameupper = mode_name:upper()
1041+
if is_console then
1042+
return string.format('[%s] %s', nameupper, msg)
1043+
else
1044+
local lineinfo = src_path .. ':' .. src_line
1045+
return string.format('[%-6s%s] %s: %s\n', nameupper, os.date(), lineinfo, msg)
1046+
end
1047+
end,
1048+
}, true)
1049+
log.level = level
1050+
end
10401051
end
10411052

1042-
--- Set up the plugin
1043-
---@param config CopilotChat.config.Config?
1044-
function M.setup(config)
1045-
-- Little bit of update magic
1046-
for k, v in pairs(vim.tbl_deep_extend('force', M.config, config or {})) do
1047-
M.config[k] = v
1053+
--- Initialize the plugin if not already initialized.
1054+
function M.init()
1055+
-- Set log level
1056+
if M.config.debug then
1057+
M.log_level('debug')
1058+
else
1059+
M.log_level(M.config.log_level)
10481060
end
10491061

10501062
-- Save proxy and insecure settings
@@ -1054,15 +1066,53 @@ function M.setup(config)
10541066
})
10551067

10561068
-- Load the providers
1057-
client:stop()
1058-
client:add_providers(function()
1069+
client:set_providers(function()
10591070
return M.config.providers
10601071
end)
10611072

1062-
if M.config.debug then
1063-
M.log_level('debug')
1064-
else
1065-
M.log_level(M.config.log_level)
1073+
-- Initialize chat
1074+
if not M.chat then
1075+
M.chat = require('CopilotChat.ui.chat')(M.config, function(bufnr)
1076+
for name, _ in pairs(M.config.mappings) do
1077+
map_key(name, bufnr)
1078+
end
1079+
1080+
require('CopilotChat.completion').enable(bufnr, M.config.chat_autocomplete)
1081+
1082+
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufLeave' }, {
1083+
buffer = bufnr,
1084+
callback = function(ev)
1085+
if ev.event == 'BufEnter' then
1086+
update_source()
1087+
end
1088+
1089+
vim.schedule(function()
1090+
select.highlight(state.source.bufnr, not (M.config.highlight_selection and M.chat:focused()))
1091+
end)
1092+
end,
1093+
})
1094+
1095+
if M.config.insert_at_end then
1096+
vim.api.nvim_create_autocmd({ 'InsertEnter' }, {
1097+
buffer = bufnr,
1098+
callback = function()
1099+
vim.cmd('normal! 0')
1100+
vim.cmd('normal! G$')
1101+
vim.v.char = 'x'
1102+
end,
1103+
})
1104+
end
1105+
1106+
finish(true)
1107+
end)
1108+
end
1109+
end
1110+
1111+
--- Set up the plugin
1112+
---@param config CopilotChat.config.Config?
1113+
function M.setup(config)
1114+
for k, v in pairs(vim.tbl_deep_extend('force', M.config, config or {})) do
1115+
M.config[k] = v
10661116
end
10671117

10681118
if not M.config.separator or M.config.separator == '' then
@@ -1073,42 +1123,13 @@ function M.setup(config)
10731123
end
10741124

10751125
if M.chat then
1126+
client:stop()
10761127
M.chat:close(state.source.bufnr)
10771128
M.chat:delete()
1129+
M.chat = nil
10781130
end
1079-
M.chat = require('CopilotChat.ui.chat')(M.config, function(bufnr)
1080-
for name, _ in pairs(M.config.mappings) do
1081-
map_key(name, bufnr)
1082-
end
1083-
1084-
require('CopilotChat.completion').enable(bufnr, M.config.chat_autocomplete)
1085-
1086-
vim.api.nvim_create_autocmd({ 'BufEnter', 'BufLeave' }, {
1087-
buffer = bufnr,
1088-
callback = function(ev)
1089-
if ev.event == 'BufEnter' then
1090-
update_source()
1091-
end
1092-
1093-
vim.schedule(function()
1094-
select.highlight(state.source.bufnr, not (M.config.highlight_selection and M.chat:focused()))
1095-
end)
1096-
end,
1097-
})
10981131

1099-
if M.config.insert_at_end then
1100-
vim.api.nvim_create_autocmd({ 'InsertEnter' }, {
1101-
buffer = bufnr,
1102-
callback = function()
1103-
vim.cmd('normal! 0')
1104-
vim.cmd('normal! G$')
1105-
vim.v.char = 'x'
1106-
end,
1107-
})
1108-
end
1109-
1110-
finish(true)
1111-
end)
1132+
M.init()
11121133

11131134
for name, prompt in pairs(list_prompts()) do
11141135
if prompt.prompt then

lua/CopilotChat/tiktoken.lua

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
local log = require('plenary.log')
21
local notify = require('CopilotChat.notify')
32
local utils = require('CopilotChat.utils')
43
local curl = require('CopilotChat.utils.curl')

0 commit comments

Comments
 (0)