|
|
|
@@ -1,17 +1,19 @@
|
|
|
|
-- ~/.config/nvim/lua/stopwatch.lua
|
|
|
|
-- ~/.config/nvim/lua/stopwatch.lua
|
|
|
|
-- Simple visible stopwatch for Neovim
|
|
|
|
-- Visible stopwatch for Neovim with centered big display and clickable buttons
|
|
|
|
local M = {}
|
|
|
|
local M = {}
|
|
|
|
local uv = vim.loop
|
|
|
|
local uv = vim.loop
|
|
|
|
|
|
|
|
|
|
|
|
local state = {
|
|
|
|
local state = {
|
|
|
|
running = false,
|
|
|
|
running = false,
|
|
|
|
start_hr = 0, -- hrtime at start (nanoseconds)
|
|
|
|
start_hr = 0,
|
|
|
|
elapsed_ns = 0, -- accumulated nanoseconds when stopped
|
|
|
|
elapsed_ns = 0,
|
|
|
|
name = nil,
|
|
|
|
name = nil,
|
|
|
|
timer = nil,
|
|
|
|
timer = nil,
|
|
|
|
bufnr = nil,
|
|
|
|
bufnr = nil,
|
|
|
|
win = nil,
|
|
|
|
win = nil,
|
|
|
|
opts = nil,
|
|
|
|
opts = nil,
|
|
|
|
|
|
|
|
big_mode = false,
|
|
|
|
|
|
|
|
button_spans = nil,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
local function ns_to_time(ns)
|
|
|
|
local function ns_to_time(ns)
|
|
|
|
@@ -29,6 +31,35 @@ local function ns_to_time(ns)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local BIG_DIGITS = {
|
|
|
|
|
|
|
|
["0"] = {" ███ ","█ █","█ █","█ █"," ███ "},
|
|
|
|
|
|
|
|
["1"] = {" █ "," ██ "," █ "," █ "," ███ "},
|
|
|
|
|
|
|
|
["2"] = {" ███ ","█ █"," ██ "," ██ ","█████"},
|
|
|
|
|
|
|
|
["3"] = {" ███ "," █"," ██ "," █"," ███ "},
|
|
|
|
|
|
|
|
["4"] = {"█ █ ","█ █ ","█████"," █ "," █ "},
|
|
|
|
|
|
|
|
["5"] = {"█████","█ ","████ "," █","████ "},
|
|
|
|
|
|
|
|
["6"] = {" ███ ","█ ","████ ","█ █"," ███ "},
|
|
|
|
|
|
|
|
["7"] = {"█████"," █"," █ "," █ "," █ "},
|
|
|
|
|
|
|
|
["8"] = {" ███ ","█ █"," ███ ","█ █"," ███ "},
|
|
|
|
|
|
|
|
["9"] = {" ███ ","█ █"," ████"," █"," ███ "},
|
|
|
|
|
|
|
|
[":"] = {" "," ░ "," "," ░ "," "},
|
|
|
|
|
|
|
|
[" "] = {" "," "," "," "," "},
|
|
|
|
|
|
|
|
["-"] = {" "," ","█████"," "," "},
|
|
|
|
|
|
|
|
["."] = {" "," "," "," "," ░ "},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function big_time_lines(timestr)
|
|
|
|
|
|
|
|
local rows = {"","","","",""}
|
|
|
|
|
|
|
|
for i = 1, #timestr do
|
|
|
|
|
|
|
|
local ch = timestr:sub(i,i)
|
|
|
|
|
|
|
|
local pat = BIG_DIGITS[ch] or BIG_DIGITS[" "]
|
|
|
|
|
|
|
|
for r = 1,5 do
|
|
|
|
|
|
|
|
rows[r] = rows[r] .. pat[r] .. " "
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
return rows
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function get_elapsed_ns()
|
|
|
|
local function get_elapsed_ns()
|
|
|
|
if state.running then
|
|
|
|
if state.running then
|
|
|
|
return state.elapsed_ns + (uv.hrtime() - state.start_hr)
|
|
|
|
return state.elapsed_ns + (uv.hrtime() - state.start_hr)
|
|
|
|
@@ -46,8 +77,18 @@ local function ensure_win()
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "filetype", "stopwatch")
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "filetype", "stopwatch")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local width = state.opts.width or 24
|
|
|
|
local width = state.opts.width or 28
|
|
|
|
local height = 1
|
|
|
|
local height = 1
|
|
|
|
|
|
|
|
if state.opts.big_display or state.big_mode then
|
|
|
|
|
|
|
|
local chars = state.opts.big_chars or 8
|
|
|
|
|
|
|
|
local char_width = 6
|
|
|
|
|
|
|
|
width = chars * char_width
|
|
|
|
|
|
|
|
height = 8
|
|
|
|
|
|
|
|
height = height + 1 -- plus button line
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
height = 1 + 1 -- one line time + button line
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local col = (vim.o.columns - width) - (state.opts.margin_right or 2)
|
|
|
|
local col = (vim.o.columns - width) - (state.opts.margin_right or 2)
|
|
|
|
local row = state.opts.row or 1
|
|
|
|
local row = state.opts.row or 1
|
|
|
|
|
|
|
|
|
|
|
|
@@ -55,15 +96,26 @@ local function ensure_win()
|
|
|
|
relative = "editor",
|
|
|
|
relative = "editor",
|
|
|
|
anchor = "NW",
|
|
|
|
anchor = "NW",
|
|
|
|
row = row,
|
|
|
|
row = row,
|
|
|
|
col = col,
|
|
|
|
col = math.max(0, col),
|
|
|
|
width = width,
|
|
|
|
width = math.min(width, vim.o.columns - 1),
|
|
|
|
height = height,
|
|
|
|
height = height,
|
|
|
|
style = "minimal",
|
|
|
|
style = "minimal",
|
|
|
|
focusable = false,
|
|
|
|
focusable = true, -- <-- must be focusable for clicks to work reliably
|
|
|
|
noautocmd = true,
|
|
|
|
noautocmd = true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if state.win and vim.api.nvim_win_is_valid(state.win) then
|
|
|
|
|
|
|
|
pcall(vim.api.nvim_win_close, state.win, true)
|
|
|
|
|
|
|
|
end
|
|
|
|
state.win = vim.api.nvim_open_win(state.bufnr, false, win_opts)
|
|
|
|
state.win = vim.api.nvim_open_win(state.bufnr, false, win_opts)
|
|
|
|
vim.api.nvim_win_set_option(state.win, "winblend", state.opts.winblend or 5)
|
|
|
|
vim.api.nvim_win_set_option(state.win, "winblend", state.opts.winblend or 5)
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "buftype", "nofile")
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "wrap", false)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- buffer-local mouse mapping: LeftMouse triggers click handler
|
|
|
|
|
|
|
|
pcall(function()
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_keymap(state.bufnr, "n", "<LeftMouse>", "<Cmd>lua require('stopwatch')._on_click()<CR>", {nowait=true, noremap=true, silent=true})
|
|
|
|
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function close_win()
|
|
|
|
local function close_win()
|
|
|
|
@@ -71,7 +123,23 @@ local function close_win()
|
|
|
|
pcall(vim.api.nvim_win_close, state.win, true)
|
|
|
|
pcall(vim.api.nvim_win_close, state.win, true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
state.win = nil
|
|
|
|
state.win = nil
|
|
|
|
-- keep buf so it can be reused
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function build_button_line()
|
|
|
|
|
|
|
|
local btns = { "> Toggle", "O Reset", "X Hide" }
|
|
|
|
|
|
|
|
local sep = " "
|
|
|
|
|
|
|
|
local line = table.concat(btns, sep)
|
|
|
|
|
|
|
|
local spans = {}
|
|
|
|
|
|
|
|
local cur = 1
|
|
|
|
|
|
|
|
for i, b in ipairs(btns) do
|
|
|
|
|
|
|
|
local s = line:find(b, cur, true)
|
|
|
|
|
|
|
|
if s then
|
|
|
|
|
|
|
|
local e = s + #b - 1
|
|
|
|
|
|
|
|
table.insert(spans, {name = b, s = s, e = e})
|
|
|
|
|
|
|
|
cur = e + #sep + 1
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
return line, spans
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function update_win()
|
|
|
|
local function update_win()
|
|
|
|
@@ -79,11 +147,68 @@ local function update_win()
|
|
|
|
ensure_win()
|
|
|
|
ensure_win()
|
|
|
|
if not state.bufnr or not vim.api.nvim_buf_is_valid(state.bufnr) then return end
|
|
|
|
if not state.bufnr or not vim.api.nvim_buf_is_valid(state.bufnr) then return end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local lines = {}
|
|
|
|
local label = state.name and ("[" .. state.name .. "] ") or ""
|
|
|
|
local label = state.name and ("[" .. state.name .. "] ") or ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if state.opts.big_display or state.big_mode then
|
|
|
|
|
|
|
|
-- compute time string
|
|
|
|
|
|
|
|
local total_s = math.floor(get_elapsed_ns() / 1e9)
|
|
|
|
|
|
|
|
local h = math.floor(total_s / 3600)
|
|
|
|
|
|
|
|
local m = math.floor((total_s % 3600) / 60)
|
|
|
|
|
|
|
|
local s = total_s % 60
|
|
|
|
|
|
|
|
local timestr
|
|
|
|
|
|
|
|
if h > 0 then
|
|
|
|
|
|
|
|
timestr = string.format("%02d:%02d:%02d", h, m, s)
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
timestr = string.format("%02d:%02d", m, s)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local b_lines = big_time_lines(timestr)
|
|
|
|
|
|
|
|
-- center horizontally inside window by adding left padding
|
|
|
|
|
|
|
|
local win_w = vim.api.nvim_win_get_width(state.win)
|
|
|
|
|
|
|
|
local char_width = 6 -- matches BIG_DIGITS width+gap
|
|
|
|
|
|
|
|
local displayed_w = #timestr * char_width
|
|
|
|
|
|
|
|
local leftpad = math.max(0, math.floor((win_w - displayed_w) / 2))
|
|
|
|
|
|
|
|
local pad = string.rep(" ", leftpad)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
table.insert(lines, "") -- top blank line
|
|
|
|
|
|
|
|
for _, l in ipairs(b_lines) do table.insert(lines, pad .. l) end
|
|
|
|
|
|
|
|
table.insert(lines, "") -- blank between time and buttons
|
|
|
|
|
|
|
|
local btn_line, spans = build_button_line()
|
|
|
|
|
|
|
|
btn_line = pad .. btn_line
|
|
|
|
|
|
|
|
-- adjust spans by leftpad
|
|
|
|
|
|
|
|
for _, sp in ipairs(spans) do
|
|
|
|
|
|
|
|
sp.s = sp.s + leftpad
|
|
|
|
|
|
|
|
sp.e = sp.e + leftpad
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
table.insert(lines, btn_line)
|
|
|
|
|
|
|
|
table.insert(lines, "") -- bottom blank
|
|
|
|
|
|
|
|
state.button_spans = spans
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
local status_sym = state.running and "⏱ " or "⏸ "
|
|
|
|
local status_sym = state.running and "⏱ " or "⏸ "
|
|
|
|
local txt = status_sym .. " " .. label .. ns_to_time(get_elapsed_ns())
|
|
|
|
local txt = status_sym .. label .. ns_to_time(get_elapsed_ns())
|
|
|
|
|
|
|
|
local win_w = vim.api.nvim_win_get_width(state.win)
|
|
|
|
|
|
|
|
local strw = vim.fn.strwidth(txt)
|
|
|
|
|
|
|
|
local leftpad = math.max(0, math.floor((win_w - strw) / 2))
|
|
|
|
|
|
|
|
local pad = string.rep(" ", leftpad)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
table.insert(lines, "") -- top blank
|
|
|
|
|
|
|
|
table.insert(lines, pad .. txt)
|
|
|
|
|
|
|
|
table.insert(lines, "") -- blank between time and buttons
|
|
|
|
|
|
|
|
local btn_line, spans = build_button_line()
|
|
|
|
|
|
|
|
btn_line = pad .. btn_line
|
|
|
|
|
|
|
|
for _, sp in ipairs(spans) do
|
|
|
|
|
|
|
|
sp.s = sp.s + leftpad
|
|
|
|
|
|
|
|
sp.e = sp.e + leftpad
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
table.insert(lines, btn_line)
|
|
|
|
|
|
|
|
table.insert(lines, "") -- bottom blank
|
|
|
|
|
|
|
|
state.button_spans = spans
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "modifiable", true)
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "modifiable", true)
|
|
|
|
vim.api.nvim_buf_set_lines(state.bufnr, 0, -1, false, {txt})
|
|
|
|
vim.api.nvim_buf_set_lines(state.bufnr, 0, -1, false, lines)
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "modifiable", false)
|
|
|
|
vim.api.nvim_buf_set_option(state.bufnr, "modifiable", false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
@@ -106,15 +231,12 @@ local function stop_timer_loop()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- Public API
|
|
|
|
|
|
|
|
function M.start(name)
|
|
|
|
function M.start(name)
|
|
|
|
if state.running then return end
|
|
|
|
if state.running then return end
|
|
|
|
state.name = name or state.name
|
|
|
|
state.name = name or state.name
|
|
|
|
state.start_hr = uv.hrtime() - state.elapsed_ns
|
|
|
|
state.start_hr = uv.hrtime() - state.elapsed_ns
|
|
|
|
state.running = true
|
|
|
|
state.running = true
|
|
|
|
if state.opts.visible then
|
|
|
|
if state.opts.visible then ensure_win() end
|
|
|
|
ensure_win()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
start_timer_loop()
|
|
|
|
start_timer_loop()
|
|
|
|
update_win()
|
|
|
|
update_win()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
@@ -132,21 +254,41 @@ function M.stop()
|
|
|
|
local duration = ns_to_time(state.elapsed_ns)
|
|
|
|
local duration = ns_to_time(state.elapsed_ns)
|
|
|
|
local line = string.format("- %s | %s | %s\n", time_str, name, duration)
|
|
|
|
local line = string.format("- %s | %s | %s\n", time_str, name, duration)
|
|
|
|
local f = io.open(log_path, "a")
|
|
|
|
local f = io.open(log_path, "a")
|
|
|
|
if f then
|
|
|
|
if f then f:write(line) f:close() end
|
|
|
|
f:write(line)
|
|
|
|
|
|
|
|
f:close()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Pause (anhalten, aber nicht als "Stop"/Log)
|
|
|
|
|
|
|
|
function M.pause()
|
|
|
|
|
|
|
|
if not state.running then return end
|
|
|
|
|
|
|
|
state.elapsed_ns = get_elapsed_ns()
|
|
|
|
|
|
|
|
state.running = false
|
|
|
|
|
|
|
|
stop_timer_loop()
|
|
|
|
|
|
|
|
update_win()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Resume (fortsetzen)
|
|
|
|
|
|
|
|
function M.resume()
|
|
|
|
|
|
|
|
if state.running then return end
|
|
|
|
|
|
|
|
state.start_hr = uv.hrtime() - state.elapsed_ns
|
|
|
|
|
|
|
|
state.running = true
|
|
|
|
|
|
|
|
start_timer_loop()
|
|
|
|
|
|
|
|
update_win()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Toggle zwischen Pause und Resume (für Button/Command)
|
|
|
|
function M.toggle(name)
|
|
|
|
function M.toggle(name)
|
|
|
|
if state.running then
|
|
|
|
if state.running then
|
|
|
|
M.stop()
|
|
|
|
M.pause()
|
|
|
|
else
|
|
|
|
else
|
|
|
|
M.start(name)
|
|
|
|
-- optional: wenn name übergeben wurde, setze neuen Namen
|
|
|
|
|
|
|
|
if name and name ~= "" then state.name = name end
|
|
|
|
|
|
|
|
M.resume()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function M.reset()
|
|
|
|
function M.reset()
|
|
|
|
state.running = false
|
|
|
|
state.running = false
|
|
|
|
state.elapsed_ns = 0
|
|
|
|
state.elapsed_ns = 0
|
|
|
|
@@ -175,20 +317,56 @@ function M.log_now()
|
|
|
|
local duration = ns_to_time(get_elapsed_ns())
|
|
|
|
local duration = ns_to_time(get_elapsed_ns())
|
|
|
|
local line = string.format("- %s | %s | %s\n", time_str, name, duration)
|
|
|
|
local line = string.format("- %s | %s | %s\n", time_str, name, duration)
|
|
|
|
local f = io.open(log_path, "a")
|
|
|
|
local f = io.open(log_path, "a")
|
|
|
|
if f then
|
|
|
|
if f then f:write(line) f:close() end
|
|
|
|
f:write(line)
|
|
|
|
|
|
|
|
f:close()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function M.status()
|
|
|
|
function M.status()
|
|
|
|
-- returns a short string for statusline
|
|
|
|
|
|
|
|
local elapsed = get_elapsed_ns()
|
|
|
|
local elapsed = get_elapsed_ns()
|
|
|
|
local prefix = state.running and "⏱" or "⏸"
|
|
|
|
local prefix = state.running and "⏱" or "⏸"
|
|
|
|
local name = state.name and (" " .. state.name) or ""
|
|
|
|
local name = state.name and (" " .. state.name) or ""
|
|
|
|
return prefix .. name .. " " .. ns_to_time(elapsed)
|
|
|
|
return prefix .. name .. " " .. ns_to_time(elapsed)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function M.toggle_big()
|
|
|
|
|
|
|
|
state.big_mode = not state.big_mode
|
|
|
|
|
|
|
|
update_win()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Mouse click handler
|
|
|
|
|
|
|
|
function M._on_click()
|
|
|
|
|
|
|
|
-- only proceed when our floating window is focused
|
|
|
|
|
|
|
|
local cur = vim.api.nvim_get_current_win()
|
|
|
|
|
|
|
|
if cur ~= state.win then return end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local pos = vim.fn.getmousepos()
|
|
|
|
|
|
|
|
if not pos then return end
|
|
|
|
|
|
|
|
local click_line = pos.line
|
|
|
|
|
|
|
|
local col = pos.column
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- button line is the second-to-last line because we add a bottom blank line
|
|
|
|
|
|
|
|
local total = vim.api.nvim_buf_line_count(state.bufnr)
|
|
|
|
|
|
|
|
local btn_line_index = total - 1
|
|
|
|
|
|
|
|
if click_line ~= btn_line_index then return end
|
|
|
|
|
|
|
|
if not state.button_spans then return end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, sp in ipairs(state.button_spans) do
|
|
|
|
|
|
|
|
if col >= sp.s and col <= sp.e then
|
|
|
|
|
|
|
|
local name = sp.name
|
|
|
|
|
|
|
|
if name:find("Toggle",1,true) then M.toggle()
|
|
|
|
|
|
|
|
elseif name:find("Hide",1,true) then M.hide()
|
|
|
|
|
|
|
|
elseif name:find("Reset",1,true) then M.reset() end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- visual feedback
|
|
|
|
|
|
|
|
pcall(function()
|
|
|
|
|
|
|
|
local ns = vim.api.nvim_create_namespace("stopwatch_click")
|
|
|
|
|
|
|
|
vim.api.nvim_buf_add_highlight(state.bufnr, ns, "Visual", btn_line_index-1, sp.s-1, sp.e)
|
|
|
|
|
|
|
|
vim.defer_fn(function() vim.api.nvim_buf_clear_namespace(state.bufnr, ns, 0, -1) end, 120)
|
|
|
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function M.setup(opts)
|
|
|
|
function M.setup(opts)
|
|
|
|
opts = opts or {}
|
|
|
|
opts = opts or {}
|
|
|
|
state.opts = vim.tbl_extend("keep", opts, {
|
|
|
|
state.opts = vim.tbl_extend("keep", opts, {
|
|
|
|
@@ -200,32 +378,21 @@ function M.setup(opts)
|
|
|
|
winblend = 5,
|
|
|
|
winblend = 5,
|
|
|
|
log_on_stop = false,
|
|
|
|
log_on_stop = false,
|
|
|
|
log_path = nil,
|
|
|
|
log_path = nil,
|
|
|
|
|
|
|
|
big_display = false,
|
|
|
|
|
|
|
|
big_chars = 8,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
state.big_mode = state.opts.big_display or false
|
|
|
|
|
|
|
|
|
|
|
|
-- Create user commands
|
|
|
|
vim.api.nvim_create_user_command("StopwatchStart", function(opts) M.start(opts.args ~= "" and opts.args or nil) end, { nargs = "?" })
|
|
|
|
vim.api.nvim_create_user_command("StopwatchStart", function(opts)
|
|
|
|
vim.api.nvim_create_user_command("StopwatchStop", function() M.stop() end, {})
|
|
|
|
M.start(opts.args ~= "" and opts.args or nil)
|
|
|
|
vim.api.nvim_create_user_command("StopwatchToggle", function(opts) M.toggle(opts.args ~= "" and opts.args or nil) end, { nargs = "?" })
|
|
|
|
end, { nargs = "?" })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_create_user_command("StopwatchStop", function()
|
|
|
|
|
|
|
|
M.stop()
|
|
|
|
|
|
|
|
end, {})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_create_user_command("StopwatchToggle", function(opts)
|
|
|
|
|
|
|
|
M.toggle(opts.args ~= "" and opts.args or nil)
|
|
|
|
|
|
|
|
end, { nargs = "?" })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vim.api.nvim_create_user_command("StopwatchReset", function() M.reset() end, {})
|
|
|
|
vim.api.nvim_create_user_command("StopwatchReset", function() M.reset() end, {})
|
|
|
|
vim.api.nvim_create_user_command("StopwatchShow", function() M.show() end, {})
|
|
|
|
vim.api.nvim_create_user_command("StopwatchShow", function() M.show() end, {})
|
|
|
|
vim.api.nvim_create_user_command("StopwatchHide", function() M.hide() end, {})
|
|
|
|
vim.api.nvim_create_user_command("StopwatchHide", function() M.hide() end, {})
|
|
|
|
vim.api.nvim_create_user_command("StopwatchLog", function() M.log_now() end, {})
|
|
|
|
vim.api.nvim_create_user_command("StopwatchLog", function() M.log_now() end, {})
|
|
|
|
|
|
|
|
vim.api.nvim_create_user_command("StopwatchToggleBig", function() M.toggle_big() end, {})
|
|
|
|
|
|
|
|
|
|
|
|
-- optionally show initially
|
|
|
|
if state.opts.visible then ensure_win() update_win() end
|
|
|
|
if state.opts.visible then
|
|
|
|
|
|
|
|
ensure_win()
|
|
|
|
|
|
|
|
update_win()
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return M
|
|
|
|
return M
|
|
|
|
|
|
|
|
|
|
|
|
|