home-manager: Add neovim configuration

Signed-off-by: Christoph Heiss <christoph@c8h4.io>
This commit is contained in:
Christoph Heiss 2023-04-18 19:39:42 +02:00
parent 8d94745d9f
commit a0bcd443b7
Signed by: c8h4
GPG key ID: 6817E9C75C0785D7
6 changed files with 537 additions and 5 deletions

4
extra/nvim/init.lua Normal file
View file

@ -0,0 +1,4 @@
require('basic')
require('plugins')
require('autocmds')
require('mappings')

View file

@ -0,0 +1,83 @@
vim.api.nvim_create_autocmd({ 'FileType' }, {
pattern = { 'lua', 'html', 'nix' },
callback = function()
vim.opt_local.tabstop = 2
vim.opt_local.shiftwidth = 2
end,
})
vim.api.nvim_create_autocmd({ 'FileType' }, {
pattern = { 'gitsendemail', 'gitcommit', 'mail' },
callback = function()
vim.opt_local.textwidth = 72
vim.opt_local.colorcolumn = '73'
end,
})
vim.api.nvim_create_autocmd({ 'FileType' }, {
pattern = 'make',
callback = function()
vim.opt_local.expandtab = false
end,
})
vim.api.nvim_create_autocmd({ 'BufWritePre' }, {
pattern = '*',
callback = function()
if vim.bo.ft ~= 'diff' and vim.bo.ft ~= 'markdown' then
vim.cmd([[%s/\s\+$//e]])
end
end,
})
vim.api.nvim_create_autocmd({ 'TermEnter' }, {
pattern = '*',
callback = function()
vim.opt_local.scrolloff = 0
end,
})
vim.api.nvim_create_autocmd({ 'TermLeave' }, {
pattern = '*',
callback = function()
vim.opt_local.scrolloff = 5
end,
})
vim.api.nvim_create_autocmd({ 'BufReadPost' }, {
pattern = '*',
callback = function()
local line = vim.fn.line('\'"')
if line > 1 and line <= vim.fn.line('$') then
vim.cmd['normal!']('g`"')
end
end,
})
-- Automatically switch between absolute and relative line numbers when
-- entering insert mode
local numbertoggle_group = vim.api.nvim_create_augroup('numbertoggle', {})
vim.api.nvim_create_autocmd(
{ 'BufEnter', 'FocusGained', 'InsertLeave', 'WinEnter' },
{
pattern = '*',
group = numbertoggle_group,
callback = function()
if vim.fn.mode() ~= 'i' then
vim.opt.relativenumber = true
end
end,
}
)
vim.api.nvim_create_autocmd(
{ 'BufLeave', 'FocusLost', 'InsertEnter', 'WinLeave' },
{
pattern = '*',
group = numbertoggle_group,
callback = function()
vim.opt.relativenumber = false
end,
}
)

88
extra/nvim/lua/basic.lua Normal file
View file

@ -0,0 +1,88 @@
-- Basic setup
vim.g.mapleader = ','
vim.cmd.filetype('plugin', 'indent', 'on')
vim.cmd.syntax('on')
vim.opt.ruler = true
vim.opt.number = true
vim.opt.laststatus = 2
vim.opt.colorcolumn = '80,100,120'
vim.opt.autoread = true
vim.opt.showmode = false
vim.opt.shell = vim.env.SHELL or '/bin/sh'
vim.opt.clipboard:append('unnamedplus')
-- Modelines
vim.opt.modeline = true
vim.opt.modelines = 4
-- https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md
vim.opt.modelineexpr = false
-- Always use UTF-8
vim.opt.encoding = 'utf-8'
vim.opt.fileencoding = 'utf-8'
vim.opt.fileencodings = 'utf-8'
vim.opt.fileformats = 'unix,dos,mac'
-- Fix backspace indent
vim.opt.backspace = 'indent,eol,start'
-- Default indent settings
vim.opt.tabstop = 4
vim.opt.softtabstop = 0
vim.opt.shiftwidth = 4
vim.opt.expandtab = true
-- Hidden buffers
vim.opt.hidden = true
-- Searching options
vim.opt.hlsearch = true
vim.opt.incsearch = true
vim.opt.ignorecase = true
vim.opt.smartcase = true
-- Disable mouse support
vim.opt.mouse = ''
-- Disable netrw
vim.g.loaded_netrwPlugin = 0
-- Wildmenu
vim.opt.wildmenu = true
vim.opt.wildmode = 'list:longest,list:full'
vim.opt.wildignore:append(table.concat({
'*.o',
'*.so',
'*.swp',
'*.zip',
'*.tar',
'*.db',
'*.sqlite',
'*.obj',
'*.rbc',
'*.pyc',
'*.pdf',
'*.webp',
'*.png',
'*.jpg',
'*/.git/*',
'*/__pycache__/*',
'*/node_modules/*',
'*/tmp/*',
}, ','))
-- Host-specific config
if vim.fn.hostname() == 'maui' then
vim.opt.tabstop = 8
vim.opt.softtabstop = 4
vim.opt.shiftwidth = 4
vim.opt.textwidth = 100
vim.opt.noexpandtab = true
vim.opt.nocopyindent = true
vim.opt.autoindent = true
vim.opt.smartindent = true
vim.opt.cinoptions = '(0,u0,U0'
end

View file

@ -0,0 +1,35 @@
-- Dvorak layout remaps
vim.keymap.set('', 'd', '<left>')
vim.keymap.set('', 'h', '<down>')
vim.keymap.set('', 't', '<up>')
vim.keymap.set('', 'n', '<right>')
vim.keymap.set('', 'e', 'd')
vim.keymap.set('', '<C-e>', '<C-d>')
-- Split
-- Configure like tmux, which reverses the meaning of v- and h-splits
vim.keymap.set('', '<leader>v', '<cmd>split<cr>')
vim.keymap.set('', '<leader>b', '<cmd>vsplit<cr>')
-- Window navigation
vim.keymap.set('', '<C-d>', '<C-w>h')
vim.keymap.set('', '<C-h>', '<C-w>j')
vim.keymap.set('', '<C-t>', '<C-w>k')
vim.keymap.set('', '<C-n>', '<C-w>l')
-- Search
vim.keymap.set('n', '<leader><space>', '<cmd>nohlsearch<cr>')
vim.keymap.set('n', 'l', 'nzzzv')
vim.keymap.set('n', 'L', 'Nzzzv')
-- Maintain visual blocks when shifting
vim.keymap.set('v', '<', '<gv')
vim.keymap.set('v', '>', '>gv')
-- Move visual blocks down/up
vim.keymap.set('v', 'H', ":move '>+1<cr>gv=gv")
vim.keymap.set('v', 'T', ":move '<-2<cr>gv=gv")
-- Quitting
vim.keymap.set('n', '<leader>w', '<cmd>w<cr>')
vim.keymap.set('n', '<leader>q', '<cmd>wqall<cr>')

311
extra/nvim/lua/plugins.lua Normal file
View file

@ -0,0 +1,311 @@
local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
'git',
'clone',
'--filter=blob:none',
'https://github.com/folke/lazy.nvim.git',
'--branch=stable',
lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
vim.g.loaded_node_provider = 0
vim.g.loaded_perl_provider = 0
vim.g.loaded_ruby_provider = 0
require('lazy').setup({
{
'dracula/vim',
name = 'dracula',
priority = 100,
config = function()
vim.g.dracula_colorterm = 0
vim.cmd.colorscheme('dracula')
end,
},
{
'itchyny/lightline.vim',
config = function()
vim.g.lightline = {
enable = {
tabline = 0,
},
colorscheme = 'one',
active = {
left = {
{ 'mode', 'paste' },
{ 'readonly', 'filename', 'modified' },
{ 'gitbranch' },
},
},
component = {
gitbranch = '\226\142\135 %{FugitiveHead()}',
},
}
end,
},
{
'romgrk/barbar.nvim',
init = function()
vim.g.barbar_auto_setup = false
vim.keymap.set('n', '<Tab>', '<cmd>BufferNext<cr>')
vim.keymap.set('n', '<S-Tab>', '<cmd>BufferPrevious<cr>')
vim.keymap.set('n', '<leader><Tab>', '<cmd>BufferPick<cr>')
vim.keymap.set('n', '<leader><S-Tab>', '<cmd>BufferPickDelete<cr>')
vim.keymap.set('n', '<leader>c', '<cmd>BufferClose<cr>')
vim.keymap.set('n', '<S-t>', '<cmd>tabnew<cr>')
end,
opts = {
clickable = false,
icons = {
button = '',
filetype = { enabled = false },
pinned = {
button = '\240\159\147\140',
filename = true,
},
},
},
},
{
'tpope/vim-fugitive',
init = function()
vim.keymap.set('n', '<leader>ga', '<cmd>Git add -p<cr>')
vim.keymap.set('n', '<leader>gb', '<cmd>Git blame<cr>')
vim.keymap.set('n', '<leader>gd', '<cmd>Git diff<cr>')
vim.keymap.set('n', '<leader>gl', '<cmd>Git log --oneline<cr>')
end,
},
{ 'tpope/vim-commentary' },
{ 'Raimondi/delimitMate' },
{ 'editorconfig/editorconfig-vim', submodules = false },
{ 'easymotion/vim-easymotion' },
{
'airblade/vim-gitgutter',
init = function()
vim.keymap.set('n', '<leader>ht', '<Plug>(GitGutterPrevHunk)')
vim.keymap.set('n', '<leader>hh', '<Plug>(GitGutterNextHunk)')
vim.keymap.set('n', '<leader>hd', '<Plug>(GitGutterPreviewHunk)')
end,
},
{
'folke/persistence.nvim',
tag = 'v1.1.0',
opts = {
options = { 'buffers', 'curdir', 'tabpages', 'winsize', 'globals' },
pre_save = function()
vim.api.nvim_exec_autocmds('User', { pattern = 'SessionSavePre' })
end,
},
},
{
'junegunn/fzf.vim',
dependencies = { 'junegunn/fzf' },
init = function()
if vim.fn.executable('fzf') == 0 then
vim.notify(
'`fzf` not found in PATH, all fuzzy-find commands disabled',
vim.log.levels.WARN
)
return
end
vim.keymap.set('n', '<leader>b', '<cmd>Buffers<cr>')
vim.keymap.set('n', '<leader>y', '<cmd>History:<cr>')
vim.keymap.set('n', '<leader>s', '<cmd>BLines<cr>')
vim.keymap.set(
'n',
'<leader>u',
[[<cmd>call fzf#vim#files('', fzf#vim#with_preview({'sink': 'tabedit'}))<cr>]]
)
vim.keymap.set(
'n',
'<leader>e',
[[<cmd>call fzf#vim#gitfiles('', fzf#vim#with_preview({'sink': 'tabedit'}))<cr>]]
)
vim.keymap.set(
'n',
'<leader>m',
[[<cmd>call fzf#vim#gitfiles('?', fzf#vim#with_preview({'sink': 'tabedit'}))<cr>]]
)
if vim.fn.executable('rg') == 0 then
vim.notify(
'`rg` not found in PATH, fuzzy grep and optimized file search disabled',
vim.log.levels.WARN
)
else
vim.env.FZF_DEFAULT_COMMAND =
'rg --files --hidden --follow --glob "!.git/*"'
vim.keymap.set('n', '<leader>f', '<cmd>Rg<cr>')
end
end,
},
{
'Yggdroot/indentLine',
config = function()
vim.g.indentLine_concealcursor = ''
vim.g.indentLine_char = ''
vim.g.indentLine_faster = 1
end,
},
-- HTML
{ 'hail2u/vim-css3-syntax', ft = { 'css', 'sass', 'scss' } },
{ 'gko/vim-coloresque', ft = { 'html', 'sass', 'scss', 'less', 'yaml' } },
-- Perl
{ 'vim-perl/vim-perl', ft = 'perl' },
-- Rust
{ 'rust-lang/rust.vim', ft = 'rust' },
-- Nix
{ 'LnL7/vim-nix', ft = 'nix' },
-- Autocomplete
{
'hrsh7th/nvim-cmp',
dependencies = {
'neovim/nvim-lspconfig',
'hrsh7th/cmp-nvim-lsp',
'hrsh7th/cmp-buffer',
'hrsh7th/cmp-path',
'hrsh7th/cmp-cmdline',
'hrsh7th/cmp-nvim-lsp-signature-help',
'kdheepak/cmp-latex-symbols',
'saadparwaiz1/cmp_luasnip',
'rafamadriz/friendly-snippets',
{
'L3MON4D3/LuaSnip',
tag = 'v1.2.1',
submodules = false,
config = function()
require('luasnip.loaders.from_vscode').lazy_load()
end,
},
{ 'j-hui/fidget.nvim', config = true },
{
'f3fora/cmp-spell',
config = function()
vim.opt.spell = false
vim.opt.spelllang = 'en_us'
vim.keymap.set('n', '<leader>p', '<cmd>set spell!<cr>')
end,
},
{
'jose-elias-alvarez/null-ls.nvim',
config = function()
local null_ls = require('null-ls')
null_ls.setup({
sources = {
-- null_ls.builtins.formatting.stylua,
},
})
end,
},
{
'simrat39/rust-tools.nvim',
ft = 'rust',
opts = {
tools = {
inlay_hints = {
auto = true,
},
},
server = {
settings = {
['rust-analyzer'] = {
checkOnSave = {
command = 'clippy',
},
},
},
},
},
},
{
'saecki/crates.nvim',
tag = 'v0.3.0',
dependencies = { 'nvim-lua/plenary.nvim' },
config = function()
local crates = require('crates')
vim.keymap.set('n', '<leader>rv', crates.show_versions_popup)
vim.keymap.set('n', '<leader>rf', crates.show_features_popup)
vim.keymap.set('n', '<leader>ri', crates.open_crates_io)
crates.setup({
popup = {
autofocus = true,
},
})
end,
},
},
config = function()
local cmp = require('cmp')
cmp.setup({
snippet = {
expand = function(args)
require('luasnip').lsp_expand(args.body)
end,
},
window = {
completion = cmp.config.window.bordered(),
documentation = cmp.config.window.bordered(),
},
mapping = cmp.mapping.preset.insert({
['<C-t>'] = cmp.mapping.scroll_docs(-5),
['<C-h>'] = cmp.mapping.scroll_docs(5),
['<Tab>'] = cmp.mapping.select_next_item(),
['<S-Tab>'] = cmp.mapping.select_prev_item(),
['<C-cr>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<cr>'] = cmp.mapping.confirm({ select = true }),
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
{ name = 'nvim_lsp_signature_help' },
{ name = 'luasnip' },
{ name = 'crates' },
}, {
{ name = 'buffer' },
}),
})
cmp.setup.cmdline(':', {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = 'path' },
}, {
{ name = 'cmdline' },
}),
})
vim.opt.completeopt = 'menuone,noinsert,noselect'
vim.opt.shortmess:append('c')
end,
},
})
-- Fix color scheme collision
vim.cmd.highlight('comment', 'ctermfg=7')
-- Bring modified buffers to attention
vim.cmd['highlight!']('BufferInactiveMod', 'cterm=bold')
vim.cmd['highlight!']('BufferCurrentMod', 'cterm=bold')

View file

@ -5,6 +5,11 @@ let
package = pkgs.apple-cursor;
name = "macOS-Monterey";
};
nvimLuaModuleNames = [ "basic" "plugins" "autocmds" "mappings" ];
nvimLuaModules = builtins.listToAttrs (map (m: {
name = "nvim/lua/${m}.lua";
value.source = ../../extra/nvim/lua + "/${m}.lua";
}) nvimLuaModuleNames);
in {
home-manager.users.christoph = {
imports = [ ./email.nix ./sway.nix ./terminal.nix ];
@ -45,6 +50,9 @@ in {
};
};
# Needed by the luasnip plugin
programs.neovim.extraLuaPackages = luaPkgs: with luaPkgs; [ jsregexp ];
programs.ssh = {
enable = true;
matchBlocks."*" = {
@ -90,10 +98,13 @@ in {
pinentryFlavor = "tty";
};
xdg.configFile."latexmk/latexmkrc".text = ''
$pdf_previewer = '${pkgs.zathura}/bin/zathura';
$latex = 'latex -interaction=nonstopmode';
$pdflatex = 'pdflatex -interaction=nonstopmode';
'';
xdg.configFile = {
"latexmk/latexmkrc".text = ''
$pdf_previewer = '${pkgs.zathura}/bin/zathura';
$latex = 'latex -interaction=nonstopmode';
$pdflatex = 'pdflatex -interaction=nonstopmode';
'';
"nvim/init.lua".source = ../../extra/nvim/init.lua;
} // nvimLuaModules;
};
}