-- vim: fdm=marker fdl=0 vim.cmd [[ function! LessInitFunc() set nolist set nocursorcolumn nocursorline set laststatus=0 set readonly set nonumber endfunction ]] local g = vim.g g.mapleader = ' ' -- key to g.maplocalleader = '\\' -- OPTIONS -- {{{ local opt = vim.opt opt.backspace = 'indent,eol,start' opt.clipboard:prepend({ 'unnamedplus' }) opt.cmdheight = 1 opt.colorcolumn = '+1' opt.formatoptions:remove('t') -- opt.complete = '.,w,b,u' opt.completeopt = { 'menu', 'menuone', 'noinsert' } opt.concealcursor = '' opt.conceallevel = 2 opt.cursorline = true opt.expandtab = false opt.exrc = true opt.fillchars:append({ fold = '─', horiz = '─', }) opt.foldenable = true opt.foldmethod = 'expr' opt.foldexpr = "v:lua.vim.treesitter.foldexpr()" opt.foldtext = 'v:lua.vim.treesitter.foldtext()' -- opt.foldlevel = 0 opt.foldlevelstart = 999 opt.hidden = true opt.hlsearch = false opt.ignorecase = true opt.inccommand = 'split' opt.incsearch = true -- 3; https://github.com/neovim/neovim/pull/17266 opt.laststatus = 3 opt.lazyredraw = true opt.list = true opt.listchars:append({ trail = '¬', tab = '> ', -- space/lead = '⋅', }) opt.mouse = 'a' opt.number = true opt.relativenumber = false opt.pumheight = 12 -- 0 use available screenspace opt.redrawtime = 1500 opt.ruler = true opt.scrolloff = 3 opt.shiftround = true opt.shortmess:append({ c = true }) opt.breakindent = true opt.breakindentopt = { shift = 2 } opt.showbreak = '↪ ' opt.showcmd = false opt.showmode = true opt.showmatch = true opt.signcolumn = 'auto' opt.smartcase = true opt.spell = false opt.spelllang = { 'en_gb' } -- opt.splitkeep = 'topline' opt.termguicolors = true opt.textwidth = 80 opt.timeoutlen = 400 opt.title = true opt.ttimeoutlen = 10 opt.undolevels = 1000 opt.updatetime = 200 opt.wrap = true opt.path = { '', '.', '.;$HOME', '/usr/include/**' } opt.isfname:remove(':') opt.guicursor = { -- block shape in normal/visual/command 'n-c-v:block', -- bar in insert/cmdline-insert/visual-exclusive 'i-ci-ve:ver15', -- underline in replace/cmdline-replace/operator-pending 'r-cr-o:hor10', -- 'sm:block-blinkwait175-blinkoff150-blinkon175', -- 'a:blinkwait700-blinkoff400-blinkon250-Cgrsor/lCursor', -- 'a:blinkon0-Cursor', } -- configure :grep to use ripgrep if it's available if vim.fn.executable('rg') then opt.grepprg = 'rg --vimgrep --smart-case --hidden' opt.grepformat = '%f:%l:%c:%m' end -- persistent undo local undodir = vim.fn.stdpath('cache') .. '/undodir' if vim.fn.isdirectory(undodir) == 0 then vim.fn.mkdir(undodir, 'p', '0700') end g.undodir = undodir opt.undofile = true -- }}} opt.background = 'dark' require('internal.syncbg').setup() require('_globals') require('plugins') require('internal.hardmode') -- TODO: load internal.* like normal plugins using lazy -- DIAGNOSITIC {{{ vim.diagnostic.config({ signs = true, underline = { severity = { min = vim.diagnostic.severity.WARN }, }, float = { severity = { min = vim.diagnostic.severity.INFO }, }, virtual_text = { severity = { min = vim.diagnostic.severity.ERROR }, }, severity_sort = true, }) vim.fn.sign_define({ { name = 'DiagnosticSignError', text = '✗', texthl = 'DiagnosticSignError', linehl = 'Search' }, { name = 'DiagnosticSignWarn', text = '▷', texthl = 'DiagnosticSignWarn' }, { name = 'DiagnosticSignInfo', text = 'ℹ', texthl = 'DiagnosticSignInfo' }, { name = 'DiagnosticSignHint', text = '🞶', texthl = 'DiagnosticSignHint' }, }) vim.keymap.set('n', ']d', vim.diagnostic.goto_next, { desc = 'Next diagnostic' }) vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, { desc = 'Prev diagnostic' }) vim.keymap.set( 'n', 'DD', vim.diagnostic.open_float, { desc = 'show line diagnositics' } ) vim.keymap.set('n', 'td', function() if not _G.diagnostic_hidden then vim.diagnostic.hide() else vim.diagnostic.show() end _G.diagnostic_hidden = not _G.diagnostic_hidden end, { desc = 'toggle diagnositics' }) -- }}} -- KEY BINDS -- {{{ vim.keymap.set('n', 'Q', [[ :quitall ]], { silent = true }) vim.keymap.set('n', 'gb', [[ :bnext ]], { silent = true }) vim.keymap.set('n', 'gB', [[ :bprevious ]], { silent = true }) vim.keymap.set('n', '', [[ :normal za ]], { silent = true }) -- vim.keymap.set('n', '', [[ :exe 'normal za' | IndentBlanklineRefresh ]], {silent = true}) vim.keymap.set({ 'n', 'v' }, 'gf', function() local Path = require('plenary.path') -- call twice to expand env vars local cfile = vim.fn.expand(vim.fn.expand('')) if string.sub(cfile, 0, 7) == 'file://' then cfile = string.sub(cfile, 8) end if not Path:new(cfile):is_absolute() then cfile = Path:new(vim.fn.expand('%:p:h'), cfile):normalize() end vim.cmd.edit(cfile) end, { desc = 'extends `:e ` with path normalization' }) vim.keymap.set('n', '{', [[ {zz ]]) vim.keymap.set('n', '}', [[ }zz ]]) -- this makes c jump to the start of the line -- vim.keymap.set({'n', 'v'}, 'c', '_c') -- vim.keymap.set({'n', 'v'}, 'C', '_C') vim.keymap.set('t', '', [[ ]]) vim.keymap.set('t', 'qq', [[ :bdelete! ]]) vim.keymap.set('v', 'T', function() vim.cmd([[retab!]]) vim.api.nvim_input('') end) vim.keymap.set('n', 'dgl', 'diffget LOCAL', { desc = 'diff get local' }) vim.keymap.set('n', 'dgr', 'diffget REMOTE', { desc = 'diff get remote' }) vim.keymap.set('n', 'dpl', 'diffpush LOCAL', { desc = 'diff push local' }) vim.keymap.set('n', 'dpr', 'diffpush REMOTE', { desc = 'diff push remote' }) -- vim.keymap.set('v', '', [[y:%s/h//gc]], { noremap = true, silent = true }) vim.keymap.set('n', 'yP', function() local fnln = (vim.fn.expand('%:p') .. ':' .. vim.fn.line('.')) vim.fn.setreg('+', fnln) vim.notify(fnln) end, { desc = 'yank absolute file path' }) vim.keymap.set('n', 'yT', function() local fnln = (vim.fn.expand('%:t') .. ':' .. vim.fn.line('.')) vim.fn.setreg('+', fnln) vim.notify(fnln) end, { desc = 'yank file name' }) -- }}} -- MENU -- {{{ vim.cmd [[unmenu PopUp.-1-]] vim.cmd [[unmenu PopUp.How-to\ disable\ mouse]] vim.cmd [[nnoremenu PopUp.Inspect :normal K]] vim.cmd [[nnoremenu PopUp.Goto :normal gd]] vim.cmd [[nnoremenu PopUp.References :normal gR]] vim.cmd [[nnoremenu PopUp.Diagnostic :normal DD]] -- }}} -- AUTO GROUPS -- {{{ local augroup = vim.api.nvim_create_augroup local autocmd = vim.api.nvim_create_autocmd autocmd('TextYankPost', { callback = vim.highlight.on_yank }) do local group = augroup('ObviousActiveWin', { clear = true }) autocmd('WinEnter', { command = 'set cul', group = group }) autocmd('WinLeave', { command = 'set nocul', group = group }) end do local group = augroup('OpenQuickFix', { clear = true }) autocmd('QuickFixCmdPost', { callback = function() local qf = vim.fn.getqflist({ qfbufnr = true, size = true }) if (not qf == vim.empty_dict()) and qf and qf.size > 0 then -- check if the quickfix buffer is already open for bufnr in ipairs(vim.api.nvim_list_bufs()) do if vim.api.nvim_buf_get_option_value(bufnr, 'buftype') == 'quickfix' then return end end vim.cmd.copen() end end, group = group, }) autocmd('BufEnter', { pattern = 'qf', command = [[silent normal! G]], group = group, }) end do local group = augroup('ManualCommentString', { clear = true }) autocmd('FileType', { pattern = 'i3config', callback = function() vim.opt_local.commentstring = '# %s' end, group = group, }) autocmd('FileType', { pattern = 'jsonc', callback = function() vim.opt_local.commentstring = '// %s' end, group = group, }) end do local group = augroup('ManualFolds', { clear = true }) autocmd('VimEnter', { pattern = 'vim/*', callback = function() vim.opt_local.foldenable = true end, group = group, }) autocmd('FileType', { pattern = 'json,jsonc,yaml,toml', callback = function() vim.opt_local.foldenable = false end, group = group, }) end do local group = augroup('EasyQuit', { clear = true }) autocmd('FileType', { pattern = 'help,neorg,dap-float,qf', callback = function() vim.keymap.set('n', 'q', 'close', { silent = true, buffer = 0 }) end, group = group, }) autocmd('FileType', { pattern = 'alpha', callback = function() vim.keymap.set('n', 'q', 'bdel', { silent = true, buffer = 0 }) end, group = group, }) autocmd('TermClose', { pattern = 'term://*', command = [[ if !v:event.status | exe 'bdelete! '..expand('') | endif ]], group = group, }) end autocmd({ 'BufRead', 'BufNewFile' }, { pattern = '/home/robert/bin/*', callback = function() vim.opt_local.filetype = 'sh' end, group = augroup('DetectBinDir', {}), }) -- autocmd({ 'FileType' }, { -- pattern = 'dirbuf', -- callback = function() -- if not vim.startswith(vim.api.nvim_buf_get_name(0), '/home/robert/zettelkasten') then return end -- vim.notify('hi') -- for i, l in ipairs(vim.api.nvim_buf_get_lines(0, 0, -1, true)) do -- vim.notify(vim.inspect(i, l)) -- end -- end, -- group = augroup('DetectZkDirbuf', {}), -- }) -- autocmd({ 'TermOpen' }, { -- pattern = 'term://*', -- callback = function() -- local bufnr = vim.api.nvim_get_current_buf() -- vim.opt_local.number = false -- vim.opt_local.relativenumber = false -- vim.opt_local.signcolumn = 'no' -- vim.cmd.split('#0') -- split the previous window -- vim.api.nvim_win_set_height(vim.fn.win_findbuf(bufnr)[1], 20) -- vim.cmd.startinsert() -- end, -- group = augroup('CustomizeTermBuffer', {}), -- }) -- custom diagnostic settings for zk autocmd({ 'DiagnosticChanged' }, { pattern = '*.md', callback = function(args) if not (args.data.diagnostics or args.data.diagnostics[1].source == 'zk') then return end if vim.b.did_configure_diagnostics then return end for key, ns in pairs(vim.api.nvim_get_namespaces()) do if vim.startswith(key, 'vim.lsp.zk') then vim.b.did_configure_diagnostics = true vim.diagnostic.config({ signs = { severity = vim.diagnostic.severity.INFO, }, virtual_text = { source = false, prefix = '', }, }, ns) end end end, group = augroup('DiagnosticConfigZk', {}), }) do local group = augroup('VisualModeRelativeNumber', {}) autocmd({ 'ModeChanged' }, { pattern = '*:[vV\x16]*', callback = function() vim.opt_local.relativenumber = true end, group = group, }) autocmd({ 'ModeChanged' }, { pattern = '[vV\x16]*:*', callback = function() -- vim.opt_local.relativenumber = (vim.api.nvim_get_mode().mode ~= '^[vV\x16]') vim.opt_local.relativenumber = false end, group = group, }) end -- }}} require('internal.misc').setup() require('internal.find').setup() require('internal.sortline').setup() _G.statusline_enable_notifysend = false require('internal.statusline') require('internal.job').setup({}) -- TODO: remove eventually local is_gotmpl = function(bufnr) for ln = 1, vim.api.nvim_buf_line_count(bufnr), 1 do local line = vim.api.nvim_buf_get_lines(bufnr, ln - 1, ln, true) if #line == 0 then break end if line[1]:match('{{.+}}') then return true end end return false end vim.filetype.add({ extension = { ha = 'hare', html = function(_, bufnr) return is_gotmpl(bufnr) and 'gotmpl.html' or 'html' end, yaml = function(_, bufnr) return is_gotmpl(bufnr) and 'gotmpl.yaml' or 'yaml' end, }, filename = { ['Caddyfile'] = 'conf', ['TODO'] = 'todofile', }, pattern = { ['${ZK_NOTEBOOK_DIR}/.*md$'] = 'zk.markdown', } }) -- use bash parsers for gentoo ebuilds vim.treesitter.language.register('bash', 'ebuild')