2021-11-03 14:10:54 +01:00
-- Aliases
local cmd = vim.cmd
local fn = vim.fn
local g = vim.g
local opt = vim.opt
local map = vim.api . nvim_set_keymap
-- Helpers
local function noremap ( mode , lhs , rhs , opts )
local options = { noremap = true }
if opts then options = vim.tbl_extend ( ' force ' , options , opts ) end
2022-12-10 17:16:34 +01:00
vim.keymap . set ( mode , lhs , rhs , options )
2021-11-03 14:10:54 +01:00
end
local function associate_filetype ( glob , ft )
cmd ( ' autocmd BufRead,BufNewFile ' .. glob .. ' set filetype= ' .. ft )
end
2023-03-09 19:57:45 +01:00
local function setup_filetype ( ft , tab , opts )
2021-11-03 14:10:54 +01:00
local cmdline = ' autocmd Filetype ' .. ft .. ' setlocal '
if tab then cmdline = cmdline .. ' ts= ' .. tab .. ' sw= ' .. tab .. ' sts= ' .. tab end
if opts then cmdline = cmdline .. ' ' .. opts end -- FIXME: opts should be a table
cmd ( cmdline )
end
local has_words_before = function ( )
local line , col = unpack ( vim.api . nvim_win_get_cursor ( 0 ) )
return col ~= 0 and vim.api . nvim_buf_get_lines ( 0 , line - 1 , line , true ) [ 1 ] : sub ( col , col ) : match ( ' %s ' ) == nil
end
-- Display
opt.number = true -- line numbers
opt.colorcolumn = { ' 80 ' } -- line at 80 characters
opt.scrolloff = 5 -- context at top/bottom
opt.sidescrolloff = 8 -- context on the left/right side
opt.conceallevel = 1 -- conceal inactive lines
opt.termguicolors = true
cmd ( ' colorscheme solarized ' )
-- Undo
opt.undofile = true
opt.undolevels = 4096
opt.undoreload = 16384
2022-06-12 21:03:32 +02:00
cmd ( ' autocmd BufWritePre /dev/shm/* setlocal noundofile ' ) -- exclude pass
cmd ( ' autocmd BufWritePre /tmp/* setlocal noundofile ' ) -- exclude sops
2021-11-03 14:10:54 +01:00
-- Behaviour
opt.hidden = true -- background buffers
opt.expandtab = true -- spaces instead of tabs by default
opt.smartindent = true -- automatic indentation
opt.tabstop = 2 -- tabs have width of 2 by default
opt.shiftwidth = 0 -- shift width = tab width
opt.joinspaces = false -- no double spaces when joining
opt.clipboard = ' unnamedplus ' -- use system clipboard
opt.modeline = true
2022-12-10 17:16:34 +01:00
opt.mouse = ' ' ; -- I want the mouse to only interact with the terminal, not vim
2021-11-03 14:10:54 +01:00
cmd ( [ [
autocmd BufReadPost * if line ( " ' \" " ) >= 1 && line ( " ' \" " ) <= line ( " $ " ) && & ft ! ~# ' commit ' | exe " normal! g` \" " | endif
] ] ) -- see :h last-position-jump
-- Search
opt.ignorecase = true -- ignore case
2022-04-12 17:58:52 +02:00
opt.inccommand = ' nosplit ' -- live preview of substitution
2021-11-03 14:10:54 +01:00
opt.smartcase = true -- but only with all-lowercase searches
-- Highlight trailing spaces
cmd ( [[autocmd BufWinEnter * match errorMsg /\s\+$\| \+\ze\t/]] )
-- Mappings
g.mapleader = ' , '
noremap ( ' n ' , ' <CR> ' , ' :nohlsearch<CR> ' , { silent = true } ) -- hide highlights on enter
noremap ( ' v ' , ' <Leader>s ' , ' :sort<CR> ' ) -- sort in visual mode
noremap ( ' t ' , ' <Esc><Esc> ' , [[<C-\><C-n>]] )
-- Filetypes
associate_filetype ( ' *.vpy ' , ' python ' ) -- vapoursynth scripts
setup_filetype ( ' bib ' , 1 )
setup_filetype ( ' c ' , 4 )
2023-04-21 09:10:08 +02:00
setup_filetype ( ' cpp ' , 2 )
2021-11-03 14:10:54 +01:00
setup_filetype ( ' dockerfile ' , 4 )
setup_filetype ( ' gitcommit ' , nil , ' colorcolumn=72 ' )
setup_filetype ( ' go ' , 4 , ' noexpandtab ' )
setup_filetype ( ' haskell ' , 4 )
2023-04-07 23:28:31 +02:00
setup_filetype ( ' java ' , 4 )
2021-11-03 14:10:54 +01:00
setup_filetype ( ' lua ' , 4 )
2023-09-24 14:00:45 +02:00
setup_filetype ( ' nftables ' , 4 , ' noexpandtab ' )
2021-11-03 14:10:54 +01:00
setup_filetype ( ' python ' , 4 )
setup_filetype ( ' sh ' , 4 , ' noexpandtab ' )
setup_filetype ( ' tex ' , 1 )
setup_filetype ( ' zsh ' , 4 )
-- Plugins
-- Status line
local custom_solarized_lualine = require ( ' lualine.themes.solarized ' )
-- default colours are very hard to read
custom_solarized_lualine.normal . b = { fg = ' #eee8d5 ' , bg = ' #586e75 ' }
require ( ' lualine ' ) . setup {
options = {
theme = custom_solarized_lualine ,
} ,
sections = {
lualine_c = {
' filename ' ,
' lsp_progress ' ,
} ,
} ,
}
-- Tagbar
noremap ( ' n ' , ' <F8> ' , ' :TagbarToggle<CR> ' )
-- Keymap popup
require ( ' which-key ' ) . setup { }
-- Icons
require ( ' nvim-web-devicons ' ) . setup { default = true }
-- Git
require ( ' plenary ' ) -- otherwise neogit SIGABRTs
require ( ' neogit ' ) . setup {
disable_commit_confirmation = true ,
integrations = {
diffview = true ,
} ,
}
cmd ( [ [
hi NeogitNotificationInfo guifg =# 268 bd2
hi NeogitNotificationWarning guifg =# cb4b16
hi NeogitNotificationError guifg =# dc322f
] ] )
2022-06-12 21:12:50 +02:00
require ( ' gitsigns ' ) . setup {
-- copied from upstream readme
on_attach = function ( bufnr )
local gs = package.loaded . gitsigns
local function map ( mode , l , r , opts )
opts = opts or { }
opts.buffer = bufnr
vim.keymap . set ( mode , l , r , opts )
end
-- Navigation
map ( ' n ' , ' ]c ' , function ( )
if vim.wo . diff then return ' ]c ' end
vim.schedule ( function ( ) gs.next_hunk ( ) end )
return ' <Ignore> '
end , { expr = true } )
map ( ' n ' , ' [c ' , function ( )
if vim.wo . diff then return ' [c ' end
vim.schedule ( function ( ) gs.prev_hunk ( ) end )
return ' <Ignore> '
end , { expr = true } )
-- Actions
map ( { ' n ' , ' v ' } , ' <leader>hs ' , ' :Gitsigns stage_hunk<CR> ' )
map ( { ' n ' , ' v ' } , ' <leader>hr ' , ' :Gitsigns reset_hunk<CR> ' )
map ( ' n ' , ' <leader>hS ' , gs.stage_buffer )
map ( ' n ' , ' <leader>hu ' , gs.undo_stage_hunk )
map ( ' n ' , ' <leader>hR ' , gs.reset_buffer )
map ( ' n ' , ' <leader>hp ' , gs.preview_hunk )
map ( ' n ' , ' <leader>hb ' , function ( ) gs.blame_line { full = true } end )
map ( ' n ' , ' <leader>tb ' , gs.toggle_current_line_blame )
map ( ' n ' , ' <leader>hd ' , gs.diffthis )
map ( ' n ' , ' <leader>hD ' , function ( ) gs.diffthis ( ' ~ ' ) end )
map ( ' n ' , ' <leader>td ' , gs.toggle_deleted )
-- Text object
map ( { ' o ' , ' x ' } , ' ih ' , ' :<C-U>Gitsigns select_hunk<CR> ' )
end
}
2021-11-03 14:10:54 +01:00
require ( ' diffview ' ) . setup { }
-- Fuzzy finder/option picker
require ( ' telescope ' ) . setup { }
2022-12-10 17:16:34 +01:00
require ( " telescope " ) . load_extension ( " ui-select " )
2021-11-03 14:10:54 +01:00
-- Completion/Snippets
local cmp = require ( ' cmp ' )
local lspkind = require ( ' lspkind ' )
local luasnip = require ( ' luasnip ' )
luasnip.config . set_config {
enable_autosnippets = true ,
}
require ( ' snippets ' )
cmp.setup {
snippet = {
expand = function ( args ) luasnip.lsp_expand ( args.body ) end ,
} ,
2022-05-31 14:40:18 +02:00
mapping = cmp.mapping . preset.insert ( {
2021-11-03 14:10:54 +01:00
[ ' <C-d> ' ] = cmp.mapping ( cmp.mapping . scroll_docs ( - 4 ) , { ' i ' , ' c ' } ) ,
[ ' <C-f> ' ] = cmp.mapping ( cmp.mapping . scroll_docs ( 4 ) , { ' i ' , ' c ' } ) ,
[ ' <C-e> ' ] = cmp.mapping ( { i = cmp.mapping . abort ( ) , c = cmp.mapping . close ( ) } ) ,
[ ' <CR> ' ] = cmp.mapping . confirm ( { select = false } ) ,
[ ' <Tab> ' ] = cmp.mapping ( function ( fallback )
if luasnip.expand_or_jumpable ( ) then
luasnip.expand_or_jump ( )
elseif cmp.visible ( ) then
cmp.select_next_item ( )
elseif has_words_before ( ) then
cmp.complete ( )
else
fallback ( )
end
end , { ' i ' , ' s ' } ) ,
[ ' <S-Tab> ' ] = cmp.mapping ( function ( fallback )
if luasnip.jumpable ( - 1 ) then
luasnip.jump ( - 1 )
elseif cmp.visible ( ) then
cmp.select_prev_item ( )
else
fallback ( )
end
end , { ' i ' , ' s ' } ) ,
2022-05-31 14:40:18 +02:00
} ) ,
2021-11-03 14:10:54 +01:00
sources = cmp.config . sources ( {
{ name = ' nvim_lsp ' } ,
{ name = ' luasnip ' } ,
{ name = ' path ' }
} , {
{
name = ' buffer ' ,
2022-05-31 14:40:18 +02:00
option = {
2021-11-03 14:10:54 +01:00
keyword_pattern = [[\k\+]] , -- allow unicode multibyte characters
} ,
}
} ) ,
formatting = {
format = lspkind.cmp_format ( {
with_text = false ,
maxwidth = 50 ,
} )
} ,
}
-- LSP
local lsp = require ( ' lspconfig ' )
vim.lsp . handlers [ ' textDocument/publishDiagnostics ' ] = vim.lsp . with ( vim.lsp . diagnostic.on_publish_diagnostics , {
update_in_insert = true , -- update suggestions in insert mode
} )
2023-06-02 11:31:08 +02:00
for type , icon in pairs ( { Error = ' ' , Warn = ' ' , Hint = ' ' , Info = ' ' } ) do
2022-05-31 14:40:18 +02:00
fn.sign_define ( " DiagnosticSign " .. type , { text = icon , texthl = " Diagnostic " .. type } )
2021-11-03 14:10:54 +01:00
end
local on_attach = function ( client , bufnr )
2022-12-10 17:16:34 +01:00
vim.api . nvim_buf_set_option ( bufnr , ' omnifunc ' , ' v:lua.vim.lsp.omnifunc ' )
2021-11-03 14:10:54 +01:00
local opts = { noremap = true , silent = true }
2022-12-10 17:16:34 +01:00
vim.keymap . set ( ' n ' , ' gD ' , vim.lsp . buf.declaration , opts )
vim.keymap . set ( ' n ' , ' gd ' , require ( " telescope.builtin " ) . lsp_definitions , opts )
vim.keymap . set ( ' n ' , ' K ' , vim.lsp . buf.hover , opts )
vim.keymap . set ( ' n ' , ' gi ' , require ( " telescope.builtin " ) . lsp_implementations , opts )
vim.keymap . set ( ' n ' , ' <C-k> ' , vim.lsp . buf.signature_help , opts )
vim.keymap . set ( ' n ' , ' <Leader>wa ' , vim.lsp . buf.add_workspace_folder , opts )
vim.keymap . set ( ' n ' , ' <Leader>wr ' , vim.lsp . buf.remove_workspace_folder , opts )
vim.keymap . set ( ' n ' , ' <Leader>wl ' , function ( ) print ( vim.inspect ( vim.lsp . buf.list_workspace_folders ( ) ) ) end , opts )
vim.keymap . set ( ' n ' , ' <Leader>D ' , require ( " telescope.builtin " ) . lsp_type_definitions , opts )
vim.keymap . set ( ' n ' , ' <Leader>rn ' , vim.lsp . buf.rename , opts )
vim.keymap . set ( ' n ' , ' <Leader>ca ' , vim.lsp . buf.code_action , opts )
vim.keymap . set ( ' n ' , ' gr ' , vim.lsp . buf.references , opts )
vim.keymap . set ( ' n ' , ' <Leader>d ' , vim.diagnostic . open_float , opts )
vim.keymap . set ( ' n ' , ' [d ' , vim.diagnostic . goto_prev , opts )
vim.keymap . set ( ' n ' , ' ]d ' , vim.diagnostic . goto_next , opts )
vim.keymap . set ( ' n ' , ' <Leader>q ' , vim.diagnostic . setloclist , opts )
vim.keymap . set ( ' n ' , ' <Leader>f ' , function ( ) vim.lsp . buf.format { async = true } end , opts )
2022-06-12 22:34:27 +02:00
require ( ' illuminate ' ) . on_attach ( client )
2022-12-10 17:16:34 +01:00
vim.keymap . set ( ' n ' , ' <a-n> ' , function ( ) require ( " illuminate " ) . next_reference { wrap = true } end , opts )
vim.keymap . set ( ' n ' , ' <a-p> ' , function ( ) require ( " illuminate " ) . next_reference { reverse = true , wrap = true } end , opts )
2021-11-03 14:10:54 +01:00
end
2023-04-21 09:10:08 +02:00
lsp.ccls . setup {
on_attach = on_attach ,
init_options = {
compilationDatabaseDirectory = ' build ' ;
index = {
threads = 0 ;
} ;
clang = {
excludeArgs = { ' -frounding-math ' } ;
} ;
}
}
2021-11-03 14:10:54 +01:00
lsp.gopls . setup {
on_attach = on_attach ,
}
lsp.hls . setup {
on_attach = on_attach ,
root_dir = lsp.util . root_pattern ( ' *.cabal ' , ' stack.yaml ' , ' cabal.project ' , ' package.yaml ' , ' hie.yaml ' , ' .git ' ) ,
}
2023-04-07 23:28:31 +02:00
lsp.jdtls . setup {
on_attach = on_attach ,
cmd = { ' jdt-language-server ' , ' -configuration ' , ' /home/simon/.cache/jdtls/config ' , ' -data ' , ' /home/simon/.cache/jdtls/workspace ' } , -- copied from upstream, but changed executable name
}
2023-04-18 15:55:03 +02:00
lsp.ltex . setup {
on_attach = on_attach ,
settings = {
ltex = {
language = ' en-GB ' ,
languageToolHttpServerUri = ' https://languagetool.sbruder.de/ ' ,
} ,
} ,
-- both taken from upstream, extended
filetypes = {
' bib ' ,
' gitcommit ' ,
' mail ' ,
' markdown ' ,
' org ' ,
' plaintex ' ,
' rst ' ,
' rnoweb ' ,
' tex ' ,
' pandoc '
} ,
get_language_id = function ( _ , filetype )
local language_id_mapping = {
bib = ' bibtex ' ,
gitcommit = ' git-commit ' ,
mail = ' markdown ' , -- quite wrong, but allows magic commands
pandoc = ' markdown ' ,
plaintex = ' tex ' ,
rnoweb = ' sweave ' ,
rst = ' restructuredtext ' ,
tex = ' latex ' ,
xhtml = ' xhtml ' ,
}
local language_id = language_id_mapping [ filetype ]
if language_id then
return language_id
else
return filetype
end
end ,
}
2021-11-03 14:10:54 +01:00
lsp.pylsp . setup {
on_attach = on_attach ,
}
lsp.rnix . setup {
on_attach = on_attach ,
}
lsp.rust_analyzer . setup {
on_attach = on_attach ,
settings = {
[ ' rust-analyzer ' ] = {
checkOnSave = {
command = ' clippy ' ,
} ,
} ,
} ,
}
require ( ' trouble ' ) . setup { }
2022-06-12 22:44:55 +02:00
-- Tree Sitter
require ( ' nvim-treesitter.configs ' ) . setup {
highlight = {
enable = true ,
additional_vim_regex_highlighting = false ,
} ,
indent = {
enable = true ,
} ,
}
2021-11-03 14:10:54 +01:00
-- VimTeX
g.tex_flavor = ' latex '
g.vimtex_view_method = ' zathura '
g.tex_conceal = ' abdmg '
-- this disables some helful warnings that often have a reason why I ignore them
g.vimtex_quickfix_ignore_filters = {
[[Underfull \\hbox (badness [0-9]*) in ]] ,
[[Overfull \\hbox ([0-9]*.[0-9]*pt too wide) in ]] ,
[[Overfull \\vbox ([0-9]*.[0-9]*pt too high) detected ]] ,
[[Package hyperref Warning: Token not allowed in a PDF string]] ,
[[Package typearea Warning: Bad type area settings!]] ,
}
2022-11-02 00:26:16 +01:00
g.vimtex_syntax_custom_cmds = {
{
name = ' llbracket ' ,
mathmode = true ,
concealchar = ' ⟦ ' ,
} ,
{
name = ' rrbracket ' ,
mathmode = true ,
concealchar = ' ⟧ ' ,
} ,
}
2021-11-03 14:10:54 +01:00
-- When using math environments vim does not know if if it currently is in one or outside of one
-- unless it parses the file from the start.
-- Parsing the file from the start each time fixes this
-- but leads to a performance drop (depending on the number of lines).
-- Also, somehow using FileType tex does not work, so this will enable slow syntax highlighting
-- everywhere once a *.tex file is opened.
cmd ( [[autocmd BufEnter *.tex syntax sync fromstart]] )
-- rust.vim
g.rustfmt_autosave_if_config_present = 1
g.rust_fold = 1
noremap ( ' n ' , ' <Leader>rt ' , ' :RustTest<CR> ' )
-- Markdown
g.vim_markdown_folding_disabled = 1