Author:ptrace
Comitter:ptrace
Date:2025-08-23 16:53:30 UTC
diff --git a/.gitignore b/.gitignore
index 4871fd5..e69de29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +0,0 @@
test.txt
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..1d44c41
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,5 @@
.PHONY: test
test:
@echo "===> Testing"
nvim -u dev/min.lua --noplugin test_data
diff --git a/README.md b/README.md
index 8abc257..4510dd1 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,22 @@
# Proc-List
Shows all procedures for Jai inside the current buffer and jumps to them.
# Proc-List for Jai
Shows all procedures, structs, or enums inside the current buffer and jumps to them.
## Install & Setup
```lua
use {
"worstprgr/proclist", branch = 'stable',
config = function()
require("proclist").setup({ key = "<leader>q" })
require("proclist").setup({
proc_key = "<leader>q", -- searches for procedures
struct_key = "<leader>w", -- .. .. structs
enum_key = "<leader>e", -- .. .. enums
check_file_extension = true -- if true, it's only enabled
}) -- for *.jai files
end
}
```
## Default Keybinds
```plain
<leader>q -> shows procedures
```
## Caveat
Very buggy, I didn't put much effort in it.
## Todo
- activate only in *.jai files
- add support for structs and enums
- show scroll bar
- resize window dynamically; add max-width, max-height
## Dev
Using `make test` opens a new Neovim session without any plugins,
except Netrw and this (local) plugin.
diff --git a/dev/min.lua b/dev/min.lua
new file mode 100644
index 0000000..035e94d
--- /dev/null
+++ b/dev/min.lua
@@ -0,0 +1,17 @@
-- minimal setup for testing
vim.opt.runtimepath = {
vim.fn.expand("$VIMRUNTIME"),
vim.fn.getcwd(),
}
vim.o.swapfile = false
vim.g.mapleader = " "
vim.keymap.set("n", "<leader>pv", vim.cmd.Ex)
vim.cmd("runtime! plugin/netrwPlugin.vim")
require("proclist").setup({
proc_key = "<leader>q",
struct_key = "<leader>w",
enum_key = "<leader>e",
check_file_extension = true
})
diff --git a/lua/proclist/init.lua b/lua/proclist/init.lua
index 647f430..77a26fd 100644
--- a/lua/proclist/init.lua
+++ b/lua/proclist/init.lua
@@ -1,28 +1,34 @@
local su = require("proclist.string_util")
local Proclist = {}
local state = {}
function Proclist.trim(s)
return s:match("^%s*(.-)%s*$")
end
Proclist.prefix = "[Proclist]: "
Proclist.check_file_extension = true
Proclist.is_jai_file = false
state.window_open = false
function Proclist.remove_braces(s)
return s:gsub("[%{%}]", "")
end
function Proclist.show_matches(matches)
function Proclist.show_matches()
local buf = vim.api.nvim_create_buf(false, true)
local display = {}
for _, match in ipairs(matches) do
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.5)
local height = math.min(#matches, math.floor(vim.o.lines * 0.3))
local row = math.floor((vim.o.lines - height) / 2)
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",
@@ -37,54 +43,113 @@ function Proclist.show_matches(matches)
vim.api.nvim_buf_set_option(buf, "modifiable", false)
vim.api.nvim_win_set_option(win, "cursorline", true)
local opts = { nowait = true, noremap = true, silent = true }
vim.api.nvim_buf_set_keymap(buf, "n", "<Esc>", "<cmd>close<CR>", opts)
vim.api.nvim_buf_set_keymap(buf, "n", "q", "<cmd>close<CR>", opts)
vim.api.nvim_buf_set_keymap(buf, "n", "<CR>", "", {
noremap = true, silent = true,
callback = function()
local line = vim.api.nvim_win_get_cursor(win)[1]
vim.api.nvim_win_close(win, true)
local target = matches[line]
if target then
vim.api.nvim_win_set_cursor(0, {target.line_number, 0})
end
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", "<Esc>", "", 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", "<CR>", "", vim.tbl_extend("force", opts, {
callback = handle_close,
nowait = true,
}))
end
function Proclist.window_state_set(b)
state.window_open = b
end
function Proclist.list()
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 start_pattern = "\\w\\s*::\\s*("
local matches = {}
local i = 1
while i <= #lines do
local line = lines[i]
if vim.fn.match(line, start_pattern) >= 0 then
if vim.fn.match(line, Proclist.proc_pattern) >= 0 then
local start_line = i
local func_line = Proclist.trim(line)
local func_line = su.trim(line)
while not func_line:find("{") and i < #lines do
i = i + 1
func_line = func_line .. " " .. Proclist.trim(lines[i])
func_line = func_line .. " " .. su.trim(lines[i])
end
local cleaned = Proclist.trim(Proclist.remove_braces(func_line))
table.insert(matches, { line_number = start_line, text = cleaned })
local cleaned = su.trim(su.remove_braces(func_line))
table.insert(state.matches, { line_number = start_line, text = cleaned })
end
i = i + 1
end
Proclist.show_matches(matches)
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 key = opts.key or "<leader>q"
vim.keymap.set("n", key, Proclist.list, { noremap = true, silent = true })
local proc_key = opts.proc_key or "<leader>q"
local struct_key = opts.struct_key or "<leader>w"
local enum_key = opts.enum_key or "<leader>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
return Proclist
vim.api.nvim_create_autocmd("BufReadPost", {
pattern = "*.jai",
callback = function()
Proclist.is_jai_file = true
end,
})
return Proclist
diff --git a/lua/proclist/string_util.lua b/lua/proclist/string_util.lua
new file mode 100644
index 0000000..b3bcb73
--- /dev/null
+++ b/lua/proclist/string_util.lua
@@ -0,0 +1,11 @@
local string_utils = {}
function string_utils.trim(s)
return s:match("^%s*(.-)%s*$")
end
function string_utils.remove_braces(s)
return s:gsub("[%{%}]", "")
end
return string_utils
diff --git a/test_data/test1.jai b/test_data/test1.jai
new file mode 100644
index 0000000..9895e1b
--- /dev/null
+++ b/test_data/test1.jai
@@ -0,0 +1,18 @@
foo :: () {}
bar :: (test: []string, bazz: s64) -> bool {}
spam :: (
a: int,
b: int,
c: Vector2
) -> w: int,
x: int,
y: string,
z: Vector4
) {}
Foo :: struct {}
Bar :: enum {}
diff --git a/test_data/test1.txt b/test_data/test1.txt
new file mode 100644
index 0000000..be85d1d
--- /dev/null
+++ b/test_data/test1.txt
@@ -0,0 +1,23 @@
asdasdasd
asdfasdfasdf
asdfasdfasdf
df
f foo()
jköafdshijfdashjlkfa foo()
foo() foo()
hello:: () {
doener :: () {}
}
hello ::() {}
hello :: () {}
fifi :: (
test: *void,
yolo: string
) -> bool {
return false;
}
diff --git a/test_data/test2.txt b/test_data/test2.txt
new file mode 100644
index 0000000..ccab938
--- /dev/null
+++ b/test_data/test2.txt
@@ -0,0 +1,11 @@
asdasdasd
asdfasdfasdf
asdfasdfasdf
df
f foo()
jköafdshijfdashjlkfa foo()
foo() foo()