From f35b13d669867209427449840ff0930a732591dc Mon Sep 17 00:00:00 2001 From: Squibid Date: Fri, 24 Nov 2023 21:38:31 -0500 Subject: more stuff too lazy to seperate --- lua/.luarc.json | 9 ++ lua/bootstrap.lua | 4 +- lua/cfgmenu.lua | 71 --------- lua/components.lua | 315 -------------------------------------- lua/conf/auto.lua | 85 ++++++++++ lua/conf/binds.lua | 174 +++++++++++++++++++++ lua/conf/init.lua | 4 + lua/conf/opts.lua | 65 ++++++++ lua/conf/plugins.lua | 141 +++++++++++++++++ lua/core/auto.lua | 30 ---- lua/core/binds.lua | 162 -------------------- lua/core/cmds.lua | 8 - lua/core/conf.lua | 81 ++++++++++ lua/core/handler.lua | 5 - lua/core/misc.lua | 30 ++++ lua/core/opts.lua | 65 -------- lua/core/plugins.lua | 134 ---------------- lua/core/statusbar/components.lua | 315 ++++++++++++++++++++++++++++++++++++++ lua/core/theme.lua | 76 +++++++++ lua/snippet/c.lua | 22 +++ 20 files changed, 1003 insertions(+), 793 deletions(-) create mode 100644 lua/.luarc.json delete mode 100644 lua/cfgmenu.lua delete mode 100644 lua/components.lua create mode 100644 lua/conf/auto.lua create mode 100644 lua/conf/binds.lua create mode 100644 lua/conf/init.lua create mode 100644 lua/conf/opts.lua create mode 100644 lua/conf/plugins.lua delete mode 100644 lua/core/auto.lua delete mode 100644 lua/core/binds.lua delete mode 100644 lua/core/cmds.lua create mode 100644 lua/core/conf.lua delete mode 100644 lua/core/handler.lua create mode 100644 lua/core/misc.lua delete mode 100644 lua/core/opts.lua delete mode 100644 lua/core/plugins.lua create mode 100644 lua/core/statusbar/components.lua create mode 100644 lua/core/theme.lua (limited to 'lua') diff --git a/lua/.luarc.json b/lua/.luarc.json new file mode 100644 index 0000000..8d322a3 --- /dev/null +++ b/lua/.luarc.json @@ -0,0 +1,9 @@ +{ + "diagnostics.globals": [ + "g", + "o", + "a", + "vim", + ], + "workspace.checkThirdParty": false +} diff --git a/lua/bootstrap.lua b/lua/bootstrap.lua index 3312b33..f522833 100644 --- a/lua/bootstrap.lua +++ b/lua/bootstrap.lua @@ -1,7 +1,5 @@ -local path = vim.fn.stdpath("data") .. "/site/pack/deps/opt/dep" - +local path = vim.fn.stdpath("data").."/site/pack/deps/opt/dep" if vim.fn.empty(vim.fn.glob(path)) > 0 then vim.fn.system({ "git", "clone", "--depth=1", "https://git.squi.bid/dep", path }) end - vim.cmd("packadd dep") diff --git a/lua/cfgmenu.lua b/lua/cfgmenu.lua deleted file mode 100644 index 7335079..0000000 --- a/lua/cfgmenu.lua +++ /dev/null @@ -1,71 +0,0 @@ --- helper functions that can come in handy ------------------------------------ -local function run(cmd) - local x = io.popen(cmd) - if not x then return 1 end - local y = x:read("*a") - x:close() - return y -end - --- custom menu for simpler neovim managment ----------------------------------- -local function genmenu() - local list = {} - local function add(name, plug) - if not plug then - table.insert(list, name) - return - end - if package.loaded[plug] then - table.insert(list, name) - end - end - - add('edit config', nil) - add('update plugins', 'dep') - add('show keybinds', 'telescope') - add('change colorscheme', 'telescope') - add('new plugins', 'telescope') - - return list -end - -local function configmenu() - local list = genmenu() - vim.ui.select(list, { vpt = 'Config Menu' }, - function(choice) - if choice == 'edit config' then - vim.cmd('e $XDG_CONFIG_HOME/nvim/init.lua') - end - if choice == 'update plugins' then - require('dep').sync() - if package.loaded['nvim-treesitter'] then - vim.cmd('TSUpdate') - end - if package.loaded['mason'] then - require('mason.api.command').MasonUpdate() - end - end - if choice == 'show keybinds' then - require('telescope.builtin').keymaps() - end - if choice == 'change colorscheme' then - vim.cmd("Colorscheme") - end - -- search though plugins (powered by nvim.sh) - if choice == 'new plugins' then - local result = run("curl -s https://nvim.sh/s") - local array = {} - for s in string.gmatch(result, "[^\r\n]+") do - table.insert(array, s) - end - local header = table.remove(array, 1) - vim.ui.select(array, { vpt = header }, function(choice) - end) - end - end) -end - -vim.keymap.set('n', 'm', configmenu, { - desc = "Neovim config manager menu", -}) -vim.api.nvim_create_user_command("ConfigMenu", configmenu, {}) diff --git a/lua/components.lua b/lua/components.lua deleted file mode 100644 index cce3127..0000000 --- a/lua/components.lua +++ /dev/null @@ -1,315 +0,0 @@ -if not pcall(require, "el") then return end - -local job = require "plenary.job" -local el_sub = require "el.subscribe" - -local M = {} - -function M.extract_hl(spec) - if not spec or vim.tbl_isempty(spec) then return end - local hl_name, hl_opts = { "El" }, {} - for attr, val in pairs(spec) do - if type(val) == "table" then - table.insert(hl_name, attr) - assert(vim.tbl_count(val) == 1) - local hl, what = next(val) - local hlID = vim.fn.hlID(hl) - if hlID > 0 then - table.insert(hl_name, hl) - local col = vim.fn.synIDattr(hlID, what) - if col and #col > 0 then - table.insert(hl_name, what) - hl_opts[attr] = col - end - end - else - -- bold, underline, etc - hl_opts[attr] = val - end - end - hl_name = table.concat(hl_name, "_") - -- if highlight exists, verify it has - -- the correct colorscheme highlights - local newID = vim.fn.hlID(hl_name) - if newID > 0 then - for what, expected in pairs(hl_opts) do - local res = vim.fn.synIDattr(newID, what) - if type(expected) == "boolean" then - -- synIDattr returns '1' for boolean - res = res and res == "1" and true - end - if res ~= expected then - -- need to regen the highlight - -- print("color mismatch", hl_name, what, "e:", expected, "c:", res) - newID = 0 - end - end - end - if newID == 0 then - vim.api.nvim_set_hl(0, hl_name, hl_opts) - end - return hl_name -end - -local function set_hl(hls, s) - if not hls or not s then return s end - hls = type(hls) == "string" and { hls } or hls - for _, hl in ipairs(hls) do - if vim.fn.hlID(hl) > 0 then - return ("%%#%s#%s%%0*"):format(hl, s) - end - end - return s -end - -local function wrap_fnc(opts, fn) - return function(window, buffer) - -- buf_autocmd doesn't send win - if not window and buffer then - window = { win_id = vim.fn.bufwinid(buffer.bufnr) } - end - if opts.hide_inactive and window and - window.win_id ~= vim.api.nvim_get_current_win() then - return "" - end - return fn(window, buffer) - end -end - -function M.mode(opts) - opts = opts or {} - return wrap_fnc(opts, function(_, _) - local fmt = opts.fmt or "%s%s" - local mode = vim.api.nvim_get_mode().mode - local mode_data = opts.modes and opts.modes[mode] - local hls = mode_data and mode_data[3] - local icon = opts.hl_icon_only and set_hl(hls, opts.icon) or opts.icon - mode = mode_data and mode_data[1]:upper() or mode - mode = (fmt):format(icon or "", mode) - return not opts.hl_icon_only and set_hl(hls, mode) or mode - end) -end - -function M.git_branch(opts) - opts = opts or {} - return el_sub.buf_autocmd("el_git_branch", "BufEnter", - wrap_fnc(opts, function(_, buffer) - -- Try fugitive first as it's most reliable - local branch = vim.g.loaded_fugitive == 1 and - vim.fn.FugitiveHead() or nil - -- buffer can be null and code will crash with: - -- E5108: Error executing lua ... 'attempt to index a nil value' - if not buffer or not (buffer.bufnr > 0) then - return - end - -- fugitive is empty or not loaded, try gitsigns - if not branch or #branch == 0 then - local ok, res = pcall(vim.api.nvim_buf_get_var, - buffer.bufnr, "gitsigns_head") - if ok then branch = res end - end - -- last resort run git command - if not branch then - local j = job:new { - command = "git", - args = { "branch", "--show-current" }, - cwd = vim.fn.fnamemodify(buffer.name, ":h"), - } - - local ok, result = pcall(function() - return vim.trim(j:sync()[1]) - end) - if ok then - branch = result - end - end - - if branch and #branch > 0 then - local fmt = opts.fmt or "%s %s" - local icon = opts.icon or "" - return set_hl(opts.hl, (fmt):format(icon, branch)) - end - end)) -end - -local function git_changes_formatter(opts) - local specs = { - insert = { - regex = "(%d+) insertions?", - icon = opts.icon_insert or "+", - hl = opts.hl_insert, - }, - change = { - regex = "(%d+) files? changed", - icon = opts.icon_change or "~", - hl = opts.hl_change, - }, - delete = { - regex = "(%d+) deletions?", - icon = opts.icon_delete or "-", - hl = opts.hl_delete, - }, - } - return function(_, _, s) - local result = {} - for k, v in pairs(specs) do - local count = nil - if type(s) == "string" then - -- 'git diff --shortstat' output - -- from 'git_changes_all' - count = tonumber(string.match(s, v.regex)) - else - -- map from 'git_changes_buf' - count = s[k] - end - if count and count > 0 then - table.insert(result, set_hl(v.hl, ("%s%d"):format(v.icon, count))) - end - end - return table.concat(result, " ") - end -end - --- requires gitsigns -function M.git_changes_buf(opts) - opts = opts or {} - local formatter = opts.formatter or git_changes_formatter(opts) - return wrap_fnc(opts, function(window, buffer) - local stats = {} - if buffer and buffer.bufnr > 0 then - local ok, res = pcall(vim.api.nvim_buf_get_var, - buffer.bufnr, "vgit_status") - if ok then stats = res end - end - if buffer and buffer.bufnr > 0 then - local ok, res = pcall(vim.api.nvim_buf_get_var, - buffer.bufnr, "gitsigns_status_dict") - if ok then stats = res end - end - local counts = { - insert = stats.added > 0 and stats.added or nil, - change = stats.changed > 0 and stats.changed or nil, - delete = stats.removed > 0 and stats.removed or nil, - } - if not vim.tbl_isempty(counts) then - local fmt = opts.fmt or "%s" - local out = formatter(window, buffer, counts) - return out and fmt:format(out) or nil - else - -- el functions that return a - -- string must not return nil - return "" - end - end) -end - -function M.git_changes_all(opts) - opts = opts or {} - local formatter = opts.formatter or git_changes_formatter(opts) - return el_sub.buf_autocmd("el_git_changes", "BufWritePost", - wrap_fnc(opts, function(window, buffer) - if not buffer or - not (buffer.bufnr > 0) or - vim.bo[buffer.bufnr].bufhidden ~= "" or - vim.bo[buffer.bufnr].buftype == "nofile" or - vim.fn.filereadable(buffer.name) ~= 1 then - return - end - - local j = job:new { - command = "git", - args = { "diff", "--shortstat" }, - -- makes no sense to run for one file as - -- 'file(s) changed' will always be 1 - -- args = { "diff", "--shortstat", buffer.name }, - cwd = vim.fn.fnamemodify(buffer.name, ":h"), - } - - local ok, git_changes = pcall(function() - return formatter(window, buffer, vim.trim(j:sync()[1])) - end) - - if ok then - local fmt = opts.fmt or "%s" - return git_changes and fmt:format(git_changes) or nil - end - end)) -end - -function M.lsp_srvname(opts) - local fmt = opts.fmt or "%s" - local icon = opts.icon or "" - local buf_clients = vim.lsp.buf_get_clients(0) - if not buf_clients or #buf_clients == 0 then - return "" - end - local names = "" - for i, c in ipairs(buf_clients) do - if i > 1 then names = names .. ", " end - names = names .. c.name - end - return icon..fmt:format(names) -end - -local function diag_formatter(opts) - return function(_, buffer, counts) - local items = {} - local icons = { - ["errors"] = { opts.icon_err or "x", opts.hl_err or "DiagnosticError"}, - ["warnings"] = { opts.icon_warn or "!", opts.hl_warn or "DiagnosticWarn"}, - ["infos"] = { opts.icon_info or "i", opts.hl_info or "DiagnosticInfo"}, - ["hints"] = { opts.icon_hint or "h", opts.hl_hint or "DiagnosticHint"}, - } - for _, k in ipairs({ "errors", "warnings", "infos", "hints" }) do - if counts[k] > 0 then - table.insert(items, - set_hl(icons[k][2], ("%s:%s"):format(icons[k][1], counts[k]))) - end - end - local fmt = opts.fmt or "%s" - if vim.tbl_isempty(items) then - return "" - else - return fmt:format(table.concat(items, " ")) - end - end -end - -local function get_buffer_counts(diagnostic, _, buffer) - local counts = { 0, 0, 0, 0 } - local diags = diagnostic.get(buffer.bufnr) - if diags and not vim.tbl_isempty(diags) then - for _, d in ipairs(diags) do - if tonumber(d.severity) then - counts[d.severity] = counts[d.severity] + 1 - end - end - end - return { - errors = counts[1], - warnings = counts[2], - infos = counts[3], - hints = counts[4], - } -end - -function M.diagnostics(opts) - opts = opts or {} - local formatter = opts.formatter or diag_formatter(opts) - return el_sub.buf_autocmd("el_buf_diagnostic", "LspAttach,DiagnosticChanged", - wrap_fnc(opts, function(window, buffer) - return formatter(window, buffer, get_buffer_counts(vim.diagnostic, window, buffer)) - end)) -end - -function M.line(opts) - opts = opts or {} - local fmt = opts.fmt or "%s" - return wrap_fnc(opts, function(_, _) - local al = vim.api.nvim_buf_line_count(0) - local cl = vim.api.nvim_win_get_cursor(0)[1] - return (fmt):format(cl.."/"..al.." "..math.floor((cl / al) * 100).."%%") - end) -end - -return M diff --git a/lua/conf/auto.lua b/lua/conf/auto.lua new file mode 100644 index 0000000..8c990d6 --- /dev/null +++ b/lua/conf/auto.lua @@ -0,0 +1,85 @@ +local function auto(event, opts) + a.nvim_create_autocmd(event, opts) +end + +local function augroup(name, opts) + opts = opts or {} + opts['clear'] = true + a.nvim_create_augroup(name, opts) +end + +local winchange = augroup('winchange') +local bufcheck = augroup('bufcheck') +local toggles = augroup('toggles') + +auto({ "FocusGained", "TermClose", "TermLeave" }, { + group = bufcheck, + desc = 'Update contents of file.', + command = "checktime", +}) + +auto("VimResized", { + group = winchange, + desc = 'Resize splits when window is resized.', + callback = function() + local current_tab = vim.fn.tabpagenr() + vim.cmd("tabdo wincmd =") + vim.cmd("tabnext " .. current_tab) + end, +}) + +auto('TextYankPost', { + group = bufcheck, + pattern = '*', + desc = 'Highlight on yank.', + callback = function() + vim.highlight.on_yank{ timeout = 250 } + end +}) + +auto('BufRead', { + pattern = '*', + group = bufcheck, + desc = 'Return to the last place the buffer was closed in.', + callback = function() vim.cmd([[call setpos(".", getpos("'\""))]]) end +}) + +auto('FileType', { + pattern = { 'gitcommit', 'markdown' }, + desc = 'Spell checking and wrapping in commit buffers and markdown files.', + callback = function() + vim.opt_local.wrap = true + vim.opt_local.spell = true + end +}) + +auto('BufWritePre', { + pattern = '*', + group = bufcheck, + desc = 'Basically mkdir -p.', + callback = function(ctx) + if ctx.match:match("^%w%w+://") then return end + local dir = vim.fn.fnamemodify(ctx.file, ':p:h') + vim.fn.mkdir(dir, 'p') + end +}) + +auto('WinLeave', { + pattern = '!Alpha', + desc = 'Unset cursorline', + group = toggles, + callback = function() vim.opt.cursorline = false end +}) + +auto('WinEnter', { + pattern = '!Alpha', + desc = 'Set cursorline', + group = toggles, + callback = function() vim.opt.cursorline = true end +}) + +auto('ColorScheme', { + desc = 'Update statusline on colorscheme change', + group = winchange, + callback = function() require('el').reset_windows() end +}) diff --git a/lua/conf/binds.lua b/lua/conf/binds.lua new file mode 100644 index 0000000..5fc8055 --- /dev/null +++ b/lua/conf/binds.lua @@ -0,0 +1,174 @@ +local conf = require('core.conf') + +local function map(mode, bind, cmd, opts) + opts = opts or {} + opts['noremap'] = true + opts['silent'] = true + + if type(bind) == 'table' then + for i in pairs(bind) do + vim.keymap.set(mode, bind[i], cmd, opts) + end + elseif type(bind) == 'string' then + vim.keymap.set(mode, bind, cmd, opts) + end +end + +-- vim binds ------------------------------------------------------------------ +g.mapleader = ' ' -- set leader key + +map('x', 'p', [["_dP]], { desc = 'Greatest remap of all time.' }) +map('n', '', ':nohlsearch:echo', { desc = 'Clear search.' }) +map('t', '', '', { desc = 'make work in terminals.' }) +-- move selected text up/down +map('v', '', ":m '<-2gv=gv", { desc = 'Move selected text up.' }) +map('v', '', ":m '>+1gv=gv", { desc = 'Move selected text down.' }) + +-- the cursor STAYS IN THE MIDDLE +map('n', '', 'mzJ`zdelm z') -- when combining lines +map('n', 'n', 'nzzzv') -- when searching +map('n', 'N', 'Nzzzv') +map('n', '', 'zz') -- half page jumping +map('n', '', 'zz') + +map('n', 'x', '!chmod +x "%"') -- execute order 111 + +-- add some keybinds to the file view (netrw) +a.nvim_create_autocmd('FileType', { + pattern = 'netrw', + callback = function() + local bind = function(lhs, rhs) + vim.keymap.set('n', lhs, rhs, { remap = true, buffer = true }) + end + bind('h', '-^') -- Go up a directory + bind('l', '') -- Go down a directory / open a file + bind('.', 'gh') -- Toggle hidden files + bind('P', 'z') -- Close preview window + bind('', 'q') -- Close netrw + end +}) + +-- tabs +map('n', '[]', 'tabnew') +map('n', '][', 'tabc') +map('n', '[[', 'tabp') +map('n', ']]', 'tabN') + +-- config binds --------------------------------------------------------------- +map('n', 'm', conf.configmenu, { desc = 'Neovim config manager menu', }) + +-- plugin binds --------------------------------------------------------------- + +-- pretty lsp view +map('n', 'gd', 'Glance definitions') +map('n', 'gr', 'Glance references') +map('n', 'gy', 'Glance type_definitions') +map('n', 'gi', 'Glance implementations') + +if pcall(require, "treesj") then + local treesj = require('treesj') -- treesj + map('n', 'j', treesj.toggle) +end + +if pcall(require, "telescope") then + local telebuilt = require('telescope.builtin') -- telescope + -- local telexten = require('telescope').extensions + map('n', 'sf', telebuilt.find_files, { desc = 'Find files.' }) + map('n', 'so', telebuilt.oldfiles, { desc = 'Find old files.' }) + map('n', 'sg', telebuilt.git_files, { desc = 'Find git files.' }) + -- search urls in buffer + map('n', 'su', 'UrlView', { desc = 'Find urls in buffer.' }) + -- search lsp symbols + map('n', 'ss', telebuilt.lsp_document_symbols, + { desc = 'Find LSP Symbols.' }) + -- search for keybinds + map('n', 'sk', telebuilt.keymaps, + { desc = 'Find nvim Keymaps.' }) + -- search for highlights + map('n', 'sh', telebuilt.highlights, + { desc = 'Find nvim Highlights.' }) + -- search for autocommands + map('n', 'sa', telebuilt.autocommands, + { desc = 'Find nvim Autocommands.' }) + -- search for vim options + map('n', 'sv', telebuilt.vim_options, { desc = 'Find vim options.' }) + -- search for string in project + map('n', 'sp', function() + vim.ui.input({ prompt = 'Find string in project' }, function(input) + if not input or input == '' then + vim.notify('No query!', vim.log.levels.WARN, { title = misc.appid }) + return nil + end + telebuilt.grep_string({ search = input }) + end) + end, { desc = 'Find string in project.' }) + -- Code Actions (requires telescope) + if pcall(require, "actions-preview") then + map({ "n", "v" }, "ca", require("actions-preview").code_actions, { + desc = 'preview code actions' + }) + end +end + +map('n', 'u', 'UndotreeToggle', { desc = 'Open undo tree.' }) +map('n', 'f', 'SFMToggle', { desc = 'Open file tree view.' }) +map('n', 'b', 'JABSOpen', { desc = 'Switch between buffers.' }) + +if pcall(require, "smart-splits") then + local smartsplits = require('smart-splits') -- resizing buffers (toggleable) + map('n', 'r', smartsplits.start_resize_mode) +end + +-- toggle term (don't use leader key in these binds) +map({'n', 't'}, '', 'ToggleTerm direction=float') +map({'n', 't'}, '', 'lua _glow()') + +-- true zen +if pcall(require, "true-zen") then + map('n', 'zf', require("true-zen.focus").toggle, { + desc = 'fullscreen', + }) + map('n', 'zm', require("true-zen.minimalist").toggle, { + desc = 'minimal', + }) + map('n', 'za', require("true-zen.ataraxis").toggle, { + desc = 'zen', + }) +end + +-- git +map('n', 'gp', 'Gitsigns preview_hunk_inline') +map('n', 'gs', 'Gitsigns stage_hunk') +map('n', 'gb', 'Gitsigns blame_line') +map('n', 'g]', 'Gitsigns next_hunk') +map('n', 'g[', 'Gitsigns prev_hunk') + +-- neogen +if pcall(require, "neogen") then + map('n', 'df', require("neogen").generate, { + desc = 'Generate anotations', + }) +end + +-- venn +function _G.Toggle_venn() + local mapb = vim.api.nvim_buf_set_keymap + local venn_enabled = vim.inspect(vim.b.venn_enabled) + if venn_enabled == "nil" then + vim.b.venn_enabled = true + vim.cmd([[setlocal ve=all]]) + -- draw a line on HJKL keystokes + mapb(0, "n", "J", "j:VBox", { noremap = true }) + mapb(0, "n", "K", "k:VBox", { noremap = true }) + mapb(0, "n", "L", "l:VBox", { noremap = true }) + mapb(0, "n", "H", "h:VBox", { noremap = true }) + -- draw a box by pressing "f" with visual selection + mapb(0, "v", "f", ":VBox", { noremap = true }) + else + vim.cmd[[setlocal ve=]] + vim.cmd[[mapclear ]] + vim.b.venn_enabled = nil + end +end +-- toggle keymappings for venn using v +map('n', 'v', ":lua Toggle_venn()") diff --git a/lua/conf/init.lua b/lua/conf/init.lua new file mode 100644 index 0000000..2029141 --- /dev/null +++ b/lua/conf/init.lua @@ -0,0 +1,4 @@ +misc.include('conf.plugins') -- load plugins first to allow colorscheme to be set in opts +misc.include('conf.opts') +misc.include('conf.binds') +misc.include('conf.auto') diff --git a/lua/conf/opts.lua b/lua/conf/opts.lua new file mode 100644 index 0000000..3997b5f --- /dev/null +++ b/lua/conf/opts.lua @@ -0,0 +1,65 @@ +-- better ui ------------------------------------------------------------------ +if pcall(require, "notify") then vim.notify = require("notify") end +o.colorcolumn = { 80 } + +-- buffer +o.scrolloff = 5 +o.wrap = true -- wraping lines +o.linebreak = true -- fix where line is wraped +o.cursorline = true + +-- statusbar +o.laststatus = 3 +o.cmdheight = 1 +o.showmode = false -- stop vim from showing mode (we have a statusbar) + +-- tabline +o.showtabline = 2 + +-- status column +o.signcolumn = 'yes:1' -- show gutter + +-- indents + tabs +local tabwidth = 2 +o.expandtab = true +o.smarttab = true +o.cindent = true +o.autoindent = true +o.tabstop = tabwidth +o.shiftwidth = tabwidth +o.softtabstop = tabwidth + +-- colorscheme +o.termguicolors = true +misc.colorscheme('mellow') + +-- better editing ------------------------------------------------------------- +o.clipboard = 'unnamedplus' -- system clipboard +o.splitkeep = "screen" -- keep same text on screen when spliting + +-- file saving ---------------------------------------------------------------- +o.swapfile = false +o.undofile = true +o.confirm = true + +-- searching ------------------------------------------------------------------ +o.ignorecase = true +o.smartcase = true +o.wrapscan = true +o.showmatch = true +o.incsearch = true + +-- wild menus ----------------------------------------------------------------- +o.wildoptions = 'pum' +o.pumblend = 3 +o.pumheight = 20 + +o.wildignorecase = true +o.wildignore = '*.o' + +-- netrw ---------------------------------------------------------------------- +g.netrw_banner = 1 +g.netrw_localcopydircmd = 'cp -r' +g.netrw_winsize = 30 +g.netrw_liststyle = 1 +g.netrw_preview = 1 diff --git a/lua/conf/plugins.lua b/lua/conf/plugins.lua new file mode 100644 index 0000000..23be6c6 --- /dev/null +++ b/lua/conf/plugins.lua @@ -0,0 +1,141 @@ +require('dep') { + -- dep manages dep ---------------------------------------------------------- + { 'squibid/dep', + url = 'https://git.squi.bid/dep', + pin = true, + -- branch = 'dev' + }, + + -- colorschemes ------------------------------------------------------------- + { 'kvrohit/mellow.nvim', + requires = 'nvim-treesitter/nvim-treesitter' + }, + + -- ui ----------------------------------------------------------------------- + { 'lukas-reineke/indent-blankline.nvim' }, -- indentation indicators + { 'folke/which-key.nvim' }, -- key map help + { 'rcarriga/nvim-notify' }, -- notifications + { 'tjdevries/express_line.nvim', -- status bar + requires = 'nvim-lua/plenary.nvim' + }, + { 'goolord/alpha-nvim' }, -- start page + { 'dinhhuy258/sfm.nvim', -- tree view + deps = 'dinhhuy258/sfm-git.nvim' + }, + { 'matbme/JABS.nvim' }, -- buffer switcher + { 'stevearc/dressing.nvim', -- nice ui selectors + requires = 'nvim-telescope/telescope.nvim' + }, + { 'lukas-reineke/headlines.nvim', + requires = 'nvim-neorg/neorg' + }, + + -- functional plugins ------------------------------------------------------- + { 'lewis6991/gitsigns.nvim' }, -- very helpful git things + { 'squibid/git-yodel', -- git cache diff preview when in commit buffer + url = 'https://git.squi.bid/git-yodel', + }, + { 'chentoast/marks.nvim' }, -- marks in gutter + { 'vidocqh/auto-indent.nvim' }, -- better tabbing into indents + { 'mbbill/undotree' }, -- careful this one is written in vimscript + { 'dhruvasagar/vim-table-mode' }, -- same with this one + { 'windwp/nvim-autopairs' }, + { 'numToStr/Comment.nvim' }, + { 'ahmedkhalf/project.nvim' }, -- cd into root of project + { 'akinsho/toggleterm.nvim' }, -- TODO: switch to tmux based popup terminal + { 'mrjones2014/smart-splits.nvim'}, -- buffer resizing + + -- note taking -------------------------------------------------------------- + { 'nvim-neorg/neorg', + config = function() + if package.loaded['nvim-treesitter'] then + vim.cmd(':Neorg sync-parsers') + end + end, + requires = { + 'nvim-lua/plenary.nvim', + 'nvim-treesitter/nvim-treesitter' + }, + deps = 'nvim-neorg/neorg-telescope' + }, + + { 'jbyuki/venn.nvim' }, + + -- fzf ---------------------------------------------------------------------- + { 'nvim-telescope/telescope.nvim', + requires = 'nvim-lua/plenary.nvim', + deps = { + 'nvim-telescope/telescope-file-browser.nvim', + 'nvim-telescope/telescope-symbols.nvim', + 'axieax/urlview.nvim' + } + }, + { 'nvim-telescope/telescope-fzf-native.nvim', + config = function() + vim.cmd('make') + end, + requires = 'nvim-telescope/telescope.nvim' + }, + + -- treesitter + colorizing -------------------------------------------------- + { 'nvim-treesitter/nvim-treesitter', + deps = { + 'm-demare/hlargs.nvim', + 'Wansmer/treesj', + 'nvim-treesitter/nvim-treesitter-context' + } + }, + { 'NvChad/nvim-colorizer.lua' }, + { 'folke/todo-comments.nvim', + requires = 'nvim-lua/plenary.nvim' + }, + + -- cmp ---------------------------------------------------------------------- + { 'hrsh7th/nvim-cmp', + deps = { + 'lukas-reineke/cmp-under-comparator', -- better results + 'hrsh7th/cmp-buffer', -- buffers + 'FelipeLema/cmp-async-path', -- path + 'hrsh7th/cmp-calc', -- calculator + 'hrsh7th/cmp-nvim-lsp', -- lsp + 'uga-rosa/cmp-dictionary', -- dictionary + 'hrsh7th/cmp-nvim-lua', -- nvim lua api + { 'doxnit/cmp-luasnip-choice', -- luasnip + requires = 'L3MON4D3/LuaSnip' + } + }, + }, + + -- snippets ----------------------------------------------------------------- + { 'L3MON4D3/LuaSnip', + deps = 'rafamadriz/friendly-snippets' + }, + + -- lsp ---------------------------------------------------------------------- + { 'neovim/nvim-lspconfig' }, -- setup lsp + { 'j-hui/fidget.nvim', -- shows lsp progress + branch = 'legacy' + }, + + { 'ray-x/lsp_signature.nvim' }, -- see information about the current function + { 'dnlhc/glance.nvim' }, -- diagnostic info at a glance + { 'aznhe21/actions-preview.nvim', -- codeactions + requires = 'nvim-telescope/telescope.nvim' + }, + + { 'danymat/neogen', -- generate lsp annotations + requires = 'nvim-treesitter/nvim-treesitter' + }, + + { 'whynothugo/lsp_lines.nvim', + url = 'https://git.sr.ht/~whynothugo/lsp_lines.nvim' + }, + + -- mason -------------------------------------------------------------------- + { 'williamboman/mason.nvim', + deps = { + 'WhoIsSethDaniel/mason-tool-installer.nvim', + 'williamboman/mason-lspconfig.nvim' + } + } +} diff --git a/lua/core/auto.lua b/lua/core/auto.lua deleted file mode 100644 index 170f2d7..0000000 --- a/lua/core/auto.lua +++ /dev/null @@ -1,30 +0,0 @@ -local function auto(event, opts) - a.nvim_create_autocmd(event, opts) -end - -a.nvim_create_augroup('bufcheck', { clear = true }) - -auto('TextYankPost', { -- highlight yanks - group = 'bufcheck', - pattern = '*', - desc = 'Highlight on yank.', - callback = function() - vim.highlight.on_yank{ timeout = 250 } - end -}) - -auto('BufRead', { -- return to last place - pattern = '*', - command = [[call setpos(".", getpos("'\""))]], - desc = 'Return to the last place the buffer was closed in.', -}) - -auto('BufWritePre', { -- make dirs when they don't exist - pattern = '*', - group = vim.api.nvim_create_augroup('auto_create_dir', { clear = true }), - desc = 'Basically mkdir -p.', - callback = function(ctx) - local dir = vim.fn.fnamemodify(ctx.file, ':p:h') - vim.fn.mkdir(dir, 'p') - end -}) diff --git a/lua/core/binds.lua b/lua/core/binds.lua deleted file mode 100644 index b1e98be..0000000 --- a/lua/core/binds.lua +++ /dev/null @@ -1,162 +0,0 @@ -local function map(mode, bind, cmd, opts) - opts = opts or {} - opts['noremap'] = true - opts['silent'] = true - - if type(bind) == 'table' then - for i in pairs(bind) do - vim.keymap.set(mode, bind[i], cmd, opts) - end - elseif type(bind) == 'string' then - vim.keymap.set(mode, bind, cmd, opts) - end -end - --- vim binds ------------------------------------------------------------------ -g.mapleader = ' ' -- set leader key - -map('x', 'p', [["_dP]], { desc = 'Greatest remap of all time.' }) -map('n', '', ':nohlsearch:echo', { desc = 'Clear search.' }) -map('t', '', '', { desc = 'make work in terminals.' }) --- move selected text up/down -map('v', '', ":m '<-2gv=gv", { desc = 'Move selected text up.' }) -map('v', '', ":m '>+1gv=gv", { desc = 'Move selected text down.' }) - --- the cursor STAYS IN THE MIDDLE -map('n', '', 'mzJ`zdelm z') -- when combining lines -map('n', 'n', 'nzzzv') -- when searching -map('n', 'N', 'Nzzzv') -map('n', '', 'zz') -- half page jumping -map('n', '', 'zz') - -map('n', 'x', '!chmod +x "%"') -- execute order 111 - --- add some keybinds to the file view (netrw) -a.nvim_create_autocmd('FileType', { - pattern = 'netrw', - callback = function() - local bind = function(lhs, rhs) - vim.keymap.set('n', lhs, rhs, { remap = true, buffer = true }) - end - bind('h', '-^') -- Go up a directory - bind('l', '') -- Go down a directory / open a file - bind('.', 'gh') -- Toggle hidden files - bind('P', 'z') -- Close preview window - bind('', 'q') -- Close netrw - end -}) - --- tabs -map('n', '[]', 'tabnew') -map('n', '][', 'tabc') -map('n', '[[', 'tabp') -map('n', ']]', 'tabN') - --- plugin binds --------------------------------------------------------------- - --- pretty lsp view -map('n', 'gd', 'Glance definitions') -map('n', 'gr', 'Glance references') -map('n', 'gy', 'Glance type_definitions') -map('n', 'gi', 'Glance implementations') - -if pcall(require, "treesj") then - local treesj = require('treesj') -- treesj - map('n', 'j', treesj.toggle) -end - -if pcall(require, "telescope") then - local telebuilt = require('telescope.builtin') -- telescope - -- local telexten = require('telescope').extensions - map('n', 'sf', telebuilt.find_files, { desc = 'Find files.' }) - map('n', 'so', telebuilt.oldfiles, { desc = 'Find old files.' }) - map('n', 'sg', telebuilt.git_files, { desc = 'Find git files.' }) - -- search urls in buffer - map('n', 'su', 'UrlView', { desc = 'Find urls in buffer.' }) - -- search lsp symbols - map('n', 'ss', telebuilt.lsp_document_symbols, - { desc = 'Find LSP Symbols.' }) - -- search for keybinds - map('n', 'sk', telebuilt.keymaps, - { desc = 'Find nvim Highlights.' }) - -- search for highlights - map('n', 'sh', telebuilt.highlights, - { desc = 'Find nvim Highlights.' }) - -- search for autocommands - map('n', 'sa', telebuilt.autocommands, - { desc = 'Find nvim Autocommands.' }) - -- search for vim options - map('n', 'sv', telebuilt.vim_options, { desc = 'Find vim options.' }) - -- search for string in project - map('n', 'sp', function() - telebuilt.grep_string({ search = vim.fn.input('Find string in project > ')}) - end, { desc = 'Find string in project.' }) - -- Code Actions (requires telescope) - if pcall(require, "actions-preview") then - map({ "n", "v" }, "ca", require("actions-preview").code_actions, { - desc = 'preview code actions' - }) - end -end - -map('n', 'u', 'UndotreeToggle', { desc = 'Open undo tree.' }) -map('n', 'f', 'SFMToggle', { desc = 'Open file tree view.' }) -map('n', 'b', 'JABSOpen', { desc = 'Switch between buffers.' }) - -if pcall(require, "smart-splits") then - local smartsplits = require('smart-splits') -- resizing buffers (toggleable) - map('n', 'r', smartsplits.start_resize_mode) -end - --- toggle term (don't use leader key in these binds) -map({'n', 't'}, '', 'ToggleTerm direction=float') -map({'n', 't'}, '', 'lua _glow()') - --- true zen -if pcall(require, "true-zen") then - map('n', 'zf', require("true-zen.focus").toggle, { - desc = 'fullscreen', - }) - map('n', 'zm', require("true-zen.minimalist").toggle, { - desc = 'minimal', - }) - map('n', 'za', require("true-zen.ataraxis").toggle, { - desc = 'zen', - }) -end - --- git -map('n', 'gp', 'Gitsigns preview_hunk_inline') -map('n', 'gs', 'Gitsigns stage_hunk') -map('n', 'gb', 'Gitsigns blame_line') -map('n', 'g]', 'Gitsigns next_hunk') -map('n', 'g[', 'Gitsigns prev_hunk') - --- neogen -if pcall(require, "neogen") then - map('n', 'df', require("neogen").generate, { - desc = 'Generate anotations', - }) -end - --- venn -function _G.Toggle_venn() - local venn_enabled = vim.inspect(vim.b.venn_enabled) - if venn_enabled == "nil" then - vim.b.venn_enabled = true - vim.cmd([[setlocal ve=all]]) - -- draw a line on HJKL keystokes - vim.api.nvim_buf_set_keymap(0, "n", "J", "j:VBox", {noremap = true}) - vim.api.nvim_buf_set_keymap(0, "n", "K", "k:VBox", {noremap = true}) - vim.api.nvim_buf_set_keymap(0, "n", "L", "l:VBox", {noremap = true}) - vim.api.nvim_buf_set_keymap(0, "n", "H", "h:VBox", {noremap = true}) - -- draw a box by pressing "f" with visual selection - vim.api.nvim_buf_set_keymap(0, "v", "f", ":VBox", {noremap = true}) - else - vim.cmd[[setlocal ve=]] - vim.cmd[[mapclear ]] - vim.b.venn_enabled = nil - end -end --- toggle keymappings for venn using v -vim.api.nvim_set_keymap('n', 'v', ":lua Toggle_venn()", { noremap = true}) diff --git a/lua/core/cmds.lua b/lua/core/cmds.lua deleted file mode 100644 index 3cc78e1..0000000 --- a/lua/core/cmds.lua +++ /dev/null @@ -1,8 +0,0 @@ -local function cmd(name, exec, opts) - opts = opts or {} - vim.api.nvim_create_user_command(name, exec, opts) -end - -cmd('Colorscheme', function() - require('telescope.builtin').colorscheme() -end) diff --git a/lua/core/conf.lua b/lua/core/conf.lua new file mode 100644 index 0000000..72dd9bf --- /dev/null +++ b/lua/core/conf.lua @@ -0,0 +1,81 @@ +local pickers = require("telescope.pickers") +local finders = require("telescope.finders") +local previewers = require("telescope.previewers") +local conf = require("telescope.config").values +local actions = require("telescope.actions") +local action_state = require("telescope.actions.state") + +local M = {} + +local function genmenu() + local list = {} + local function add(name, plug) + if not plug then + table.insert(list, name) + elseif package.loaded[plug] then + table.insert(list, name) + end + end + + add('Edit Config', nil) + add('Update Plugins', 'dep') + add('Keybinds', 'telescope') + add('Colorscheme', 'telescope') + + return list +end + +function M.configmenu() + pickers.new({ + prompt_title = "Nvim Config Menu", + finder = finders.new_table { results = genmenu() }, + sorter = conf.generic_sorter(), + previewer = previewers.new_buffer_previewer { + define_preview = function(self, entry) + local lines = { + 'a' + } + if entry.value == "Edit Config" then + lines = misc.readf(os.getenv('XDG_CONFIG_HOME')..'/nvim/init.lua') + local ft = vim.filetype.match({ + filename = os.getenv('XDG_CONFIG_HOME')..'/nvim/init.lua' }) + require("telescope.previewers.utils").highlighter(self.state.bufnr, ft) + elseif entry.value == "Colorscheme" then + lines = vim.fn.getcompletion('', 'color') + for k, v in pairs(lines) do + if v.find(v, '.ext') then + table.remove(lines, k) + break + end + end + end + vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines) + end + }, + + attach_mappings = function(bufnr, map) + actions.select_default:replace(function() + actions.close(bufnr) + local selection = action_state.get_selected_entry() + if selection[1] == 'Edit Config' then + vim.cmd('e $XDG_CONFIG_HOME/nvim/init.lua') + elseif selection[1] == 'Update Plugins' then + require('dep').sync() + if package.loaded['nvim-treesitter'] then + vim.cmd('TSUpdate') + end + if package.loaded['mason'] then + require('mason.api.command').MasonUpdate() + end + elseif selection[1] == 'Keybinds' then + require('telescope.builtin').keymaps() + elseif selection[1] == 'Colorscheme' then + require('core.theme').switcher() + end + end) + return true + end, + }):find() +end + +return M diff --git a/lua/core/handler.lua b/lua/core/handler.lua deleted file mode 100644 index 0038146..0000000 --- a/lua/core/handler.lua +++ /dev/null @@ -1,5 +0,0 @@ -require('core.plugins') -- load plugins first to allow colorscheme to be set in opts -require('core.opts') -require('core.binds') -require('core.auto') -require('core.cmds') diff --git a/lua/core/misc.lua b/lua/core/misc.lua new file mode 100644 index 0000000..41cbf93 --- /dev/null +++ b/lua/core/misc.lua @@ -0,0 +1,30 @@ +local M = {} + +M.appid = "Nvim Config" + +function M.colorscheme(name) + vim.cmd('colorscheme '..name) + for k, v in pairs(vim.fn.getcompletion('', 'color')) do + if v == name..'.ext' then + vim.cmd('colorscheme '..name..'.ext') + end + end +end + +function M.include(fn) + if not pcall(require, fn) then + vim.notify('Could not find '..fn, vim.log.levels.WARN, { title = M.appid }) + end +end + +function M.readf(fn) + local f = io.open(fn, "r") + if not f then return nil end + local tab = {} + for l in f:lines() do + table.insert(tab, l) + end + return tab +end + +return M diff --git a/lua/core/opts.lua b/lua/core/opts.lua deleted file mode 100644 index 82d88bd..0000000 --- a/lua/core/opts.lua +++ /dev/null @@ -1,65 +0,0 @@ --- better ui ------------------------------------------------------------------ -if pcall(require, "notify") then vim.notify = require("notify") end -o.colorcolumn = { 80 } - --- buffer -o.scrolloff = 5 -o.wrap = true -- wraping lines -o.linebreak = true -- fix where line is wraped -o.cursorline = true - --- statusbar -o.laststatus = 3 -o.cmdheight = 1 -o.showmode = false -- stop vim from showing mode (we have a statusbar) - --- tabline -o.showtabline = 2 - --- status column -o.signcolumn = 'yes:1' -- show gutter - --- indents + tabs -local tabwidth = 2 -o.expandtab = true -o.smarttab = true -o.cindent = true -o.autoindent = true -o.tabstop = tabwidth -o.shiftwidth = tabwidth -o.softtabstop = tabwidth - --- colorscheme -o.termguicolors = true -vim.cmd('colorscheme mellow') -- mellow -vim.cmd('colorscheme mellow+') -- some changes - --- better editing ------------------------------------------------------------- -o.clipboard = 'unnamedplus' -- system clipboard - --- file saving ---------------------------------------------------------------- -o.swapfile = false -o.undofile = true -o.confirm = true - --- searching ------------------------------------------------------------------ -o.ignorecase = true -o.smartcase = true -o.wrapscan = true -o.showmatch = true -o.incsearch = true - --- wild menus ----------------------------------------------------------------- -o.wildoptions = 'pum' -o.pumblend = 3 -o.pumheight = 20 - -o.wildignorecase = true -o.wildignore = '*.o' - --- netrw ---------------------------------------------------------------------- -g.netrw_banner = 1 -g.netrw_localcopydircmd = 'cp -r' -g.netrw_winsize = 30 -g.netrw_liststyle = 1 -g.netrw_preview = 1 diff --git a/lua/core/plugins.lua b/lua/core/plugins.lua deleted file mode 100644 index db20075..0000000 --- a/lua/core/plugins.lua +++ /dev/null @@ -1,134 +0,0 @@ -require 'dep' { - sync = "always", - -- dep manages dep ---------------------------------------------------------- - { 'squibid/dep', - url = 'https://git.squi.bid/dep', - -- branch = 'dev' - }, - - { 'squibid/git-yodel', - url = 'https://git.squi.bid/git-yodel' - }, - - -- colorschemes ------------------------------------------------------------- - { 'kvrohit/mellow.nvim', - requires = 'nvim-treesitter/nvim-treesitter' - }, - - -- ui ----------------------------------------------------------------------- - { 'lukas-reineke/indent-blankline.nvim' }, -- indentation indicators - { 'folke/which-key.nvim' }, -- key map help - { 'rcarriga/nvim-notify' }, -- notifications - { 'tjdevries/express_line.nvim', -- status bar - requires = 'nvim-lua/plenary.nvim', - }, - { 'goolord/alpha-nvim' }, -- start page - { 'dinhhuy258/sfm.nvim', -- tree view - deps = 'dinhhuy258/sfm-git.nvim', - }, - { 'matbme/JABS.nvim' }, -- buffer switcher - { 'tomiis4/Hypersonic.nvim' }, -- regex helper/displayer - - -- functional plugins ------------------------------------------------------- - { 'lewis6991/gitsigns.nvim' }, -- very helpful git things - { 'squibid/git-yodel', -- git cache diff preview when in commit buffer - url = 'https://git.squi.bid/git-yodel' - }, - { 'chentoast/marks.nvim' }, -- marks in gutter - { 'vidocqh/auto-indent.nvim' }, -- better tabbing into indents - { 'mbbill/undotree' }, -- careful this one is written in vimscript - { 'dhruvasagar/vim-table-mode' }, -- same with this one - { 'windwp/nvim-autopairs' }, - { 'numToStr/Comment.nvim' }, - { 'ahmedkhalf/project.nvim' }, -- cd into root of project - { 'akinsho/toggleterm.nvim' }, -- TODO: switch to tmux based popup terminal - { 'mrjones2014/smart-splits.nvim'}, -- buffer resizing - - -- note taking -------------------------------------------------------------- - { 'nvim-neorg/neorg', - config = function() - if package.loaded['nvim-treesitter'] then - vim.cmd(':Neorg sync-parsers') - end - end, - requires = { - 'nvim-lua/plenary.nvim', - 'nvim-treesitter/nvim-treesitter' - }, - deps = 'nvim-neorg/neorg-telescope' - }, - - { 'jbyuki/venn.nvim' }, - - -- fzf ---------------------------------------------------------------------- - { 'nvim-telescope/telescope.nvim', - requires = 'nvim-lua/plenary.nvim', - deps = { - 'nvim-telescope/telescope-file-browser.nvim', - 'nvim-telescope/telescope-ui-select.nvim', - 'nvim-telescope/telescope-symbols.nvim', - 'axieax/urlview.nvim', - } - }, - - -- treesitter + colorizing -------------------------------------------------- - { 'nvim-treesitter/nvim-treesitter', - deps = { - 'm-demare/hlargs.nvim', - 'Wansmer/treesj', - 'nvim-treesitter/nvim-treesitter-context', - } - }, - { 'NvChad/nvim-colorizer.lua' }, - { 'folke/todo-comments.nvim', - requires = 'nvim-lua/plenary.nvim', - }, - - -- cmp ---------------------------------------------------------------------- - { 'hrsh7th/nvim-cmp', - deps = { - 'lukas-reineke/cmp-under-comparator', -- better results - 'hrsh7th/cmp-buffer', -- buffers - 'FelipeLema/cmp-async-path', -- path - 'hrsh7th/cmp-calc', -- calculator - 'saadparwaiz1/cmp_luasnip', -- snippets - 'hrsh7th/cmp-nvim-lsp', -- lsp - 'uga-rosa/cmp-dictionary', -- dictionary - 'hrsh7th/cmp-nvim-lua', -- nvim lua api - }, - }, - - -- snippets ----------------------------------------------------------------- - { 'L3MON4D3/LuaSnip', - deps = 'rafamadriz/friendly-snippets', - }, - { 'doxnit/cmp-luasnip-choice' }, - - -- lsp ---------------------------------------------------------------------- - { 'neovim/nvim-lspconfig' }, -- setup lsp - { 'j-hui/fidget.nvim', -- shows lsp progress - branch = 'legacy', - }, - - { 'ray-x/lsp_signature.nvim' }, -- see information about the current function - { 'dnlhc/glance.nvim' }, -- diagnostic info at a glance - { 'aznhe21/actions-preview.nvim', -- codeactions - requires = 'nvim-telescope/telescope.nvim' - }, - - { 'danymat/neogen', -- generate lsp annotations - requires = 'nvim-treesitter/nvim-treesitter' - }, - - { 'whynothugo/lsp_lines.nvim', - url = 'https://git.sr.ht/~whynothugo/lsp_lines.nvim', - }, - - -- mason -------------------------------------------------------------------- - { 'williamboman/mason.nvim', - deps = { - 'WhoIsSethDaniel/mason-tool-installer.nvim', - 'williamboman/mason-lspconfig.nvim', - } - } -} diff --git a/lua/core/statusbar/components.lua b/lua/core/statusbar/components.lua new file mode 100644 index 0000000..cce3127 --- /dev/null +++ b/lua/core/statusbar/components.lua @@ -0,0 +1,315 @@ +if not pcall(require, "el") then return end + +local job = require "plenary.job" +local el_sub = require "el.subscribe" + +local M = {} + +function M.extract_hl(spec) + if not spec or vim.tbl_isempty(spec) then return end + local hl_name, hl_opts = { "El" }, {} + for attr, val in pairs(spec) do + if type(val) == "table" then + table.insert(hl_name, attr) + assert(vim.tbl_count(val) == 1) + local hl, what = next(val) + local hlID = vim.fn.hlID(hl) + if hlID > 0 then + table.insert(hl_name, hl) + local col = vim.fn.synIDattr(hlID, what) + if col and #col > 0 then + table.insert(hl_name, what) + hl_opts[attr] = col + end + end + else + -- bold, underline, etc + hl_opts[attr] = val + end + end + hl_name = table.concat(hl_name, "_") + -- if highlight exists, verify it has + -- the correct colorscheme highlights + local newID = vim.fn.hlID(hl_name) + if newID > 0 then + for what, expected in pairs(hl_opts) do + local res = vim.fn.synIDattr(newID, what) + if type(expected) == "boolean" then + -- synIDattr returns '1' for boolean + res = res and res == "1" and true + end + if res ~= expected then + -- need to regen the highlight + -- print("color mismatch", hl_name, what, "e:", expected, "c:", res) + newID = 0 + end + end + end + if newID == 0 then + vim.api.nvim_set_hl(0, hl_name, hl_opts) + end + return hl_name +end + +local function set_hl(hls, s) + if not hls or not s then return s end + hls = type(hls) == "string" and { hls } or hls + for _, hl in ipairs(hls) do + if vim.fn.hlID(hl) > 0 then + return ("%%#%s#%s%%0*"):format(hl, s) + end + end + return s +end + +local function wrap_fnc(opts, fn) + return function(window, buffer) + -- buf_autocmd doesn't send win + if not window and buffer then + window = { win_id = vim.fn.bufwinid(buffer.bufnr) } + end + if opts.hide_inactive and window and + window.win_id ~= vim.api.nvim_get_current_win() then + return "" + end + return fn(window, buffer) + end +end + +function M.mode(opts) + opts = opts or {} + return wrap_fnc(opts, function(_, _) + local fmt = opts.fmt or "%s%s" + local mode = vim.api.nvim_get_mode().mode + local mode_data = opts.modes and opts.modes[mode] + local hls = mode_data and mode_data[3] + local icon = opts.hl_icon_only and set_hl(hls, opts.icon) or opts.icon + mode = mode_data and mode_data[1]:upper() or mode + mode = (fmt):format(icon or "", mode) + return not opts.hl_icon_only and set_hl(hls, mode) or mode + end) +end + +function M.git_branch(opts) + opts = opts or {} + return el_sub.buf_autocmd("el_git_branch", "BufEnter", + wrap_fnc(opts, function(_, buffer) + -- Try fugitive first as it's most reliable + local branch = vim.g.loaded_fugitive == 1 and + vim.fn.FugitiveHead() or nil + -- buffer can be null and code will crash with: + -- E5108: Error executing lua ... 'attempt to index a nil value' + if not buffer or not (buffer.bufnr > 0) then + return + end + -- fugitive is empty or not loaded, try gitsigns + if not branch or #branch == 0 then + local ok, res = pcall(vim.api.nvim_buf_get_var, + buffer.bufnr, "gitsigns_head") + if ok then branch = res end + end + -- last resort run git command + if not branch then + local j = job:new { + command = "git", + args = { "branch", "--show-current" }, + cwd = vim.fn.fnamemodify(buffer.name, ":h"), + } + + local ok, result = pcall(function() + return vim.trim(j:sync()[1]) + end) + if ok then + branch = result + end + end + + if branch and #branch > 0 then + local fmt = opts.fmt or "%s %s" + local icon = opts.icon or "" + return set_hl(opts.hl, (fmt):format(icon, branch)) + end + end)) +end + +local function git_changes_formatter(opts) + local specs = { + insert = { + regex = "(%d+) insertions?", + icon = opts.icon_insert or "+", + hl = opts.hl_insert, + }, + change = { + regex = "(%d+) files? changed", + icon = opts.icon_change or "~", + hl = opts.hl_change, + }, + delete = { + regex = "(%d+) deletions?", + icon = opts.icon_delete or "-", + hl = opts.hl_delete, + }, + } + return function(_, _, s) + local result = {} + for k, v in pairs(specs) do + local count = nil + if type(s) == "string" then + -- 'git diff --shortstat' output + -- from 'git_changes_all' + count = tonumber(string.match(s, v.regex)) + else + -- map from 'git_changes_buf' + count = s[k] + end + if count and count > 0 then + table.insert(result, set_hl(v.hl, ("%s%d"):format(v.icon, count))) + end + end + return table.concat(result, " ") + end +end + +-- requires gitsigns +function M.git_changes_buf(opts) + opts = opts or {} + local formatter = opts.formatter or git_changes_formatter(opts) + return wrap_fnc(opts, function(window, buffer) + local stats = {} + if buffer and buffer.bufnr > 0 then + local ok, res = pcall(vim.api.nvim_buf_get_var, + buffer.bufnr, "vgit_status") + if ok then stats = res end + end + if buffer and buffer.bufnr > 0 then + local ok, res = pcall(vim.api.nvim_buf_get_var, + buffer.bufnr, "gitsigns_status_dict") + if ok then stats = res end + end + local counts = { + insert = stats.added > 0 and stats.added or nil, + change = stats.changed > 0 and stats.changed or nil, + delete = stats.removed > 0 and stats.removed or nil, + } + if not vim.tbl_isempty(counts) then + local fmt = opts.fmt or "%s" + local out = formatter(window, buffer, counts) + return out and fmt:format(out) or nil + else + -- el functions that return a + -- string must not return nil + return "" + end + end) +end + +function M.git_changes_all(opts) + opts = opts or {} + local formatter = opts.formatter or git_changes_formatter(opts) + return el_sub.buf_autocmd("el_git_changes", "BufWritePost", + wrap_fnc(opts, function(window, buffer) + if not buffer or + not (buffer.bufnr > 0) or + vim.bo[buffer.bufnr].bufhidden ~= "" or + vim.bo[buffer.bufnr].buftype == "nofile" or + vim.fn.filereadable(buffer.name) ~= 1 then + return + end + + local j = job:new { + command = "git", + args = { "diff", "--shortstat" }, + -- makes no sense to run for one file as + -- 'file(s) changed' will always be 1 + -- args = { "diff", "--shortstat", buffer.name }, + cwd = vim.fn.fnamemodify(buffer.name, ":h"), + } + + local ok, git_changes = pcall(function() + return formatter(window, buffer, vim.trim(j:sync()[1])) + end) + + if ok then + local fmt = opts.fmt or "%s" + return git_changes and fmt:format(git_changes) or nil + end + end)) +end + +function M.lsp_srvname(opts) + local fmt = opts.fmt or "%s" + local icon = opts.icon or "" + local buf_clients = vim.lsp.buf_get_clients(0) + if not buf_clients or #buf_clients == 0 then + return "" + end + local names = "" + for i, c in ipairs(buf_clients) do + if i > 1 then names = names .. ", " end + names = names .. c.name + end + return icon..fmt:format(names) +end + +local function diag_formatter(opts) + return function(_, buffer, counts) + local items = {} + local icons = { + ["errors"] = { opts.icon_err or "x", opts.hl_err or "DiagnosticError"}, + ["warnings"] = { opts.icon_warn or "!", opts.hl_warn or "DiagnosticWarn"}, + ["infos"] = { opts.icon_info or "i", opts.hl_info or "DiagnosticInfo"}, + ["hints"] = { opts.icon_hint or "h", opts.hl_hint or "DiagnosticHint"}, + } + for _, k in ipairs({ "errors", "warnings", "infos", "hints" }) do + if counts[k] > 0 then + table.insert(items, + set_hl(icons[k][2], ("%s:%s"):format(icons[k][1], counts[k]))) + end + end + local fmt = opts.fmt or "%s" + if vim.tbl_isempty(items) then + return "" + else + return fmt:format(table.concat(items, " ")) + end + end +end + +local function get_buffer_counts(diagnostic, _, buffer) + local counts = { 0, 0, 0, 0 } + local diags = diagnostic.get(buffer.bufnr) + if diags and not vim.tbl_isempty(diags) then + for _, d in ipairs(diags) do + if tonumber(d.severity) then + counts[d.severity] = counts[d.severity] + 1 + end + end + end + return { + errors = counts[1], + warnings = counts[2], + infos = counts[3], + hints = counts[4], + } +end + +function M.diagnostics(opts) + opts = opts or {} + local formatter = opts.formatter or diag_formatter(opts) + return el_sub.buf_autocmd("el_buf_diagnostic", "LspAttach,DiagnosticChanged", + wrap_fnc(opts, function(window, buffer) + return formatter(window, buffer, get_buffer_counts(vim.diagnostic, window, buffer)) + end)) +end + +function M.line(opts) + opts = opts or {} + local fmt = opts.fmt or "%s" + return wrap_fnc(opts, function(_, _) + local al = vim.api.nvim_buf_line_count(0) + local cl = vim.api.nvim_win_get_cursor(0)[1] + return (fmt):format(cl.."/"..al.." "..math.floor((cl / al) * 100).."%%") + end) +end + +return M diff --git a/lua/core/theme.lua b/lua/core/theme.lua new file mode 100644 index 0000000..9d508f2 --- /dev/null +++ b/lua/core/theme.lua @@ -0,0 +1,76 @@ +local pickers = require("telescope.pickers") +local finders = require("telescope.finders") +local previewers = require("telescope.previewers") +local conf = require("telescope.config").values +local actions = require("telescope.actions") +local action_set = require("telescope.actions.set") +local action_state = require("telescope.actions.state") +local misc = require('core.misc') + +local M = {} + +function M.switcher() + local bufnr = vim.api.nvim_get_current_buf() + + -- show current buffer content in previewer + local colors = vim.fn.getcompletion('', 'color') + for k, v in pairs(colors) do + if v.find(v, '.ext') then + table.remove(colors, k) + break + end + end + + -- our picker function: colors + pickers.new({ + prompt_title = "Set Nvim Colorscheme", + finder = finders.new_table { results = colors }, + sorter = conf.generic_sorter(), + previewer = previewers.new_buffer_previewer { + define_preview = function(self, entry) + -- add content + local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false) + vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines) + + -- add syntax highlighting in previewer + local ft = (vim.filetype.match { buf = bufnr } or "diff"):match "%w+" + require("telescope.previewers.utils").highlighter(self.state.bufnr, ft) + end + }, + + attach_mappings = function(prompt_bufnr, map) + -- reload theme while typing + vim.schedule(function() + vim.api.nvim_create_autocmd("TextChangedI", { + buffer = prompt_bufnr, + callback = function() + if action_state.get_selected_entry() then + misc.colorscheme(action_state.get_selected_entry()[1]) + end + end, + }) + end) + + -- reload theme on cycling + actions.move_selection_previous:replace(function() + action_set.shift_selection(prompt_bufnr, -1) + misc.colorscheme(action_state.get_selected_entry()[1]) + end) + actions.move_selection_next:replace(function() + action_set.shift_selection(prompt_bufnr, 1) + misc.colorscheme(action_state.get_selected_entry()[1]) + end) + + -- reload theme on selection + actions.select_default:replace(function() + if action_state.get_selected_entry() then + actions.close(prompt_bufnr) + misc.colorscheme(action_state.get_selected_entry()[1]) + end + end) + return true + end, + }):find() +end + +return M diff --git a/lua/snippet/c.lua b/lua/snippet/c.lua index 3c1e127..7ef2e51 100644 --- a/lua/snippet/c.lua +++ b/lua/snippet/c.lua @@ -54,4 +54,26 @@ ls.add_snippets('c', { } ) ), + s({ + name = 'Variadic function parser', + trig = 'infinite vars', + dscr = 'Parse an infinite number of arguments passed to a function', + }, + { + t({ + "/*", + " * NOTE: the function must have a int before the ... argument", + " * and you need to include for this to work", + " */", + "va_list ptr;", + "va_start(ptr, ", i(1, "n"), + ");", + "for (int i = 0; i < ", ri(1), + "; i++) {", + i(2), + "}", + "va_end(ptr);", + }), + } + ) }) -- cgit v1.2.1