204 lines
5.4 KiB
Lua
204 lines
5.4 KiB
Lua
---@alias EngineName "Lua" | "Jq" | "Node" | "Nvim"
|
|
|
|
---@class Argument
|
|
---@field value string
|
|
|
|
---@class Command
|
|
---@field name string
|
|
---@field engine EngineName
|
|
---@field executable_path string
|
|
---@field arguments? Argument[]
|
|
---@field working_dir? string
|
|
---@field output? "terminal" | "register"
|
|
|
|
local M = {}
|
|
|
|
---@type table<EngineName, string>
|
|
local Engine_prefixes = {
|
|
["Lua"] = "lua",
|
|
["Jq"] = "jq",
|
|
["Node"] = "tsx",
|
|
["Nvim"] = "source",
|
|
}
|
|
|
|
M.setup = function ()
|
|
vim.api.nvim_create_user_command(
|
|
"QC",
|
|
function(opts) M.execute(opts) end,
|
|
{ desc = "[Q]uick [C]ommand" }
|
|
)
|
|
end
|
|
|
|
M.execute = function (opts)
|
|
local options = {}
|
|
package.loaded["quick-command.commands"] = nil
|
|
local commands = require("quick-command.commands")
|
|
for _, v in ipairs(commands) do
|
|
table.insert(options, v.name)
|
|
end
|
|
|
|
vim.ui.select(
|
|
options,
|
|
{ prompt = "Select command", },
|
|
function (_, idx)
|
|
if not idx then
|
|
return
|
|
end
|
|
local command = commands[idx]
|
|
ExecuteCommand(command)
|
|
end
|
|
)
|
|
end
|
|
|
|
---@param command Command
|
|
function ExecuteCommand(command)
|
|
local executable_path = ReplaceVariables(command.executable_path)
|
|
|
|
-- if Engine_prefixes[command.engine] then
|
|
-- executable_path = Engine_prefixes[command.engine] .. " " .. executable_path
|
|
-- end
|
|
|
|
-- if command.working_dir then
|
|
-- command_text = "cd /d \"" .. command.working_dir .. "\" && " .. command_text
|
|
-- end
|
|
|
|
if command.engine == "Nvim" then
|
|
vim.api.nvim_command(":" .. executable_path)
|
|
return
|
|
-- else
|
|
-- command_text = "[[" .. command_text .. "]]"
|
|
-- command_text = ":split | terminal " .. command_text
|
|
end
|
|
|
|
local arguments = {}
|
|
table.insert(arguments, Engine_prefixes[command.engine])
|
|
table.insert(arguments, executable_path)
|
|
for _, argument in ipairs(command.arguments or {}) do
|
|
local argument_parsed = ReplaceVariables(argument.value)
|
|
table.insert(arguments, argument_parsed)
|
|
end
|
|
|
|
-- if command.engine ~= "Nvim" then
|
|
|
|
---@type vim.SystemOpts
|
|
local options = {
|
|
text = true
|
|
}
|
|
if command.working_dir then
|
|
options.cwd = ReplaceVariables(command.working_dir)
|
|
end
|
|
-- for index, value in ipairs(arguments) do
|
|
-- print(value)
|
|
-- end
|
|
local buf = vim.api.nvim_create_buf(false, true)
|
|
vim.api.nvim_command("split")
|
|
vim.api.nvim_set_current_buf(buf)
|
|
vim.bo[buf].buftype = "nofile"
|
|
|
|
SetBufferContents(buf, { "Executing command..." })
|
|
local time_elapsed = 0
|
|
local timer = vim.uv.new_timer()
|
|
local timer_interval = 100
|
|
if timer then
|
|
timer:start(0, timer_interval, vim.schedule_wrap(function ()
|
|
time_elapsed = time_elapsed + timer_interval
|
|
SetBufferContents(buf, { "Executing command... (" .. (time_elapsed / 1000) .. "s)"})
|
|
end))
|
|
end
|
|
|
|
vim.system(
|
|
arguments,
|
|
options,
|
|
function (result)
|
|
local lines = {}
|
|
if result.code == 0 then
|
|
lines = SplitIntoLines(result.stdout)
|
|
else
|
|
lines = SplitIntoLines(result.stdout)
|
|
lines = SplitIntoLines(result.stderr)
|
|
end
|
|
vim.schedule(function ()
|
|
if timer then
|
|
timer:stop()
|
|
end
|
|
SetBufferContents(buf, lines)
|
|
end)
|
|
end
|
|
)
|
|
|
|
-- local result = vim.system(
|
|
-- arguments,
|
|
-- options
|
|
-- ):wait()
|
|
-- local lines = {}
|
|
-- if result.code == 0 then
|
|
-- lines = SplitIntoLines(result.stdout)
|
|
-- else
|
|
-- lines = SplitIntoLines(result.stdout)
|
|
-- lines = SplitIntoLines(result.stderr)
|
|
-- end
|
|
-- vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
|
|
|
|
|
-- else
|
|
-- -- print(command_text)
|
|
-- local cmd = vim.api.nvim_parse_cmd(executable_path, {})
|
|
-- -- print(command_text)
|
|
-- vim.api.nvim_command(executable_path)
|
|
-- end
|
|
|
|
end
|
|
|
|
---@param buf integer
|
|
---@param lines string[]
|
|
function SetBufferContents(buf, lines)
|
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
|
|
end
|
|
|
|
---@param contents string | nil
|
|
---@return string
|
|
function CreateTempFile(contents)
|
|
contents = contents or ""
|
|
local temp_name = os.tmpname()
|
|
local file = io.open(temp_name, "w")
|
|
if not file then
|
|
error("Error creating temporary file")
|
|
end
|
|
file:write(contents)
|
|
file:close()
|
|
return temp_name
|
|
end
|
|
|
|
function ReplaceVariables(input)
|
|
local result = input
|
|
result = ReplaceBufferName(result)
|
|
result = ReplaceHomeDirectory(result)
|
|
return result
|
|
end
|
|
|
|
function ReplaceBufferName(input)
|
|
local buf_name = vim.api.nvim_buf_get_name(0)
|
|
if buf_name == "" then
|
|
local buffer_lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
|
local buffer_content = table.concat(buffer_lines, "\n")
|
|
buf_name = CreateTempFile(buffer_content)
|
|
end
|
|
return string.gsub(input, "<BUF_NAME>", buf_name)
|
|
end
|
|
|
|
function ReplaceHomeDirectory(input)
|
|
local home_directory = os.getenv("HOME") or os.getenv("USERPROFILE") or os.getenv("HOMEPATH") or "~"
|
|
return string.gsub(input, "<HOME>", home_directory)
|
|
end
|
|
|
|
function SplitIntoLines(text)
|
|
local lines = {}
|
|
for line in (text--[[ .. "\n" ]]):gmatch("(.-)\n") do
|
|
line = line:gsub("\r$", "")
|
|
table.insert(lines, line)
|
|
end
|
|
return lines
|
|
end
|
|
|
|
return M
|