Initial blog setup

This commit is contained in:
2024-10-01 19:24:07 +08:00
commit 278fb99277
17 changed files with 2502 additions and 0 deletions

153
lua/lemon.lua Normal file
View File

@@ -0,0 +1,153 @@
Lemon = {
ws = {},
ws_file = '.nvim.workspace.lua',
term_buf = nil,
term_win_cmd = 'belowright 12split',
}
function LoadWorkspace()
-- Load persistent configuration from .workspace.lua
local loaded, workspace = pcall(dofile, Lemon.ws_file)
if not loaded then return nil end
return workspace
end
function WriteWorkspace()
-- A very minimal serializer for workspace configuration
local s = { l = "", ls = {}, i = "" }
local function w(v) s.l = s.l .. v end
local function nl()
s.ls[#s.ls + 1] = s.l; s.l = s.i;
end
local function wv(v)
local t = type(v)
if t == 'table' then
w('{'); local pi = s.i; s.i = s.i .. " "
for k1, v1 in pairs(v) do
nl(); w('['); wv(k1); w('] = '); wv(v1); w(',')
end
s.i = pi; nl(); w('}');
elseif t == 'number' then
w(tostring(v))
elseif t == 'string' then
w('"' .. v .. '"')
else
w(tostring(v))
end
end
-- Write the workspace file
w("return "); wv(Lemon.ws); nl()
vim.fn.writefile(s.ls, Lemon.ws_file)
end
-- Loads the workspace from the file, or return the default
---@param default table
---@return table
function InitWorkspace(default)
Lemon.ws = LoadWorkspace()
if Lemon.ws == nil then
Lemon.ws = default
end
return Lemon.ws
end
function TermShow()
local info = GetTermInfo()
if info == nil then
-- Create new terminal buffer
vim.cmd(Lemon.term_win_cmd)
vim.cmd('terminal')
Lemon.term_buf = vim.api.nvim_get_current_buf()
-- Mark buffer so we can identify it later
vim.api.nvim_buf_set_var(Lemon.term_buf, 'lemon_terminal', true)
info = GetTermInfo()
elseif info.win == nil then
-- Buffer exists but not visible, open it
vim.cmd(Lemon.term_win_cmd)
vim.api.nvim_win_set_buf(0, Lemon.term_buf)
else
-- Window is visible, switch to it
vim.api.nvim_set_current_win(info.win)
end
return info
end
-- Find or create persistent terminal buffer, open window, and run command
function TermRun(cmd)
local info = TermShow()
-- Send command to terminal
vim.fn.chansend(info.job_id, '\021' .. cmd .. '\n')
vim.fn.feedkeys("G", "n")
end
-- Get terminal buffer and job_id if valid, returns {buf, job_id, win}
-- win is nil if terminal is not currently visible
function GetTermInfo()
if Lemon.term_buf == nil or not vim.api.nvim_buf_is_valid(Lemon.term_buf) then
return nil
end
local job_id = vim.api.nvim_buf_get_var(Lemon.term_buf, 'terminal_job_id')
-- Find window showing the terminal buffer
local win = nil
for _, w in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_get_buf(w) == Lemon.term_buf then
win = w
break
end
end
return { buf = Lemon.term_buf, job_id = job_id, win = win }
end
-- Compatibility wrapper - returns window ID if terminal is visible
function SwitchToExistingTerm()
local info = GetTermInfo()
return info and info.win or nil
end
-- Runs the make command and runs the callback when it completes
function MakeAnd(run_callback)
-- Create a one-time autocmd that fires when make completes
local group = vim.api.nvim_create_augroup('MakeAnd', { clear = false })
vim.api.nvim_create_autocmd('QuickFixCmdPost', {
group = group,
pattern = 'make',
once = true,
callback = function()
local qf_list = vim.fn.getqflist()
local has_errors = false
for _, item in ipairs(qf_list) do
if item.valid == 1 then
has_errors = true
break
end
end
vim.schedule(function()
if not has_errors then
run_callback()
else
vim.api.nvim_echo({ { "Build failed", "ErrorMsg" } }, false, {})
end
end)
end
})
vim.cmd('silent make')
end
function TabCurrent()
return vim.fn.tabpagenr()
end
function TabSwitch(tab)
vim.cmd('tabnext ' .. tab)
end