neovim: Rework configuration in lua
Many plugins are not yet configured, but the basic functionality is there.neovim-lua
parent
cc63ca0e9a
commit
43067ad796
@ -1,35 +0,0 @@
|
||||
snippet sha256 "dummy sha256 hash"
|
||||
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||
endsnippet
|
||||
|
||||
snippet unpackPhase "unpackPhase template"
|
||||
unpackPhase = ''
|
||||
runHook preUnpack
|
||||
$1
|
||||
runHook postUnpack
|
||||
'';
|
||||
endsnippet
|
||||
|
||||
snippet configurePhase "configurePhase template"
|
||||
configurePhase = ''
|
||||
runHook preConfigure
|
||||
$1
|
||||
runHook postConfigure
|
||||
'';
|
||||
endsnippet
|
||||
|
||||
snippet buildPhase "buildPhase template"
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
$1
|
||||
runHook postBuild
|
||||
'';
|
||||
endsnippet
|
||||
|
||||
snippet installPhase "installPhase template"
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
$1
|
||||
runHook postInstall
|
||||
'';
|
||||
endsnippet
|
@ -1,7 +0,0 @@
|
||||
snippet disp "Display trait implentation"
|
||||
impl fmt::Display for ${1:Struct} {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "${2}", ${3})
|
||||
}
|
||||
}${0}
|
||||
endsnippet
|
@ -1,19 +0,0 @@
|
||||
extends tex
|
||||
|
||||
snippet s "Section" b
|
||||
\section{$1}
|
||||
|
||||
|
||||
endsnippet
|
||||
|
||||
snippet ss "Subsection" b
|
||||
\subsection{$1}
|
||||
|
||||
|
||||
endsnippet
|
||||
|
||||
snippet sss "Subsubsection" b
|
||||
\subsubsection{$1}
|
||||
|
||||
|
||||
endsnippet
|
@ -1,23 +0,0 @@
|
||||
extends texmath
|
||||
|
||||
snippet qf "Quadratic formula (user is responsible for parentheses)" w
|
||||
\frac{-${2:b} \pm \sqrt{$2^2 - 4 \cdot ${1:a} \cdot ${3:c}}}{2 \cdot $1}$0
|
||||
endsnippet
|
||||
|
||||
snippet aligned "aligned environment (in math mode)" w
|
||||
\begin{aligned}
|
||||
$1 &= $0 \\\\
|
||||
\end{aligned}
|
||||
endsnippet
|
||||
|
||||
snippet si "Insert SI unit (only works with simple numbers)" w
|
||||
\SI{${1:amount}}{${2:unit}}
|
||||
endsnippet
|
||||
|
||||
snippet · "Insert multiplication sign" A
|
||||
\cdot $0
|
||||
endsnippet
|
||||
|
||||
snippet // "Fraction" iA
|
||||
\frac{$1}{$2}$0
|
||||
endsnippet
|
@ -0,0 +1,290 @@
|
||||
-- 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
|
||||
vim.api.nvim_set_keymap(mode, lhs, rhs, options)
|
||||
end
|
||||
|
||||
local function associate_filetype(glob, ft)
|
||||
cmd('autocmd BufRead,BufNewFile ' .. glob .. ' set filetype=' .. ft)
|
||||
end
|
||||
local function setup_filetype(ft, tab, expandtab, opts)
|
||||
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
|
||||
|
||||
-- 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
|
||||
|
||||
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
|
||||
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)
|
||||
setup_filetype('cpp', 4)
|
||||
setup_filetype('dockerfile', 4)
|
||||
setup_filetype('gitcommit', nil, 'colorcolumn=72')
|
||||
setup_filetype('go', 4, 'noexpandtab')
|
||||
setup_filetype('haskell', 4)
|
||||
setup_filetype('lua', 4)
|
||||
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=#268bd2
|
||||
hi NeogitNotificationWarning guifg=#cb4b16
|
||||
hi NeogitNotificationError guifg=#dc322f
|
||||
]])
|
||||
require('gitsigns').setup()
|
||||
require('diffview').setup {}
|
||||
|
||||
-- Fuzzy finder/option picker
|
||||
require('telescope').setup {}
|
||||
|
||||
-- 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,
|
||||
},
|
||||
mapping = {
|
||||
['<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' }),
|
||||
},
|
||||
sources = cmp.config.sources({
|
||||
{ name = 'nvim_lsp' },
|
||||
{ name = 'luasnip' },
|
||||
{ name = 'path' }
|
||||
}, {
|
||||
{
|
||||
name = 'buffer',
|
||||
opts = {
|
||||
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
|
||||
})
|
||||
|
||||
for type, icon in pairs({ Error = ' ', Warning = ' ', Hint = ' ', Information = ' ' }) do
|
||||
local hl = 'LspDiagnosticsSign' .. type
|
||||
fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
|
||||
end
|
||||
|
||||
local on_attach = function(client, bufnr)
|
||||
local function buf_set_keymap(...) vim.api.nvim_buf_set_keymap(bufnr, ...) end
|
||||
local function buf_set_option(...) vim.api.nvim_buf_set_option(bufnr, ...) end
|
||||
|
||||
buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')
|
||||
|
||||
local opts = { noremap = true, silent = true }
|
||||
|
||||
buf_set_keymap('n', 'gD', '<cmd>lua vim.lsp.buf.declaration()<CR>', opts)
|
||||
buf_set_keymap('n', 'gd', '<cmd>lua require("telescope.builtin").lsp_definitions()<CR>', opts)
|
||||
buf_set_keymap('n', 'K', '<cmd>lua vim.lsp.buf.hover()<CR>', opts)
|
||||
buf_set_keymap('n', 'gi', '<cmd>lua require("telescope.builtin").lsp_implementations()<CR>', opts)
|
||||
buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>D', '<cmd>lua require("telescope.builtin").lsp_type_definitions()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>ca', '<cmd>lua require("telescope.builtin").lsp_code_actions()<CR>', opts)
|
||||
buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>d', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>', opts)
|
||||
buf_set_keymap('n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>', opts)
|
||||
buf_set_keymap('n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>q', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>', opts)
|
||||
buf_set_keymap('n', '<Leader>f', '<cmd>lua vim.lsp.buf.formatting()<CR>', opts)
|
||||
end
|
||||
|
||||
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'),
|
||||
}
|
||||
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 {}
|
||||
|
||||
-- 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!]],
|
||||
}
|
||||
|
||||
-- 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
|
@ -0,0 +1,88 @@
|
||||
{ lib, pkgs }:
|
||||
let
|
||||
mkSnippet = prefix: description: body: mkSnippet' prefix description body { };
|
||||
mkSnippet' = prefix: description: body: { autotrigger ? false }: {
|
||||
inherit prefix description body;
|
||||
luasnip = {
|
||||
inherit autotrigger;
|
||||
};
|
||||
};
|
||||
|
||||
snippets = {
|
||||
nix = {
|
||||
Sha256Dummy = mkSnippet "sha256" "Dummy SHA256 hash" "sha256 = \"0000000000000000000000000000000000000000000000000000\";";
|
||||
} // (lib.mapAttrs
|
||||
(name: _:
|
||||
let
|
||||
upperName = (lib.toUpper (builtins.substring 0 1 name))
|
||||
+ (builtins.substring 1 (builtins.stringLength name - 1) name);
|
||||
in
|
||||
mkSnippet "${name}Phase" "${name}Phase skeleton" ''
|
||||
runHook pre${upperName}
|
||||
$1
|
||||
runHook post${upperName}'')
|
||||
(builtins.listToAttrs
|
||||
(map
|
||||
(name: lib.nameValuePair name { })
|
||||
[ "unpack" "configure" "build" "install" ])));
|
||||
rust = {
|
||||
DisplayTrait = mkSnippet "disp" "Display trait implentation" ''
|
||||
impl fmt::Display for ''${1:Struct} {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "$2", $3)
|
||||
}
|
||||
}$0'';
|
||||
};
|
||||
tex = {
|
||||
Section = mkSnippet "s" "Section" ''
|
||||
\section{$1}
|
||||
|
||||
'';
|
||||
SubSection = mkSnippet "ss" "Subsection" ''
|
||||
\subsection{$1}
|
||||
|
||||
'';
|
||||
SubSubSection = mkSnippet "sss" "Subsubsection" ''
|
||||
\subsubsection{$1}
|
||||
|
||||
'';
|
||||
# Math
|
||||
QuadraticFormula = mkSnippet
|
||||
"qf"
|
||||
"Quadratic formula (user is responsible for parentheses)"
|
||||
''\frac{-''${2:b} \pm \sqrt{$2^2 - 4 \cdot ''${1:a} \cdot ''${3:c}}}{2 \cdot $1}$0'';
|
||||
AlignedEnv = mkSnippet "aligned" "aligned environment (in math mode)" ''
|
||||
\begin{aligned}
|
||||
$1 &= $0 \\\\
|
||||
\end{aligned}'';
|
||||
SiUnit = mkSnippet
|
||||
"si"
|
||||
"Insert SI unit (only works with simple numbers)"
|
||||
''\SI{''${1:amount}}{''${2:unit}}'';
|
||||
MultiplicationSign = mkSnippet' "·" "Insert multiplication sign" ''\cdot $0'' { autotrigger = true; };
|
||||
Fraction = mkSnippet' "//" "Fraction" ''\frac{$1}{$2}$0'' { autotrigger = true; };
|
||||
};
|
||||
};
|
||||
|
||||
snippetsIndex = pkgs.writeTextDir "package.json" (builtins.toJSON {
|
||||
contributes.snippets = lib.mapAttrs
|
||||
(id: language: { inherit language; path = "./snippets/${id}.json"; })
|
||||
{
|
||||
nix = [ "nix" ];
|
||||
rust = [ "rust" ];
|
||||
tex = [ "tex" ];
|
||||
};
|
||||
});
|
||||
|
||||
snippetsDir = pkgs.symlinkJoin {
|
||||
name = "luasnip-snippets";
|
||||
paths = (lib.mapAttrsToList
|
||||
(ft: content: pkgs.writeTextDir "snippets/${ft}.json" (builtins.toJSON content))
|
||||
snippets) ++ (lib.singleton snippetsIndex);
|
||||
};
|
||||
in
|
||||
pkgs.writeText "snippets.lua" ''
|
||||
require("luasnip/loaders/from_vscode").load({ paths = { '${snippetsDir}' } })
|
||||
|
||||
require("luasnip/loaders/from_vscode").lazy_load() -- other snippets
|
||||
''
|
Loading…
Reference in New Issue