~piotr-machura/dotfiles

1ffb9b11305131e0b605618be195ad03ecd3ef2e — Piotr Machura a month ago 2107e75
Remove Neovim in favor of Kakoune
43 files changed, 5 insertions(+), 1425 deletions(-)

M .bashrc
M .config/ipython/profile_default/ipython_config.py
D .config/nvim/after/ftdetect/c.vim
D .config/nvim/after/ftdetect/cmdwin.vim
D .config/nvim/after/ftdetect/license.vim
D .config/nvim/after/ftdetect/prose.vim
D .config/nvim/after/ftdetect/terminal.vim
D .config/nvim/after/ftplugin/c.lua
D .config/nvim/after/ftplugin/clojure.lua
D .config/nvim/after/ftplugin/cmdwin.lua
D .config/nvim/after/ftplugin/css.lua
D .config/nvim/after/ftplugin/gitcommit.lua
D .config/nvim/after/ftplugin/go.lua
D .config/nvim/after/ftplugin/html.lua
D .config/nvim/after/ftplugin/java.lua
D .config/nvim/after/ftplugin/javascript.lua
D .config/nvim/after/ftplugin/json.lua
D .config/nvim/after/ftplugin/kotlin.lua
D .config/nvim/after/ftplugin/license.lua
D .config/nvim/after/ftplugin/lua.lua
D .config/nvim/after/ftplugin/markdown.lua
D .config/nvim/after/ftplugin/mdx.lua
D .config/nvim/after/ftplugin/prose.lua
D .config/nvim/after/ftplugin/python.lua
D .config/nvim/after/ftplugin/qf.lua
D .config/nvim/after/ftplugin/rust.lua
D .config/nvim/after/ftplugin/scss.lua
D .config/nvim/after/ftplugin/sh.lua
D .config/nvim/after/ftplugin/tex.lua
D .config/nvim/after/ftplugin/text.lua
D .config/nvim/after/ftplugin/typescript.lua
D .config/nvim/after/ftplugin/vim.lua
D .config/nvim/after/ftplugin/xml.lua
D .config/nvim/after/ftplugin/yaml.lua
D .config/nvim/after/indent/clojure.lua
D .config/nvim/after/syntax/nginx.lua
D .config/nvim/init.lua
D .config/nvim/lua/servers.lua
D .config/nvim/stylua.toml
M .local/share/pacman/aur.txt
D .local/share/pacman/packages/neovim-symlinks/PKGBUILD
M .local/share/pacman/pkg.txt
M .profile
M .bashrc => .bashrc +1 -2
@@ 26,8 26,7 @@ alias serve='python3 -m http.server --directory'
alias pdb='python3 -m pdb'

pacclean() {
    pacman -Qdtq --noconfirm |
        sudo pacman -Rns -
    pacman -Qdtq --noconfirm | sudo pacman -Rns -
    paru -Sc --noconfirm
}


M .config/ipython/profile_default/ipython_config.py => .config/ipython/profile_default/ipython_config.py +2 -0
@@ 21,6 21,8 @@ c.TerminalInteractiveShell.term_title = True
c.TerminalInteractiveShell.term_title_format = 'IPython ' + sys.version.split(' ')[0]
c.TerminalInteractiveShell.true_color = False
c.InteractiveShellApp.exec_lines = [
    'import matplotlib',
    'matplotlib.interactive(True)',
    'from matplotlib import pyplot as plt',
    'import numpy as np',
]

D .config/nvim/after/ftdetect/c.vim => .config/nvim/after/ftdetect/c.vim +0 -3
@@ 1,3 0,0 @@
" C HEADER FILETYPE DETECTION
" ---------------------------
autocmd BufRead,BufNewFile *.h setfiletype c

D .config/nvim/after/ftdetect/cmdwin.vim => .config/nvim/after/ftdetect/cmdwin.vim +0 -3
@@ 1,3 0,0 @@
" CMD FILETYPE DETECTION
" ----------------------
autocmd CmdWinEnter * setfiletype cmdwin

D .config/nvim/after/ftdetect/license.vim => .config/nvim/after/ftdetect/license.vim +0 -3
@@ 1,3 0,0 @@
" LICENSE FILETYPE DETECTION
" --------------------------
autocmd BufRead,BufNewFile LICENSE,COPYING,LICENSE-*,COPYRIGHT setfiletype license

D .config/nvim/after/ftdetect/prose.vim => .config/nvim/after/ftdetect/prose.vim +0 -5
@@ 1,5 0,0 @@
" PROSE FILETYPE DETECTION
" ------------------------
autocmd BufRead,BufNewFile *.txt if isdirectory(expand('%:p:h').'/.words')
  \| setfiletype prose
  \| endif

D .config/nvim/after/ftdetect/terminal.vim => .config/nvim/after/ftdetect/terminal.vim +0 -10
@@ 1,10 0,0 @@
" TERMINAl FILETYPE DETECTION
" ---------------------------
autocmd TermOpen * if empty(&ft)
    \| setfiletype terminal
    \| setlocal nonumber signcolumn=no
    \| startinsert
    \| endif
autocmd TermClose * if !v:event.status
    \| exe 'bdelete! '..expand('<abuf>')
    \| endif

D .config/nvim/after/ftplugin/c.lua => .config/nvim/after/ftplugin/c.lua +0 -19
@@ 1,19 0,0 @@
-- C/CPP FTPLUGIN
-- ----------
lopt.formatprg = 'indent -linux'
lopt.expandtab = false
lopt.shiftwidth = 4
lopt.tabstop = 4
lopt.textwidth = 80
gopt.wildignore:append({
  '*.o',
  '*.o.d',
  '*.epp',
  '*.elf',
  '*.hex',
  '*.lst',
  '*.map',
  '*.sym',
  '*.lss',
  '*.eep',
})

D .config/nvim/after/ftplugin/clojure.lua => .config/nvim/after/ftplugin/clojure.lua +0 -3
@@ 1,3 0,0 @@
-- CLOJURE FTPLUGIN
-- ----------------
lopt.lisp = true

D .config/nvim/after/ftplugin/cmdwin.lua => .config/nvim/after/ftplugin/cmdwin.lua +0 -4
@@ 1,4 0,0 @@
-- CMD WINDOW FTPLUGIN
-- -------------------

lopt.number = false

D .config/nvim/after/ftplugin/css.lua => .config/nvim/after/ftplugin/css.lua +0 -6
@@ 1,6 0,0 @@
-- CSS FTPLUGIN
-- ------------
lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2
lopt.formatprg = 'prettier --single-quote --trailing-comma es5 --stdin-filepath "%"'

D .config/nvim/after/ftplugin/gitcommit.lua => .config/nvim/after/ftplugin/gitcommit.lua +0 -3
@@ 1,3 0,0 @@
-- GIT COMMIT FTPLUGIN
-- -------------------
lopt.spell = true

D .config/nvim/after/ftplugin/go.lua => .config/nvim/after/ftplugin/go.lua +0 -5
@@ 1,5 0,0 @@
-- GO FTPLUGIN
-- -----------
lopt.expandtab = false
lopt.tabstop = 4
cmd([[compiler go]])

