From 534dc2819e229e0ac9d1282e9542d78b2e5cb67a Mon Sep 17 00:00:00 2001 From: DarthMooMancer <107283522+DarthMooMancer@users.noreply.github.com> Date: Wed, 23 Apr 2025 14:50:17 -0400 Subject: [PATCH] Update to documentation, update with merging run and build commands, cleaned up and organized the project manager --- docs/index.md | 4 +- docs/installation.md | 13 +-- docs/languages/c.md | 2 - docs/languages/cpp.md | 2 - docs/languages/java.md | 2 - docs/setup.md | 42 ++++--- lua/Polydev/configs.lua | 13 ++- lua/Polydev/init.lua | 193 +++++++++++++++++++++++++++++---- lua/Polydev/languages/c.lua | 32 +++--- lua/Polydev/languages/cpp.lua | 52 +++++---- lua/Polydev/languages/java.lua | 21 ++-- lua/Polydev/languages/rust.lua | 32 +++--- lua/Polydev/utils.lua | 7 ++ 13 files changed, 278 insertions(+), 137 deletions(-) diff --git a/docs/index.md b/docs/index.md index ffab57c..884b43a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,7 +23,7 @@ Modern development often involves juggling multiple languages. Setting up simila - 🌐 **Language Support**: Define custom settings per language including `project_root`, `keybinds`, and `build_attributes`. - 🪟 **Floating Terminals**: Run builds and executions in a Neovim floating terminal. - 🧱 **Scaffolding**: Automatically create the appropriate directory and file layout for new projects. -- 🎹 **Keybind Mapping**: Rebind keys to execute project-specific commands like `Build`, `Run`, or `Test`. +- 🎹 **Keybind Mapping**: Rebind keys to execute project-specific commands like `Run`, or `Test`. - 🔌 **Pluggable**: Designed to easily integrate with other tools or extend with your own commands and language presets. ## 👥 Target Audience @@ -46,7 +46,7 @@ Say you're a developer who works with Rust, Lua, and Python. Instead of remember 1. 🏗 Sets up your directory based on language conventions. 2. 📄 Generates boilerplate files. -3. 🎛 Maps `pr` to `Run`, `pb` to `Build`, and so on. +3. 🎛 Maps `pr` to `Run`, `po` to `Open Polydev Project Manager`, and so on. 4. 🖥 Opens a floating terminal to show your output. ## 🏷 Versioning diff --git a/docs/installation.md b/docs/installation.md index 9c1a863..908049b 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -3,22 +3,25 @@ Polydev can be installed using any plugin manager of your choice—or even manually. Below are some examples for popular managers to get you started. > ⚠️ **Disclaimer**: The `opts` and configuration values shown below are simply examples. You can customize them based on your preferences or even omit them entirely if not needed. + > 💡 **Heads up!** Many language presets in Polydev require a file named `.polydev` in your project root. If it's missing, Polydev will let you know (loudly 😅). +> **Note**: Languages that require to build just need to be run, building is builtin to the run command + --- ## 🛌 Lazy.nvim -This is the **recommended** way if you're using [Lazy.nvim](https://github.com/folke/lazy.nvim): +> This is the **recommended** way if you're using [Lazy.nvim](https://github.com/folke/lazy.nvim): ```lua -{ +return { "DarthMooMancer/Polydev", dependencies = { "MunifTanjim/nui.nvim", "nvim-lua/plenary.nvim" }, - opts = { + opts = { -- Below are just example values lua = { project_root = "~/Projects/Lua", keybinds = { @@ -33,8 +36,6 @@ This is the **recommended** way if you're using [Lazy.nvim](https://github.com/f } ``` -> ✅ Keep the `opts` key! It’s the modern way of setting up plugins in Lazy. - --- ## 🧸 Mini.deps @@ -54,7 +55,6 @@ require("Polydev").setup({ rust = { project_root = "~/Projects/Rust", keybinds = { - ["pb"] = "RustBuild", ["pr"] = "RustRun", }, }, @@ -111,7 +111,6 @@ require("Polydev").setup({ c = { project_root = "~/Projects/C", keybinds = { - ["pb"] = "CBuild", ["pr"] = "CRun", }, }, diff --git a/docs/languages/c.md b/docs/languages/c.md index 2a7bccd..54ee516 100644 --- a/docs/languages/c.md +++ b/docs/languages/c.md @@ -10,7 +10,6 @@ You can customize keybinds for your C projects with Polydev. | Keybind | Action | |---------------------|--------------------------------------------------| -| `pb` | Build all C files in the `src` directory | | `pr` | Run `` in your build directory | | `nh` | Create a new header file in the current project’s `src` folder | @@ -19,7 +18,6 @@ You can customize keybinds for your C projects with Polydev. ```lua require("Polydev").c.setup({ keybinds = { - ["pb"] = "CBuild", -- Build all C files in the src directory ["pr"] = "CRun", -- Run in your build directory ["nh"] = "NewCHeaderFile" -- Create a new header file in the current project’s src folder } diff --git a/docs/languages/cpp.md b/docs/languages/cpp.md index d66f366..2d9ab6d 100644 --- a/docs/languages/cpp.md +++ b/docs/languages/cpp.md @@ -10,7 +10,6 @@ You can customize keybinds for your C projects with Polydev. | Keybind | Action | |---------------------|--------------------------------------------------| -| `pb` | Build all C files in the `src` directory | | `pr` | Run `` in your build directory | | `nh` | Create a new header file in the current project’s `src` folder | @@ -19,7 +18,6 @@ You can customize keybinds for your C projects with Polydev. ```lua require("Polydev").c.setup({ keybinds = { - ["pb"] = "CppBuild", -- Build all C files in the src directory ["pr"] = "CppRun", -- Run in your build directory ["nh"] = "NewCppHeaderFile" -- Create a new header file in the current project’s src folder } diff --git a/docs/languages/java.md b/docs/languages/java.md index 9c6cf38..5f2bd57 100644 --- a/docs/languages/java.md +++ b/docs/languages/java.md @@ -5,7 +5,6 @@ You can customize the keybinds for your Java projects in Polydev. | Keybind | Action | |---------------------|-----------------------------------------------------| -| `pb` | Build all Java files in the `src` directory | | `pr` | Run `Main.java` from the `out` folder in your project | | `nf` | Create a new Java file in the `src` folder | @@ -15,7 +14,6 @@ You can customize the keybinds for your Java projects in Polydev. -- These are defaults, so no need to copy them require("Polydev").java.setup({ keybinds = { - ["pb"] = "JavaBuild", -- Build all Java files in the src directory ["pr"] = "JavaRun", -- Run Main.java in the out folder ["nf"] = "NewJavaFile" -- Create a new Java file in the src folder } diff --git a/docs/setup.md b/docs/setup.md index e015b38..06617ff 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -1,7 +1,19 @@ # Setup and Customizing Polydev ## Project Manager -Follows the netrw keybinds and allows for project management all in one spot +> Note: The project manager closely follows the netrw keybinds and allows for project management all in one spot + +| Binding | Description | +|------------------|-----------------| +| **Enter** | `Open file / Enter directory` | +| **../** | `Go to parent directory` | +| **/** | `Filter (fuzzy search)` | +| **a** | `Create new folder` | +| **%** | `Create new file` | +| **d** | `Create new project` | +| **R** | `Rename file/folder` | +| **D** | `Delete file/folder` | +| **q** | `Quit popup` | ## 🔧 Project Name Customization You can easily customize the default directory for your project! The project can be created from any directory, and Polydev will automatically create the required project root directory for you. @@ -37,8 +49,8 @@ Polydev allows you to easily manage keybinds, providing a uniform way to interac ### Keybind Categories | Keybind Type | Description | |-------------------|--------------------------------------------------| -| **Universal** | Cannot be changed through specific language settings (e.g., `nf` for a new file). | -| **Per-language** | Can be customized per language (e.g., `pb` for language build). | +| **Universal** | Cannot be changed through specific language settings (e.g., `po` for project manager). | +| **Per-language** | Can be customized per language (e.g., `pr` for language run). | ### LazyVim Example @@ -47,10 +59,9 @@ return { ... opts = { = { - ["pb"] = "languageBuild", -- Per-language ["pr"] = "languageRun", -- Per-language ["nh"] = "NewLanguageSecondaryFile", -- Universal - ["po"] = "OpenSmartTable", -- Universal + ["po"] = "PolydevManager", -- Universal } } ... @@ -62,10 +73,9 @@ return { ```lua require("Polydev").language.setup({ keybinds = { - ["pb"] = "languageBuild", -- Per-language ["pr"] = "languageRun", -- Per-language ["nh"] = "NewLanguageSecondaryFile", -- Universal - ["po"] = "OpenSmartTable", -- Universal + ["po"] = "PolydevManager", -- Universal } }) ``` @@ -78,11 +88,7 @@ You can further tweak the terminal settings to suit your preferences! These opti ### Available Terminal Settings | Setting | Default Value | Description | |------------------|-----------------|---------------------------------------------------------| -| **presets** | `centered` | Presets for where the terminal is placed in the buffer | -| **right_padding** | `0` | Padding for the right width of the terminal. | -| **left_padding** | `0` | Padding for the left width of the terminal. | -| **top_padding** | `0` | Padding for the top height of the terminal. | -| **bottom_padding**| `0` | Padding for the bottom height of the terminal. | +| **presets** | `center` | Presets for where the terminal is placed in the buffer | | **border** | `true` | Adds a rounded border to the window. | | **number** | `true` | Displays line numbers in the terminal. | | **relativenumber**| `true` | Displays relative numbers based on cursor position. | @@ -106,11 +112,7 @@ return { ... opts = { terminal = { - presets = "centered" - right_padding = 0, - bottom_padding = 0, - left_padding = 0, - top_padding = 0, + presets = "center" border = true, number = true, relativenumber = true, @@ -126,11 +128,7 @@ return { ```lua require("Polydev").setup({ terminal = { - presets = "centered" - right_padding = 0, - bottom_padding = 0, - left_padding = 0, - top_padding = 0, + presets = "center" border = true, number = true, relativenumber = true, diff --git a/lua/Polydev/configs.lua b/lua/Polydev/configs.lua index 0bc4549..fd23d49 100644 --- a/lua/Polydev/configs.lua +++ b/lua/Polydev/configs.lua @@ -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 = { + ["po"] = "PolydevManager", + } + }, html = { project_root = "~/Projects/Html", }, diff --git a/lua/Polydev/init.lua b/lua/Polydev/init.lua index 8bf7d94..1dd88c3 100644 --- a/lua/Polydev/init.lua +++ b/lua/Polydev/init.lua @@ -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:", " : Open file / Enter directory", " : 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", "", 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", "", 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", { 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", "po", ":OpenSmartTable", { silent = true }) + setupKeybinds(opts) + vim.api.nvim_create_autocmd("FileType", { pattern = "*", callback = function() diff --git a/lua/Polydev/languages/c.lua b/lua/Polydev/languages/c.lua index d3397bb..514c174 100644 --- a/lua/Polydev/languages/c.lua +++ b/lua/Polydev/languages/c.lua @@ -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", { silent = true }) - end if M.keybinds.CRun then vim.keymap.set("n", M.keybinds.CRun, ":CRun", { 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 diff --git a/lua/Polydev/languages/cpp.lua b/lua/Polydev/languages/cpp.lua index 61e5c8a..286f25e 100644 --- a/lua/Polydev/languages/cpp.lua +++ b/lua/Polydev/languages/cpp.lua @@ -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", { silent = true }) - end if M.keybinds.CppRun then vim.keymap.set("n", M.keybinds.CppRun, ":CppRun", { 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 diff --git a/lua/Polydev/languages/java.lua b/lua/Polydev/languages/java.lua index 9208221..1b70a90 100644 --- a/lua/Polydev/languages/java.lua +++ b/lua/Polydev/languages/java.lua @@ -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", { silent = true }) end - if M.keybinds.JavaBuild then - vim.keymap.set("n", M.keybinds.JavaBuild, ":JavaBuild", { 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 diff --git a/lua/Polydev/languages/rust.lua b/lua/Polydev/languages/rust.lua index 7c3c7a9..a191487 100644 --- a/lua/Polydev/languages/rust.lua +++ b/lua/Polydev/languages/rust.lua @@ -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", { silent = true }) end - if M.keybinds.RustBuild then - vim.keymap.set("n", M.keybinds.RustBuild, ":RustBuild", { 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 diff --git a/lua/Polydev/utils.lua b/lua/Polydev/utils.lua index 6390c87..7e2be44 100644 --- a/lua/Polydev/utils.lua +++ b/lua/Polydev/utils.lua @@ -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)