Skip to content

Commit 199d5ac

Browse files
committed
Added profiler and switched to using jobs to avoid work in main thread
1 parent 0108c03 commit 199d5ac

File tree

8 files changed

+274
-119
lines changed

8 files changed

+274
-119
lines changed

README.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,27 @@ You can configure Latios by calling the setup function:
3232
```lua
3333
require('latios').setup({
3434
api_key = "your-api-key",
35-
max_lines = 150,
36-
debounce_ms = 250,
35+
debounce_ms = 500,
3736
})
3837
```
3938

39+
## Performance Notes
40+
41+
Currently, it is able to generate completions and has the ergonomics of a
42+
co-pilot. There is some issue with lag especially in markdown files for whatever
43+
reason.
44+
45+
IT doesn't do a great job of "completing" or generating the next token and can
46+
instead generate existing tokens. Such as if you write "local var = " expecting
47+
it to just complete the remaining output it will often generate the entire
48+
variable declaration again or repeat part of the existing code.
49+
50+
Another issue is that the completions may not always be context-aware,
51+
especially when dealing with complex code structures or domain-specific
52+
languages. This can result in suggestions that are syntactically correct but
53+
semantically incorrect or irrelevant to the current context.
54+
55+
4056
## License
4157

4258
MIT

lua/latios/config.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ local M = {}
22

33
local default_config = {
44
api_key = "",
5-
debounce_ms = 300,
5+
debounce_ms = 500,
66
}
77

88
M.options = {}

lua/latios/context.lua

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function M.get_treesitter_context()
5555
end
5656

5757
-- In lua/latios/context.lua (continued)
58-
function M.get_full_context()
58+
local function get_full_context()
5959
return {
6060
lsp = M.get_lsp_context(),
6161
treesitter = M.get_treesitter_context(),
@@ -66,4 +66,31 @@ function M.get_full_context()
6666
}
6767
end
6868

69+
-- Reduced context
70+
local function get_reduced_context()
71+
local cursor_line = vim.api.nvim_win_get_cursor(0)[1]
72+
local start_line = math.max(1, cursor_line - 50)
73+
local end_line = math.min(vim.api.nvim_buf_line_count(0), cursor_line + 50)
74+
return {
75+
lsp = M.get_lsp_context(),
76+
treesitter = M.get_treesitter_context(),
77+
buffer_content = vim.api.nvim_buf_get_lines(0, start_line - 1, end_line, false),
78+
cursor_position = vim.api.nvim_win_get_cursor(0),
79+
filetype = vim.bo.filetype,
80+
}
81+
end
82+
83+
local context_cache = {}
84+
function M.get_cached_context()
85+
local bufnr = vim.api.nvim_get_current_buf()
86+
local changedticked = vim.b[bufnr].changedtick
87+
if context_cache[bufnr] and context_cache[bufnr].tick == changedtick then
88+
return context_cache[bufnr].context
89+
end
90+
-- local context = M.get_full_context()
91+
local context = get_reduced_context()
92+
context_cache[bufnr] = { context = context, tick = changedticked }
93+
return context
94+
end
95+
6996
return M

lua/latios/display.lua

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ local current_extmark_id = nil
2323
-- hl_mode = 'combine',
2424
-- }
2525
-- }
26-
2726
function M.show_completion(completion)
27+
if completion == 'nil' then return end
2828
local bufnr = vim.api.nvim_get_current_buf()
2929
local ns_id = vim.api.nvim_create_namespace('latios')
3030
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
@@ -112,27 +112,6 @@ function M.accept_completion()
112112

113113
vim.api.nvim_win_set_cursor(0, { end_line + 1, end_col })
114114

115-
-- -- Join all lines
116-
-- local completion_text = table.concat(completion_lines, '\n')
117-
--
118-
-- -- Insert the completion text
119-
-- local end_line = line + #completion_lines - 1
120-
-- local end_col = col
121-
-- if #completion_lines == 1 then
122-
-- end_col = col + #completion_text
123-
-- else
124-
-- end_col = #completion_lines[#completion_lines]
125-
-- end
126-
--
127-
-- -- Insert the completion text
128-
-- vim.api.nvim_buf_set_text(bufnr, line, col, end_line, end_col, completion_lines)
129-
--
130-
-- -- Move the cursor to the end of the inserted text
131-
-- -- local new_col = col + #completion_text
132-
-- -- Move the cursor to the end of the inserted text
133-
-- vim.api.nvim_win_set_cursor(0, { end_line + 1, end_col })
134-
135-
-- Ensure we're in insert mode at the end of the inserted text
136115
vim.cmd('startinsert!')
137116
end
138117
M.clear_completion()

lua/latios/init.lua

Lines changed: 6 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,18 @@ local M = {}
22
local server = require('latios.server')
33
local display = require('latios.display')
44
local utils = require('latios.utils')
5-
local config = require('latios.config')
6-
local bug = require('latios.debug')
7-
8-
local debounce_timer = nil
9-
local debounce_delay = 300
10-
local is_insert_mode = false
115

126
function M.setup(opts)
137
require('latios.config').setup(opts)
148