D .config/nvim/after/ftplugin/html.lua => .config/nvim/after/ftplugin/html.lua +0 -6
@@ 1,6 0,0 @@
-- HTML FTPLUGIN
-- -------------
lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2
lopt.formatprg = 'prettier --single-quote --trailing-comma es5 --stdin-filepath "%"'

D .config/nvim/after/ftplugin/java.lua => .config/nvim/after/ftplugin/java.lua +0 -4
@@ 1,4 0,0 @@
-- JAVA FTPLUGIN
-- -------------
lopt.path = { 'src/**' }
cmd([[compiler mvn]])

D .config/nvim/after/ftplugin/javascript.lua => .config/nvim/after/ftplugin/javascript.lua +0 -7
@@ 1,7 0,0 @@
-- JAVASCRIPT FTPLUGIN
-- -------------------
gopt.wildignore:append('node_modules')
lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2
lopt.formatprg = 'prettier --single-quote --trailing-comma es5 --stdin-filepath "%"'

D .config/nvim/after/ftplugin/json.lua => .config/nvim/after/ftplugin/json.lua +0 -5
@@ 1,5 0,0 @@
-- JSON FTPLUGIN
-- -------------
lopt.conceallevel = 2
lopt.formatprg = 'prettier --single-quote --trailing-comma es5 --stdin-filepath "%"'
g.vim_json_syntax_conceal = 1

D .config/nvim/after/ftplugin/kotlin.lua => .config/nvim/after/ftplugin/kotlin.lua +0 -5
@@ 1,5 0,0 @@
-- KOTLIN FTPLUGIN
-- ---------------
lopt.shiftwidth = 4
lopt.path = { 'src/**' }
cmd([[compiler mvn]])

