From 3d78592d97270a7704d62c4642a6ff524934609f Mon Sep 17 00:00:00 2001 From: Primoz Susa Date: Thu, 12 Sep 2024 20:58:57 +0200 Subject: [PATCH] nim-lang --- lua/compiler/languages/nim.lua | 148 ++++++++++++++++++ .../nim/build-and-run/src/helper.nim | 3 + .../languages/nim/build-and-run/src/main.nim | 7 + .../languages/nim/build/src/helper.nim | 3 + .../languages/nim/build/src/main.nim | 7 + .../languages/nim/solution/.solution.toml | 11 ++ .../nim/solution/project1/src/helper.nim | 3 + .../nim/solution/project1/src/main.nim | 7 + .../nim/solution/project2/src/helper.nim | 3 + .../nim/solution/project2/src/main.nim | 7 + tests/tests/languages/nim.lua | 34 ++++ 11 files changed, 233 insertions(+) create mode 100644 lua/compiler/languages/nim.lua create mode 100644 tests/code samples/languages/nim/build-and-run/src/helper.nim create mode 100644 tests/code samples/languages/nim/build-and-run/src/main.nim create mode 100644 tests/code samples/languages/nim/build/src/helper.nim create mode 100644 tests/code samples/languages/nim/build/src/main.nim create mode 100644 tests/code samples/languages/nim/solution/.solution.toml create mode 100644 tests/code samples/languages/nim/solution/project1/src/helper.nim create mode 100644 tests/code samples/languages/nim/solution/project1/src/main.nim create mode 100644 tests/code samples/languages/nim/solution/project2/src/helper.nim create mode 100644 tests/code samples/languages/nim/solution/project2/src/main.nim create mode 100644 tests/tests/languages/nim.lua diff --git a/lua/compiler/languages/nim.lua b/lua/compiler/languages/nim.lua new file mode 100644 index 0000000..8f9ce99 --- /dev/null +++ b/lua/compiler/languages/nim.lua @@ -0,0 +1,148 @@ +--- Nim language actions + +local M = {} + +--- Frontend - options displayed on telescope +M.options = { + { text = "Build and run main program", value = "option1" }, + { text = "Build main program", value = "option2" }, + { text = "Run main program", value = "option3" }, + { text = "Build solution", value = "option4" }, + { text = "Run this file", value = "option5" }, +} + +--- Backend - overseer tasks performed on option selected +function M.action(selected_option) + local utils = require("compiler.utils") + local overseer = require("overseer") + local current_file = vim.fn.expand("%:p") + + local entry_point = utils.os_path(vim.fn.getcwd() .. "/src/main.nim") -- working_directory/main.nim + local output_dir = utils.os_path(vim.fn.getcwd() .. "/bin/") -- working_directory/bin/ + local output = utils.os_path(vim.fn.getcwd() .. "/bin/program") -- working_directory/bin/program + local current_file_output = output_dir + .. vim.fn.fnamemodify(current_file, ":t:r") + + local arguments = "" -- arguments can be overriden in .solution + local final_message = "--task finished--" + + if selected_option == "option1" then + -- stylua: ignore start + local task = overseer.new_task({ + name = "- Nim compiler", + strategy = { "orchestrator", + tasks = {{ name = "- Build & run program → \"" .. entry_point .. "\"", + cmd = "rm -f \"" .. output .. "\" || true" .. -- clean + " && mkdir -p \"" .. output_dir .. "\"" .. -- mkdir + " && nim c -r " .. arguments .. " -o=" .. output .. " " .. entry_point .. -- compile + -- " && \"" .. output .. "\"" .. -- run + " && echo \"" .. entry_point .. "\"" .. -- echo + " && echo \"" .. final_message .. "\"", + components = { "default_extended" } + },},},}) + task:start() + -- stylua: ignore end + elseif selected_option == "option2" then + -- stylua: ignore start + local task = overseer.new_task({ + name = "- Nim compiler", + strategy = { "orchestrator", + tasks = {{ name = "- Build program → \"" .. entry_point .. "\"", + cmd = "rm -f \"" .. output .. "\" || true" .. -- clean + " && mkdir -p \"" .. output_dir .. "\"" .. -- mkdir + " && nim c " .. arguments .. " -o=" .. output .. " " .. entry_point .. -- compile + " && echo \"" .. entry_point .. "\"" .. -- echo + " && echo \"" .. final_message .. "\"", + components = { "default_extended" } + },},},}) + task:start() + -- stylua: ignore end + elseif selected_option == "option3" then + -- stylua: ignore start + local task = overseer.new_task({ + name = "- Nim compiler", + strategy = { "orchestrator", + tasks = {{ name = "- Run program → \"" .. output .. "\"", + cmd = "\"" .. output .. "\"" .. -- run + " && echo \"" .. output .. "\"" .. -- echo + " && echo \"" .. final_message .. "\"", + components = { "default_extended" } + },},},}) + task:start() + -- stylua: ignore end + elseif selected_option == "option4" then + local entry_points + local task = {} + local tasks = {} + local executables = {} + + local solution_file = utils.get_solution_file() + if solution_file then + local config = utils.parse_solution_file(solution_file) + + for entry, variables in pairs(config) do + if entry == "executables" then goto continue end + entry_point = utils.os_path(variables.entry_point) + output = utils.os_path(variables.output) + output_dir = utils.os_path(output:match("^(.-[/\\])[^/\\]*$")) + arguments = variables.arguments or arguments -- optional + -- stylua: ignore start + task = { name = "- Build program → \"" .. entry_point .. "\"", + cmd = "rm -f \"" .. output .. "\" || true" .. -- clean + " && mkdir -p \"" .. output_dir .. "\"" .. -- mkdir + " && nim c " .. arguments .. " -o=" .. output .. " " .. entry_point .. -- compile + " && echo \"" .. entry_point .. "\"" .. -- echo + " && echo \"" .. final_message .. "\"", + components = { "default_extended" } + } + -- stylua: ignore end + table.insert(tasks, task) -- store all the tasks we've created + ::continue:: + end + + local solution_executables = config["executables"] + if solution_executables then + for entry, executable in pairs(solution_executables) do + executable = utils.os_path(executable, true) + -- stylua: ignore start + task = { name = "- Run program → " .. executable, + cmd = executable .. -- run + " && echo " .. executable .. -- echo + " && echo \"" .. final_message .. "\"", + components = { "default_extended" } + } + -- stylua: ignore end + table.insert(executables, task) -- store all the executables we've created + end + end + + task = overseer.new_task({ + name = "- Nim compiler", + strategy = { + "orchestrator", + tasks = { + tasks, -- Build all the programs in the solution in parallel + executables, -- Then run the solution executable(s) + }, + }, + }) + task:start() + end + elseif selected_option == "option5" then + -- stylua: ignore start + local task = overseer.new_task({ + name = "- Nim compiler", + strategy = { "orchestrator", + tasks = {{ name = "- Build & run program → \"" .. current_file .. "\"", + cmd = "rm -f \"" .. current_file_output .. "\" || true" .. -- clean + " && mkdir -p \"" .. output_dir .. "\"" .. -- mkdir + " && nim c -r " .. arguments .. " -o=" .. current_file_output .. " " .. current_file .. -- compile + " && echo \"" .. current_file .. "\"" .. -- echo + " && echo \"" .. final_message .. "\"", + components = { "default_extended" } + },},},}) + task:start() + end +end + +return M diff --git a/tests/code samples/languages/nim/build-and-run/src/helper.nim b/tests/code samples/languages/nim/build-and-run/src/helper.nim new file mode 100644 index 0000000..8d07a6f --- /dev/null +++ b/tests/code samples/languages/nim/build-and-run/src/helper.nim @@ -0,0 +1,3 @@ +proc printHello*() = + echo "Hello, World!" + diff --git a/tests/code samples/languages/nim/build-and-run/src/main.nim b/tests/code samples/languages/nim/build-and-run/src/main.nim new file mode 100644 index 0000000..0ce6362 --- /dev/null +++ b/tests/code samples/languages/nim/build-and-run/src/main.nim @@ -0,0 +1,7 @@ +import helper + +proc main() = + printHello() + +when isMainModule: + main() diff --git a/tests/code samples/languages/nim/build/src/helper.nim b/tests/code samples/languages/nim/build/src/helper.nim new file mode 100644 index 0000000..8d07a6f --- /dev/null +++ b/tests/code samples/languages/nim/build/src/helper.nim @@ -0,0 +1,3 @@ +proc printHello*() = + echo "Hello, World!" + diff --git a/tests/code samples/languages/nim/build/src/main.nim b/tests/code samples/languages/nim/build/src/main.nim new file mode 100644 index 0000000..0ce6362 --- /dev/null +++ b/tests/code samples/languages/nim/build/src/main.nim @@ -0,0 +1,7 @@ +import helper + +proc main() = + printHello() + +when isMainModule: + main() diff --git a/tests/code samples/languages/nim/solution/.solution.toml b/tests/code samples/languages/nim/solution/.solution.toml new file mode 100644 index 0000000..3a651e8 --- /dev/null +++ b/tests/code samples/languages/nim/solution/.solution.toml @@ -0,0 +1,11 @@ +# Regular comments +[HelloWorld] +entry_point = "./project1/src/main.nim" # And also inline comments! +output = "./bin/hello_world1" # Both are... +executable = "./bin/hello_world1" # ...Accepted now. + +# Any entry containing a key with the word "executable" on it +# will be executed directly in the terminal in parallel. +[AnyNameWeWant] +executable_1 = './bin/hello_world1' +executable_2 = './bin/hello_world1' diff --git a/tests/code samples/languages/nim/solution/project1/src/helper.nim b/tests/code samples/languages/nim/solution/project1/src/helper.nim new file mode 100644 index 0000000..8d07a6f --- /dev/null +++ b/tests/code samples/languages/nim/solution/project1/src/helper.nim @@ -0,0 +1,3 @@ +proc printHello*() = + echo "Hello, World!" + diff --git a/tests/code samples/languages/nim/solution/project1/src/main.nim b/tests/code samples/languages/nim/solution/project1/src/main.nim new file mode 100644 index 0000000..0ce6362 --- /dev/null +++ b/tests/code samples/languages/nim/solution/project1/src/main.nim @@ -0,0 +1,7 @@ +import helper + +proc main() = + printHello() + +when isMainModule: + main() diff --git a/tests/code samples/languages/nim/solution/project2/src/helper.nim b/tests/code samples/languages/nim/solution/project2/src/helper.nim new file mode 100644 index 0000000..8d07a6f --- /dev/null +++ b/tests/code samples/languages/nim/solution/project2/src/helper.nim @@ -0,0 +1,3 @@ +proc printHello*() = + echo "Hello, World!" + diff --git a/tests/code samples/languages/nim/solution/project2/src/main.nim b/tests/code samples/languages/nim/solution/project2/src/main.nim new file mode 100644 index 0000000..0ce6362 --- /dev/null +++ b/tests/code samples/languages/nim/solution/project2/src/main.nim @@ -0,0 +1,7 @@ +import helper + +proc main() = + printHello() + +when isMainModule: + main() diff --git a/tests/tests/languages/nim.lua b/tests/tests/languages/nim.lua new file mode 100644 index 0000000..0539681 --- /dev/null +++ b/tests/tests/languages/nim.lua @@ -0,0 +1,34 @@ +--- This test file run all supported cases of use. +--- @usage :luafile ~/.local/share/nvim/lazy/compiler.nvim/tests/tests/languages/nim.lua + +local ms = 1000 -- wait time +local language = require("compiler.languages.nim") +local example = + require("compiler.utils").get_tests_dir("code samples/languages/nim/") + +coroutine.resume(coroutine.create(function() + local co = coroutine.running() + local function sleep() + vim.defer_fn(function() coroutine.resume(co) end, ms) + coroutine.yield() + end + + -- Build and run + vim.api.nvim_set_current_dir(example .. "build-and-run/") + language.action("option1") + sleep() + + -- Build + vim.api.nvim_set_current_dir(example .. "build/") + language.action("option2") + sleep() + + -- Run + language.action("option3") + sleep() + + -- Build solution + vim.api.nvim_set_current_dir(example .. "solution/") + language.action("option4") + sleep() +end))