local su = require("proclist.string_util") local Proclist = {} local state = {} Proclist.prefix = "[Proclist]: " Proclist.check_file_extension = true Proclist.is_jai_file = false state.window_open = false function Proclist.show_matches() local buf = vim.api.nvim_create_buf(false, true) local display = {} for _, match in ipairs(state.matches) do table.insert(display, match.line_number .. ": " .. match.text) end vim.api.nvim_buf_set_lines(buf, 0, -1, false, display) local width = math.floor(vim.o.columns * 0.8) local height = math.min(#state.matches, math.floor(vim.o.lines * 0.8)) if width <= 0 or height <= 0 then return end local col = math.floor((vim.o.columns - width) / 2) local row = math.floor((vim.o.lines - height) / 2) local win = vim.api.nvim_open_win(buf, true, { relative = "editor", width = width, height = height, row = row, col = col, style = "minimal", border = "rounded", }) vim.api.nvim_buf_set_option(buf, "modifiable", false) vim.api.nvim_win_set_option(win, "cursorline", true) local opts = { noremap = true, silent = true } local function handle_close() local line = vim.api.nvim_win_get_cursor(win)[1] vim.api.nvim_win_close(win, true) local target = state.matches[line] if target then vim.api.nvim_win_set_cursor(0, {target.line_number, 0}) end Proclist.window_state_set(false) end vim.api.nvim_buf_set_keymap(buf, "n", "", "", vim.tbl_extend("force", opts, { callback = handle_close, nowait = true, })) vim.api.nvim_buf_set_keymap(buf, "n", "q", "", vim.tbl_extend("force", opts, { callback = handle_close, nowait = true, })) vim.api.nvim_buf_set_keymap(buf, "n", "", "", vim.tbl_extend("force", opts, { callback = handle_close, nowait = true, })) end function Proclist.window_state_set(b) state.window_open = b end function Proclist.pattern(keyword) Proclist.proc_pattern = "\\w\\s*::\\s*" .. keyword end function Proclist.proc() Proclist.pattern("(") Proclist.search() end function Proclist.struct() Proclist.pattern("struct") Proclist.search() end function Proclist.enum() Proclist.pattern("enum") Proclist.search() end function Proclist.search() if Proclist.check_file_extension == true and Proclist.is_jai_file == false then return end if state.window_open == true then return end state.window_open = true state.matches = {} local buf = vim.api.nvim_get_current_buf() local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false) local i = 1 while i <= #lines do local line = lines[i] if vim.fn.match(line, Proclist.proc_pattern) >= 0 then local start_line = i local func_line = su.trim(line) while not func_line:find("{") and i < #lines do i = i + 1 func_line = func_line .. " " .. su.trim(lines[i]) end local cleaned = su.trim(su.remove_braces(func_line)) table.insert(state.matches, { line_number = start_line, text = cleaned }) end i = i + 1 end if #state.matches == 0 then print(Proclist.prefix .. "No matches found") return end Proclist.show_matches() end function Proclist.setup(opts) opts = opts or {} local proc_key = opts.proc_key or "q" local struct_key = opts.struct_key or "w" local enum_key = opts.enum_key or "e" Proclist.check_file_extension = opts.check_file_extension or true vim.keymap.set("n", proc_key, Proclist.proc, { noremap = true, silent = true }) vim.keymap.set("n", struct_key, Proclist.struct, { noremap = true, silent = true }) vim.keymap.set("n", enum_key, Proclist.enum, { noremap = true, silent = true }) end vim.api.nvim_create_autocmd("BufReadPost", { pattern = "*.jai", callback = function() Proclist.is_jai_file = true end, }) return Proclist