Created
May 27, 2025 11:32
-
-
Save even4void/9e4e15b022c63e8e82bfdfed822b51e3 to your computer and use it in GitHub Desktop.
Neovim (0.11) init file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Builtins {{{ | |
local disabled_built_ins = { | |
"gzip", | |
"zip", | |
"zipPlugin", | |
"tar", | |
"tarPlugin", | |
"getscript", | |
"getscriptPlugin", | |
"vimball", | |
"vimballPlugin", | |
"2html_plugin", | |
"tutor_mode_plugin", | |
"logipat", | |
"rrhelper", | |
"spellfile_plugin", | |
} | |
for _, plugin in pairs(disabled_built_ins) do | |
vim.g["loaded_" .. plugin] = 1 | |
end | |
if vim.fn.executable("/Users/chl/.local/lib/jupyter/bin/python3") == 1 then | |
vim.g.loaded_python_provider = 0 | |
vim.g.python3_host_prog = "/Users/chl/.local/lib/jupyter/bin/python3" | |
end | |
vim.cmd([[set statusline=%!v:lua.statusline()]]) | |
vim.g.loaded_perl_provider = 0 | |
vim.g.loaded_ruby_provider = 0 | |
vim.g.tex_flavor = "latex" | |
vim.g.mapleader = "," | |
vim.g.maplocalleader = "," | |
vim.g.netrw_banner = 0 | |
vim.g.netrw_keepdir = 0 | |
vim.g.netrw_localcopydircmd = "cp -r" | |
vim.g.python3_host_skip_check = 1 | |
vim.o.breakindent = true | |
vim.o.clipboard = "unnamedplus" | |
vim.o.completeopt = "menu,menuone,noselect,noinsert" | |
vim.o.ignorecase = true | |
vim.opt.foldenable = false | |
vim.opt.foldcolumn = "0" | |
-- vim.opt.foldtext = "" | |
vim.opt.foldlevel = 99 | |
vim.opt.foldlevelstart = 0 | |
vim.opt.shortmess:append("I", "c") | |
vim.opt.wildignore = { | |
"venv*/", | |
"__pycache__/", | |
".pytest_cache/", | |
"tags", | |
"htmlcov/.coverage", | |
"*.pyc", | |
"package-lock.json", | |
"yarn.lock", | |
} | |
vim.opt.listchars = { | |
tab = "» ", | |
nbsp = "¬", | |
trail = "·", | |
extends = "…", | |
precedes = "‹", | |
} | |
vim.o.laststatus = 3 | |
vim.o.mouse = "nv" | |
vim.o.smartcase = true | |
vim.o.splitbelow = true | |
vim.o.splitright = true | |
vim.o.undofile = true | |
vim.o.updatetime = 250 | |
vim.wo.number = false | |
vim.wo.signcolumn = "auto" | |
if vim.env.TMUX then | |
vim.loop.fs_write(2, "\27Ptmux;\27\27]11;?\7\27\\", -1, nil) | |
end | |
local fzf_theme = "bw" | |
vim.api.nvim_command([[ | |
augroup updatecolorscheme | |
autocmd colorscheme * :hi normal guibg=NONE ctermbg=NONE | | |
hi! link TabLine StatusLine | | |
hi! link TabLineFill StatusLine | | |
hi! link TabLineSel StatusLineNC | | |
hi VertSplit guibg=NONE ctermbg=NONE | | |
hi DiagnosticUnderlineError guisp = Black | | |
hi DiagnosticUnderlineWarn guisp = Black | | |
hi DiagnosticUnderlineHint guisp = NONE | | |
hi DiagnosticUnderlineInfo guisp = NONE | |
augroup END | |
]]) | |
vim.cmd.colorscheme("quiet") | |
if vim.fn.executable("rg") == 1 then | |
vim.o.grepprg = "rg --vimgrep --smart-case --hidden" | |
vim.o.grepformat = "%f:%l:%c:%m" | |
end | |
-- }}} | |
-- Autocommands {{{ | |
-- https://dmerej.info/blog/post/vim-cwd-and-neovim/ | |
-- vim.api.nvim_exec( | |
-- [[ | |
-- function! OnTabEnter(path) | |
-- if isdirectory(a:path) | |
-- let dirname = a:path | |
-- else | |
-- let dirname = fnamemodify(a:path, ":h") | |
-- endif | |
-- execute "tcd ". dirname | |
-- endfunction() | |
-- | |
-- autocmd TabNewEntered * call OnTabEnter(expand("<amatch>")) | |
-- ]], | |
-- true | |
-- ) | |
vim.api.nvim_exec( | |
[[ | |
augroup gpg | |
autocmd! | |
autocmd BufReadPre,FileReadPre *.gpg setlocal shada= noswapfile noundofile nobackup | |
autocmd BufRead *.gpg %!gpg -qd % | |
autocmd BufWriteCmd *.gpg write !gpg --batch --yes -co % | |
augroup END | |
augroup term | |
autocmd! | |
autocmd TermOpen * tnoremap <Esc> <C-\><C-n> | |
autocmd TermOpen * setlocal nonumber norelativenumber | |
augroup END | |
augroup fzf | |
autocmd! | |
autocmd FileType fzf tnoremap <buffer> <Esc> <Esc> | |
autocmd FileType fzf set laststatus=0 noshowmode noruler | |
\| autocmd BufLeave <buffer> set laststatus=3 showmode ruler | |
augroup END | |
augroup ftdetect | |
autocmd! | |
autocmd BufRead,BufNewFile *.swv set filetype=tex | |
autocmd BufRead,BufNewFile *.m,*.nb,*.wl,*.wls set filetype=mma | |
autocmd BufRead,BufNewFile *.sls,*.sps,*.ss set filetype=scheme | |
autocmd BufNewFile,BufRead *.purs set filetype=purescript | |
autocmd BufRead,BufNewFile *.rs packadd rustaceanvim | |
augroup END | |
augroup whitespace | |
autocmd! | |
autocmd BufWritePre * %s/\s\+$//e | |
augroup END | |
]], | |
true | |
) | |
vim.api.nvim_create_autocmd({ "FileType" }, { | |
pattern = { | |
"netrw", | |
"help", | |
"man", | |
}, | |
callback = function() | |
vim.cmd([[ | |
nnoremap <silent> <buffer> <C-q> :close<CR> | |
set nobuflisted | |
]]) | |
end, | |
}) | |
-- }}} | |
-- Commands/Functions {{{ | |
-- https://github.com/romainl/vim-cool/issues/9 | |
vim.api.nvim_exec( | |
[[ | |
noremap <expr> <Plug>(StopHL) execute('nohlsearch')[-1] | |
noremap! <expr> <Plug>(StopHL) execute('nohlsearch')[-1] | |
fu! HlSearch() | |
let s:pos = match(getline('.'), @/, col('.') - 1) + 1 | |
if s:pos != col('.') | |
call StopHL() | |
endif | |
endfu | |
fu! StopHL() | |
if !v:hlsearch || mode() isnot 'n' | |
return | |
else | |
sil call feedkeys("\<Plug>(StopHL)", 'm') | |
endif | |
endfu | |
augroup SearchHighlight | |
au! | |
au CursorMoved * call HlSearch() | |
au InsertEnter * call StopHL() | |
augroup end | |
]], | |
true | |
) | |
-- https://gist.github.com/romainl/eae0a260ab9c135390c30cd370c20cd7 | |
vim.api.nvim_exec( | |
[[ | |
function! Redir(cmd, rng, start, end) | |
for win in range(1, winnr('$')) | |
if getwinvar(win, 'scratch') | |
execute win . 'windo close' | |
endif | |
endfor | |
if a:cmd =~ '^!' | |
let cmd = a:cmd =~' %' | |
\ ? matchstr(substitute(a:cmd, ' %', ' ' . shellescape(escape(expand('%:p'), '\')), ''), '^!\zs.*') | |
\ : matchstr(a:cmd, '^!\zs.*') | |
if a:rng == 0 | |
let output = systemlist(cmd) | |
else | |
let joined_lines = join(getline(a:start, a:end), '\n') | |
let cleaned_lines = substitute(shellescape(joined_lines), "'\\\\''", "\\\\'", 'g') | |
let output = systemlist(cmd . " <<< $" . cleaned_lines) | |
endif | |
else | |
redir => output | |
execute a:cmd | |
redir END | |
let output = split(output, "\n") | |
endif | |
new | |
let w:scratch = 1 | |
setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile | |
call setline(1, output) | |
endfunction | |
" This command definition includes -bar, so that it is possible to "chain" Vim commands. | |
" Side effect: double quotes can't be used in external commands | |
command! -nargs=1 -complete=command -bar -range Redir silent call Redir(<q-args>, <range>, <line1>, <line2>) | |
]], | |
true | |
) | |
vim.api.nvim_exec( | |
[[ | |
command! -nargs=? Filter let @a='' | execute 'g/<args>/y A' | new | setlocal bt=nofile | put! a | |
]], | |
true | |
) | |
-- https://www.kevinli.co/posts/2017-01-19-multiple-cursors-in-500-bytes-of-vimscript/ | |
vim.api.nvim_exec( | |
[[ | |
let g:mc = "y/\\V\<C-r>=escape(@\", '/')\<CR>\<CR>" | |
nnoremap cn *``cgn | |
nnoremap cN *``cgN | |
vnoremap <expr> cn g:mc . "``cgn" | |
vnoremap <expr> cN g:mc . "``cgN" | |
function! SetupCR() | |
nnoremap <Enter> :nnoremap <lt>Enter> n@z<CR>q:<C-u>let @z=strpart(@z,0,strlen(@z)-1)<CR>n@z | |
endfunction | |
nnoremap cq :call SetupCR()<CR>*``qz | |
nnoremap cQ :call SetupCR()<CR>#``qz | |
vnoremap <expr> cq ":\<C-u>call SetupCR()\<CR>" . "gv" . g:mc . "``qz" | |
vnoremap <expr> cQ ":\<C-u>call SetupCR()\<CR>" . "gv" . substitute(g:mc, '/', '?', 'g') . "``qz" | |
]], | |
true | |
) | |
-- https://www.reddit.com/r/neovim/comments/q6lvsl/lsphelp_simple_script_to_place_a_sign_where_code/ | |
function code_action_listener() | |
local bufnr = vim.api.nvim_get_current_buf() | |
local context = { diagnostics = vim.lsp.diagnostic.get_line_diagnostics() } | |
local params = vim.lsp.util.make_range_params() | |
local ns_id = vim.api.nvim_create_namespace("code_action") | |
local r, c = unpack(vim.api.nvim_win_get_cursor(0)) | |
local curr = 1 -- FIXME: is there a better way? | |
params.context = context | |
local line = params.range.start.line | |
vim.lsp.buf_request(bufnr, "textDocument/codeAction", params, function(_, actions, _) | |
if not actions or type(actions) ~= "table" or vim.tbl_isempty(actions) then | |
vim.api.nvim_buf_del_extmark(bufnr, ns_id, curr) | |
else | |
vim.api.nvim_buf_del_extmark(bufnr, ns_id, curr) | |
vim.api.nvim_buf_set_extmark( | |
bufnr, | |
ns_id, | |
line, | |
-1, | |
{ id = curr, virt_text = { { "░", "DiagnosticInfo" } }, virt_text_pos = "eol" } | |
) | |
end | |
end) | |
end | |
function diagnostic_status() | |
local count = {} | |
local levels = { | |
errors = "Error", | |
warnings = "Warn", | |
infos = "Info", | |
hints = "Hint", | |
} | |
for k, level in pairs(levels) do | |
count[k] = vim.tbl_count(vim.diagnostic.get(0, { severity = level })) | |
end | |
local errno = "" | |
if count["errors"] ~= 0 or count["warnings"] ~= 0 or count["hints"] ~= 0 or count["infos"] ~= 0 then | |
errno = "!" .. count["errors"] + count["warnings"] + count["hints"] + count["infos"] | |
end | |
return errno | |
end | |
local function format_lsp_progress(messages) | |
local percentage | |
local result = {} | |
for _, msg in pairs(messages) do | |
if msg.message then | |
table.insert(result, msg.title .. ": " .. msg.message) | |
else | |
table.insert(result, msg.title) | |
end | |
if msg.percentage then | |
percentage = math.max(percentage or 0, msg.percentage) | |
end | |
end | |
if percentage then | |
return string.format("%03d: %s", percentage, table.concat(result, ", ")) | |
else | |
return table.concat(result, ", ") | |
end | |
end | |
-- Mathias Fußenegger, https://is.gd/BQRt7j | |
function file_or_lsp_status() | |
local mode = vim.api.nvim_get_mode().mode | |
if vim.lsp.status then | |
local lsp_status = vim.lsp.status() | |
if mode ~= "n" or lsp_status == "" then | |
return format_uri(vim.uri_from_bufnr(vim.api.nvim_get_current_buf())) | |
end | |
return lsp_status | |
end | |
local messages = vim.lsp.util.get_progress_messages() | |
if mode ~= "n" or vim.tbl_isempty(messages) then | |
return format_uri(vim.uri_from_bufnr(vim.api.nvim_get_current_buf())) | |
end | |
return format_lsp_progress(messages) | |
end | |
function format_uri(uri) | |
if vim.startswith(uri, "jdt://") then | |
local package = uri:match("contents/[%a%d._-]+/([%a%d._-]+)") or "" | |
local class = uri:match("contents/[%a%d._-]+/[%a%d._-]+/([%a%d$]+).class") or "" | |
return string.format("%s::%s", package, class) | |
else | |
return vim.fn.fnamemodify(vim.uri_to_fname(uri), ":.") | |
end | |
end | |
function statusline() | |
local parts = { | |
[[ %{luaeval("file_or_lsp_status()")} %m%r %= ]], | |
"%#warningmsg#", | |
"%{&ff!='unix'?'['.&ff.']':''}", | |
"%*", | |
"%#warningmsg#", | |
"%{(&fenc!='utf-8'&&&fenc!='')?'['.&fenc.']':''}", | |
"%*", | |
"%{&paste?'¶':''} ", | |
[[ %{luaeval("diagnostic_status()")} ]], | |
"%{'≡ '.&tw}%{&et?'':' »'} ", | |
"%{&spell?'['.&spelllang.']':''} ", | |
"%l %P ", | |
} | |
return table.concat(parts, "") | |
end | |
function only() | |
local cur_buf = vim.api.nvim_get_current_buf() | |
for _, buf in ipairs(vim.api.nvim_list_bufs()) do | |
if cur_buf ~= buf then | |
pcall(vim.cmd, "bd " .. buf) | |
end | |
end | |
end | |
function ToggleQuickFix() | |
if vim.fn.empty(vim.fn.filter(vim.fn.getwininfo(), "v:val.quickfix")) == 1 then | |
vim.cmd([[copen]]) | |
else | |
vim.cmd([[cclose]]) | |
end | |
end | |
vim.api.nvim_exec( | |
[[ | |
" https://phelipetls.github.io/posts/code-formatting-vim/ | |
" https://github.com/phelipetls/dotfiles/blob/master/.config/nvim/autoload/format.vim | |
function! s:Format(...) | |
silent keepjumps normal! '[v']gq | |
if v:shell_error > 0 | |
silent undo | |
echohl ErrorMsg | |
echomsg 'formatprg "' . &formatprg . '" exited with status ' . v:shell_error | |
echohl None | |
endif | |
endfunction | |
function! FormatFile() abort | |
let w:view = winsaveview() | |
keepjumps normal! gg | |
set operatorfunc=<SID>Format | |
keepjumps normal! g@G | |
keepjumps call winrestview(w:view) | |
unlet w:view | |
endfunction | |
command! Format call FormatFile() | |
]], | |
true | |
) | |
vim.api.nvim_exec( | |
[[ | |
function! s:start_repl(repl) abort | |
cmd = "jupyter console --simple-prompt --kernel " . repl | |
call cmd | |
endfunction | |
command! -nargs=1 StartREPL :sp term://jupyter console --simple-prompt --kernel <args> | |
]], | |
true | |
) | |
vim.api.nvim_exec( | |
[[ | |
"" Credit: https://github.com/strager/dotfiles | |
"" http://vim.wikia.com/wiki/Regex-based_text_alignment | |
function! s:align_section(regex) range abort | |
let extra = 1 | |
let sep = empty(a:regex) ? '=' : a:regex | |
let maxpos = 0 | |
let section = getline(a:firstline, a:lastline) | |
for line in section | |
let pos = match(line, ' *'.sep) | |
if maxpos < pos | |
let maxpos = pos | |
endif | |
endfor | |
call map(section, 's:align_line(v:val, sep, maxpos, extra)') | |
call setline(a:firstline, section) | |
endfunction | |
function! s:align_line(line, sep, maxpos, extra) abort | |
let m = matchlist(a:line, '\(.\{-}\) \{-}\('.a:sep.'.*\)') | |
if empty(m) | |
return a:line | |
endif | |
let spaces = repeat(' ', a:maxpos - strlen(m[1]) + a:extra) | |
return m[1] . spaces . m[2] | |
endfunction | |
command! -nargs=? -range Align <line1>,<line2>call s:align_section('<args>') | |
]], | |
true | |
) | |
vim.cmd([[command! -bar -nargs=* Jump cexpr system('git jump ' . expand(<q-args>))]]) | |
vim.cmd( | |
[[command! -range GB echo join(systemlist("git -C " . shellescape(expand('%:p:h')) . " blame -L <line1>,<line2> " . expand('%:t')), "\n")]] | |
) | |
vim.cmd([[command! -complete=dir -nargs=+ Grep silent grep <args> | redraw!]]) | |
vim.cmd([[command! -range Gist call system('gist', getbufline('%', <line1>, <line2>))]]) | |
vim.cmd([[command! Changelog execute "normal i<C-R>=strftime('%Y-%m-%d')<CR><ESC>$a chl <[email protected]> -"]]) | |
vim.cmd([[command! LspStop execute ":lua vim.lsp.stop_client(vim.lsp.get_active_clients())"]]) | |
-- }}} | |
-- Mapping's {{{ | |
vim.keymap.set("c", "<C-a>", [[<home>]], {}) | |
vim.keymap.set("c", "<C-e>", [[<end>]], {}) | |
vim.keymap.set("i", "<C-s>", [[<c-g>u<Esc>[s1z=`]a<c-g>u]]) | |
vim.keymap.set("i", "jk", "<Esc>") | |
vim.keymap.set("t", "jk", [[<C-\><C-n>]]) | |
vim.keymap.set("v", "/", "\"fy/\\V<C-R>f<CR>") | |
vim.keymap.set("n", "<leader>n", [[:set invrelativenumber]], {}) | |
vim.keymap.set("n", "<leader>:", require("fzf-lua").resume, {}) | |
vim.keymap.set("n", "<leader>r", require("fzf-lua").oldfiles, {}) | |
vim.keymap.set("n", "<C-g>", function() | |
vim.fn.setreg("w", vim.fn.expand("<cword>")) | |
require("fzf-lua").live_grep({ | |
winopts = { | |
on_create = function() | |
local b = vim.api.nvim_get_current_buf() | |
vim.keymap.set("t", "<C-r>", [['<C-\><C-N>"'.nr2char(getchar()).'pi']], { buffer = b, expr = true }) | |
end, | |
}, | |
}) | |
end, { silent = true }) | |
vim.keymap.set("n", "<leader>?", function() | |
require("fzf-lua").builtin({ winopts = { width = 1, height = 0.2, row = 1 } }) | |
end, { silent = true }) | |
vim.keymap.set("n", "<C-p>", require("fzf-lua").files, {}) | |
vim.keymap.set("n", "<C-q>", ":lua ToggleQuickFix()<cr>", { silent = true }) | |
vim.keymap.set("n", "<C-s>", [[:setlocal spell!<bar>setlocal spell?<cr>:setlocal spelllang=en<cr>]]) | |
vim.keymap.set("n", "<leader>x", ":lua only()<cr>", { silent = true }) | |
vim.keymap.set("n", "<leader>.", [[<cmd>lcd %:p:h<cr>]], {}) | |
vim.keymap.set("n", "<leader>;", require("fzf-lua").buffers, {}) | |
vim.keymap.set("n", "<leader>/", require("fzf-lua").blines, {}) | |
vim.keymap.set("n", "<leader><leader>", [[<C-^>]], {}) | |
vim.keymap.set("n", "<leader><tab>", [[<cmd>$tabnew<cr>]], {}) | |
vim.keymap.set("n", "<leader>WW", require("fzf-lua").diagnostics_workspace, {}) | |
vim.keymap.set("n", "<leader>ww", require("fzf-lua").diagnostics_document, {}) | |
vim.keymap.set("n", "<leader>gb", function() | |
require("fzf-lua").git_bcommits({ winopts = { preview = { hidden = "nohidden" } } }) | |
end, { silent = true }) | |
vim.keymap.set("n", "<leader>gg", require("fzf-lua").git_status, {}) | |
vim.keymap.set("n", "<leader>s", [[vip:sort u<cr>]]) | |
vim.keymap.set("n", "g=", "<cmd>Format<cr>") | |
vim.keymap.set("n", "gb", "`[v`]") | |
vim.keymap.set("n", "J", "mzJ`z") | |
vim.keymap.set("n", "N", "Nzz") | |
vim.keymap.set("n", "/", "ms/") | |
vim.keymap.set("n", "U", "<C-r>") | |
vim.keymap.set("n", "j", "v:count == 0 ? 'gj' : 'j'", { expr = true, silent = true }) | |
vim.keymap.set("n", "k", "v:count == 0 ? 'gk' : 'k'", { expr = true, silent = true }) | |
vim.keymap.set("n", "n", "nzz") | |
vim.keymap.set("n", "zs", "1z=") | |
vim.keymap.set("v", "_`", [["zdi`<C-R>z`]]) | |
vim.keymap.set("v", '_"', [["zdi"<C-R>z"]]) | |
vim.keymap.set("v", "_(", [["zdi(<C-R>z)]]) | |
vim.keymap.set("v", "_[", '"zdi[<C-R>z]') | |
vim.keymap.set("n", "(", "[", { remap = true }) | |
vim.keymap.set("n", ")", "]", { remap = true }) | |
vim.keymap.set("o", "(", "[", { remap = true }) | |
vim.keymap.set("o", ")", "]", { remap = true }) | |
vim.keymap.set("x", "(", "[", { remap = true }) | |
vim.keymap.set("x", ")", "]", { remap = true }) | |
-- }}} | |
-- Plugins {{{ | |
-- Treesitter {{{2 | |
require("nvim-treesitter.configs").setup({ | |
ensure_installed = { | |
"bash", | |
"bibtex", | |
"c", | |
"clojure", | |
"comment", | |
"commonlisp", | |
"cpp", | |
"elm", | |
"go", | |
"haskell", | |
"javascript", | |
"julia", | |
"latex", | |
"lua", | |
"markdown", | |
"markdown_inline", | |
"org", | |
"python", | |
"r", | |
"racket", | |
"regex", | |
"rust", | |
"scheme", | |
"tsx", | |
"typescript", | |
"vim", | |
"vimdoc", | |
}, | |
auto_install = false, | |
highlight = { | |
enable = true, | |
-- disable = { "plaintex" }, | |
}, | |
indent = { enable = true }, | |
incremental_selection = { | |
enable = true, | |
keymaps = { | |
-- init_selection = "<C-tab>", | |
init_selection = "<tab><tab>", | |
node_incremental = "<tab>", | |
node_decremental = "<S-tab>", | |
}, | |
}, | |
textobjects = { | |
select = { | |
enable = true, | |
lookahead = true, | |
keymaps = { | |
["aa"] = "@parameter.outer", | |
["ia"] = "@parameter.inner", | |
["af"] = "@function.outer", | |
["if"] = "@function.inner", | |
["ac"] = "@class.outer", | |
["ic"] = "@class.inner", | |
["ab"] = "@block.outer", | |
["ib"] = "@block.inner", | |
}, | |
selection_modes = { | |
["@parameter.outer"] = "v", -- charwise | |
["@function.outer"] = "V", -- linewise | |
["@class.outer"] = "<c-v>", -- blockwise | |
}, | |
}, | |
}, | |
}) | |
-- vim.treesitter.language.register("css") | |
-- }}} | |
-- LSP {{{2 | |
-- NOTE: omnifunc autocompletion is managed in ftplugin/*.lua | |
vim.api.nvim_create_autocmd("LspAttach", { | |
callback = function(args) | |
local client = vim.lsp.get_client_by_id(args.data.client_id) | |
local augroup = vim.api.nvim_create_augroup("LspFormatting", {}) | |
vim.keymap.set("i", "<C-k>", vim.lsp.buf.signature_help, { buffer = args.buf }) | |
vim.keymap.set("n", "K", vim.lsp.buf.hover, { buffer = args.buf }) | |
if client:supports_method("textDocument/completion") then | |
vim.lsp.completion.enable(true, client.id, args.buf, { autotrigger = false }) | |
end | |
if client.name == "ruff_lsp" then | |
client.server_capabilities.hoverProvider = false | |
end | |
if client.supports_method("callHierarchy/incomingCalls") then | |
vim.keymap.set("n", "<leader>ci", "<cmd>lua require('fzf-lua').lsp_incoming_calls()<cr>") | |
vim.keymap.set("n", "<leader>co", "<cmd>lua require('fzf-lua').lsp_outgoing_calls()<cr>") | |
end | |
vim.keymap.set("n", "gd", "<cmd>lua require('fzf-lua').lsp_definitions({ jump_to_single_result = true })<cr>") | |
vim.keymap.set("n", "gD", "<cmd>lua require('fzf-lua').lsp_declarations()<cr>") | |
vim.keymap.set("n", "g?", "<cmd>lua require('fzf-lua').lsp_finder()<cr>") | |
vim.keymap.set( | |
"n", | |
"gr", | |
"<cmd>lua require('fzf-lua').lsp_references({ ignore_current_line = true, includeDeclaration = false })<cr>" | |
) | |
-- builtin gra (0.11) | |
-- if client.server_capabilities.codeActionProvider then | |
-- -- vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, { | |
-- -- group = vim.api.nvim_create_augroup("code_action_sign", { clear = true }), | |
-- -- callback = function() | |
-- -- code_action_listener() | |
-- -- end, | |
-- -- }) | |
-- vim.keymap.set("n", "z=", "<cmd>lua require('fzf-lua').lsp_code_actions({ previewer = 'codeaction' })<cr>") | |
-- end | |
if client.supports_method("textDocument/inlayHint") then | |
vim.keymap.set("n", "zI", "<cmd>lua vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())<cr>", {}) | |
end | |
-- builtin grn (0.11) | |
-- if client.supports_method("textDocument/rename") then | |
-- vim.keymap.set("n", "zr", vim.lsp.buf.rename, { buffer = args.buf }) | |
-- end | |
if client.supports_method("textDocument/documentSymbol") then | |
vim.keymap.set("n", "gO", "<cmd>lua require('fzf-lua').lsp_document_symbols()<cr>") | |
elseif client.supports_method("workspace/symbol") then | |
vim.keymap.set("n", "gO", "<cmd>lua require('fzf-lua').lsp_workspace_symbols()<cr>") | |
end | |
if client.server_capabilities.codeLensProvider then | |
vim.api.nvim_create_autocmd({ "CursorMoved" }, { | |
callback = function() | |
vim.lsp.codelens.refresh() | |
end, | |
}) | |
vim.keymap.set("n", "z!", vim.lsp.codelens.run, { buffer = args.buf, silent = true }) | |
end | |
if client.supports_method("textDocument/formatting") then | |
vim.keymap.set("n", "g=", vim.lsp.buf.format, { buffer = args.buf }) | |
vim.api.nvim_clear_autocmds({ group = augroup, buffer = args.buf }) | |
vim.api.nvim_create_autocmd({ "BufWritePre" }, { | |
group = augroup, | |
buffer = bufnr, | |
callback = function() | |
vim.lsp.buf.format({ async = false }) | |
end, | |
}) | |
end | |
vim.api.nvim_set_hl(0, "DiagnosticError", { ctermfg = 0, guifg = Black }) | |
vim.api.nvim_set_hl(0, "DiagnosticWarn", { ctermfg = 0, guifg = Black }) | |
vim.api.nvim_set_hl(0, "DiagnosticInfo", { ctermfg = 0, guifg = Black }) | |
vim.api.nvim_set_hl(0, "DiagnosticHint", { ctermfg = 0, guifg = Black }) | |
vim.api.nvim_set_hl(0, "DiagnosticOk", { ctermfg = 0, guifg = Black }) | |
vim.api.nvim_set_hl(0, "DiagnosticUnnecessary", { ctermfg = 0, guifg = Black }) | |
end, | |
}) | |
vim.lsp.enable({ "clangd", "r_language_server", "jdtls", "lua_ls", "lsp_wl", "bashls", "rust-analyzer", "hls" }) | |
vim.diagnostic.config({ | |
virtual_text = false, | |
float = { | |
format = function(diagnostic) | |
if diagnostic.source == "rustc" | |
and diagnostic.user_data.lsp.data ~= nil | |
then | |
return diagnostic.user_data.lsp.data.rendered | |
else | |
return diagnostic.message | |
end | |
end, | |
}, | |
signs = false, | |
underline = true, | |
update_in_insert = false, | |
severity_sort = false, | |
}) | |
-- }}} | |
-- fzf-lua {{{2 | |
local actions = require("fzf-lua.actions") | |
require("fzf-lua").setup({ | |
"max-perf", | |
diagnostics = { multiline = false, diag_source = true }, | |
lsp = { symbols = { symbol_style = false } }, | |
git = { | |
status = { preview_pager = false }, | |
commits = { preview_pager = false }, | |
bcommits = { preview_pager = false } | |
}, | |
grep = { | |
rg_glob = true, | |
glob_flag = "--iglob", | |
glob_separator = "%s%-%-", | |
input_prompt = "Grep> ", | |
}, | |
keymap = { | |
fzf = { | |
["ctrl-a"] = "select-all", | |
["ctrl-d"] = "deselect-all", | |
["ctrl-t"] = "toggle-all", | |
}, | |
}, | |
winopts = { | |
-- split = "belowright 10new", | |
width = 1, | |
height = 0.20, | |
row = 1, | |
border = "single", | |
preview = { | |
default = "cat", | |
hidden = "hidden", | |
border = "border", | |
title = false, | |
layout = "horizontal", | |
horizontal = "right:50%", | |
}, | |
}, | |
hls = { | |
header_bind = "Normal", | |
header_text = "Statement", | |
buf_name = "Normal", | |
buf_nr = "Normal", | |
buf_linenr = "Normal", | |
buf_flag_cur = "Normal", | |
buf_flag_alt = "Normal", | |
path_linenr = "Normal", | |
path_colnr = "Normal", | |
tab_title = "Normal", | |
tab_marker = "Normal", | |
}, | |
fzf_opts = { | |
["--ansi"] = "", | |
["--info"] = "inline", | |
["--height"] = "100%", | |
["--layout"] = "reverse", | |
["--border"] = "none", | |
["--color"] = fzf_theme, | |
}, | |
actions = { | |
files = { | |
["enter"] = actions.file_edit_or_qf, | |
["ctrl-s"] = actions.file_split, | |
["ctrl-v"] = actions.file_vsplit, | |
["ctrl-t"] = actions.file_tabedit, | |
["ctrl-q"] = actions.file_sel_to_qf, | |
}, | |
} | |
}) | |
local default_bibfiles = { "~/Documents/notes/references.bib" } | |
local cachedir = vim.fn.stdpath("state") .. "/fzf-bibtex/" | |
local pandoc = function(selected, opts) | |
local result = vim.fn.system("bibtex-cite", selected) | |
vim.api.nvim_put({ result }, "c", false, true) | |
if opts.fzf_bibtex.mode == "i" then | |
vim.api.nvim_feedkeys("i", "n", true) | |
end | |
end | |
local cite = function(selected, opts) | |
local result = vim.fn.system('bibtex-cite -prefix="\\cite{" -postfix="}" -separator=","', selected) | |
vim.api.nvim_put({ result }, "c", false, true) | |
if opts.fzf_bibtex.mode == "i" then | |
vim.api.nvim_feedkeys("i", "n", true) | |
end | |
end | |
local markdown_print = function(selected, opts) | |
local result = vim.fn.system( | |
"bibtex-markdown -cache=" .. cachedir .. " " .. table.concat(vim.b.bibfiles, " "), | |
selected | |
) | |
local result_lines = {} | |
for line in result:gmatch("[^\n]+") do | |
table.insert(result_lines, line) | |
end | |
vim.api.nvim_put(result_lines, "l", true, true) | |
if opts.fzf_bibtex.mode == "i" then | |
vim.api.nvim_feedkeys("i", "n", true) | |
end | |
end | |
local file_open = function(selected, opts) | |
local result = vim.fn.system("bibtex-cite", selected) | |
fh = "/home/chl/Documents/papers/" .. result:sub(2) .. ".pdf" | |
vim.api.nvim_command("silent !xdg-open " .. fh .. " &") | |
end | |
local fzf_bibtex_menu = function(mode) | |
return function() | |
-- check cache directory hasn't mysteriously disappeared | |
if vim.fn.isdirectory(cachedir) == 0 then | |
vim.fn.mkdir(cachedir, "p") | |
end | |
require("fzf-lua").config.set_action_helpstr(pandoc, "@-pandoc") | |
require("fzf-lua").config.set_action_helpstr(cite, "\\cite{}") | |
require("fzf-lua").config.set_action_helpstr(markdown_print, "markdown-pretty-print") | |
require("fzf-lua").config.set_action_helpstr(file_open, "open") | |
-- header line: the bibtex filenames | |
local filenames = {} | |
for i, fullpath in ipairs(vim.b.bibfiles) do | |
filenames[i] = vim.fn.fnamemodify(fullpath, ":t") | |
end | |
local header = table.concat(filenames, "\\ ") | |
-- set default action | |
local default_action = nil | |
if vim.bo.ft == "markdown" then | |
default_action = pandoc | |
elseif vim.bo.ft == "tex" then | |
default_action = cite | |
end | |
return require("fzf-lua").fzf_exec("bibtex-ls " .. "-cache=" .. cachedir .. " " .. table.concat(vim.b.bibfiles, " "), | |
{ | |
actions = { | |
["default"] = default_action, | |
["ctrl-i"] = pandoc, | |
["ctrl-t"] = cite, | |
["ctrl-m"] = markdown_print, | |
["ctrl-o"] = file_open, | |
}, | |
fzf_bibtex = { ["mode"] = mode }, | |
fzf_opts = { ["--prompt"] = "BibTeX> ", ["--header"] = header }, | |
}) | |
end | |
end | |
vim.api.nvim_create_autocmd("Filetype", { | |
desc = "Set up keymaps for fzf-bibtex", | |
group = vim.api.nvim_create_augroup("fzf-bibtex", { clear = true }), | |
pattern = { "markdown", "tex", "text", "org", "quarto" }, | |
callback = function() | |
vim.b.bibfiles = default_bibfiles | |
vim.keymap.set("n", "gr", fzf_bibtex_menu("n"), { buffer = true, desc = "FZF: BibTeX [C]itations" }) | |
vim.keymap.set("i", "@@", fzf_bibtex_menu("i"), { buffer = true, desc = "FZF: BibTeX [C]itations" }) | |
end, | |
}) | |
-- }}} | |
-- vim: set fdm=marker: | |
-- }}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment