-- vim: fdm=marker fdl=0 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 = 'nvim_treesitter#foldexpr()' -- opt.foldlevel = 0 opt.foldlevelstart = 1 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 = 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-Cursor/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_' .. vim.env.USER if vim.fn.isdirectory(undodir) == 0 then vim.fn.mkdir(undodir, 'p', '0700') end g.undodir = undodir opt.undofile = true -- }}} -- swap between newpaper and karafuru g.night_and_day = 'night' g.do_filetype_lua = true -- g.do_legacy_filetype = false -- g.did_load_filetypes = 0 require('_globals') require('plugins') require('internal.align').setup { bindings = true } require('internal.hardmode') -- Configure builtin diagnositics {{{ vim.diagnostic.config { underline = true, virtual_text = false, -- virtual_text = { -- severity = {min=vim.diagnostic.severity.WARN}, -- source = true, -- prefix = '', -- }, signs = true, float = true, virtual_lines = { prefix = '⬐ ' }, update_in_insert = false, severity_sort = true, } vim.fn.sign_define({ {name='DiagnosticSignError', text='✗', texthl='DiagnosticSignError'}, -- {name='DiagnosticSignWarn', text='⚡', texthl='DiagnosticSignWarn'}, {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', 'd', vim.diagnostic.open_float, {desc='show line diagnositics'}) vim.keymap.set('n', 'D', 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}) -- swap gf and gF vim.keymap.set('n', 'gf', [[ :e ]]) vim.keymap.set('v', 'gf', [[ :e ]]) 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) local misc = require('internal.misc') vim.keymap.set('n', 'gd', function() misc.open_under_cursor(nil, true) end, {desc='open under cursor'}) -- vim.keymap.set('n', 'gf', function() misc.file_under_cursor(function(s) vim.cmd('edit ' .. s) end) end) vim.keymap.set('n', 'gx', function() misc.open_under_cursor('url-launcher') end, {desc='url-launcher'}) vim.keymap.set('n', 'gu', function() misc.open_under_cursor('url-launcher') end, {desc='url-launcher'}) -- vim.keymap.set('n', 'gs', function() misc.word_under_cursor(function(s) vim.fn.feedkeys(':%s/' .. s .. '//g'); cmd [[ call feedkeys("\\") ]] end) end) vim.keymap.set('n', 'r', misc.live_grep, {desc='live grep (rg)'}) vim.keymap.set('n', 'f', misc.find_files, {desc='find files (fd)'}) 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('x', 'f', [[lua require("internal.misc").fold_block()]], { noremap = true, silent = true, desc = 'fold block' }) -- vim.keymap.set('v', '', [[y:%s/h//gc]], { noremap = true, silent = true }) vim.keymap.set('n', 'C', function() local fnln = (vim.fn.expand('%') .. ':' .. vim.fn.line('.')) vim.fn.setreg('+', fnln) vim.notify(fnln) end, {desc='copy file path'}) vim.keymap.set('n', 'J', require('internal.job').list, {desc='list jobs started through internal.job'}) -- }}} -- 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 autocmd('QuickFixCmdPost', { callback = function() -- make sure there is anyting in the qflist before opening it, -- avoids: `E42: No Errors` local qf = vim.fn.getqflist({size = true}) if qf and qf.size > 0 then vim.cmd [[clist]] end end, group = augroup('OpenQuickFix', {}), }) 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', 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({'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', {}), }) -- }}} -- USER COMMANDS -- {{{ vim.api.nvim_create_user_command('Make', function(opts) require('internal.job').make(opts.fargs) end, { nargs = '*', desc = 'run make target' }) vim.api.nvim_create_user_command('Sh', function(opts) require('internal.job').sh(table.concat(opts.fargs, ' ')) end, { nargs = '*', desc = 'run shell command' }) require('internal.misc').setup { grep = true, find = true, sortline = true, } -- }}} _G.statusline_enable_notifysend = false require('internal.statusline') require('internal.exrc').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', } }