D .config/nvim/after/ftplugin/license.lua => .config/nvim/after/ftplugin/license.lua +0 -9
@@ 1,9 0,0 @@
-- LICENSE FTPLUGIN
-- ----------------
local ind = g.indent_blankline_filetype_exclude
ind[#ind + 1] = 'license'
g.indent_blankline_filetype_exclude = ind

local hex = g.Hexokinase_ftDisabled or {}
hex[#hex + 1] = 'license'
g.Hexokinase_ftDisabled = hex

D .config/nvim/after/ftplugin/lua.lua => .config/nvim/after/ftplugin/lua.lua +0 -7
@@ 1,7 0,0 @@
-- LUA FTPLUGIN
-- ------------
lopt.formatprg = 'stylua -'
lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2
lopt.textwidth = 100

D .config/nvim/after/ftplugin/markdown.lua => .config/nvim/after/ftplugin/markdown.lua +0 -16
@@ 1,16 0,0 @@
-- MARKDOWN FTPLUGIN
-- -----------------
lopt.spell = true
lopt.textwidth = 88
lopt.list = false
lopt.equalprg = ''
lopt.makeprg = ''
lopt.softtabstop = 4
lopt.shiftwidth = 4

local ind = g.indent_blankline_filetype_exclude
ind[#ind + 1] = 'markdown'
g.indent_blankline_filetype_exclude = ind

g.vim_markdown_math = 1
g.tex_conceal = 'db'

D .config/nvim/after/ftplugin/mdx.lua => .config/nvim/after/ftplugin/mdx.lua +0 -3
@@ 1,3 0,0 @@
-- MDX FTPLUGIN
-- ------------
lopt.path = { '', 'src/**', 'public/**' }

D .config/nvim/after/ftplugin/prose.lua => .config/nvim/after/ftplugin/prose.lua +0 -61
@@ 1,61 0,0 @@
-- PROSE FTPLUGIN
-- --------------
lopt.autoindent = false
lopt.breakindent = false
lopt.smartindent = false
lopt.cindent = false
lopt.breakindent = false

lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2

lopt.wrap = true
lopt.linebreak = true
lopt.scrolloff = 0
lopt.list = false
lopt.number = false
lopt.relativenumber = false
lopt.spell = true
lopt.expandtab = false

lopt.spellfile = fn.expand('%:p:h') .. '/.words/utf-8.add'
if fn.filereadable(lopt.spellfile:get()[1] .. '.spl') == 0 then
  cmd('silent! mkspell ' .. lopt.spellfile:get()[1])
end

cmd([[inoreabbrev <buffer> -- –]])
bnoremap('', 'j', 'gj', { noremap = true })
bnoremap('', 'k', 'gk', { noremap = true })
bnoremap('', '<Down>', 'g<Down>', { noremap = true })
bnoremap('', '<Up>', 'g<Up>', { noremap = true })

local ind = g.indent_blankline_filetype_exclude
ind[#ind + 1] = 'prose'
g.indent_blankline_filetype_exclude = ind

local hex = g.Hexokinase_ftDisabled or {}
hex[#hex + 1] = 'prose'
g.Hexokinase_ftDisabled = hex

function fix_formatting()
  cmd([[
        let c_line = line('.')
        let c_col = col('.')
        silent! keepjumps %s/\.\.\./…/g
        silent! keepjumps %s/’/'/g
        silent! keepjumps %s/\n\n\n/\r\r/g
        silent! keepjumps %s/”\|„\|''\|,,/"/g
        silent! keepjumps %s/\t- \|\t― /\t– /g
        silent! keepjumps %s/ - \| ― \| -- / – /g
        silent! keepjumps %s/[\x0]//g
        call cursor(c_line, c_col)
    ]])
end

cmd([[command! -buffer FixFormatting lua fix_formatting()]])

cmd([[
    syntax match TODO '&&&'
    syntax match ERROR '%%%'
]])

D .config/nvim/after/ftplugin/python.lua => .config/nvim/after/ftplugin/python.lua +0 -7
@@ 1,7 0,0 @@
-- PYTHON FTPLUGIN
-- ---------------
gopt.wildignore:append({ '__pycache__', '*.pyc', '.venv' })
g.python_highlight_all = 1
g.python_highlight_space_errors = 0
lopt.makeprg = 'poetry run'
lopt.textwidth = 88

D .config/nvim/after/ftplugin/qf.lua => .config/nvim/after/ftplugin/qf.lua +0 -6
@@ 1,6 0,0 @@
-- QUICKFIX FTPLUGIN
-- -----------------
cmd('execute "normal 8\\<C-w>_"')
lopt.number = false
lopt.spell = false
lopt.buflisted = false

D .config/nvim/after/ftplugin/rust.lua => .config/nvim/after/ftplugin/rust.lua +0 -3
@@ 1,3 0,0 @@
-- RUST FTPLUGIN
-- -------------
lopt.path = { '', '.', 'src/**', 'tests/**', 'examples/**' }

D .config/nvim/after/ftplugin/scss.lua => .config/nvim/after/ftplugin/scss.lua +0 -7
@@ 1,7 0,0 @@
-- SCSS FTPLUGIN
-- -------------
lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2
lopt.formatprg = 'prettier --single-quote --trailing-comma es5 --stdin-filepath "%"'
cmd([[highlight! link cssBraceError NormalNC]])

D .config/nvim/after/ftplugin/sh.lua => .config/nvim/after/ftplugin/sh.lua +0 -9
@@ 1,9 0,0 @@
-- BASH FTPLUGIN
-- -------------
lopt.makeprg = 'shellcheck -f gcc $* %:S'
lopt.errorformat = {
  '%f:%l:%c: %trror: %m',
  '%f:%l:%c: %tarning: %m',
  '%I%f:%l:%c: note: %m',
}
lopt.formatprg = 'shfmt -i 4 -'

D .config/nvim/after/ftplugin/tex.lua => .config/nvim/after/ftplugin/tex.lua +0 -10
@@ 1,10 0,0 @@
-- TEX FTPLUGIN
-- ------------
lopt.textwidth = 100
lopt.spell = true
g.tex_conceal = 'db'
cmd([[
  highlight! link texError Normal
]])
lopt.makeprg = 'tectonic -X -c minimal'
lopt.errorformat = { '%tote: %m', '%trror: %f:%l: %m ', '%tarning: %f:%l: %m' }

D .config/nvim/after/ftplugin/text.lua => .config/nvim/after/ftplugin/text.lua +0 -9
@@ 1,9 0,0 @@
-- TEXT FTPLUGIN
-- -------------
local ind = g.indent_blankline_filetype_exclude
ind[#ind + 1] = 'prose'
g.indent_blankline_filetype_exclude = ind

local hex = g.Hexokinase_ftDisabled or {}
hex[#hex + 1] = 'prose'
g.Hexokinase_ftDisabled = hex

D .config/nvim/after/ftplugin/typescript.lua => .config/nvim/after/ftplugin/typescript.lua +0 -4
@@ 1,4 0,0 @@
-- TYPESCRIPT FTPLUGIN
-- -------------------
lopt.path = { '', 'public/**', 'src/**' }
cmd([[runtime! after/ftplugin/javascript.lua]])

D .config/nvim/after/ftplugin/vim.lua => .config/nvim/after/ftplugin/vim.lua +0 -3
@@ 1,3 0,0 @@
-- VIM FTPLUGIN
-- ------------
lopt.modeline = false

D .config/nvim/after/ftplugin/xml.lua => .config/nvim/after/ftplugin/xml.lua +0 -5
@@ 1,5 0,0 @@
-- XML FTPLUGIN
-- ------------
lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2

D .config/nvim/after/ftplugin/yaml.lua => .config/nvim/after/ftplugin/yaml.lua +0 -6
@@ 1,6 0,0 @@
-- YAML FTPLUGIN
-- -------------
lopt.shiftwidth = 2
lopt.tabstop = 2
lopt.softtabstop = 2
lopt.formatprg = 'prettier --single-quote --trailing-comma es5 --stdin-filepath "%"'

D .config/nvim/after/indent/clojure.lua => .config/nvim/after/indent/clojure.lua +0 -3
@@ 1,3 0,0 @@
-- CLOJURE INDENT
-- --------------
lopt.shiftwidth = 1

D .config/nvim/after/syntax/nginx.lua => .config/nvim/after/syntax/nginx.lua +0 -3
@@ 1,3 0,0 @@
-- NGINX FTPLUGIN
-- --------------
cmd('hi! link ngxGzipOn ngxGzipOff')

D .config/nvim/init.lua => .config/nvim/init.lua +0 -1011
@@ 1,1011 0,0 @@
-- --------------------
-- NEOVIM EDITOR CONFIG
-- --------------------
g = vim.g
b = vim.b
fn = vim.fn
cmd = vim.cmd
api = vim.api
opt = vim.opt
lopt = vim.opt_local
gopt = vim.opt_global
lsp = vim.lsp
diagnostic = vim.diagnostic

-- OPTIONS
-- -------
opt.number = true
opt.relativenumber = false
opt.cursorline = false
opt.signcolumn = 'yes'
opt.ruler = false
opt.wrap = false

opt.hidden = true
opt.splitbelow = true
opt.splitright = true
opt.equalalways = false

gopt.expandtab = true
gopt.shiftround = true
gopt.softtabstop = 4
gopt.tabstop = 4
gopt.shiftwidth = 4

opt.updatetime = 50
opt.shortmess:append('cI')

opt.path:append({ '.', '**' })
opt.wildignore:append({ '.git', '.cache' })

opt.ignorecase = true
opt.smartcase = true

opt.undofile = true
opt.undolevels = 500
opt.autowrite = true

opt.conceallevel = 2
opt.concealcursor = ''
opt.switchbuf = 'usetab'

opt.mouse = 'ar'
opt.clipboard:append('unnamedplus')
opt.foldmethod = 'syntax'
opt.virtualedit = 'block'

opt.scrolloff = 1
opt.sidescrolloff = 4

opt.guifont = 'JetBrains Mono NL Medium:h11.5'
opt.grepprg = 'rg --line-number --column'
opt.grepformat = '%f:%l:%c:%m'
opt.pumheight = 15
opt.completeopt = { 'menuone', 'longest', 'noselect' }

opt.list = true
opt.listchars = {
  tab = ' ',
  trail = '·',
  extends = '',
  precedes = '',
}
opt.fillchars = {
  eob = ' ',
  fold = ' ',
  stl = '-',
  stlnc = '-',
  vert = '╎',
}

if fn.isdirectory(fn.stdpath('data') .. '/site/spell') == 0 then
  fn.mkdir(fn.stdpath('data') .. '/site/spell')
end
opt.spellsuggest:append('5')
opt.spelllang = { 'pl', 'en_us' }
opt.spellfile = fn.stdpath('data') .. '/site/spell/utf-8.add'

cmd([[
  augroup init_lua
  autocmd!
  augroup END

  au init_lua FileType * setlocal nofoldenable
  au init_lua BufWinEnter * setlocal fo-=c fo-=r fo-=o
  au init_lua TextYankPost * silent! lua yank_hl()
  au init_lua BufWritePre,FileWritePre * silent! call mkdir(expand('<afile>:p:h'), 'p')
]])

g.loaded_netrw = 1
g.loaded_netrwPlugin = 1

-- MAPPINGS
-- --------
map = api.nvim_set_keymap
bmap = api.nvim_buf_set_keymap

function noremap(mode, lhs, rhs)
  map(mode, lhs, rhs, { noremap = true })
end

function bnoremap(mode, lhs, rhs)
  bmap(0, mode, lhs, rhs, { noremap = true })
end

function termc(key)
  return api.nvim_replace_termcodes(key, true, true, true)
end

function feedkey(key, mode)
  api.nvim_feedkeys(termc(key), mode, true)
end

g.mapleader = termc('<Space>')
-- QoL
noremap('n', 'Y', 'y$')
noremap('n', 'Q', '@q')
noremap('n', 'ZZ', '<CMD>update<Bar>bdelete!<CR>')
noremap('n', '<BS>', '"_')
noremap('n', '[<Space>', 'O<ESC>')
noremap('n', ']<Space>', 'o<ESC>')
noremap('n', '<C-j>', 'a<CR><ESC>')
noremap('', '=', '<CMD>lua format_buffer()<CR>')
noremap('n', '<C-l>', '<CMD>noh<Bar>IndentBlanklineRefresh<CR><CMD>lua wipe_empty()<CR><C-l>')
noremap('n', '<C-n>', ':%s/<C-r>=expand("<cword>")<CR>//gc<Left><Left><Left>')
noremap('n', '<C-h>', '<CMD>echo synIDattr(synID(line("."), col("."), 1), "name")<CR>')

-- Disable mouse
noremap('n', '<MiddleMouse>', '<Nop>')
noremap('i', '<MiddleMouse>', '<Nop>')
noremap('c', '<MiddleMouse>', '<Nop>')

-- Window resizing
noremap('n', '<C-w><', '<C-w>10<')
noremap('n', '<C-w>>', '<C-w>10>')
noremap('n', '<C-w>-', '<C-w>5-')
noremap('n', '<C-w>+', '<C-w>5+')
noremap('n', '<C-w><C-t>', '<C-w>g<Tab>')
noremap('n', '<C-w><C-^>', '<C-w>v<C-^>')

-- Navigation
noremap('n', ']b', '<CMD>bnext<CR>')
noremap('n', '[b', '<CMD>bprev<CR>')
noremap('n', '[l', '<CMD>lprev<CR>')
noremap('n', ']l', '<CMD>lnext<CR>')
noremap('n', 'gl', '<CMD>lwindow<CR>')
noremap('n', '[q', '<CMD>cprev<CR>')
noremap('n', ']q', '<CMD>cnext<CR>')
noremap('n', 'gq', '<CMD>cwindow<CR>')

-- Terminal
noremap('t', '<C-w>', '<C-\\><C-n><C-w>')
noremap('t', '<C-a>', '<C-\\><C-n>')

-- FUNCTIONS
-- ---------
function check_bs()
  local line, col = unpack(api.nvim_win_get_cursor(0))
  local prevchar = api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col)
  return col == 0 or prevchar:match('%s') ~= nil
end

function format_buffer()
  local c_line = fn.line('.')
  local c_col = fn.col('.')
  local msg = ''
  -- Prioritize formaptprg
  local fmt = opt.formatprg:get()
  if fmt ~= '' then
    cmd([[silent! keepjumps normal! gggqG]])
    msg = msg .. 'Formatted with ' .. fmt:gsub(' .*', '') .. '. '
  end
  -- Use equalprg too if it's not the same as formaptprg
  local eq = opt.equalprg:get()
  if eq ~= '' and eq ~= fmt then
    cmd([[silent! keepjumps normal! gg=G]])
    msg = msg .. 'Reindented with ' .. eq:gsub(' .*', '') .. '. '
  end
  -- LSP as fallback
  if msg == '' and lsp.buf.server_ready() then
    lsp.buf.formatting()
    msg = msg .. 'Formatted buffer with LSP. '
  end
  -- Strip trailing whitespace
  cmd([[keepjumps keeppatterns %s/\s\+$//e]])
  cmd([[keepjumps keeppatterns silent! 0;/^\%(\n*.\)\@!/,$d]])
  cmd([[nohlsearch]])
  local end_row = fn.line('$')
  if c_line > end_row then
    c_line = end_row
  end
  msg = msg .. 'Stripped trailing whitespace.'
  print(msg)
  fn.cursor(c_line, c_col)
end

function wipe_empty()
  local con = function(_, bnr)
    if fn.buflisted(bnr) ~= 1 or fn.bufwinnr(bnr) > 0 then
      return false
    end
    local lines = fn.getbufline(bnr, 1, '$')
    return #lines == 1 and lines[1] == ''
  end
  local buffers = fn.filter(fn.range(1, fn.bufnr('$')), con)
  if #buffers ~= 0 then
    cmd('bwipeout ' .. fn.join(buffers, ' '))
  end
end

function yank_hl()
  vim.highlight.on_yank({
    on_visual = false,
    higroup = 'MatchParen',
    timeout = 350,
  })
end

-- STATUSLINE
-- ----------
function statusline()
  local bnr = fn.winbufnr(g.statusline_winid)
  local winnr = g.statusline_winid
  local cur = (winnr == fn.win_getid())
  local text = (cur and '%#StatusLineCT#' or '%#StatusLineNCT#')
  local ft = fn.getbufvar(bnr, '&ft')

  -- Special statusline
  if ft == 'alpha' then
    return '%*'
  elseif ft == 'terminal' then
    local termtitle = fn.getbufvar(bnr, 'term_title')
    return '%=' .. text .. '  Terminal: ' .. termtitle:gsub(string.char(0x07), '') .. ' %*%='
  elseif ft == 'help' then
    return '%=' .. text .. '  Help: ' .. fn.fnamemodify(fn.bufname(bnr), ':t') .. ' %*%='
  elseif ft == 'man' then
    return '%=' .. text .. '  Man: ' .. fn.fnamemodify(fn.bufname(bnr), ':t') .. ' %*%='
  elseif ft == 'cmdwin' then
    return '%=' .. text .. '  Command %*%='
  elseif ft == 'packer' then
    return '%=' .. text .. '  Plugins %*%='
  elseif ft == 'diff' then
    local status = fn.execute([[echon t:diffpanel.GetStatusLine()]])
    return '%=' .. text .. ' ' .. status .. ' %*%='
  elseif ft == 'undotree' then
    local status = fn.execute([[echon t:undotree.GetStatusLine()]])
    status = status:gsub('current:', ''):gsub('redo:', ':')
    return '%=' .. text .. ' ' .. status .. ' %*%='
  elseif ft == 'qf' then
    local qftitle = fn.getwinvar(winnr, 'quickfix_title')
    if fn.len(qftitle) ~= 0 then
      return '%=' .. text .. '   Quickfix: ' .. qftitle .. ' %*%='
    else
      return '%=' .. text .. '   Quickfix %*%='
    end
  end

  local stl = text .. '['
  -- Buffer name
  local name = fn.bufname(bnr)
  name = (name == '' and 'No name' or fn.fnamemodify(name, ':~:.'))
  local modifiable = fn.getbufvar(bnr, '&modifiable')
  if fn.getbufvar(bnr, '&readonly') == 1 and modifiable == 1 then
    stl = stl .. (cur and '%#StatusLineRO#' or '') .. ' '
  end
  stl = stl .. (cur and '%#StatusLineFname#' or '') .. name .. text
  -- Modified
  if fn.getbufvar(bnr, '&modified') == 1 and modifiable ~= 0 then
    stl = stl .. (cur and '%#StatusLineModified#' or '') .. '  ' .. text
  end
  stl = stl .. ']%*%='
  -- LSP
  if fn.winwidth(winnr) > 80 then
    local msgs = ''
    for d, s in pairs({ Error = '', Warn = '', Info = '', Hint = '' }) do
      local count = #diagnostic.get(bnr, { severity = d })
      if count > 0 then
        msgs = msgs .. (cur and '%#Diagnostic' .. d .. '#' or '')
        msgs = msgs .. ' ' .. s .. ' %*' .. text .. count
      end
    end
    if #msgs > 0 then
      stl = stl .. msgs .. ' '
    end
  end
  -- Columns/lines
  stl = stl .. text .. '['
  stl = stl .. (cur and '%#StatusLinelines#%l%*' or '%l')
  stl = stl .. text .. ':' .. (cur and '%#StatusLineCols#%c%*' or '%c') .. text .. ']%<'
  return stl
end
opt.laststatus = 2
opt.statusline = '%!luaeval("statusline()")'
cmd("au init_lua BufWinEnter,FileType * setlocal stl=%!luaeval('statusline()')")

-- TABLINE
-- -------
function tabline()
  local tabline = '%>%#TabLineFill#%='
  for _, i in pairs(fn.range(fn.tabpagenr('$'))) do
    if i + 1 == fn.tabpagenr() then
      tabline = tabline .. '%#TabLineSel#'
    else
      tabline = tabline .. '%#TabLine#'
    end
    tabline = tabline .. '%' .. (i + 1) .. 'T ' .. (i + 1) .. ' '
  end
  return tabline
end
opt.showtabline = 1
opt.tabline = '%!luaeval("tabline()")'

-- TITLE
-- -----
function titlestring()
  local start = 'NVIM: '
  local ft = opt.filetype:get()
  if ft == 'alpha' then
    return start .. fn.getcwd():gsub(vim.env.HOME, '~')
  elseif ft == 'packer' then
    return start .. 'Plugins'
  elseif ft == 'undotree' then
    return start .. 'Undotree'
  elseif ft == 'fzf' then
    return start .. 'Skim'
  elseif ft == 'registers' then
    return start .. 'Registers'
  elseif ft == 'man' then
    return start .. 'Man: ' .. fn.expand('%:t')
  elseif ft == 'diff' then
    return start .. 'Diff panel'
  elseif ft == 'qf' then
    return start .. 'Quickfix'
  elseif ft == 'help' then
    return start .. 'Help: ' .. fn.expand('%:t')
  elseif ft == 'terminal' then
    return start .. 'Terminal: ' .. vim.b.term_title
  elseif ft == 'cmdwin' then
    return start .. 'Commands'
  end
  local name = fn.expand('%:~:.')
  name = (name == '' and 'No name' or name)
  return start .. name
end
opt.title = true
opt.titlelen = 0
opt.titlestring = '%{luaeval("titlestring()")}'

-- FOLD TEXT
-- ---------
function foldtext()
  local line = fn.getline(vim.v.foldstart)
  local foldedlinecount = vim.v.foldend - vim.v.foldstart + 1
  return ' ' .. line .. '   (' .. foldedlinecount .. ' lines)'
end
opt.foldtext = 'luaeval("foldtext()")'

-- PLUGINS
-- -------

-- Auto-install packer
local packer_path = fn.stdpath('data') .. '/site/pack/packer/start/packer.nvim'
if fn.isdirectory(packer_path) == 0 then
  packer_bootstrap = fn.system({
    'git',
    'clone',
    '--depth',
    '1',
    'https://github.com/wbthomason/packer.nvim',
    packer_path,
  })
end

local use = require('packer').use

require('packer').startup({
  function()
    -- PACKER
    -- ------
    use({ 'wbthomason/packer.nvim' })

    -- LANGUAGE PACK
    -- -------------
    use({ 'sheerun/vim-polyglot' })

    -- MINI
    -- ----
    use({
      'echasnovski/mini.nvim',
      config = function()
        require('mini.jump').setup()
        require('mini.pairs').setup()
        require('mini.misc').setup()
        require('mini.comment').setup({
          mappings = {
            comment = 'gc',
            comment_line = 'gcc',
            textobject = 'c',
          },
        })
        require('mini.surround').setup({
          highlight_duration = 2000,
          mappings = {
            add = 'gsa',
            delete = 'gsd',
            replace = 'gsc',
            highlight = 'gsh',
            find = 'gsf',
            find_left = 'gsF',
            update_n_lines = '',
          },
        })

        -- COLORSCHEME
        require('mini.base16').setup({
          palette = {
            base00 = '#000000',
            base01 = '#303030',
            base02 = '#505050',
            base03 = '#b0b0b0',
            base04 = '#d0d0d0',
            base05 = '#e0e0e0',
            base06 = '#f5f5f5',
            base07 = '#ffffff',
            base08 = '#fb0120',
            base09 = '#fc6d24',
            base0A = '#fda331',
            base0B = '#a1c659',
            base0C = '#76c7b7',
            base0D = '#6fb3d2',
            base0E = '#d381c3',
            base0F = '#be643c',
          },
          use_cterm = false,
        })

        g.terminal_color_0 = MiniBase16.config.palette['base01']
        opt.termguicolors = true
        cmd([[
          hi PMenuSel guibg=#505050 guifg=#76c7b7
          hi TabLineFill guibg=None
          hi Folded gui=bold guibg=#303030 guifg=#b0b0b0
          hi! link QuickFixLine CursorLine
          hi! link Search PMenuSel
          hi! link IncSearch Search
          hi! link Underlined DiagnosticUnderlineInfo

          hi VertSplit guibg=None guifg=#505050
          hi StatusLine cterm=italic guibg=None guifg=#505050
          hi StatusLineNC guibg=None guifg=#505050
          hi StatusLineCT gui=bold guifg=#e0e0e0
          hi StatusLineNCT gui=bold guifg=#b0b0b0
          hi StatusLineFname gui=bold guifg=#6fb3d2
          hi StatusLineRO gui=bold guifg=#fb0120
          hi StatusLineCols gui=bold guifg=#d381c3
          hi StatusLineModified gui=bold guifg=#a1c659
          hi StatusLineLines gui=bold guifg=#fc6d24

          hi! IndentBlanklineChar guifg=#303030
          hi! link LineNr Comment
          hi! link TSDanger Todo
          hi! link SignColumn Comment
          hi! link MiniCursorword Cursorline
          hi! link MiniJump Cursorline
          hi! link MiniSurround MatchParen

          hi! link RenamerTitle TabLineSel
          hi! link RenamerBorder FloatBorder

          hi DiagnosticWarn guifg=#fda331
          hi DiagnosticFloatingWarn guifg=#fda331
          hi! link DiagnosticSignError DiagnosticError
          hi! link DiagnosticSignWarn DiagnosticWarn
          hi! link DiagnosticSignInfo DiagnosticInfo
          hi! link DiagnosticSignHint DiagnosticHint
          hi! link LspReferenceText CursorLine
          hi! link LspReferenceRead LspReferenceText
          hi! link LspReferenceWrite LspReferenceText
          hi! LspSignatureActiveParameter cterm=bold gui=bold

          hi! CmpItemAbbrDeprecated gui=strikethrough
          hi! link CmpItemKindText Comment
          hi! link CmpItemAbbrMatch SpecialComment
          hi! link CmpItemAbbrMatchFuzzy SpecialComment
          hi! link CmpItemKindValue Number
          hi! link CmpItemKindUnit Number
          hi! link CmpItemKindColor Number
          hi! link CmpItemKindOperator Operator
          hi! link CmpItemKindTypeParameter Type
          hi! link CmpItemKindVariable SpecialChar
          hi! link CmpItemKindConstant SpecialChar
          hi! link CmpItemKindProperty Decorator
          hi! link CmpItemKindField Decorator
          hi! link CmpItemKindReference Decorator
          hi! link CmpItemKindEnumMember Decorator
          hi! link CmpItemKindFunction Function
          hi! link CmpItemKindMethod Function
          hi! link CmpItemKindConstructor Function
          hi! link CmpItemKindStruct Structure
          hi! link CmpItemKindClass Structure
          hi! link CmpItemKindEnum Structure
          hi! link CmpItemKindInterface rustModPath
          hi! link CmpItemKindModule rustModPath
          hi! link CmpItemKindEvent rustModPath
          hi! link CmpItemKindKeyword Keyword
          hi! link CmpItemKindFile String
          hi! link CmpItemKindFolder String
          hi! link CmpItemKindSnippet DiagnosticHint
         ]])
      end,
    })

    -- REGISTERS
    -- ---------
    use({
      'tversteeg/registers.nvim',
      config = function()
        g.registers_show_empty_registers = 0
        g.registers_window_max_width = 35
        g.registers_return_symbol = ' '
        g.registers_tab_symbol = opt.listchars:get()['tab']
      end,
    })

    -- LSP
    -- ---
    use({
      'neovim/nvim-lspconfig',
      requires = {
        { -- Lightbulb
          'kosayoda/nvim-lightbulb',
          config = function()
            fn.sign_define('LightBulbSign', { text = '', texthl = 'Label' })
            require('nvim-lightbulb').setup({ sign = { enabled = true, priority = 10 } })
            cmd('au init_lua CursorHold * lua require("nvim-lightbulb").update_lightbulb()')
          end,
        },
        { -- Rename window
          'filipdutescu/renamer.nvim',
          requires = { 'nvim-lua/plenary.nvim' },
          config = function()
            require('renamer').setup({
              title = 'ﲒ ',
              padding = { top = 0, left = 1, bottom = 0, right = 0 },
              min_width = 20,
              max_width = 45,
              border = true,
              border_chars = { '─', '│', '─', '│', '┌', '┐', '┘', '└' },
              show_refs = true,
              with_qf_list = false,
              with_popup = true,
              handler = nil,
            })
          end,
        },
      },
      config = function()
        publish = lsp.diagnostic.on_publish_diagnostics
        diagnostic.config({
          update_in_insert = false,
          virtual_text = false,
          underline = false,
          severity_sort = true,
        })
        lsp.buffer_setup_ = function()
          local cmp = require('cmp')
          cmp.setup.buffer({ completion = { autocomplete = { 'TextChanged' } } })
          bnoremap('n', 'K', '<CMD>lua lsp.buf.hover()<CR>')
          bnoremap('n', '<C-k>a', '<CMD>silent! lua lsp.buf.code_action()<CR>')
          bnoremap('n', '<C-k>s', '<CMD>silent! lua lsp.buf.document_symbol()<CR>')
          bnoremap('n', '<C-k><C-s>', '<CMD>silent! lua lsp.buf.workspace_symbol()<CR>')
          bnoremap('n', '[k', '<CMD>silent! lua diagnostic.goto_prev()<CR>')
          bnoremap('n', ']k', '<CMD>silent! lua diagnostic.goto_next()<CR>')
          bnoremap('n', '<C-n>', '<CMD>silent! lua require("renamer").rename()<CR>')
          bnoremap('n', '<C-t>', '<CMD>silent! lua lsp.buf.references()<CR>')
          bnoremap('n', '<C-k><C-]>', '<CMD>silent! lua lsp.buf.type_definition()<CR>')
          bnoremap('n', '<C-]>', '<CMD>silent! lua lsp.buf.definition()<CR>')
          bnoremap(
            'n',
            '<C-k><C-k>',
            '<CMD>silent! lua diagnostic.open_float(nil, { scope = "line" })<CR>'
          )
          bnoremap(
            'n',
            '<C-k>k',
            '<CMD>lua diagnostic.setloclist{ open = true, title = "Buffer diagnostics" }<CR>'
          )
          bnoremap(
            'n',
            '<C-k>K',
            '<CMD>lua diagnostic.setqflist{ open = true, title = "Workspace diagnostics" }<CR>'
          )
        end

        lsp.update_diagnostics_ = function(global_too)
          local loc = vim.fn.getloclist(vim.fn.winnr(), { title = 0, winid = 0 })
          local qf = vim.fn.getqflist({ title = 0, winid = 0 })
          if fn.win_getid() == loc.winid or fn.win_getid() == qf.winid then
            return
          end

          if loc.title == 'Buffer diagnostics' then
            diagnostic.setloclist({ open = false, title = 'Buffer diagnostics' })
          end

          if global_too and qf.title == 'Workspace diagnostics' then
            diagnostic.setqflist({ open = false, title = 'Workspace diagnostics' })
          end
        end

        cmd('au init_lua BufWinEnter * lua lsp.update_diagnostics_(false)')
        cmd('au init_lua DiagnosticChanged * lua lsp.update_diagnostics_(true)')

        fn.sign_define('DiagnosticSignError', { text = '', texthl = 'DiagnosticSignError' })
        fn.sign_define('DiagnosticSignWarn', { text = '', texthl = 'DiagnosticSignWarn' })
        fn.sign_define('DiagnosticSignInfo', { text = '', texthl = 'DiagnosticSignInfo' })
        fn.sign_define('DiagnosticSignHint', { text = '', texthl = 'DiagnosticSignHint' })
        require('servers')
      end,
    })

    -- QUICKFIX
    -- --------
    use({
      'https://gitlab.com/yorickpeterse/nvim-pqf.git',
      config = function()
        require('pqf').setup({
          signs = {
            error = ' ',
            warning = ' ',
            info = ' ',
            hint = ' ',
          },
        })
      end,
    })

    -- SKIM
    -- ----
    use({
      'vijaymarupudi/nvim-fzf',
      config = function()
        fzf = require('fzf')
        fzf.default_options = {
          border = 'single',
          fzf_binary = 'sk',
          fzf_cli_args = '--height=100% --margin=0,1',
          width = 80,
          height = 30,
          window_on_create = function()
            lopt.buflisted = false
            lopt.winhl = 'Normal:Normal'
          end,
        }
        sk = {}
        -- Files
        sk.files = function()
          coroutine.wrap(function()
            local result = fzf.fzf(nil, ' --multi --header=Edit:')
            if result then
              for _, value in ipairs(result) do
                cmd('edit ' .. value)
              end
              wipe_empty()
            end
          end)()
        end
        -- Buffers
        sk.buffers = function()
          coroutine.wrap(function()
            local result = fzf.fzf(function(cb)
              for line in fn.trim(fn.execute('ls'), '\n'):gmatch('([^\n]*)\n?') do
                if #line > 0 then
                  cb(line, function(err)
                    if err then
                      return
                    end
                  end)
                end
              end
              cb(nil)
            end, ' --header=Buffers:')
            if result then
              cmd('buffer ' .. result[1]:match('%d+'))
            end
          end)()
        end
        -- Working directory
        sk.cwd = function()
          coroutine.wrap(function()
            local result = fzf.fzf(function(cb)
              for line in
                fn.trim(fn.system('fd -H --exclude ".git" --type directory'), '\n'):gmatch(
                  '([^\n]*)\n?'
                )
              do
                if #line > 0 then
                  cb(line, nil)
                end
              end
              -- All parent dirs
              local parent = fn.fnamemodify(fn.getcwd(), ':h')
              while parent ~= '/' do
                cb(parent)
                parent = fn.fnamemodify(parent, ':h')
              end
              cb(nil)
            end, ' --header=Directories:')
            -- All child dirs
            if result then
              cmd('cd ' .. result[1])
              wipe_empty()
            end
          end)()
        end

        noremap('n', '<C-p>', '<CMD>lua sk.files()<CR>')
        noremap('n', '<C-s>', '<CMD>lua sk.buffers()<CR>')
        noremap('n', '<C-g>', '<CMD>lua sk.cwd()<CR>')
      end,
    })

    -- COMPLETION
    -- ----------
    use({
      'hrsh7th/nvim-cmp',
      requires = {
        'hrsh7th/cmp-nvim-lsp',
        'hrsh7th/cmp-buffer',
        'hrsh7th/cmp-path',
        'hrsh7th/cmp-vsnip',
        'hrsh7th/vim-vsnip',
        'rafamadriz/friendly-snippets',
        'onsails/lspkind-nvim',
        { -- Signature
          'ray-x/lsp_signature.nvim',
          config = function()
            require('lsp_signature').setup({
              doc_lines = 0,
              hint_enable = false,
              always_trigger = false,
              toggle_key = '<C-b>',
              handler_opts = { border = 'none' },
            })
          end,
        },
      },
      config = function()
        local cmp = require('cmp')
        cmp.setup({
          completion = { autocomplete = false },
          sources = cmp.config.sources({
            { name = 'nvim_lsp' },
          }, {
            { name = 'vsnip' },
            { name = 'buffer' },
            { name = 'path' },
          }),
          snippet = {
            expand = function(args)
              fn['vsnip#anonymous'](args.body)
            end,
          },
          mapping = {
            ['<C-y>'] = cmp.config.disable,
            ['<C-e>'] = cmp.config.disable,
            ['<C-u>'] = cmp.mapping(cmp.mapping.scroll_docs(-4)),
            ['<C-d>'] = cmp.mapping(cmp.mapping.scroll_docs(4)),
            ['<CR>'] = cmp.mapping.confirm({ select = false }),
            ['<C-Space>'] = cmp.mapping(function(_)
              if cmp.visible() then
                cmp.abort()
              else
                cmp.complete()
              end
            end),
            ['<Tab>'] = cmp.mapping(function(fallback)
              if cmp.visible() then
                cmp.select_next_item()
              elseif check_bs() then
                fallback()
              else
                cmp.complete()
              end
            end),
            ['<S-Tab>'] = cmp.mapping(function(fallback)
              if cmp.visible() then
                cmp.select_prev_item()
              else
                fallback()
              end
            end),
          },
          formatting = {
            format = require('lspkind').cmp_format({
              mode = 'symbol',
              maxwidth = 30,
            }),
          },
          enabled = true,
        })
        map(
          'i',
          '<C-j>',
          'vsnip#available(1) ? "<Plug>(vsnip-expand-or-jump)" : "<C-j>"',
          { noremap = false, expr = true }
        )
        map(
          'i',
          '<C-k>',
          'vsnip#jumpable(-1)  ? "<Plug>(vsnip-jump-prev)" : "<C-k>"',
          { noremap = false, expr = true }
        )
      end,
    })

    -- TREESITTER
    -- ----------
    use({
      'nvim-treesitter/nvim-treesitter',
      run = ':TSUpdate',
      requires = {
        'windwp/nvim-ts-autotag',
        'JoosepAlviste/nvim-ts-context-commentstring',
      },
      config = function()
        require('nvim-treesitter.configs').setup({
          ensure_installed = 'all',
          highlight = {
            enable = true,
            disable = {
              'tex',
              'latex',
              'rust',
              'html',
            },
          },
          context_commentstring = { enable = true },
          autotag = { enable = true },
        })
      end,
    })

    -- UNDOTREE
    -- --------
    use({
      'mbbill/undotree',
      config = function()
        g.undotree_SetFocusWhenToggle = 1
        g.undotree_WindowLayout = 2
        g.undotree_HelpLine = 0
        g.undotree_HighlightChangedText = 0
        g.undotree_ShortIndicators = 1
        g.undotree_CursorLine = 1
        g.undotree_DiffpanelHeight = 6
        g.undotree_TreeNodeShape = '⭘'
        g.undotree_TreeVertShape = '|'
        noremap('n', 'U', '<CMD>UndotreeToggle<CR>')
        cmd([[
          au init_lua FileType undotree sign define UndotreeAdd text=┃ texthl=GitGutterAdd
          au init_lua FileType undotree sign define UndotreeChg text=┃ texthl=GitGutterChange
          au init_lua FileType undotree sign define UndotreeDel text= texthl=GitGutterDelete
          au init_lua FileType undotree sign define UndotreeDelEnd text= texthl=GitGutterDelete
        ]])
      end,
    })

    -- INDENT LINES
    -- ------------
    use({
      'lukas-reineke/indent-blankline.nvim',
      config = function()
        require('indent_blankline').setup({
          show_first_indent_level = true,
          char = '│',
          context_char = '',
          buftype_exclude = { 'help', 'quickfix', 'terminal', 'nofile', 'nowrite', 'prompt' },
          filetype_exclude = { 'man', 'packer' },
        })
      end,
    })

    -- ZEN MODE
    -- --------
    use({
      'folke/zen-mode.nvim',
      config = function()
        require('zen-mode').setup({
          window = {
            backdrop = 1,
            width = 80,
            height = 0.85,
            options = { number = false, signcolumn = 'no' },
          },
        })
      end,
    })

    -- JUPYTER
    -- -------
    use({
      'GCBallesteros/jupytext.vim',
      config = function()
        g.jupytext_fmt = 'py'
        g.jupytext_style = 'percent'
      end,
    })

    -- CSS COLORS
    -- ----------
    use({
      'rrethy/vim-hexokinase',
      run = 'make hexokinase',
      config = function()
        g.Hexokinase_optOutPatterns = { 'colour_names' }
        g.Hexokinase_termDisabled = 1
        g.Hexokinase_ftDisabled = {
          'undotree',
          'qf',
          'man',
          'cmdwin',
          'peekaboo',
          'fzf',
          'diff',
          'help',
          'packer',
        }
      end,
    })

    -- DASHBOARD
    -- ---------
    use({
      'goolord/alpha-nvim',
      config = function()
        local alpha = require('alpha')
        local dashboard = require('alpha.themes.dashboard')
        local ver = vim.version()

        -- Set header
        dashboard.section.header.val = {
          [[ ]],
          'NVIM v' .. ver.major .. '.' .. ver.minor .. '.' .. ver.patch,
        }
        dashboard.section.header.opts.hl = 'StatusLineFname'

        local button = function(key, title, cmd)
          local btn = dashboard.button(key, title, cmd)
          btn.opts.hl_shortcut = 'String'
          return btn
        end

        dashboard.section.buttons.val = {
          button('e', '  New', '<CMD>ene<BAR>startinsert<CR>'),
          button('f', '  Find', '<CMD>lua sk.files()<CR>'),
          button('d', '  Directory', '<CMD>lua sk.cwd()<CR>'),
          button('c', '  Config', '<CMD>cd ' .. fn.stdpath('config') .. '<Bar>e init.lua<CR>'),
          button('p', '  Plugins', '<CMD>PackerSync<CR>'),
          button('q', '  Quit', '<CMD>q<CR>'),
        }
        dashboard.section.buttons.opts.hl = 'String'

        dashboard.section.footer.val = function()
          return 'ﱮ  ' .. fn.fnamemodify(fn.getcwd(), ':~')
        end
        dashboard.section.footer.opts.hl = 'StatusLine'

        alpha.setup(dashboard.opts)

        cmd([[
          au init_lua FileType alpha setlocal nonumber
          \| exec 'autocmd CursorHold <buffer> exec "AlphaRedraw"'
          au init_lua BufEnter * if isdirectory(expand('%')) && &ft != 'alpha'
          \| call chdir(expand('%:p'))
          \| exec 'Alpha'
          \| call luaeval('wipe_empty()')
          \| endif
          au init_lua VimEnter * if empty(expand('%')) && &ft != 'alpha'
          \| exec 'Alpha'
          \| call luaeval('wipe_empty()')
          \| endif
        ]])
      end,
    })
    if packer_bootstrap then
      require('packer').sync()
    end
  end,

  config = {
    display = { open_cmd = 'botright new', prompt_border = 'none' },
    compile_path = fn.stdpath('data') .. '/site/pack/packer_compiled.lua',
  },
})

-- Automatic init.lua source
cmd('luafile ' .. fn.stdpath('data') .. '/site/pack/packer_compiled.lua')
cmd(
  'au init_lua BufWritePost '
    .. fn.stdpath('config')
    .. '/init.lua source <afile> | setfiletype lua | PackerCompile'
)

D .config/nvim/lua/servers.lua => .config/nvim/lua/servers.lua +0 -114
@@ 1,114 0,0 @@
-- SERVERS
-- -------

local capabilities = require('cmp_nvim_lsp').update_capabilities(
  lsp.protocol.make_client_capabilities()
)

-- Python language server
require('lspconfig').pylsp.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
  cmd = { 'poetry-pylsp' },
  settings = {
    pylsp = {
      plugins = {
        pylint = { enabled = true },
        pydocstyle = { enabled = true, convention = 'google' },
        mccabe = { enabled = true },
        isort = { enabled = true },
        pyls_mypy = { enabled = true },
        black = { enabled = true },
      },
    },
  },
})

-- Rust language server
require('lspconfig').rust_analyzer.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
  settings = {
    ['rust-analyzer'] = {
      checkOnSave = {
        command = 'clippy',
      },
    },
  },
})

-- LaTeX language server
require('lspconfig').texlab.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
  settings = {
    texlab = {
      build = { onSave = false },
      formatterLineLength = 120,
      latexFormatter = 'texlab',
    },
  },
})

-- C/C++ language server
require('lspconfig').clangd.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
})

-- Lua language server
require('lspconfig').sumneko_lua.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
  settings = {
    Lua = {
      runtime = {
        version = 'LuaJIT',
        path = {
          'lua/?.lua',
          'lua/?/init.lua',
          unpack(fn.split(package.path, ';')),
        },
      },
      diagnostics = {
        globals = { 'vim' },
        disable = { 'lowercase-global' },
      },
      workspace = { library = api.nvim_get_runtime_file('', true) },
      telemetry = { enable = false },
    },
  },
})

-- CSS language server
require('lspconfig').cssls.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
})

-- HTML language server
require('lspconfig').html.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
})

-- JSON language server
require('lspconfig').jsonls.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
})

-- YAML language server
require('lspconfig').yamlls.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
  yaml = {
    schemaStore = { enable = true },
  },
})

-- Bash language server
require('lspconfig').bashls.setup({
  on_attach = lsp.buffer_setup_,
  capabilities = capabilities,
})

D .config/nvim/stylua.toml => .config/nvim/stylua.toml +0 -6
@@ 1,6 0,0 @@
column_width = 100
line_endings = "Unix"
indent_type = "Spaces"
indent_width = 2
quote_style = "AutoPreferSingle"
no_call_parentheses = false

M .local/share/pacman/aur.txt => .local/share/pacman/aur.txt +0 -3
@@ 1,11 1,8 @@
base-devel-meta
compiledb
kak-smarttab-git
kak-surround-git
lightdm-mini-greeter
neovim-symlinks
paru-bin
python-bashlex
python-jupytext
python-lsp-isort
rar

D .local/share/pacman/packages/neovim-symlinks/PKGBUILD => .local/share/pacman/packages/neovim-symlinks/PKGBUILD +0 -24
@@ 1,24 0,0 @@
# Convinience package for vim-nvim interoperability

