live-server.nvim/lua/live-server.lua

142 lines
3 KiB
Lua

local M = {}
local initialized = false
local job_cache = {}
local defaults = {
args = { '--port=5555' },
}
local config = vim.deepcopy(defaults)
local function log(message, level)
vim.notify(string.format('live-server.nvim: %s', message), vim.log.levels[level])
end
local function is_windows()
return vim.loop.os_uname().version:match('Windows')
end
local function init()
if initialized then
return true
end
local user_config = vim.g.live_server or {}
config = vim.tbl_deep_extend('force', defaults, user_config)
if not vim.fn.executable('live-server') and not (is_windows() and vim.fn.executable('live-server.cmd')) then
log('live-server is not executable. Ensure the npm module is properly installed', 'ERROR')
return false
end
initialized = true
return true
end
local function find_cached_dir(dir)
if not dir then
return nil
end
local cur = dir
while not job_cache[cur] do
if cur == '/' or cur:match('^[A-Z]:\\$') then
return nil
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 resolve_dir(dir)
if not dir or dir == '' then
dir = '%:p:h'
end
return vim.fn.expand(vim.fn.fnamemodify(vim.fn.expand(dir), ':p'))
end
function M.start(dir)
if not init() then
return
end
dir = resolve_dir(dir)
if is_running(dir) then
log('live-server already running', 'INFO')
return
end
local cmd_exe = is_windows() and 'live-server.cmd' or 'live-server'
local cmd = { cmd_exe, dir }
vim.list_extend(cmd, config.args)
local job_id = vim.fn.jobstart(cmd, {
on_stderr = function(_, data)
if not data or data[1] == '' then
return
end
log(data[1]:match('.-m(.-)\27') or data[1], 'ERROR')
end,
on_exit = function(_, exit_code)
job_cache[dir] = nil
if exit_code == 143 then
return
end
log(string.format('stopped with code %s', exit_code), 'INFO')
end,
})
local port = 'unknown'
for _, arg in ipairs(config.args) do
local p = arg:match('%-%-port=(%d+)')
if p then
port = p
break
end
end
log(string.format('live-server started on 127.0.0.1:%s', port), 'INFO')
job_cache[dir] = job_id
end
function M.stop(dir)
dir = resolve_dir(dir)
local cached_dir = find_cached_dir(dir)
if cached_dir and job_cache[cached_dir] then
vim.fn.jobstop(job_cache[cached_dir])
job_cache[cached_dir] = nil
log('live-server stopped', 'INFO')
end
end
function M.toggle(dir)
dir = resolve_dir(dir)
if is_running(dir) then
M.stop(dir)
else
M.start(dir)
end
end
---@deprecated Use `vim.g.live_server` instead
function M.setup(user_config)
vim.notify_once(
'live-server.nvim: setup() is deprecated. Use vim.g.live_server instead.',
vim.log.levels.WARN
)
if user_config then
vim.g.live_server = vim.tbl_deep_extend('force', vim.g.live_server or {}, user_config)
end
init()
end
return M