Update to documentation, update with merging run and build commands, cleaned up and organized the project manager

This commit is contained in:
DarthMooMancer
2025-04-23 14:50:17 -04:00
parent 9db6059fb7
commit 534dc2819e
13 changed files with 278 additions and 137 deletions
+11 -2
View File
@@ -8,7 +8,7 @@ local M = {}
---@field project_root? string
---@field keybinds? KeybindConfigs -- ? makes fields optional
---@field build_attributes? string
---
---@class TerminalConfigs
---@field presets string
---@field right_padding integer
@@ -18,8 +18,12 @@ local M = {}
---@field border boolean
---@field number boolean
---@field relativenumber boolean
---
---@class GlobalsConfigs
---@field keybinds KeybindConfigs
---@class Defaults
---@field globals GlobalsConfigs
---@field html LanguageConfigs
---@field rust LanguageConfigs
---@field java LanguageConfigs
@@ -31,6 +35,11 @@ local M = {}
---@type Defaults
M.defaults = {
globals = {
keybinds = {
["<leader>po"] = "PolydevManager",
}
},
html = {
project_root = "~/Projects/Html",
},
+169 -24
View File
@@ -2,6 +2,7 @@ local config = require("Polydev.configs")
local utils = require("Polydev.utils")
local templates = require("Polydev.templates")
local Popup = require("nui.popup")
local Layout = require("nui.layout")
local event = require("nui.utils.autocmd").event
local Path = require("plenary.path")
@@ -51,7 +52,7 @@ local function get_entries(path)
is_project = is_project
})
end
table.sort(result, function(a, b)
table.sort(result, function(a, b)
-- Sort projects first, then directories, then files
if a.is_project ~= b.is_project then
return a.is_project
@@ -86,27 +87,123 @@ local function open_filtered_table()
local entries = get_entries(cwd)
local current_view = vim.deepcopy(entries)
local popup = Popup({
local popup, search, preview, keybinds = Popup({
enter = true,
focusable = true,
border = {
style = "rounded",
style = "rounded", -- "double", "none", "rounded", "shadow", "single" or "solid".
text = { top = " Project Manager ", top_align = "center" },
highlight = "Normal",
},
position = "50%",
size = { width = 60, height = 14 },
buf_options = { modifiable = true, readonly = false },
}), Popup({
enter = false,
focusable = true,
border = {
style = "rounded", -- "double", "none", "rounded", "shadow", "single" or "solid".
text = { top = " Search ", top_align = "center" },
highlight = "Normal",
},
buf_options = { modifiable = true, readonly = false },
}), Popup({
enter = false,
focusable = false,
border = {
style = "rounded",
text = { top = " Preview ", top_align = "center" },
highlight = "Normal",
},
position = "50%",
buf_options = { modifiable = true, readonly = false },
}), Popup({
enter = false,
focusable = false,
border = {
style = "rounded",
text = { top = " Keybinds ", top_align = "center" },
highlight = "Normal",
},
position = "50%",
buf_options = { modifiable = true, readonly = false },
})
local layout = Layout({
position = "50%",
size = { width = "70%", height = "70%" },
},
Layout.Box({
Layout.Box(search, { size = "10%" }),
Layout.Box({
Layout.Box({
Layout.Box(popup, { size = "55%" }),
Layout.Box(keybinds, {size = "45%" }),
}, { dir = "col", size = "50%" }),
Layout.Box(preview, { size = "50%" }),
}, { dir = "row", size = "90%" }),
}, { dir = "col" })
)
layout:mount()
local function get_selected_entry()
local row = vim.api.nvim_win_get_cursor(0)[1] - 1
local row = vim.api.nvim_win_get_cursor(popup.winid)[1] - 1
return current_view[row], row
end
local function update_preview()
if not preview.bufnr then return end
vim.api.nvim_buf_set_lines(preview.bufnr, 0, -1, false, {}) -- Clear
local entry = get_selected_entry()
if not entry then return end
if entry.type == "file" or entry.type == "project" then
-- Preview file contents (first 100 lines)
local lines = {}
local fd = io.open(entry.full_path, "r")
if fd then
for i = 1, 100 do
local line = fd:read("*line")
if not line then break end
table.insert(lines, line)
end
fd:close()
else
table.insert(lines, "[Failed to read file]")
end
vim.api.nvim_buf_set_lines(preview.bufnr, 0, -1, false, lines)
elseif entry.type == "directory" then
-- List contents of directory
local contents = get_entries(entry.full_path)
local lines = {}
for _, item in ipairs(contents) do
table.insert(lines, string.format("- %s", item.name))
end
if #lines == 0 then
table.insert(lines, "[Empty folder]")
end
vim.api.nvim_buf_set_lines(preview.bufnr, 0, -1, false, lines)
end
end
vim.api.nvim_create_autocmd("CursorMoved", {
buffer = popup.bufnr,
callback = function()
vim.schedule(update_preview)
end,
})
local function refresh()
entries = get_entries(cwd)
local root = vim.fn.expand("~/Projects")
-- If we're not in the Projects folder, redirect to Projects
if not cwd:find(root, 1, true) then
cwd = root
entries = get_entries(cwd)
end
-- Only add ".." if we're inside Projects and not at the root
if cwd ~= root then
table.insert(entries, 1, {
name = "../",
@@ -122,14 +219,12 @@ local function open_filtered_table()
if not popup.bufnr then return end
vim.api.nvim_buf_set_lines(popup.bufnr, 0, -1, false, {})
for i, item in ipairs(current_view) do
local line = string.format("%-3d | %-30s | %-6s", i, item.name, item.type)
local line = string.format("%-2d | %-27s | %-6s", i, item.name, item.type)
vim.api.nvim_buf_set_lines(popup.bufnr, -1, -1, false, { line })
end
-- Add key mappings legend
local hints = {
"",
"Keybinds:",
" <CR> : Open file / Enter directory",
" <BS> : Go to parent directory",
" / : Filter (fuzzy search)",
@@ -141,21 +236,42 @@ local function open_filtered_table()
" q : Quit popup",
}
vim.api.nvim_buf_set_lines(popup.bufnr, -1, -1, false, hints)
if not keybinds.bufnr then return end
vim.api.nvim_buf_set_lines(keybinds.bufnr, 0, -1, false, {})
vim.api.nvim_buf_set_lines(keybinds.bufnr, -1, -1, false, hints)
update_preview()
end
local function prompt_filter()
vim.ui.input({ prompt = "Search: " }, function(input)
if input then
vim.api.nvim_buf_set_lines(search.bufnr, 0, -1, false, { "" })
vim.api.nvim_buf_set_option(search.bufnr, "modifiable", true)
if search.winid and vim.api.nvim_win_is_valid(search.winid) then
vim.api.nvim_set_current_win(search.winid)
end
vim.cmd("startinsert")
vim.keymap.set("i", "<CR>", function()
local input = vim.api.nvim_buf_get_lines(search.bufnr, 0, 1, false)[1]
if input and input ~= "" then
current_view = fuzzy_filter(entries, input)
render()
end
end)
vim.api.nvim_buf_set_lines(search.bufnr, 0, -1, false, { "" })
vim.api.nvim_set_current_win(popup.winid)
vim.cmd("stopinsert") -- exit insert mode
end, { buffer = search.bufnr, noremap = true })
vim.keymap.set("i", "<Esc>", function()
vim.api.nvim_set_current_win(popup.winid)
vim.cmd("stopinsert") -- ensure we are in normal mode
end, { buffer = search.bufnr, noremap = true })
end
popup:map("n", "/", function() vim.schedule(prompt_filter) end)
-- Mappings
popup:map("n", "q", function() popup:unmount() end)
popup:map("n", "/", prompt_filter)
-- Creates a new folder
popup:map("n", "a", function()
@@ -190,9 +306,10 @@ local function open_filtered_table()
if M.load_language_module(lang) and templates.files[lang] and templates.files[lang].run then
vim.ui.input({ prompt = "Enter file name: " }, function(file_name)
if not file_name or file_name == "" then return print("File creation canceled.") end
templates.files[lang].run(file_name)
refresh()
render()
popup:unmount()
vim.schedule(function()
templates.files[lang].run(file_name)
end)
end)
else
print("Error: No File creation method for " .. lang)
@@ -207,10 +324,11 @@ local function open_filtered_table()
if not lang or lang == "" then return print("Project creation canceled.") end
opts = vim.tbl_deep_extend("force", {}, config.get(lang), opts or {})
if M.load_language_module(lang) and templates.projects[lang] and templates.projects[lang].run then
templates.create_project(lang, opts.project_root)
vim.cmd("cd " .. templates.dir .. "/src")
refresh()
render()
popup:unmount()
vim.schedule(function()
templates.create_project(lang, opts.project_root)
end)
else
print("Error: No project creation method for " .. lang)
end
@@ -242,7 +360,10 @@ local function open_filtered_table()
render()
end
if entry and entry.type == "file" then
vim.cmd("edit " .. entry.name)
popup:unmount()
vim.schedule(function()
vim.cmd("edit " .. vim.fn.fnameescape(entry.full_path))
end)
end
end)
@@ -255,13 +376,37 @@ local function open_filtered_table()
end
end)
popup:on(event.BufLeave, function() popup:unmount() end)
popup:on(event.BufLeave, function()
vim.defer_fn(function()
if not (popup.winid and vim.api.nvim_win_is_valid(popup.winid)) and
not (search.winid and vim.api.nvim_win_is_valid(search.winid)) then
popup:unmount()
end
end, 50)
end)
popup:mount()
refresh()
render()
end
---@type table
M.keybinds = {}
local function setupKeybinds(opts)
M.opts = {}
M.opts = vim.tbl_deep_extend("force", {}, config.get("globals"), opts or {})
for key, command in pairs(M.opts.keybinds) do
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("PolydevProjectManagerOpen", open_filtered_table, {})
if M.keybinds.PolydevManager then
vim.keymap.set("n", M.keybinds.PolydevManager, ":PolydevProjectManagerOpen<CR>", { silent = true })
end
end
---@param opts table
function M.setup(opts)
opts = opts or {}
@@ -272,8 +417,8 @@ function M.setup(opts)
config.user_config[lang] = vim.tbl_deep_extend("force", default, user_opts)
end
vim.api.nvim_create_user_command("OpenSmartTable", open_filtered_table, {})
vim.keymap.set("n", "<leader>po", ":OpenSmartTable<CR>", { silent = true })
setupKeybinds(opts)
vim.api.nvim_create_autocmd("FileType", {
pattern = "*",
callback = function()
+15 -17
View File
@@ -11,12 +11,8 @@ function M.setup(opts)
end
vim.api.nvim_create_user_command("NewCHeaderFile", M.create_new_header_file, {})
vim.api.nvim_create_user_command("CBuild", M.build, {})
vim.api.nvim_create_user_command("CRun", M.run, {})
if M.keybinds.CBuild then
vim.keymap.set("n", M.keybinds.CBuild, ":CBuild<CR>", { silent = true })
end
if M.keybinds.CRun then
vim.keymap.set("n", M.keybinds.CRun, ":CRun<CR>", { silent = true })
end
@@ -56,27 +52,29 @@ function M.get_project_root()
end
end
function M.build()
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local cmd = "cd " .. build_dir .. " && cmake --build ."
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.list_extend({ success and "Compilation successful!" or "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local files = vim.fn.glob(build_dir .. "/*.polydev", true, true)
if #files == 0 then return print("Error: No .polydev file found in build directory.") end
utils.open_float_terminal("cd " .. build_dir .. " && ./" .. files[1]:match("([^/]+)%.polydev$"))
if not success then
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
if success then
local files = vim.fn.glob(build_dir .. "/*.polydev", true, true)
if #files == 0 then return print("Error: No .polydev file found in build directory.") end
utils.open_float_terminal("cd " .. build_dir .. " && ./" .. files[1]:match("([^/]+)%.polydev$"))
end
end
return M
+25 -27
View File
@@ -11,12 +11,8 @@ function M.setup(opts)
end
vim.api.nvim_create_user_command("NewCppHeaderFile", M.create_new_header_file, {})
vim.api.nvim_create_user_command("CppBuild", M.build, {})
vim.api.nvim_create_user_command("CppRun", M.run, {})
if M.keybinds.CppBuild then
vim.keymap.set("n", M.keybinds.CppBuild, ":CppBuild<CR>", { silent = true })
end
if M.keybinds.CppRun then
vim.keymap.set("n", M.keybinds.CppRun, ":CppRun<CR>", { silent = true })
end
@@ -25,6 +21,16 @@ function M.setup(opts)
end
end
function M.get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 or vim.fn.filereadable(dir .. "/CMakeLists.txt") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
function M.create_new_header_file()
vim.ui.input({ prompt = "Enter header file name: " }, function(header_name)
if not header_name then return print("Header file creation canceled.") end
@@ -46,37 +52,29 @@ void example_function();
end)
end
function M.get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 or vim.fn.filereadable(dir .. "/CMakeLists.txt") == 1 then
return dir
end
dir = vim.fn.fnamemodify(dir, ":h")
end
end
function M.build()
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local cmd = "cd " .. build_dir .. " && cmake --build ."
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.list_extend({ success and "Compilation successful!" or "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
local build_dir = root .. "/build"
local files = vim.fn.glob(build_dir .. "/*.polydev", true, true)
if #files == 0 then return print("Error: No .polydev file found in build directory.") end
utils.open_float_terminal("cd " .. build_dir .. " && ./" .. files[1]:match("([^/]+)%.polydev$"))
if not success then
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
if success then
local files = vim.fn.glob(build_dir .. "/*.polydev", true, true)
if #files == 0 then return print("Error: No .polydev file found in build directory.") end
utils.open_float_terminal("cd " .. build_dir .. " && ./" .. files[1]:match("([^/]+)%.polydev$"))
end
end
return M
+7 -14
View File
@@ -10,28 +10,27 @@ function M.setup(opts)
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("JavaBuild", M.build, {})
vim.api.nvim_create_user_command("JavaRun", M.run, {})
if M.keybinds.JavaRun then
vim.keymap.set("n", M.keybinds.JavaRun, ":JavaRun<CR>", { silent = true })
end
if M.keybinds.JavaBuild then
vim.keymap.set("n", M.keybinds.JavaBuild, ":JavaBuild<CR>", { silent = true })
end
end
function M.build()
function M.run()
local project_root = vim.fn.expand("%:p:h"):match("(.*)/src")
if not project_root then return print("Error: Could not detect project root directory.") end
if not project_root then return print("Error: Must be inside the 'src' directory.") end
local out_dir = project_root .. "/build"
vim.fn.mkdir(out_dir, "p")
if not utils.is_dir(out_dir) then
vim.fn.mkdir(out_dir, "p")
end
local compile_command = string.format("javac -d %s %s/*.java", out_dir, project_root .. "/src")
local compile_status = vim.fn.system(compile_command)
if vim.v.shell_error == 0 then
print("Compilation successful!")
utils.open_float_terminal("java -cp " .. project_root .. "/build" .. " Main")
else
print("Error during compilation. Opening terminal for details...")
local term_buf = utils.open_float_terminal(compile_command)
@@ -41,10 +40,4 @@ function M.build()
end
end
function M.run()
local project_root = vim.fn.expand("%:p:h"):match("(.*)/src")
if not project_root then return print("Error: Must be inside the 'src' directory.") end
utils.open_float_terminal("java -cp " .. project_root .. "/build" .. " Main")
end
return M
+16 -16
View File
@@ -10,18 +10,14 @@ function M.setup(opts)
M.keybinds[command] = key
end
vim.api.nvim_create_user_command("RustBuild", M.build, {})
vim.api.nvim_create_user_command("RustRun", M.run, {})
if M.keybinds.RustRun then
vim.keymap.set("n", M.keybinds.RustRun, ":RustRun<CR>", { silent = true })
end
if M.keybinds.RustBuild then
vim.keymap.set("n", M.keybinds.RustBuild, ":RustBuild<CR>", { silent = true })
end
end
function M.get_project_root()
local function get_project_root()
local dir = vim.fn.expand("%:p:h")
while dir ~= "/" do
if vim.fn.isdirectory(dir .. "/src") == 1 then
@@ -31,22 +27,26 @@ function M.get_project_root()
end
end
function M.build()
local root = M.get_project_root()
function M.run()
local root = get_project_root()
if not root then return print("Error: Project root not found.") end
local cmd = "cargo build"
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
local output = vim.fn.system(cmd)
local success = vim.v.shell_error == 0
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false, vim.list_extend({ success and "Compilation successful!" or "Error during compilation:" }, vim.split(output, "\n", { trimempty = true })))
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
function M.run()
local root = M.get_project_root()
if not root then return print("Error: Project root not found.") end
utils.open_float_terminal("cargo run")
if not success then
local term_buf = utils.open_float_terminal(cmd)
vim.api.nvim_buf_set_option(term_buf, "modifiable", true)
vim.api.nvim_buf_set_lines(term_buf, 0, -1, false,
vim.list_extend({ "Error during compilation:" }, vim.split(output, "\n", { trimempty = true }))
)
vim.api.nvim_buf_set_option(term_buf, "modifiable", false)
end
if success then
utils.open_float_terminal("cargo run")
end
end
return M
+7
View File
@@ -15,6 +15,13 @@ function M.setup(opts)
M.opts = vim.tbl_deep_extend("force", {}, require("Polydev.configs").get("terminal"), opts or {})
end
---@param path string
---@return boolean
function M.is_dir(path)
local stat = vim.loop.fs_stat(path)
return stat and stat.type == "directory"
end
---@param path string
---@param content string
function M.write_file(path, content)