-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcontext.lua
More file actions
144 lines (119 loc) · 3.69 KB
/
Copy pathcontext.lua
File metadata and controls
144 lines (119 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
local M = {}
---@class ctx
---@field scopes TSNode[] Scopes of each function around the cursor
---@field globals string[] Current line the cursor is at
---@field imports string[] This is related to Lsp stuff so we are going to integrate this in future
---@class ModelCmp.ContextEngine
---@field bufnr integer current buffer number
---@field cursor integer[] current cursor pos
---@field lang string querylanguage to choose
---@field ctx ctx
M.ContextEngine = {
bufnr = 0,
cursor = { 0, 0 },
lang = "text",
ctx = {
scopes = {},
globals = {},
imports = {},
},
}
function M.ContextEngine:clear_ctx()
self.ctx = {
scopes = {},
globals = {},
imports = {},
}
end
function M.ContextEngine:get_root()
local parser = vim.treesitter.get_parser(0, self.lang, {})
if parser == nil then
return {}
end
local tree = parser:parse()[1]
return tree:root()
end
function M.ContextEngine:get_nodes_from_query(which_query)
local ok, query = pcall(vim.treesitter.query.get, self.lang, which_query)
if not ok or query == nil then
return {}
end
local root = self:get_root()
local return_nodes = {}
for _, match, _ in query:iter_matches(root, self.bufnr, 0, -1, { all = true }) do
for _, nodes in pairs(match) do
for _, node in ipairs(nodes) do
table.insert(return_nodes, node)
end
end
end
return return_nodes
end
function M.ContextEngine:get_scopes_and_ranges()
local scope_query = "context-scope"
self.ctx.scopes = self:get_nodes_from_query(scope_query)
if #self.ctx.scopes == 0 then
scope_query = "context-all"
self.ctx.scopes = self:get_nodes_from_query(scope_query)
end
end
function M.ContextEngine:get_imports()
local import_query = "context-import"
self.ctx.imports = self:get_nodes_from_query(import_query)
end
function M.ContextEngine:get_globals()
local global_query = "context-globals"
self.ctx.globals = self:get_nodes_from_query(global_query)
end
function M.ContextEngine:get_ctx()
self.bufnr = vim.api.nvim_get_current_buf()
self.cursor = vim.api.nvim_win_get_cursor(0)
self.lang = vim.bo.ft
self:get_scopes_and_ranges()
self:get_imports()
self:get_globals()
end
---@param node TSNode
---@return boolean
local function scopes_inrange(node, cursor)
local start_r, _, end_r, _ = node:range()
return cursor[1] >= start_r and cursor[1] <= end_r
end
local function node_to_line_array(node_text)
local lines = {}
for line in node_text:gmatch("([^\n]*)[\n]?") do
if line ~= "" then
table.insert(lines, line)
end
end
return lines
end
local function add_missing_tag(line, cursor)
local missing = string.sub(line, 1, cursor[2]) .. "<missing>" .. string.sub(line, cursor[2] + 1)
return missing
end
function M.ContextEngine:generate_context_text()
local lines = [[]]
self:get_ctx()
for _, k in ipairs(self.ctx.scopes) do
if scopes_inrange(k, self.cursor) then
lines = lines .. vim.treesitter.get_node_text(k, self.bufnr)
end
end
local lines_list = node_to_line_array(lines)
local currentline = vim.api.nvim_buf_get_lines(self.bufnr, self.cursor[1] - 1, self.cursor[1] + 1, false)
if #lines_list == 0 then
lines_list = vim.api.nvim_buf_get_lines(self.bufnr, 1, -1, false)
end
for i, _ in ipairs(lines_list) do
if lines_list[i] == currentline[1] then
lines_list[i] = add_missing_tag(currentline[1], self.cursor)
end
end
lines = [[]]
for _, k in ipairs(lines_list) do
lines = lines .. k .. "\n"
end
return lines
end
return M