mirror of https://github.com/folke/lazy.nvim.git
feat: added `opts.headless` to control ansi output when running headless
This commit is contained in:
parent
93b3a77286
commit
a0a51c06c2
|
@ -130,6 +130,17 @@ M.defaults = {
|
|||
},
|
||||
},
|
||||
},
|
||||
-- Output options for headless mode
|
||||
headless = {
|
||||
-- show the output from process commands like git
|
||||
process = true,
|
||||
-- show log messages
|
||||
log = true,
|
||||
-- show task start/end
|
||||
task = true,
|
||||
-- use ansi colors
|
||||
colors = true,
|
||||
},
|
||||
diff = {
|
||||
-- diff command <d> can be one of:
|
||||
-- * browser: opens the github compare view. Note that this is always mapped to <K> as well,
|
||||
|
|
|
@ -48,6 +48,7 @@ local uv = vim.uv
|
|||
---@field cwd? string
|
||||
---@field on_line? fun(string)
|
||||
---@field on_exit? fun(ok:boolean, output:string)
|
||||
---@field on_data? fun(string)
|
||||
---@field timeout? number
|
||||
---@field env? table<string,string>
|
||||
|
||||
|
@ -145,6 +146,11 @@ function M.spawn(cmd, opts)
|
|||
assert(not err, err)
|
||||
|
||||
if data then
|
||||
if opts.on_data then
|
||||
vim.schedule(function()
|
||||
opts.on_data(data)
|
||||
end)
|
||||
end
|
||||
output = output .. data:gsub("\r\n", "\n")
|
||||
local lines = vim.split(vim.trim(output:gsub("\r$", "")):gsub("[^\n\r]+\r", ""), "\n")
|
||||
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
local Async = require("lazy.async")
|
||||
local Config = require("lazy.core.config")
|
||||
local Process = require("lazy.manage.process")
|
||||
local Terminal = require("lazy.terminal")
|
||||
|
||||
local colors = Config.options.headless.colors
|
||||
|
||||
---@class LazyTaskDef
|
||||
---@field skip? fun(plugin:LazyPlugin, opts?:TaskOptions):any?
|
||||
|
@ -96,6 +100,10 @@ function Task:_start(task)
|
|||
assert(not self:has_started(), "task already started")
|
||||
assert(not self:has_ended(), "task already done")
|
||||
|
||||
if Config.headless() and Config.options.headless.task then
|
||||
self:log("Running task " .. self.name, vim.log.levels.INFO)
|
||||
end
|
||||
|
||||
self._started = vim.uv.hrtime()
|
||||
---@async
|
||||
self._running = Async.run(function()
|
||||
|
@ -122,6 +130,27 @@ function Task:log(msg, level)
|
|||
---@cast msg string
|
||||
table.insert(self._log, { msg = msg, level = level })
|
||||
vim.api.nvim_exec_autocmds("User", { pattern = "LazyRender", modeline = false })
|
||||
if Config.headless() then
|
||||
self:headless()
|
||||
end
|
||||
end
|
||||
|
||||
function Task:headless()
|
||||
if not Config.options.headless.log then
|
||||
return
|
||||
end
|
||||
local msg = self._log[#self._log]
|
||||
if not msg or msg.level == vim.log.levels.TRACE then
|
||||
return
|
||||
end
|
||||
local map = {
|
||||
[vim.log.levels.ERROR] = Terminal.red,
|
||||
[vim.log.levels.WARN] = Terminal.yellow,
|
||||
[vim.log.levels.INFO] = Terminal.blue,
|
||||
}
|
||||
local color = Config.options.headless.colors and map[msg.level]
|
||||
io.write(Terminal.prefix(color and color(msg.msg) or msg.msg, self:prefix()))
|
||||
io.write("\n")
|
||||
end
|
||||
|
||||
---@param msg string|string[]
|
||||
|
@ -143,6 +172,10 @@ function Task:_done()
|
|||
return
|
||||
end
|
||||
|
||||
if Config.headless() and Config.options.headless.task then
|
||||
local ms = math.floor(self:time() + 0.5)
|
||||
self:log("Finished task " .. self.name .. " in " .. ms .. "ms", vim.log.levels.INFO)
|
||||
end
|
||||
self._ended = vim.uv.hrtime()
|
||||
if self._opts.on_done then
|
||||
self._opts.on_done(self)
|
||||
|
@ -172,8 +205,12 @@ function Task:spawn(cmd, opts)
|
|||
local on_line = opts.on_line
|
||||
local on_exit = opts.on_exit
|
||||
|
||||
local headless = Config.headless() and Config.options.headless.process
|
||||
|
||||
function opts.on_line(line)
|
||||
self:log(line, vim.log.levels.TRACE)
|
||||
if not headless then
|
||||
return self:log(line, vim.log.levels.TRACE)
|
||||
end
|
||||
if on_line then
|
||||
pcall(on_line, line)
|
||||
end
|
||||
|
@ -182,18 +219,36 @@ function Task:spawn(cmd, opts)
|
|||
local running = true
|
||||
---@param output string
|
||||
function opts.on_exit(ok, output)
|
||||
if not headless then
|
||||
self:log(vim.trim(output), ok and vim.log.levels.DEBUG or vim.log.levels.ERROR)
|
||||
end
|
||||
if on_exit then
|
||||
pcall(on_exit, ok, output)
|
||||
end
|
||||
running = false
|
||||
end
|
||||
|
||||
if headless then
|
||||
opts.on_data = function(data)
|
||||
-- prefix with plugin name
|
||||
local prefix = self:prefix()
|
||||
io.write(Terminal.prefix(data, prefix))
|
||||
end
|
||||
end
|
||||
Process.spawn(cmd, opts)
|
||||
while running do
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
|
||||
function Task:prefix()
|
||||
local plugin = "[" .. self.plugin.name .. "] "
|
||||
local task = string.rep(" ", 20 - #(self.name .. self.plugin.name)) .. self.name
|
||||
|
||||
return colors and Terminal.magenta(plugin) .. Terminal.cyan(task) .. Terminal.bright_black(" | ")
|
||||
or plugin .. " " .. task .. " | "
|
||||
end
|
||||
|
||||
function Task:wait()
|
||||
while self:is_running() do
|
||||
vim.wait(10)
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
---@class Ansi: table<string, fun(string):string>
|
||||
local M = {}
|
||||
|
||||
M.colors = {
|
||||
reset = "\27[0m",
|
||||
black = "\27[30m",
|
||||
red = "\27[31m",
|
||||
green = "\27[32m",
|
||||
yellow = "\27[33m",
|
||||
blue = "\27[34m",
|
||||
magenta = "\27[35m",
|
||||
cyan = "\27[36m",
|
||||
white = "\27[37m",
|
||||
bright_black = "\27[90m",
|
||||
bright_red = "\27[91m",
|
||||
bright_green = "\27[92m",
|
||||
bright_yellow = "\27[93m",
|
||||
bright_blue = "\27[94m",
|
||||
bright_magenta = "\27[95m",
|
||||
bright_cyan = "\27[96m",
|
||||
bright_white = "\27[97m",
|
||||
}
|
||||
|
||||
function M.color(text, color)
|
||||
return M.colors[color] .. text .. M.colors.reset
|
||||
end
|
||||
|
||||
-- stylua: ignore start
|
||||
function M.black(text) return M.color(text, "black") end
|
||||
function M.red(text) return M.color(text, "red") end
|
||||
function M.green(text) return M.color(text, "green") end
|
||||
function M.yellow(text) return M.color(text, "yellow") end
|
||||
function M.blue(text) return M.color(text, "blue") end
|
||||
function M.magenta(text) return M.color(text, "magenta") end
|
||||
function M.cyan(text) return M.color(text, "cyan") end
|
||||
function M.white(text) return M.color(text, "white") end
|
||||
function M.bright_black(text) return M.color(text, "bright_black") end
|
||||
function M.bright_red(text) return M.color(text, "bright_red") end
|
||||
function M.bright_green(text) return M.color(text, "bright_green") end
|
||||
function M.bright_yellow(text) return M.color(text, "bright_yellow") end
|
||||
function M.bright_blue(text) return M.color(text, "bright_blue") end
|
||||
function M.bright_magenta(text) return M.color(text, "bright_magenta") end
|
||||
function M.bright_cyan(text) return M.color(text, "bright_cyan") end
|
||||
function M.bright_white(text) return M.color(text, "bright_white") end
|
||||
-- stylua: ignore end
|
||||
|
||||
---@param data string
|
||||
---@param prefix string
|
||||
function M.prefix(data, prefix)
|
||||
-- Normalize Windows-style newlines to simple newlines
|
||||
data = data:gsub("\r\n", "\n")
|
||||
|
||||
-- Handle prefix for the first line, if data starts immediately
|
||||
data = prefix .. data
|
||||
|
||||
-- Prefix new lines ensuring not to double prefix if a line starts with \r
|
||||
data = data:gsub("(\n)([^\r])", "%1" .. prefix .. "%2")
|
||||
|
||||
-- Handle carriage returns properly to avoid double prefixing
|
||||
-- Replace any \r not followed by \n with \r, then add a prefix only if the following character isn't the start of our prefix
|
||||
data = data:gsub("\r([^\n])", function(nextChar)
|
||||
if nextChar:sub(1, #prefix) == prefix then
|
||||
return "\r" .. nextChar
|
||||
else
|
||||
return "\r" .. prefix .. nextChar
|
||||
end
|
||||
end)
|
||||
return data
|
||||
end
|
||||
|
||||
return M
|
|
@ -6,22 +6,22 @@ for _, name in ipairs({ "config", "data", "state", "cache" }) do
|
|||
vim.env[("XDG_%s_HOME"):format(name:upper())] = root .. "/" .. name
|
||||
end
|
||||
|
||||
-- -- Bootstrap lazy.nvim
|
||||
-- local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
||||
-- if not (vim.uv or vim.loop).fs_stat(lazypath) then
|
||||
-- local lazyrepo = "https://github.com/folke/lazy.nvim.git"
|
||||
-- vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
|
||||
-- end
|
||||
-- vim.opt.rtp:prepend(lazypath)
|
||||
vim.opt.rtp:prepend(".")
|
||||
|
||||
vim.o.loadplugins = true -- enable since nvim -l disables plugins
|
||||
|
||||
-- Setup lazy.nvim
|
||||
require("lazy").setup({
|
||||
spec = {
|
||||
"lunarmodules/busted", -- add busted
|
||||
},
|
||||
rocks = { hererocks = true },
|
||||
})
|
||||
|
||||
local Config = require("lazy.core.config")
|
||||
-- disable termnial output for the tests
|
||||
Config.options.headless = {}
|
||||
|
||||
-- run busted
|
||||
return pcall(require("busted.runner"), {
|
||||
standalone = false,
|
||||
|
|
Loading…
Reference in New Issue