mirror of
https://github.com/pojokcodeid/nvim-lazy.git
synced 2025-06-22 17:03:36 +02:00
enc: add npm runner with popup modal
This commit is contained in:
parent
c1e9e57f17
commit
23a8cf07bf
2 changed files with 210 additions and 36 deletions
|
@ -1,11 +1,31 @@
|
||||||
local function open_new_buffer(name)
|
local function show_modal(text)
|
||||||
local buf = vim.api.nvim_create_buf(true, false)
|
local buf = vim.api.nvim_create_buf(false, true) -- buffer untuk modal
|
||||||
vim.api.nvim_set_current_buf(buf)
|
|
||||||
vim.api.nvim_buf_set_option(buf, "modifiable", true)
|
vim.api.nvim_buf_set_lines(buf, 0, -1, false, { text, "", "Press q to close" })
|
||||||
if name then
|
|
||||||
vim.api.nvim_buf_set_name(buf, name)
|
local width = 50
|
||||||
end
|
local height = 5
|
||||||
return buf
|
local row = math.floor((vim.o.lines - height) / 2)
|
||||||
|
local col = math.floor((vim.o.columns - width) / 2)
|
||||||
|
|
||||||
|
local win = vim.api.nvim_open_win(buf, true, {
|
||||||
|
relative = "editor",
|
||||||
|
width = width,
|
||||||
|
height = height,
|
||||||
|
row = row,
|
||||||
|
col = col,
|
||||||
|
style = "minimal",
|
||||||
|
border = "rounded",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- keymap untuk menutup modal dengan 'q'
|
||||||
|
vim.api.nvim_buf_set_keymap(buf, "n", "q", "", {
|
||||||
|
noremap = true,
|
||||||
|
silent = true,
|
||||||
|
callback = function()
|
||||||
|
vim.api.nvim_win_close(win, true)
|
||||||
|
end,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
@ -98,32 +118,20 @@ M.start = function(dir)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local buffer_name = "npmrun.txt"
|
|
||||||
local output_buf = open_new_buffer(buffer_name)
|
|
||||||
vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, {})
|
|
||||||
|
|
||||||
local function append_to_buffer(lines)
|
local function append_to_buffer(lines)
|
||||||
if not lines then
|
if not lines then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not vim.api.nvim_buf_is_valid(output_buf) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local filtered = {}
|
|
||||||
for _, l in ipairs(lines) do
|
|
||||||
if l ~= "" then
|
|
||||||
table.insert(filtered, l)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #filtered > 0 then
|
|
||||||
local line_count = vim.api.nvim_buf_line_count(output_buf)
|
|
||||||
vim.api.nvim_buf_set_lines(output_buf, line_count, line_count, false, filtered)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function close_output_buffer()
|
for _, line in ipairs(lines) do
|
||||||
if output_buf and vim.api.nvim_buf_is_valid(output_buf) then
|
if line ~= "" then
|
||||||
vim.api.nvim_buf_delete(output_buf, { force = true })
|
line = tostring(line)
|
||||||
|
line = line:gsub("^%s*(.-)%s*$", "%1")
|
||||||
|
if string.find(line, "http") then
|
||||||
|
show_modal(line)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -139,14 +147,12 @@ M.start = function(dir)
|
||||||
return "[ERR] " .. l
|
return "[ERR] " .. l
|
||||||
end, data))
|
end, data))
|
||||||
end,
|
end,
|
||||||
on_exit = function(_, code)
|
on_exit = function(_, _)
|
||||||
append_to_buffer({ string.format(main_cmd .. " exited with code %d", code) })
|
|
||||||
close_output_buffer()
|
|
||||||
job_cache[dir] = nil
|
job_cache[dir] = nil
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
job_cache[dir] = { job_id = job_id, buf = output_buf }
|
job_cache[dir] = { job_id = job_id }
|
||||||
log(main_cmd .. " started", "INFO")
|
log(main_cmd .. " started", "INFO")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -158,9 +164,6 @@ M.stop = function(dir)
|
||||||
local job_entry = job_cache[cached_dir]
|
local job_entry = job_cache[cached_dir]
|
||||||
if job_entry then
|
if job_entry then
|
||||||
vim.fn.jobstop(job_entry.job_id)
|
vim.fn.jobstop(job_entry.job_id)
|
||||||
if job_entry.buf and vim.api.nvim_buf_is_valid(job_entry.buf) then
|
|
||||||
vim.api.nvim_buf_delete(job_entry.buf, { force = true })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
job_cache[cached_dir] = nil
|
job_cache[cached_dir] = nil
|
||||||
log(main_cmd .. " stopped", "INFO")
|
log(main_cmd .. " stopped", "INFO")
|
||||||
|
|
171
lua/pcode/user/npmrun2.lua
Normal file
171
lua/pcode/user/npmrun2.lua
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
local function open_new_buffer(name)
|
||||||
|
local buf = vim.api.nvim_create_buf(true, false)
|
||||||
|
vim.api.nvim_set_current_buf(buf)
|
||||||
|
vim.api.nvim_buf_set_option(buf, "modifiable", true)
|
||||||
|
if name then
|
||||||
|
vim.api.nvim_buf_set_name(buf, name)
|
||||||
|
end
|
||||||
|
return buf
|
||||||
|
end
|
||||||
|
|
||||||
|
local M = {}
|
||||||
|
|
||||||
|
local main_cmd = "npm run dev" -- default
|
||||||
|
|
||||||
|
local function log(message, level)
|
||||||
|
vim.notify(string.format("npm-dev-runner: %s", message), vim.log.levels[level])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Cache: dir -> { job_id=..., buf=... }
|
||||||
|
local job_cache = {}
|
||||||
|
|
||||||
|
local function find_cached_dir(dir)
|
||||||
|
if not dir then
|
||||||
|
vim.notify("npm-dev-runner: No directory provided to find_cached_dir()", vim.log.levels.ERROR)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local cur = dir
|
||||||
|
while not job_cache[cur] do
|
||||||
|
if cur == "/" or string.match(cur, "^[A-Z]:\\$") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
cur = vim.fn.fnamemodify(cur, ":h")
|
||||||
|
end
|
||||||
|
return cur
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_running(dir)
|
||||||
|
local cached_dir = find_cached_dir(dir)
|
||||||
|
return cached_dir and job_cache[cached_dir]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_windows()
|
||||||
|
return vim.loop.os_uname().version:match("Windows")
|
||||||
|
end
|
||||||
|
|
||||||
|
M.toggle = function(dir)
|
||||||
|
local running = is_running(dir)
|
||||||
|
if not running then
|
||||||
|
M.start(dir)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
M.stop(dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Fungsi setup menerima argumen command utama, contoh: require("npmrun").setup("pnpm dev")
|
||||||
|
M.setup = function(cmd)
|
||||||
|
main_cmd = cmd or "npm run dev"
|
||||||
|
if not vim.fn.executable(main_cmd:match("%S+")) then
|
||||||
|
log(main_cmd .. " is not executable. Make sure it is installed and in PATH.", "ERROR")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local function find_dir(args)
|
||||||
|
local dir = args ~= "" and args or "%:p:h"
|
||||||
|
return vim.fn.expand(vim.fn.fnamemodify(vim.fn.expand(dir), ":p"))
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command("DevStart", function(opts)
|
||||||
|
M.start(find_dir(opts.args))
|
||||||
|
end, { nargs = "?" })
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command("DevStop", function(opts)
|
||||||
|
M.stop(find_dir(opts.args))
|
||||||
|
end, { nargs = "?" })
|
||||||
|
|
||||||
|
vim.api.nvim_create_user_command("DevToggle", function(opts)
|
||||||
|
M.toggle(find_dir(opts.args))
|
||||||
|
end, { nargs = "?" })
|
||||||
|
end
|
||||||
|
|
||||||
|
M.start = function(dir)
|
||||||
|
if is_running(dir) then
|
||||||
|
log(main_cmd .. " already running", "INFO")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local cmd
|
||||||
|
if is_windows() then
|
||||||
|
cmd = { "cmd.exe", "/C" }
|
||||||
|
for word in main_cmd:gmatch("%S+") do
|
||||||
|
table.insert(cmd, word)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
cmd = {}
|
||||||
|
for word in main_cmd:gmatch("%S+") do
|
||||||
|
table.insert(cmd, word)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local buffer_name = "npmrun.txt"
|
||||||
|
local output_buf = open_new_buffer(buffer_name)
|
||||||
|
vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, {})
|
||||||
|
|
||||||
|
local function append_to_buffer(lines)
|
||||||
|
if not lines then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not vim.api.nvim_buf_is_valid(output_buf) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local filtered = {}
|
||||||
|
for _, l in ipairs(lines) do
|
||||||
|
if l ~= "" then
|
||||||
|
table.insert(filtered, l)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #filtered > 0 then
|
||||||
|
local line_count = vim.api.nvim_buf_line_count(output_buf)
|
||||||
|
vim.api.nvim_buf_set_lines(output_buf, line_count, line_count, false, filtered)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function close_output_buffer()
|
||||||
|
if output_buf and vim.api.nvim_buf_is_valid(output_buf) then
|
||||||
|
vim.api.nvim_buf_delete(output_buf, { force = true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local job_id = vim.fn.jobstart(cmd, {
|
||||||
|
cwd = dir,
|
||||||
|
stdout_buffered = false, -- streaming mode
|
||||||
|
stderr_buffered = false,
|
||||||
|
on_stdout = function(_, data)
|
||||||
|
append_to_buffer(data)
|
||||||
|
end,
|
||||||
|
on_stderr = function(_, data)
|
||||||
|
append_to_buffer(vim.tbl_map(function(l)
|
||||||
|
return "[ERR] " .. l
|
||||||
|
end, data))
|
||||||
|
end,
|
||||||
|
on_exit = function(_, code)
|
||||||
|
append_to_buffer({ string.format(main_cmd .. " exited with code %d", code) })
|
||||||
|
close_output_buffer()
|
||||||
|
job_cache[dir] = nil
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
job_cache[dir] = { job_id = job_id, buf = output_buf }
|
||||||
|
log(main_cmd .. " started", "INFO")
|
||||||
|
end
|
||||||
|
|
||||||
|
M.stop = function(dir)
|
||||||
|
local running = is_running(dir)
|
||||||
|
if running then
|
||||||
|
local cached_dir = find_cached_dir(dir)
|
||||||
|
if cached_dir then
|
||||||
|
local job_entry = job_cache[cached_dir]
|
||||||
|
if job_entry then
|
||||||
|
vim.fn.jobstop(job_entry.job_id)
|
||||||
|
if job_entry.buf and vim.api.nvim_buf_is_valid(job_entry.buf) then
|
||||||
|
vim.api.nvim_buf_delete(job_entry.buf, { force = true })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
job_cache[cached_dir] = nil
|
||||||
|
log(main_cmd .. " stopped", "INFO")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
Loading…
Add table
Add a link
Reference in a new issue