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 function SaveAllCode() -- Filetypes you want to save local valid_ft = { c = true, cpp = true, h = true, hpp = true, } -- Iterate through all buffers for _, buf in ipairs(vim.api.nvim_list_bufs()) do -- Only act on listed + loaded buffers if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buflisted then local ft = vim.bo[buf].filetype -- If filetype matches, write the buffer if valid_ft[ft] and vim.bo[buf].modified then -- vim.print("Saving buffer", buf) vim.api.nvim_buf_call(buf, function() vim.cmd("write") end) end end end end -- Runs the make command and runs the callback when it completes function MakeAnd(run_callback, silent_) local silent if silent_ ~= nil then silent = silent_ else silent = false end -- Create a one-time autocmd that fires when make completes local group = vim.api.nvim_create_augroup('MakeAnd', { clear = false }) local wnd = vim.api.nvim_get_current_win() local pos = vim.api.nvim_win_get_cursor(wnd) 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 vim.api.nvim_echo({ { "Build succeeded", "Normal" } }, false, {}) run_callback() vim.api.nvim_win_set_cursor(wnd, pos) else vim.api.nvim_echo({ { "Build failed", "ErrorMsg" } }, false, {}) end end) end }) if silent then vim.cmd('silent make!') else vim.cmd('make!') end end function TabCurrent() return vim.fn.tabpagenr() end function TabSwitch(tab) vim.cmd('tabnext ' .. tab) end