15-
debounce_delay = config.options.debounce_ms
16-
179
vim.api.nvim_create_autocmd({ "InsertEnter", "CursorMovedI", "CompleteChanged" }, {
1810
callback = function()
1911
if vim.g.latios_enabled and not utils.is_telescope_buffer() then
20-
is_insert_mode = true
21-
M.debounced_completion()
12+
server.debounced_request_completion(function(completion)
13+
if completion then
14+
display.show_completion(completion)
15+
end
16+
end)
2217
end
2318
end,
2419
})
@@ -27,63 +22,11 @@ function M.setup(opts)
2722
callback = function()
2823
is_insert_mode = false
2924
if vim.g.latios_enabled and not utils.is_telescope_buffer() then
30-
if debounce_timer then
31-
debounce_timer:stop()
32-
debounce_timer:close()
33-
debounce_timer = nil
34-
end
25+
server.cancel_ongoing_requests()
3526
display.clear_completion()
3627
end
3728
end,
3829
})
39-
-- vim.api.nvim_create_autocmd("CursorMovedI", {
40-
-- callback = function()
41-
-- if is_insert_mode and vim.g.latios_enabled and not utils.is_telescope_buffer() then
42-
-- display.clear_completion()
43-
-- M.debounced_completion()
44-
-- end
45-
-- end,
46-
-- })
47-
-- vim.api.nvim_create_autocmd("BufUnload", {
48-
-- pattern = "*",
49-
-- callback = function()
50-
-- if debounce_timer then
51-
-- debounce_timer:stop()
52-
-- debounce_timer:close()
53-
-- debounce_timer = nil
54-
-- end
55-
-- end,
56-
-- })
57-
end
58-
59-
local function trigger_completion()
60-
if is_insert_mode then
61-
server.request_completion(function(completion)
62-
if is_insert_mode then
63-
display.show_completion(completion)
64-
end
65-
end)
66-
else
67-
display.clear_completion()
68-
end
69-
end
70-
71-
function M.debounced_completion()
72-
display.clear_completion()
73-
if debounce_timer then
74-
debounce_timer:stop()
75-
end
76-
77-
debounce_timer = vim.loop.new_timer()
78-
debounce_timer:start(debounce_delay, 0, vim.schedule_wrap(function()
79-
if is_insert_mode then
80-
trigger_completion()
81-
else
82-
display.clear_completion()
83-
end
84-
debounce_timer:close()
85-
debounce_timer = nil
86-
end))
8730
end
8831

8932
return M

lua/latios/profiler.lua

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
-- lua/latios/profiler.lua
2+
local M = {}
3+
4+
M.profiles = {}
5+
M.is_active = false
6+
7+
function M.start()
8+
M.is_active = true
9+
M.profiles = {}
10+
end
11+
12+
function M.stop()
13+
M.is_active = false
14+
end
15+
16+
function M.profile(name, fn)
17+
return function(...)
18+
if not M.is_active then
19+
return fn(...)
20+
end
21+
22+
local start_time = vim.loop.hrtime()
23+
local result = { fn(...) }
24+
local end_time = vim.loop.hrtime()
25+
26+
local duration = (end_time - start_time) / 1e6 -- Convert to milliseconds
27+
if not M.profiles[name] then
28+
M.profiles[name] = { count = 0, total_time = 0 }
29+
end
30+
M.profiles[name].count = M.profiles[name].count + 1
31+
M.profiles[name].total_time = M.profiles[name].total_time + duration
32+
33+
return unpack(result)
34+
end
35+
end
36+
37+
local stack = {}
38+
39+
function M.start_span(name)
40+
if not M.is_active then return end
41+
local span = { name = name, start_time = vim.loop.hrtime(), children = {} }
42+
table.insert(stack, span)
43+
end
44+
45+
function M.end_span()
46+
if not M.is_active then return end
47+
local span = table.remove(stack)
48+
if span then
49+
span.end_time = vim.loop.hrtime()
50+
span.duration = (span.end_time - span.start_time) / 1e6 -- Convert to milliseconds
51+
if #stack > 0 then
52+
table.insert(stack[#stack].children, span)
53+
else
54+
table.insert(M.profiles, span)
55+
end
56+
end
57+
end
58+
59+
function M.report()
60+
local function print_span(span, depth)
61+
local indent = string.rep(" ", depth)
62+
print(string.format("%s%s: %.2f ms", indent, span.name, span.duration))
63+
for _, child in ipairs(span.children) do
64+
print_span(child, depth + 1)
65+
end
66+
end
67+
68+
print("Profiling Report:")
69+
for _, span in ipairs(M.profiles) do
70+
print_span(span, 0)
71+
end
72+
end
73+
74+
-- function M.report()
75+
-- local sorted_profiles = {}
76+
-- for name, data in pairs(M.profiles) do
77+
-- table.insert(sorted_profiles, { name = name, count = data.count, total_time = data.total_time })
78+
-- end
79+
--
80+
-- table.sort(sorted_profiles, function(a, b) return a.total_time > b.total_time end)
81+
--
82+
-- local report = "Profiling Report:\n"
83+
-- for _, profile in ipairs(sorted_profiles) do
84+
-- report = report .. string.format("%s: %d calls, %.2f ms total, %.2f ms avg\n",
85+
-- profile.name, profile.count, profile.total_time, profile.total_time / profile.count)
86+
-- end
87+
--
88+
-- print(report)
89+
-- end
90+
91+
return M

0 commit comments

Comments
 (0)