pkgname=neovim-symlinks
pkgver=5
pkgrel=1
pkgdesc='Runs neovim if vi or vim is called'
arch=('any')
depends=('neovim' 'sh')
provides=('vim' 'vi')
conflicts=('vim' 'vi' 'vi-vim-symlink')

package() {
  install -dm755 "$pkgdir/usr/bin/"
  cd "$pkgdir/usr/bin/"

  echo -e '#!/bin/sh\nexec nvim -e "$@"'  > ex
  echo -e '#!/bin/sh\nexec nvim -R "$@"'  > view
  echo -e '#!/bin/sh\nexec nvim -d "$@"'  > vimdiff
  chmod 755 *

  for _link in edit vedit vi vim; do
    ln -s nvim $_link
  done
}

M .local/share/pacman/pkg.txt => .local/share/pacman/pkg.txt +1 -3
@@ 3,6 3,7 @@ aspell-en
aspell-pl
base
bash-language-server
bear
bottom
chromium
clang


@@ 36,7 37,6 @@ lua-language-server
maim
man-db
mkvtoolnix-cli
neovim
networkmanager
noto-fonts-emoji
npm


@@ 82,8 82,6 @@ ttf-nerd-fonts-symbols-mono
ufw
unclutter
unzip
vim-spell-en
vim-spell-pl
xarchiver
xclip
xorg-server

M .profile => .profile +1 -0
@@ 8,6 8,7 @@ export PAGER='less -r'
export TERMINAL='alacritty -e'
export BROWSER='firefox'
export MANPAGER='less -r'
export DIFFPROG='delta'
export TMPDIR='/tmp'

# XDG BASE DIRECTORY SPECIFICATION