Skip to content

Commit fdc46e8

Browse files
author
Bassam Data
committed
Merge branch 'Add_filters_commands'
2 parents bba9bd4 + fa83227 commit fdc46e8

File tree

8 files changed

+743
-114
lines changed

8 files changed

+743
-114
lines changed

lua/namu/init.lua

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ M.setup = function(opts)
1414
M.config = vim.tbl_deep_extend("force", M.config, opts)
1515

1616
if M.config.namu_symbols.enable then
17+
require("namu.selecta.selecta").setup(M.config.namu_symbols.options)
1718
require("namu.namu_symbols").setup(M.config.namu_symbols.options)
1819
end
1920

lua/namu/namu_symbols/helpers.lua

+318
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
local M = {}
2+
local request_symbols = require("namu.namu_symbols").request_symbols
3+
local filter_symbol_types = require("namu.namu_symbols").config.filter_symbol_types
4+
5+
-- Shared constants and utilities
6+
---@enum LSPSymbolKinds
7+
local lsp_symbol_kinds = {
8+
[1] = "File",
9+
[2] = "Module",
10+
[3] = "Namespace",
11+
[4] = "Package",
12+
[5] = "Class",
13+
[6] = "Method",
14+
[7] = "Property",
15+
[8] = "Field",
16+
[9] = "Constructor",
17+
[10] = "Enum",
18+
[11] = "Interface",
19+
[12] = "Function",
20+
[13] = "Variable",
21+
[14] = "Constant",
22+
[15] = "String",
23+
[16] = "Number",
24+
[17] = "Boolean",
25+
[18] = "Array",
26+
[19] = "Object",
27+
[20] = "Key",
28+
[21] = "Null",
29+
[22] = "EnumMember",
30+
[23] = "Struct",
31+
[24] = "Event",
32+
[25] = "Operator",
33+
[26] = "TypeParameter",
34+
}
35+
36+
-- Shared UI setup function
37+
---@param buf number
38+
---@param filetype string
39+
local function setup_buffer(buf, filetype)
40+
vim.api.nvim_set_option_value("buftype", "nofile", { buf = buf })
41+
vim.api.nvim_set_option_value("bufhidden", "wipe", { buf = buf })
42+
vim.api.nvim_set_option_value("swapfile", false, { buf = buf })
43+
vim.api.nvim_set_option_value("modifiable", false, { buf = buf })
44+
vim.api.nvim_set_option_value("filetype", filetype, { buf = buf })
45+
46+
local opts = { noremap = true, silent = true }
47+
vim.api.nvim_buf_set_keymap(buf, "n", "q", ":close<CR>", opts)
48+
vim.api.nvim_buf_set_keymap(buf, "n", "<Esc>", ":close<CR>", opts)
49+
end
50+
51+
---@param buf number
52+
---@param content_lines string[]
53+
---@return number window ID
54+
local function create_floating_window(buf, content_lines)
55+
local width = math.min(70, vim.o.columns - 4)
56+
local height = math.min(#content_lines, vim.o.lines - 12)
57+
local row = math.floor((vim.o.lines - height) / 2)
58+
local col = math.floor((vim.o.columns - width) / 2)
59+
60+
local win = vim.api.nvim_open_win(buf, true, {
61+
relative = "editor",
62+
width = width,
63+
height = height,
64+
row = row,
65+
col = col,
66+
style = "minimal",
67+
border = "rounded",
68+
})
69+
70+
-- Set window-local options
71+
vim.api.nvim_set_option_value("conceallevel", 2, { win = win })
72+
vim.api.nvim_set_option_value("foldenable", false, { win = win })
73+
vim.api.nvim_set_option_value("wrap", false, { win = win })
74+
75+
return win
76+
end
77+
78+
-- Highlight management
79+
---@param buf number
80+
---@param ns_id number
81+
---@param line number
82+
---@param col_start number
83+
---@param col_end number
84+
---@param hl_group string
85+
local function add_highlight(buf, ns_id, line, col_start, col_end, hl_group)
86+
local line_content = vim.api.nvim_buf_get_lines(buf, line, line + 1, true)[1] or ""
87+
local end_col = col_end == -1 and #line_content or math.min(col_end, #line_content)
88+
89+
if end_col > col_start then
90+
vim.api.nvim_buf_add_highlight(buf, ns_id, hl_group, line, col_start, end_col)
91+
end
92+
end
93+
94+
local function helper_highlights()
95+
vim.cmd([[
96+
highlight default link NamuHelperHeader Title
97+
highlight default link NamuHelperSubHeader Statement
98+
highlight default link NamuHelperCount Number
99+
highlight default link NamuHelperKind Type
100+
highlight default link NamuHelperFilter Special
101+
highlight default link NamuHelperPath Comment
102+
highlight default link NamuHelperCode Special
103+
]])
104+
end
105+
106+
---@param current_bufname string
107+
---@param total_symbols number
108+
---@param kind_count table<string, number>
109+
---@param kind_examples table<string, string>
110+
---@param default_symbol_types table
111+
---@return string[]
112+
function M.create_analysis_content(current_bufname, total_symbols, kind_count, kind_examples, default_symbol_types)
113+
local lines = {
114+
"Symbol Analysis",
115+
string.rep("=", 50),
116+
"",
117+
string.format("File: %s", vim.fn.fnamemodify(current_bufname, ":.")),
118+
string.format("Total Symbols: %d", total_symbols),
119+
"",
120+
"Symbol Distribution:",
121+
string.rep("-", 50),
122+
"",
123+
}
124+
125+
-- Find matching symbol types
126+
local matched_types = {}
127+
for kind, _ in pairs(kind_count) do
128+
for code, symbol_type in pairs(default_symbol_types) do
129+
if vim.tbl_contains(symbol_type.kinds, kind) then
130+
matched_types[kind] = code
131+
break
132+
end
133+
end
134+
end
135+
136+
-- Add symbol counts and examples
137+
for kind, count in pairs(kind_count) do
138+
local filter_code = matched_types[kind] or "??"
139+
local example = kind_examples[kind] or "N/A"
140+
table.insert(lines, string.format(" %s (%d symbols)", kind, count))
141+
table.insert(lines, string.format(" Filter: /%s", filter_code)) -- Updated to use / instead of %
142+
table.insert(lines, string.format(" Example: %s", example))
143+
table.insert(lines, "")
144+
end
145+
146+
-- Add usage hints
147+
table.insert(lines, "Usage Tips:")
148+
table.insert(lines, string.rep("-", 50))
149+
table.insert(lines, " - Use the filters shown above to narrow down symbols")
150+
table.insert(lines, " - Combine with text: /fn main")
151+
table.insert(lines, " - Press ? in symbol picker for more help")
152+
153+
return lines
154+
end
155+
156+
-- Symbol analysis
157+
---@param symbol table
158+
---@param kind_count table<string, number>
159+
---@param kind_examples table<string, string>
160+
---@return number total_count
161+
local function analyze_symbol(symbol, kind_count, kind_examples)
162+
local total_count = 0
163+
164+
if symbol.kind then
165+
local kind_str = type(symbol.kind) == "number" and lsp_symbol_kinds[symbol.kind] or symbol.kind
166+
if kind_str then
167+
kind_count[kind_str] = (kind_count[kind_str] or 0) + 1
168+
total_count = total_count + 1
169+
170+
if not kind_examples[kind_str] and symbol.name then
171+
kind_examples[kind_str] = symbol.name
172+
end
173+
end
174+
end
175+
176+
if symbol.children then
177+
for _, child in ipairs(symbol.children) do
178+
total_count = total_count + analyze_symbol(child, kind_count, kind_examples)
179+
end
180+
end
181+
182+
return total_count
183+
end
184+
185+
local function set_buffer_lines(buf, lines)
186+
vim.api.nvim_set_option_value("modifiable", true, { buf = buf })
187+
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
188+
vim.api.nvim_set_option_value("modifiable", false, { buf = buf })
189+
end
190+
191+
---@return number, number buffer window ID, number window ID
192+
function M.create_help_buffer()
193+
local buf = vim.api.nvim_create_buf(false, true)
194+
setup_buffer(buf, "namu-help")
195+
196+
local lines = {
197+
"Namu Symbol Types",
198+
string.rep("=", 40),
199+
"",
200+
"Usage: Type /xx followed by search term",
201+
"Example: /fn main - finds functions containing 'main'",
202+
"",
203+
"Available Symbol Types:",
204+
string.rep("-", 40),
205+
"",
206+
}
207+
208+
for code, symbol_type in pairs(filter_symbol_types) do
209+
table.insert(lines, string.format(" %s - %s", code, symbol_type.description))
210+
table.insert(lines, string.format(" Matches: %s", table.concat(symbol_type.kinds, ", ")))
211+
table.insert(lines, "")
212+
end
213+
214+
set_buffer_lines(buf, lines)
215+
216+
local win = create_floating_window(buf, lines)
217+
218+
helper_highlights()
219+
local ns_id = vim.api.nvim_create_namespace("namu_help")
220+
221+
-- Apply highlights with unified groups
222+
add_highlight(buf, ns_id, 0, 0, -1, "NamuHelperHeader")
223+
add_highlight(buf, ns_id, 3, 0, 5, "NamuHelperSubHeader")
224+
add_highlight(buf, ns_id, 4, 0, -1, "NamuHelperCode")
225+
add_highlight(buf, ns_id, 6, 0, -1, "NamuHelperSubHeader")
226+
227+
local current_line = 9
228+
for _ in pairs(filter_symbol_types) do
229+
add_highlight(buf, ns_id, current_line, 2, 4, "NamuHelperCode")
230+
add_highlight(buf, ns_id, current_line, 7, -1, "NamuHelperKind")
231+
add_highlight(buf, ns_id, current_line + 1, 4, -1, "NamuHelperFilter")
232+
current_line = current_line + 3
233+
end
234+
235+
return buf, win
236+
end
237+
238+
-- Analyzer functionality
239+
---@return number, number buffer ID, number window ID
240+
function M.create_analysis_buffer()
241+
local current_buf = vim.api.nvim_get_current_buf()
242+
local current_bufname = vim.api.nvim_buf_get_name(current_buf)
243+
local buf = vim.api.nvim_create_buf(false, true)
244+
245+
setup_buffer(buf, "namu-analysis")
246+
-- Create initial window while waiting for symbols
247+
set_buffer_lines(buf, { "Loading symbols..." })
248+
local win = create_floating_window(buf, { "Loading symbols..." })
249+
250+
-- Setup highlights
251+
helper_highlights()
252+
local ns_id = vim.api.nvim_create_namespace("namu_analysis")
253+
254+
-- Collect and analyze symbols
255+
request_symbols(current_buf, function(err, symbols)
256+
if err then
257+
vim.notify("Error fetching symbols: " .. vim.inspect(err), vim.log.levels.ERROR)
258+
return
259+
end
260+
261+
local kind_count = {}
262+
local kind_examples = {}
263+
local total_symbols = 0
264+
265+
-- Analyze symbols
266+
for _, symbol in ipairs(symbols or {}) do
267+
total_symbols = total_symbols + analyze_symbol(symbol, kind_count, kind_examples)
268+
end
269+
270+
-- Create and set content
271+
local lines =
272+
M.create_analysis_content(current_bufname, total_symbols, kind_count, kind_examples, filter_symbol_types)
273+
274+
if win and vim.api.nvim_win_is_valid(win) then
275+
vim.api.nvim_win_set_buf(win, buf)
276+
set_buffer_lines(buf, lines)
277+
-- Adjust window height for new content
278+
local new_height = math.min(#lines, vim.o.lines - 6)
279+
local width = math.min(70, vim.o.columns - 4)
280+
281+
-- Update both height and position
282+
vim.api.nvim_win_set_config(win, {
283+
relative = "editor",
284+
row = math.floor((vim.o.lines - new_height - 4) / 2),
285+
col = math.floor((vim.o.columns - width) / 2),
286+
height = new_height,
287+
})
288+
end
289+
290+
add_highlight(buf, ns_id, 0, 0, -1, "NamuHelperHeader")
291+
add_highlight(buf, ns_id, 3, 0, 5, "NamuHelperSubHeader")
292+
add_highlight(buf, ns_id, 3, 6, -1, "NamuHelperPath")
293+
add_highlight(buf, ns_id, 4, 0, 14, "NamuHelperSubHeader")
294+
add_highlight(buf, ns_id, 4, 15, -1, "NamuHelperCount")
295+
add_highlight(buf, ns_id, 6, 0, -1, "NamuHelperSubHeader")
296+
297+
-- Symbol Distribution section
298+
add_highlight(buf, ns_id, 6, 0, -1, "NamuAnalysisSubHeader")
299+
300+
-- Highlight symbol sections
301+
local current_line = 9
302+
for kind, _ in pairs(kind_count) do
303+
-- Kind line
304+
add_highlight(buf, ns_id, current_line, 2, -1, "NamuHelperKind")
305+
-- Filter line
306+
add_highlight(buf, ns_id, current_line + 1, 12, -1, "NamuHelperFilter")
307+
current_line = current_line + 4
308+
end
309+
310+
-- Usage section
311+
add_highlight(buf, ns_id, current_line, 0, -1, "NamuAnalysisSubHeader")
312+
add_highlight(buf, ns_id, current_line + 1, 0, -1, "NamuAnalysisFilter")
313+
end)
314+
315+
return buf, win
316+
end
317+
318+
return M

0 commit comments

Comments
 (0)