summary refs log tree commit diff
path: root/.vim/lua/internal
diff options
context:
space:
mode:
authorRobert Günzler <r@gnzler.io>2023-01-19 18:33:43 +0100
committerRobert Günzler <r@gnzler.io>2023-01-19 18:33:43 +0100
commitfc67eecc8a40bf28d3d2b190702e58c580bfba9f (patch)
tree0b8d0455046ae484e036d2f9dfa69306bbea811d /.vim/lua/internal
parentc03b74ce367d6e9e2988dbb4a18985bc372dd8a6 (diff)
vim: format config with stylua
Signed-off-by: Robert Günzler <r@gnzler.io>
Diffstat (limited to '.vim/lua/internal')
-rw-r--r--.vim/lua/internal/align.lua75
-rw-r--r--.vim/lua/internal/dap.lua63
-rw-r--r--.vim/lua/internal/exrc.lua49
-rw-r--r--.vim/lua/internal/hardmode.lua10
-rw-r--r--.vim/lua/internal/job.lua59
-rw-r--r--.vim/lua/internal/lsp.lua258
-rw-r--r--.vim/lua/internal/misc.lua146
-rw-r--r--.vim/lua/internal/snips.lua106
-rw-r--r--.vim/lua/internal/spell.lua3
-rw-r--r--.vim/lua/internal/statusline.lua215
10 files changed, 504 insertions, 480 deletions
diff --git a/.vim/lua/internal/align.lua b/.vim/lua/internal/align.lua
index 5dcf7c0..1ada01d 100644
--- a/.vim/lua/internal/align.lua
+++ b/.vim/lua/internal/align.lua
@@ -14,11 +14,15 @@ function M.align_lines(pat, line1, line2, preview_ns, preview_bufnr)
   local max = -1
   for _, line in pairs(lines) do
     local s = re:match_str(line)
-    if s and max < s then max = s end
+    if s and max < s then
+      max = s
+    end
   end
 
   -- exit if nothing was found
-  if max == -1 then return error('nothing found') end
+  if max == -1 then
+    return error('nothing found')
+  end
 
   for i, line in pairs(lines) do
     local s = re:match_str(line)
@@ -27,33 +31,45 @@ function M.align_lines(pat, line1, line2, preview_ns, preview_bufnr)
       local changeset = {
         string.sub(line, 1, s),
         string.rep(' ', rep),
-        string.sub(line, s+1),
+        string.sub(line, s + 1),
       }
       local newline = table.concat(changeset)
 
       -- append to changse if not inside the preview callback
       if not preview_ns then
-        newlines[#newlines+1] = newline
+        newlines[#newlines + 1] = newline
       end
 
       if preview_ns ~= nil then
         -- set extmarks inside the live buffer
-        vim.api.nvim_buf_set_extmark(bufnr, preview_ns, line1+i - 2, 0,
-          {
-            hl_mode = 'combine',
-            virt_text_pos = 'overlay',
-            virt_text = {
-              {changeset[1]},
-              {changeset[2], 'Substitute'},
-              {changeset[3]},
-            },
-          })
+        vim.api.nvim_buf_set_extmark(bufnr, preview_ns, line1 + i - 2, 0, {
+          hl_mode = 'combine',
+          virt_text_pos = 'overlay',
+          virt_text = {
+            { changeset[1] },
+            { changeset[2], 'Substitute' },
+            { changeset[3] },
+          },
+        })
 
         -- modify preview buffer
         if preview_bufnr ~= nil then
           local prefix = string.format('|%d| ', line1 + i - 1)
-          vim.api.nvim_buf_set_lines(preview_bufnr, preview_buf_line, preview_buf_line, false, { prefix .. newline })
-          vim.api.nvim_buf_add_highlight(preview_bufnr, preview_ns, 'Substitute', preview_buf_line, #prefix + s, #prefix + s + #changeset[2])
+          vim.api.nvim_buf_set_lines(
+            preview_bufnr,
+            preview_buf_line,
+            preview_buf_line,
+            false,
+            { prefix .. newline }
+          )
+          vim.api.nvim_buf_add_highlight(
+            preview_bufnr,
+            preview_ns,
+            'Substitute',
+            preview_buf_line,
+            #prefix + s,
+            #prefix + s + #changeset[2]
+          )
           preview_buf_line = preview_buf_line + 1
         end
       end
@@ -63,7 +79,9 @@ function M.align_lines(pat, line1, line2, preview_ns, preview_bufnr)
   -- only change buffer when not previewing
   if not preview_ns then
     -- exit if nothing was changed
-    if #newlines == 0 then return error('nothing changed') end
+    if #newlines == 0 then
+      return error('nothing changed')
+    end
     vim.api.nvim_buf_set_lines(bufnr, line1 - 1, line2, 0, newlines)
     return 0
   end
@@ -75,10 +93,10 @@ function M.align_lines(pat, line1, line2, preview_ns, preview_bufnr)
 end
 
 function M.align(pat)
-    local top, bot = vim.fn.getpos("'<"), vim.fn.getpos("'>")
-    M.align_lines(pat, top[2]-1, bot[2])
-    vim.fn.setpos("'<", top)
-    vim.fn.setpos("'>", bot)
+  local top, bot = vim.fn.getpos("'<"), vim.fn.getpos("'>")
+  M.align_lines(pat, top[2] - 1, bot[2])
+  vim.fn.setpos("'<", top)
+  vim.fn.setpos("'>", bot)
 end
 
 local function aligncmd(opts, preview_ns, preview_bufnr)
@@ -86,18 +104,21 @@ local function aligncmd(opts, preview_ns, preview_bufnr)
 end
 
 local default_opts = {
-  bindings = true
+  bindings = true,
 }
 
 function M.setup(opts)
   opts = vim.tbl_extend('keep', opts or {}, default_opts)
 
-  vim.api.nvim_create_user_command('SimpleAlign', aligncmd,
-    {nargs = 1, range = '%', preview = aligncmd})
+  vim.api.nvim_create_user_command(
+    'SimpleAlign',
+    aligncmd,
+    { nargs = 1, range = '%', preview = aligncmd }
+  )
 
-  if opts.bindings then
-    vim.keymap.set('v', '<enter>', ':SimpleAlign ')
-  end
+  -- if opts.bindings then
+  --   vim.keymap.set('v', '<enter>', ':SimpleAlign ')
+  -- end
 end
 
 return M
diff --git a/.vim/lua/internal/dap.lua b/.vim/lua/internal/dap.lua
index aa419ea..1790575 100644
--- a/.vim/lua/internal/dap.lua
+++ b/.vim/lua/internal/dap.lua
@@ -10,30 +10,43 @@ dap.listeners.after['event_initialized']['me'] = function()
 end
 
 -- signs
-vim.fn.sign_define({{name='DapBreakpoint', text='🞱', texthl='DapBreakpoint', linehl='DapBreakpointLn'}})
-vim.fn.sign_define({{name='DapStopped', text='→', texthl='DapStopped', linehl='DapStoppedLn'}})
+vim.fn.sign_define({
+  { name = 'DapBreakpoint', text = '🞱', texthl = 'DapBreakpoint', linehl = 'DapBreakpointLn' },
+})
+vim.fn.sign_define({
+  { name = 'DapStopped', text = '→', texthl = 'DapStopped', linehl = 'DapStoppedLn' },
+})
 
 -- keymaps
-vim.keymap.set('n', '<leader>dd', dap.toggle_breakpoint, {desc='toggle breakpoint'}) -- convenience
-vim.keymap.set('n', '<leader>db', dap.toggle_breakpoint, {desc='toggle breakpoint'})
-vim.keymap.set('n', '<leader>dc', dap.continue, {desc='continue'})
-vim.keymap.set('n', '<leader>do', dap.step_over, {desc='step over'})
-vim.keymap.set('n', '<leader>di', dap.step_into, {desc='step into'})
-vim.keymap.set('n', '<leader>dO', dap.step_out, {desc='step out'})
-vim.keymap.set('n', '<leader>dR', dap.repl.toggle, {desc='toggle REPL'})
-vim.keymap.set('n', '<leader>dL', dap.run_last, {desc='run last'})
-vim.keymap.set('n', '<leader>dt', dap.terminate, {desc='terminate'})
+vim.keymap.set('n', '<leader>dd', dap.toggle_breakpoint, { desc = 'toggle breakpoint' }) -- convenience
+vim.keymap.set('n', '<leader>db', dap.toggle_breakpoint, { desc = 'toggle breakpoint' })
+vim.keymap.set('n', '<leader>dc', dap.continue, { desc = 'continue' })
+vim.keymap.set('n', '<leader>do', dap.step_over, { desc = 'step over' })
+vim.keymap.set('n', '<leader>di', dap.step_into, { desc = 'step into' })
+vim.keymap.set('n', '<leader>dO', dap.step_out, { desc = 'step out' })
+vim.keymap.set('n', '<leader>dR', dap.repl.toggle, { desc = 'toggle REPL' })
+vim.keymap.set('n', '<leader>dL', dap.run_last, { desc = 'run last' })
+vim.keymap.set('n', '<leader>dt', dap.terminate, { desc = 'terminate' })
 
 local widgets = require('dap.ui.widgets')
-vim.keymap.set('n', '<leader>dh', widgets.hover, {desc='hover'})
-vim.keymap.set('n', '<leader>dB', require('telescope').extensions.dap.list_breakpoints, {desc='list breakpoints'})
+vim.keymap.set('n', '<leader>dh', widgets.hover, { desc = 'hover' })
+vim.keymap.set(
+  'n',
+  '<leader>dB',
+  require('telescope').extensions.dap.list_breakpoints,
+  { desc = 'list breakpoints' }
+)
 
 -- Common
 local bin_from_var_or_pick = function()
   local ok, retval = pcall(vim.api.nvim_buf_get_var, 0, 'dap_bin')
-  if ok then return retval end
+  if ok then
+    return retval
+  end
   local bin = nil
-  vim.ui.input({prompt = 'DAP Binary: '}, function(choice) bin = choice end)
+  vim.ui.input({ prompt = 'DAP Binary: ' }, function(choice)
+    bin = choice
+  end)
   return bin
 end
 
@@ -44,21 +57,29 @@ dap.adapters.go_dlv_local = function(callback, config) -- {{{
   local pid_or_err
   local port = 38697
   local opts = {
-    stdio = {nil, stdout},
-    args = {'dap', '-l', '127.0.0.1:' .. port},
+    stdio = { nil, stdout },
+    args = { 'dap', '-l', '127.0.0.1:' .. port },
     detached = true,
   }
-  handle, pid_or_err = vim.loop.spawn("dlv", opts, function(exit)
+  handle, pid_or_err = vim.loop.spawn('dlv', opts, function(exit)
     stdout:close()
     handle:close()
-    if exit ~= 0 then vim.notify('dlv exited with exit code ' .. exit) end
+    if exit ~= 0 then
+      vim.notify('dlv exited with exit code ' .. exit)
+    end
   end)
   assert(handle, 'Error running dlv: ' .. tostring(pid_or_err))
   stdout:read_start(function(err, chunk)
     assert(not err, err)
-    if chunk then vim.schedule(function() require('dap.repl').append(chunk) end) end
+    if chunk then
+      vim.schedule(function()
+        require('dap.repl').append(chunk)
+      end)
+    end
   end)
-  vim.defer_fn(function() callback({type = 'server', host = '127.0.0.1', port = port}) end, 100)
+  vim.defer_fn(function()
+    callback({ type = 'server', host = '127.0.0.1', port = port })
+  end, 100)
 end -- }}}
 
 dap.adapters.go_dlv_remote = {
diff --git a/.vim/lua/internal/exrc.lua b/.vim/lua/internal/exrc.lua
deleted file mode 100644
index 1b3b22b..0000000
--- a/.vim/lua/internal/exrc.lua
+++ /dev/null
@@ -1,49 +0,0 @@
-local root_pattern = require('lspconfig.util').root_pattern
-
-local M = {
-  config = {
-    filenames = {'.nvimrc'}
-  }
-}
-
-M.setup = function (opt)
-  vim.validate {
-    filenames = { opt.filenames, 'table', true },
-  }
-
-  M.config = vim.tbl_extend('force', M.config, opt)
-
-  local group = vim.api.nvim_create_augroup('ExrcLoad', { clear = true })
-  vim.api.nvim_create_autocmd('VimEnter', {
-    callback = M.load,
-    group = group,
-  })
-end
-
-local load = function (root, filename)
-  local fpath = root .. '/' .. filename
-  if root and vim.loop.fs_stat(fpath) then
-    vim.cmd('luafile ' .. fpath)
-    vim.g.nvimrc_loaded = fpath
-  else
-    error(string.format('[exrc] %s not found', fpath))
-  end
-end
-
-M.load = function ()
-  local root = vim.fn.getcwd()
-  for _, fname in ipairs(M.config.filenames) do
-    local ok = false
-    ok, _ = pcall(load, root, fname)
-    if ok then return true end
-
-    -- try harder by searching up the dir tree
-    root = root_pattern(fname)(root)
-    ok, _ = pcall(load, root, fname)
-    if ok then return true end
-  end
-
-  return false
-end
-
-return M
diff --git a/.vim/lua/internal/hardmode.lua b/.vim/lua/internal/hardmode.lua
index cc71baf..2774ead 100644
--- a/.vim/lua/internal/hardmode.lua
+++ b/.vim/lua/internal/hardmode.lua
@@ -1,10 +1,10 @@
 -- hard mode means we're not using the arrow keys!
 
 local bail = function()
-  vim.cmd [[silent! echohl ErrorMsg | echo "HARD MODE: hjkl operation only" | echohl None]]
+  vim.cmd([[silent! echohl ErrorMsg | echo "HARD MODE: hjkl operation only" | echohl None]])
 end
 
-vim.keymap.set({'n', 'v', 'i'}, '<up>',      bail)
-vim.keymap.set({'n', 'v', 'i'}, '<down>',    bail)
-vim.keymap.set({'n', 'v', 'i'}, '<left>',    bail)
-vim.keymap.set({'n', 'v', 'i'}, '<right>',   bail)
+vim.keymap.set({ 'n', 'v', 'i' }, '<up>', bail)
+vim.keymap.set({ 'n', 'v', 'i' }, '<down>', bail)
+vim.keymap.set({ 'n', 'v', 'i' }, '<left>', bail)
+vim.keymap.set({ 'n', 'v', 'i' }, '<right>', bail)
diff --git a/.vim/lua/internal/job.lua b/.vim/lua/internal/job.lua
index 64d9837..42a548b 100644
--- a/.vim/lua/internal/job.lua
+++ b/.vim/lua/internal/job.lua
@@ -1,7 +1,5 @@
-local spinner_ok, spinner = pcall(require, 'spinner.core')
-
 local M = {
-  current_jobs = {}
+  current_jobs = {},
 }
 
 local strip_ansi = function(line)
@@ -14,14 +12,15 @@ local setqf = function(opts, pid, data)
   end
   vim.fn.setqflist({}, 'a', {
     title = opts.format_title,
-    lines = {strip_ansi(data)},
+    lines = { strip_ansi(data) },
     efm = '%m',
     context = {
-      cmd = {opts.command, unpack(opts.args)},
+      cmd = { opts.command, unpack(opts.args) },
       pid = pid,
       source = 'jobstart',
-    }
+    },
   })
+  vim.cmd.doautocmd('QuickFixCmdPost')
 end
 
 --create a new job and register
@@ -29,13 +28,14 @@ end
 function M.jobstart(opts)
   opts = opts or {}
 
+  local spinner_ok, spinner = pcall(require, 'spinner.core')
+
   -- default options
-  -- opts.enable_recording = true
   opts.enable_spinner = (opts.enable_spinner or true) and spinner_ok
   opts.populate_quickfix = opts.populate_quickfix or 'onerror'
 
   if opts.format_title == nil then
-    opts.format_title = table.concat({opts.command, unpack(opts.args)}, ' ')
+    opts.format_title = table.concat({ opts.command, unpack(opts.args) }, ' ')
   elseif type(opts.format_title) == 'function' then
     opts.format_title = opts.format_title(opts.command, opts.args)
   elseif type(opts.format_title) == 'string' then
@@ -45,7 +45,7 @@ function M.jobstart(opts)
   end
 
   opts.on_start = vim.schedule_wrap(function(j)
-    table.insert(M.current_jobs, j.pid, j)
+    M.current_jobs[j.pid] = j
 
     if opts.populate_quickfix then
       vim.fn.setqflist({}, 'r') -- clear quickfix
@@ -57,7 +57,7 @@ function M.jobstart(opts)
   end)
 
   opts.on_exit = vim.schedule_wrap(function(j, code)
-    table.remove(M.current_jobs, j.pid)
+    M.current_jobs[j.pid] = nil
 
     if not (code == 0) then
       vim.notify(string.format('[%d] exit %d', j.pid, code), vim.log.levels.ERROR)
@@ -67,7 +67,7 @@ function M.jobstart(opts)
       spinner.on_exit(nil, nil, j.pid)
     end
     if opts.populate_quickfix then
-      vim.cmd.doautocmd [[QuickFixCmdPost]]
+      vim.cmd.doautocmd('QuickFixCmdPost')
     end
   end)
 
@@ -92,11 +92,11 @@ function M.jobstart(opts)
   end)
 
   -- run vim.fn.expand() on all args
-  for i=1, #opts.args do
+  for i = 1, #opts.args do
     opts.args[i] = vim.fn.expandcmd(opts.args[i])
   end
 
-  local j = require ('plenary.job'):new(opts)
+  local j = require('plenary.job'):new(opts)
   j:start()
 
   return j
@@ -116,31 +116,44 @@ function M.make(extra_args)
     cwd = require('lspconfig.util').root_pattern('Makefile')(cwd)
   end
 
-  table.foreach(extra_args or {}, function(_, v) table.insert(args, v) end)
+  for _, v in pairs(extra_args or {}) do
+    table.insert(args, v)
+  end
+  -- table.foreach(extra_args or {}, function(_, v) end)
 
-  return M.jobstart {
+  return M.jobstart({
     command = command,
     args = args,
     cwd = cwd,
-  }
+  })
 end
 
 function M.sh(command_string)
-  return M.jobstart {
+  return M.jobstart({
     command = vim.env.SHELL,
-    args = {'-c', command_string},
+    args = { '-c', command_string },
 
     -- strip 'sh -c' from the title (used by progress reporting etc.)
     format_title = function(_, args)
-      return table.concat({unpack(args, 2, #args)}, ' ')
-    end
-  }
+      return table.concat({ unpack(args, 2, #args) }, ' ')
+    end,
+  })
 end
 
-
 function M.list()
-  require('telescope').load_extension('jobs')
   require('telescope._extensions').manager['jobs']['jobs']()
 end
 
+function M.setup()
+  require('telescope').load_extension('jobs')
+
+  vim.keymap.set(
+    'n',
+    '<leader>J',
+    require('internal.job').list,
+    { desc = 'list jobs managed by internal.job' }
+  )
+  vim.api.nvim_create_user_command('Jobs', M.list, { desc = 'list jobs managed by internal.job' })
+end
+
 return M
diff --git a/.vim/lua/internal/lsp.lua b/.vim/lua/internal/lsp.lua
index aa2794e..2bdd270 100644
--- a/.vim/lua/internal/lsp.lua
+++ b/.vim/lua/internal/lsp.lua
@@ -1,5 +1,9 @@
-local lsp         = require('lspconfig')
-local lspstatus   = require('lsp-status')
+-- TODO vim.api.nvim_create_autocmd('LspAttach', {
+-- 	callback = function(args)
+-- 		local client = vim.lsp.get_client_by_id(args.data.client_id)
+-- 		local bufnr = args.buf
+-- 	end,
+-- })
 
 local my_attach = function(client, bufnr)
   if vim.opt.diff:get() then
@@ -13,67 +17,112 @@ local my_attach = function(client, bufnr)
     buffer = bufnr,
     group = group,
     callback = function()
-      if not _G.diagnostic_hidden then
-        vim.diagnostic.open_float(nil, {
-          focusable = false,
-          close_events = {'BufLeave', 'CursorMoved', 'InsertEnter', 'FocusLost'},
-          border = _G.floating_win_border,
-          source = 'always',
-          prefix = ' ',
-          scope = 'cursor',
-        })
+      if _G.diagnostic_hidden then
+        return
+      end
+      -- evalutate if there's already a floating preview buffer
+      local existing = vim.F.npcall(vim.api.nvim_buf_get_var, bufnr, 'lsp_floating_preview')
+      if not existing or not vim.api.nvim_win_is_valid(existing) then
+        vim.diagnostic.open_float()
       end
     end,
   })
 
-  lspstatus.on_attach(client)
+  require('lsp-status').on_attach(client)
   if client.supports_method('textDocument/documentSymbol') then
     require('nvim-navic').attach(client, bufnr)
     -- require('aerial').on_attach(client, bufnr)
     -- vim.keymap.set('n', 'g0', vim.lsp.buf.document_symbol, {buffer = bufnr})
   end
   if client.supports_method('workspace/symbol') then
-    vim.keymap.set('n', 'gW'        , vim.lsp.buf.workspace_symbol, {buffer = bufnr, desc = 'goto symbol'})
-    vim.keymap.set('n', ';s'        , require('telescope.builtin').lsp_workspace_symbols, {desc='lsp workspace symbols'})
+    vim.keymap.set(
+      'n',
+      'gW',
+      vim.lsp.buf.workspace_symbol,
+      { buffer = bufnr, desc = 'goto symbol' }
+    )
+    vim.keymap.set(
+      'n',
+      ';s',
+      require('telescope.builtin').lsp_workspace_symbols,
+      { desc = 'lsp workspace symbols' }
+    )
   end
   if client.supports_method('textDocument/definition') then
-    vim.keymap.set('n', '<C-]>'     , vim.lsp.buf.definition, {buffer = bufnr, desc = 'goto definition'})
-    vim.keymap.set('n', 'gd'        , vim.lsp.buf.definition, {buffer = bufnr, desc = 'goto definition'})
-    vim.keymap.set('n', 'gR'        , vim.lsp.buf.references, {buffer = bufnr, desc = 'goto references'})
-    vim.keymap.set('n', ';R'        , require('telescope.builtin').lsp_references, {desc='lsp references'})
+    vim.keymap.set(
+      'n',
+      '<C-]>',
+      vim.lsp.buf.definition,
+      { buffer = bufnr, desc = 'goto definition' }
+    )
+    vim.keymap.set('n', 'gd', vim.lsp.buf.definition, { buffer = bufnr, desc = 'goto definition' })
+    vim.keymap.set('n', 'gR', vim.lsp.buf.references, { buffer = bufnr, desc = 'goto references' })
+    vim.keymap.set(
+      'n',
+      ';R',
+      require('telescope.builtin').lsp_references,
+      { desc = 'lsp references' }
+    )
   end
   if client.supports_method('textDocument/hover') then
-    vim.keymap.set('n', 'K'         , vim.lsp.buf.hover, {buffer = bufnr, desc = 'hover'})
+    vim.keymap.set('n', 'K', vim.lsp.buf.hover, { buffer = bufnr, desc = 'hover' })
   end
   if client.supports_method('textDocument/rename') then
-    vim.keymap.set('n', 'grr'       , vim.lsp.buf.rename, {buffer = bufnr, desc = 'rename'})
+    vim.keymap.set('n', 'grr', vim.lsp.buf.rename, { buffer = bufnr, desc = 'rename' })
   end
   if client.supports_method('signatureHelp') then
-    vim.keymap.set('n', '<c-h>'     , vim.lsp.buf.signature_help, {buffer = bufnr, desc = 'signature help'})
+    vim.keymap.set(
+      'n',
+      '<c-h>',
+      vim.lsp.buf.signature_help,
+      { buffer = bufnr, desc = 'signature help' }
+    )
   end
   if client.supports_method('textDocument/formatting') then
     vim.api.nvim_buf_set_option(bufnr, 'formatexpr', 'v:lua.vim.lsp.formatexpr()')
-    vim.keymap.set('n', '<leader>f' , vim.lsp.buf.format, {buffer = bufnr, desc = 'format'})
+    vim.keymap.set('n', '<leader>f', vim.lsp.buf.format, { buffer = bufnr, desc = 'format' })
     vim.api.nvim_create_autocmd('BufWritePre', {
       buffer = bufnr,
       group = group,
-      callback = function() require('internal.lsp').format(vim.fn.expand('<afile>:p')) end,
+      callback = function()
+        require('internal.lsp').format(vim.fn.expand('<afile>:p'))
+      end,
     })
   end
   if client.supports_method('textDocument/typeDefinition') then
-    vim.keymap.set('n', 'gT'        , vim.lsp.buf.type_definition, {buffer = bufnr, desc = 'goto typedef'})
+    vim.keymap.set(
+      'n',
+      'gT',
+      vim.lsp.buf.type_definition,
+      { buffer = bufnr, desc = 'goto typedef' }
+    )
   end
   if client.supports_method('textDocument/declaration') then
-    vim.keymap.set('n', 'gD'        , vim.lsp.buf.declaration, {buffer = bufnr, desc = 'goto declaration'})
+    vim.keymap.set(
+      'n',
+      'gD',
+      vim.lsp.buf.declaration,
+      { buffer = bufnr, desc = 'goto declaration' }
+    )
   end
   if client.supports_method('textDocument/implementation') then
-    vim.keymap.set('n', 'gI'        , vim.lsp.buf.implementation, {buffer = bufnr, desc = 'goto implementation'})
+    vim.keymap.set(
+      'n',
+      'gI',
+      vim.lsp.buf.implementation,
+      { buffer = bufnr, desc = 'goto implementation' }
+    )
   end
   if client.supports_method('textDocument/codeAction') then
-    vim.keymap.set('n', 'ga', vim.lsp.buf.code_action, {buffer = bufnr, desc = 'code action'})
+    vim.keymap.set('n', 'ga', vim.lsp.buf.code_action, { buffer = bufnr, desc = 'code action' })
   end
   if client.supports_method('textDocument/documentHighlight') then
-    vim.keymap.set('n', '<leader>8', vim.lsp.buf.document_highlight, {buffer = bufnr, desc = 'document highlight'})
+    vim.keymap.set(
+      'n',
+      '<leader>8',
+      vim.lsp.buf.document_highlight,
+      { buffer = bufnr, desc = 'document highlight' }
+    )
     -- vim.keymap.set('n', '', vim.lsp.buf.clear_references, {buffer = bufnr, desc = 'clear references'})
     vim.api.nvim_create_autocmd('CursorMoved', {
       callback = vim.lsp.buf.clear_references,
@@ -82,8 +131,7 @@ local my_attach = function(client, bufnr)
   end
 end
 
-local my_exit = function(_, _, _)
-end
+local my_exit = function(_, _, _) end
 
 local capabilities = function()
   local caps = vim.lsp.protocol.make_client_capabilities()
@@ -94,33 +142,22 @@ local capabilities = function()
       'documentation',
       'detail',
       'additionalTextEdits',
-    }
+    },
   }
   -- add window/workDoneProgress capability
-  caps = vim.tbl_extend('keep', caps or {}, lspstatus.capabilities)
+  caps = vim.tbl_extend('keep', caps or {}, require('lsp-status').capabilities)
   return caps
 end
 
 local servers = {
-  ccls = { disabled = true,
-    root_dir = lsp.util.root_pattern('.ccls','meson.build','.git'),
-    init_options = {
-      compilationDatabaseDirectory = "build",
-      index = { threads = 0 },
-      completion = {
-        filterAndSort = false,
-      },
-      clang = { excludeArgs = { '-frounding-math' } },
-    },
-  },
   clangd = {},
   elixirls = {
     cmd = { 'elixir-ls' },
     settings = {
       elixirLS = {
         dialyzerEnabled = false,
-      }
-    }
+      },
+    },
   },
   gopls = {
     settings = {
@@ -135,11 +172,12 @@ local servers = {
         },
         gofumpt = true,
         -- hoverKind = 'Structured',
-      }
-    }
+      },
+    },
   },
   sumneko_lua = {
-    cmd = { 'lua-language-server' },
+    -- cmd = { 'lua-language-server' },
+    cmd = { 'luals' },
     settings = {
       Lua = {
         runtime = {
@@ -153,7 +191,8 @@ local servers = {
             'error',
             'os',
             'package',
-            'pairs', 'ipairs',
+            'pairs',
+            'ipairs',
             'pcall',
             'require',
             'string',
@@ -165,14 +204,14 @@ local servers = {
           },
           neededFileStatus = {
             ['code-style-check'] = 'Any',
-          }
+          },
         },
         format = {
-          enable =  true,
+          enable = true,
           defaultConfig = {
             indent_style = 'space',
             indent_size = '2',
-          }
+          },
         },
         workspace = {
           -- library = vim.api.nvim_get_runtime_file("", true),
@@ -180,7 +219,7 @@ local servers = {
             [vim.env.VIMRUNTIME .. '/lua'] = true,
             [vim.env.VIMRUNTIME .. '/lua/vim/lsp'] = true,
             [vim.fn.stdpath('config') .. '/lua'] = true,
-          }
+          },
         },
         telemetry = {
           enable = false,
@@ -189,61 +228,69 @@ local servers = {
     },
   },
   rust_analyzer = {
-    cmd = { 'env', 'CARGO_TARGET_DIR=/tmp', 'RUST_SRC_PATH=/usr/src/rustlib/library', 'rust-analyzer' },
+    -- cmd = { 'env', 'CARGO_TARGET_DIR=/tmp', 'RUST_SRC_PATH=/usr/src/rustlib/library', 'rust-analyzer' },
     settings = {
       ['rust-analyzer'] = {
         checkOnSave = {
-          command = 'clippy'
-        }
-      }
-    },
-  },
-  tsserver = { disabled = true,
-    cmd = {
-      'toolbox', 'run', '--',
-      'sh', '-c',
-      '. /etc/profile.d/nvm.sh && typescript-language-server --stdio'
+          command = 'clippy',
+        },
+      },
     },
   },
-  zls = { disabled = true,
-  },
-  zk = { disabled = true,
-    root_dir = lsp.util.root_pattern('.zk'),
-  },
+  pylsp = {},
+  -- tsserver = { disabled = true,
+  --   cmd = {
+  --     'toolbox', 'run', '--',
+  --     'sh', '-c',
+  --     '. /etc/profile.d/nvm.sh && typescript-language-server --stdio'
+  --   },
+  -- },
+  -- zls = { disabled = true },
+  -- zk = {
+  --   cmd = {'zk', 'lsp', '--log', '/tmp/zk-lsp.log'},
+  --   autostart = true,
+  -- },
 }
 
 local setup = function()
   -- configure floating win handlers
-  vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(
-    vim.lsp.handlers.hover, { border = _G.floating_win_border })
-  vim.lsp.handlers['textDocument/signature_help'] = vim.lsp.with(
-    vim.lsp.handlers.signature_help, { border = _G.floating_win_border })
+  vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, {
+    focus = false,
+    zindex = 100,
+    border = _G.floating_win_border,
+  })
+  vim.lsp.handlers['textDocument/signature_help'] =
+    vim.lsp.with(vim.lsp.handlers.signature_help, { border = _G.floating_win_border })
 
   local caps = capabilities()
   for server, opts in pairs(servers) do
     if not opts.disabled then
       opts = vim.tbl_extend('error', opts, {
-        on_attach    = my_attach,
-        on_exit      = my_exit,
+        on_attach = my_attach,
+        on_exit = my_exit,
         capabilities = caps,
       })
       -- lsp-status custom handlers
-      local ok, lspstatus_ext = pcall(lspstatus.extensions[server])
+      local ok, lspstatus_ext = pcall(require('lsp-status').extensions[server])
       if ok then
         opts = vim.tbl_extend('error', opts, {
           handlers = lspstatus_ext.setup(),
         })
       end
-      lsp[server].setup(opts)
+      require('lspconfig')[server].setup(opts)
     end
   end
 end
 
 local format = function(afile)
-  if vim.g.nofmt then return end
+  if vim.g.nofmt then
+    return
+  end
 
   local ok, isMatch = pcall(string.match, afile, '^/home/robert/devel/upstream')
-  if not ok or isMatch then return end
+  if not ok or isMatch then
+    return
+  end
 
   local errhandler = function(err)
     vim.notify('fmt failed: ' .. err, vim.log.levels.ERROR)
@@ -251,54 +298,21 @@ local format = function(afile)
   end
   xpcall(vim.lsp.buf.format, errhandler)
   if string.match(afile, '.go$') then
-    xpcall(vim.lsp.buf.code_action, errhandler, {context = {only = {'source.organizeImports'}}, apply = true})
+    xpcall(
+      vim.lsp.buf.code_action,
+      errhandler,
+      { context = { only = { 'source.organizeImports' } }, apply = true }
+    )
   end
   -- vim.notify('%#MoreMsg#󰃢%#Italic# fmt', vim.log.levels.INFO)
   vim.notify('󰃢 ', vim.log.levels.INFO)
 end
 
-local symbols = {
-  -- 󰆼  󱆃
-  Array = '󰨾 ',
-  Boolean = '󰦍 ',
-  Class = '󰙀 ',
-  Color = '󰉦 ',
-  Constant = ' ',
-  Constructor = '󱇿 ',
-  Enum = ' ',
-  EnumMember = ' ',
-  Event = '󱐋 ',
-  -- Field = '󰽜 ',
-  Field = '󰆈 ',
-  File = '󰈔 ',
-  Folder = '󰝰 ',
-  Function = ' ',
-  Interface = '󱦜 ',
-  Key = '󰌋 ',
-  Keyword = '󰓽 ',
-  Method = '󰒓 ',
-  Module = '󰏖 ',
-  Namespace = '󰆧 ',
-  Null = '󰎣 ',
-  Object = '󰘦 ',
-  Operator = '󱓉 ',
-  Property = '󰐱 ',
-  Package = '󰏗 ',
-  Reference = '󰌹 ',
-  Snippet = '󰯁 ',
-  Struct = '󰙅 ',
-  Text = '󰉿 ',
-  TypeParameter = '󰌨 ',
-  Unit = '󰠱 ',
-  Value = '󰎠 ',
-  Variable = '󱄑 ',
-}
-
 return {
-  my_attach    = my_attach,
-  my_exit      = my_exit,
+  my_attach = my_attach,
+  my_exit = my_exit,
   capabilities = capabilities,
-  setup        = setup,
-  format       = format,
-  symbols       = symbols,
+  setup = setup,
+  format = format,
+  symbols = symbols,
 }
diff --git a/.vim/lua/internal/misc.lua b/.vim/lua/internal/misc.lua
index b7d1a06..8664cbc 100644
--- a/.vim/lua/internal/misc.lua
+++ b/.vim/lua/internal/misc.lua
@@ -28,19 +28,23 @@ function M.open_under_cursor(cmd, detect_cmd)
       if vim.regex([[^(\.\./|[\w\d_/\-])*(\.[\w\d]+)?$]]):match_str(txt) then
         cmd = ':edit'
       end
-      vim.notify("open_under_cursor: detected command " .. txt .. " => " .. (cmd or "<nil>"))
+      vim.notify('open_under_cursor: detected command ' .. txt .. ' => ' .. (cmd or '<nil>'))
     end
     if not cmd then
       vim.fn.inputsave()
-      vim.ui.input('open with: ', function(result) cmd = result end)
+      vim.ui.input('open with: ', function(result)
+        cmd = result
+      end)
       vim.fn.inputrestore()
-      if not cmd then return end
+      if not cmd then
+        return
+      end
     end
     -- detect vim command
-    if cmd:sub(1, 1) == ":" then
+    if cmd:sub(1, 1) == ':' then
       vim.cmd(cmd:sub(2) .. ' ' .. txt)
     else
-      vim.loop.spawn(cmd, {args = {txt}})
+      vim.loop.spawn(cmd, { args = { txt } })
     end
   end)
 end
@@ -54,7 +58,7 @@ local function get_visual_selection()
   if vim.opt.selection:get() == 'inclusive' then
     lines[#lines] = lines[#lines]:sub(1, bot.col)
   else
-    lines[#lines] = lines[#lines]:sub(1, (bot.col -1))
+    lines[#lines] = lines[#lines]:sub(1, (bot.col - 1))
   end
   lines[1] = lines[1]:sub(top.col)
   return top, bot, lines
@@ -64,12 +68,12 @@ function M.sort_lines(_, preview_ns, preview_bufnr)
   local bufnr = vim.api.nvim_get_current_buf()
 
   local top, bot, lines = get_visual_selection()
-  for i=1, #lines do
-    lines[i] = vim.fn.join(vim.fn.sort(vim.fn.split(lines[i], " ")))
+  for i = 1, #lines do
+    lines[i] = vim.fn.join(vim.fn.sort(vim.fn.split(lines[i], ' ')))
   end
 
   if not preview_ns then
-    vim.api.nvim_buf_set_lines(bufnr, top.ln-1, bot.ln, false, lines)
+    vim.api.nvim_buf_set_lines(bufnr, top.ln - 1, bot.ln, false, lines)
     vim.notify('no preview')
     return 0
   end
@@ -77,16 +81,23 @@ function M.sort_lines(_, preview_ns, preview_bufnr)
   -- inccommand preview
   if preview_ns ~= nil then
     for i, line in ipairs(lines) do
-      vim.api.nvim_buf_set_extmark(bufnr, preview_ns, top.ln+i - 2, 0, {
+      vim.api.nvim_buf_set_extmark(bufnr, preview_ns, top.ln + i - 2, 0, {
         hl_mode = 'combine',
         virt_text_pos = 'overlay',
-        virt_text = {{line, 'Substitute'}},
+        virt_text = { { line, 'Substitute' } },
       })
 
       if preview_bufnr ~= nil then
         local prefix = string.format('|%d| ', top.ln + i - 1)
-        vim.api.nvim_buf_set_lines(preview_bufnr, i-1, -1, false, { prefix .. line })
-        vim.api.nvim_buf_add_highlight(preview_bufnr, preview_ns, 'Substitute', i, #prefix, #prefix+#line)
+        vim.api.nvim_buf_set_lines(preview_bufnr, i - 1, -1, false, { prefix .. line })
+        vim.api.nvim_buf_add_highlight(
+          preview_bufnr,
+          preview_ns,
+          'Substitute',
+          i,
+          #prefix,
+          #prefix + #line
+        )
       end
     end
     return (#lines > 1 and 2 or 1)
@@ -96,20 +107,24 @@ end
 local get_searchdirs = function(dirs)
   if type(dirs) == 'table' and #dirs > 0 then
     return dirs
-  elseif type(dirs) == 'string' and not (dirs == "") then
+  elseif type(dirs) == 'string' and not (dirs == '') then
     dirs = vim.split(dirs, ',')
   end
   -- skip asking if we're looking at known filetypes
   local ft = vim.api.nvim_buf_get_option(0, 'filetype')
   if #dirs == 0 and (ft == 'dirbuf' or ft == 'alpha') then
-    dirs = {'%:p:h'}
+    dirs = { '%:p:h' }
   end
   -- ask user
   if #dirs == 0 then
-    vim.ui.input({prompt = 'Search directories: '}, function(result) dirs = {result} end)
+    vim.ui.input({ prompt = 'Search directories: ' }, function(result)
+      dirs = { result }
+    end)
   end
   -- default to something reasonable
-  if #dirs == 0 then dirs = {'%:p:h'} end
+  if #dirs == 0 then
+    dirs = { '%:p:h' }
+  end
   -- finally return
   for i = 1, #dirs do
     dirs[i] = vim.fn.expand(dirs[i])
@@ -118,11 +133,15 @@ local get_searchdirs = function(dirs)
 end
 
 function onchoice(opts, cb)
-  if not cb then return end
+  if not cb then
+    return
+  end
   opts.attach_mappings = function(prompt_bufnr)
     require('telescope.actions').select_default:replace(function()
       local selection = require('telescope.actions.state').get_selected_entry()
-      if selection == nil then return end
+      if selection == nil then
+        return
+      end
       require('telescope.actions').close(prompt_bufnr)
       on_choice(selection.path)
     end)
@@ -134,25 +153,28 @@ function M.live_grep(dirs, opts, cb)
   opts = opts or {}
   local search_dirs = get_searchdirs(dirs)
   opts.search_dirs = search_dirs
-  opts.prompt_title = 'Grep: '.. vim.inspect(search_dirs)
+  opts.prompt_title = 'Grep: ' .. vim.inspect(search_dirs)
   onchoice(opts, cb)
   require('telescope.builtin').live_grep(opts)
 end
 
 function M.find_files(dirs, opts, cb)
   -- convenience aliases
-  if dirs == 'plugins' then dirs = vim.fn.stdpath('data') .. '/site/pack/' end
+  if dirs == 'plugins' then
+    dirs = vim.fn.stdpath('data') .. '/site/pack/'
+  end
 
   opts = opts or {}
   local search_dirs = dirs
-  if type(dirs) == 'string' then search_dirs = get_searchdirs(dirs) end
+  if type(dirs) == 'string' then
+    search_dirs = get_searchdirs(dirs)
+  end
   opts.search_dirs = search_dirs
-  opts.prompt_title = 'Find: '.. vim.inspect(search_dirs)
+  opts.prompt_title = 'Find: ' .. vim.inspect(search_dirs)
   onchoice(opts, cb)
   require('telescope.builtin').find_files(opts)
 end
 
-
 function M.fold_block() -- {{{
   local Comment = require('Comment.api')
   local m = vim.api.nvim_buf_get_mark
@@ -179,51 +201,67 @@ end -- }}}
 
 function M.link_preview()
   local link = vim.fn.expand('<cfile>')
-  if not link then return end
+  if not link then
+    return
+  end
 
   local buf = vim.api.nvim_get_current_buf()
-  local ln = (vim.api.nvim_win_get_cursor(0)[1]) - 1
-
-  require('job').jobstart({
-    format_title = function() return "link-preview"  end,
-    command = vim.env.SHELL,
-    args = {'-c', [[ curl -sSfL ]] .. link .. [[ | grep -iPo '(?<=property="og:title" content=")([^\"]+)(?=")' ]]},
-    populate_quickfix = false,
-    enable_recording = true,
-  }):after_success(
-    vim.schedule_wrap(function(j, code, _)
+  local ln = vim.api.nvim_win_get_cursor(0)[1] - 1
+
+  require('job')
+    .jobstart({
+      format_title = function()
+        return 'link-preview'
+      end,
+      command = vim.env.SHELL,
+      args = {
+        '-c',
+        [[ curl -sSfL ]]
+          .. link
+          .. [[ | grep -iPo '(?<=property="og:title" content=")([^\"]+)(?=")' ]],
+      },
+      populate_quickfix = false,
+      enable_recording = true,
+    })
+    :after_success(vim.schedule_wrap(function(j, code, _)
       local results = j:result()
-      if not code == 0 or #results == 0 then return end
+      if not code == 0 or #results == 0 then
+        return
+      end
 
       local ns = vim.api.nvim_create_namespace('')
       vim.api.nvim_buf_set_extmark(buf, ns, ln, 0, {
-        virt_text = {{results[1], 'Error'}},
-        virt_text_pos = 'eol'
+        virt_text = { { results[1], 'Error' } },
+        virt_text_pos = 'eol',
       })
-    end)
-  )
+    end))
 end
 
 function M.setup(opts)
   if opts.sortline then
-    vim.api.nvim_create_user_command('SortLine', M.sort_lines,
-      { desc = 'sort line', range = '%', preview = M.sort_lines })
+    vim.api.nvim_create_user_command(
+      'SortLine',
+      M.sort_lines,
+      { desc = 'sort line', range = '%', preview = M.sort_lines }
+    )
   end
   if opts.grep then
-    vim.api.nvim_create_user_command('Grep', function(o) M.live_grep(table.concat(o.fargs)) end,
-      {
-        desc = 'live grep (rg)',
-        nargs = '*',
-        complete = 'dir',
-      })
+    vim.api.nvim_create_user_command('Grep', function(o)
+      M.live_grep(table.concat(o.fargs))
+    end, {
+      desc = 'live grep (rg)',
+      nargs = '*',
+      complete = 'dir',
+    })
   end
   if opts.find then
-    vim.api.nvim_create_user_command('Find', function(o) M.find_files(table.concat(o.fargs)) end,
-      {
-        desc = 'find files (fd)',
-        nargs = '*',
-        complete = 'dir',
-      })
+    vim.api.nvim_create_user_command('Find', function(o)
+      M.find_files(table.concat(o.fargs))
+    end, {
+      desc = 'find files (fd)',
+      nargs = '*',
+      complete = 'dir',
+    })
   end
 end
 
diff --git a/.vim/lua/internal/snips.lua b/.vim/lua/internal/snips.lua
index 318c9f7..423eec6 100644
--- a/.vim/lua/internal/snips.lua
+++ b/.vim/lua/internal/snips.lua
@@ -1,4 +1,3 @@
-
 local ls = require('luasnip')
 local types = require('luasnip.util.types')
 
@@ -13,7 +12,7 @@ vim.api.nvim_set_hl(0, 'LuasnipIndicator', {
 local autowrap = function(top, bot, inner)
   local autoinsert = function(args, _, _, wrap_with)
     local nodes = {}
-    if vim.trim(table.concat(args[1] or {})) ~= "" then
+    if vim.trim(table.concat(args[1] or {})) ~= '' then
       table.insert(nodes, wrap_with)
     end
     return ls.sn(nil, nodes)
@@ -31,9 +30,11 @@ local autowrap = function(top, bot, inner)
   end
 
   local nodes = {}
-  table.insert(nodes, ls.d(maxpos+1, autoinsert, argnodes, {user_args = {top}}))
-  for _, e in ipairs(inner) do table.insert(nodes, e) end
-  table.insert(nodes, ls.d(maxpos+2, autoinsert, argnodes, {user_args = {bot}}))
+  table.insert(nodes, ls.d(maxpos + 1, autoinsert, argnodes, { user_args = { top } }))
+  for _, e in ipairs(inner) do
+    table.insert(nodes, e)
+  end
+  table.insert(nodes, ls.d(maxpos + 2, autoinsert, argnodes, { user_args = { bot } }))
   return nodes
 end
 
@@ -41,61 +42,88 @@ end
 local comment = function(wrapped, blockcomment)
   -- commentstring helper
   local get_cstring = function()
-    local cs = require('Comment.ft').calculate {
+    local cs = require('Comment.ft').calculate({
       ctype = blockcomment and 2 or 1,
-      range = require('Comment.utils').get_region()
-    }
-    local tbl = vim.split(cs or '', '%s', {plain = true, trimempty = true})
-    return (#tbl == 0) and {'', ''}
-      or ((#tbl == 1) and {tbl[1] .. ' ', ''}
-        or {tbl[1], tbl[2]})
+      range = require('Comment.utils').get_region(),
+    })
+    local tbl = vim.split(cs or '', '%s', { plain = true, trimempty = true })
+    return (#tbl == 0) and { '', '' }
+      or ((#tbl == 1) and { tbl[1] .. ' ', '' } or { tbl[1], tbl[2] })
   end
 
-  if type(wrapped) ~= "table" then
-    wrapped = {wrapped}
+  if type(wrapped) ~= 'table' then
+    wrapped = { wrapped }
   end
 
   local nodes = {}
-  table.insert(nodes, ls.f(function() return get_cstring()[1] end))
-  for _, n in ipairs(wrapped) do table.insert(nodes, n) end
-  table.insert(nodes, ls.f(function() return get_cstring()[2] end))
+  table.insert(
+    nodes,
+    ls.f(function()
+      return get_cstring()[1]
+    end)
+  )
+  for _, n in ipairs(wrapped) do
+    table.insert(nodes, n)
+  end
+  table.insert(
+    nodes,
+    ls.f(function()
+      return get_cstring()[2]
+    end)
+  )
   return nodes
 end
 
 -- exec: inserts the output of command
 local exec = function(command)
   return ls.f(function(_, _, ...)
-    local results, code = require('plenary.job'):new({
-      command = vim.env.SHELL,
-      args = {'-c', ...},
-      enable_recording = true,
-    }):sync()
+    local results, code = require('plenary.job')
+      :new({
+        command = vim.env.SHELL,
+        args = { '-c', ... },
+        enable_recording = true,
+      })
+      :sync()
     if not code == 0 or #results == 0 then
       error(string.format('exec "%s" failed', ...))
     end
     return results
-  end, {}, {user_args = {command}})
+  end, {}, { user_args = { command } })
+end
+
+local file_contents = function(path, vargs)
+  return ls.d(1, function(_, _, _, ...)
+    local lines = {}
+    for line in io.lines(path) do
+      table.insert(lines, line)
+    end
+    return ls.sn(nil, require('luasnip.extras.fmt').fmt(table.concat(lines, '\n'), ...))
+  end, {}, { user_args = { vargs } })
 end
 
-ls.setup {
+ls.setup({
   ext_opts = {
     [types.snippet] = {
-      active = { virt_text = {{ '<-- luasnip', 'LuasnipIndicator' }}, virt_text_pos = 'right_align' }
+      active = {
+        virt_text = { { '<-- luasnip', 'LuasnipIndicator' } },
+        virt_text_pos = 'right_align',
+      },
     },
     [types.insertNode] = {
-      unvisited = { hl_group = 'LuasnipIndicator' }
+      unvisited = { hl_group = 'LuasnipIndicator' },
     },
     [types.choiceNode] = {
       active = {
-        virt_text = {{'<-- choice node', 'LuasnipIndicator'}},
-      }
-    }
+        virt_text = { { '<-- choice node', 'LuasnipIndicator' } },
+      },
+    },
   },
 
   snip_env = vim.tbl_extend('keep', ls.session.config.snip_env, {
     autowrap = autowrap,
     exec = exec,
     comment = comment,
+    file_contents = file_contents,
 
     user_email = {
       exec([[git config --get user.name]]),
@@ -107,18 +135,16 @@ ls.setup {
       }),
       ls.t('>'),
     },
-  })
-}
+  }),
+})
 
 -- snipmate snippets
-require('luasnip.loaders.from_snipmate').lazy_load {paths = './after/snippets'}
+require('luasnip.loaders.from_snipmate').lazy_load({ paths = './after/snippets' })
 -- lua snippets
-require("luasnip.loaders.from_lua").lazy_load {paths = './snippets'}
+require('luasnip.loaders.from_lua').lazy_load({ paths = './snippets' })
 
-vim.api.nvim_create_user_command('LuaSnipUnlinkAll',
-  function()
-    while #package.loaded.luasnip.session.current_nodes > 0 do
-      package.loaded.luasnip.unlink_current()
-    end
-  end,
-  { desc = 'unlink all active snippets' })
+vim.api.nvim_create_user_command('LuaSnipUnlinkAll', function()
+  while #package.loaded.luasnip.session.current_nodes > 0 do
+    package.loaded.luasnip.unlink_current()
+  end
+end, { desc = 'unlink all active snippets' })
diff --git a/.vim/lua/internal/spell.lua b/.vim/lua/internal/spell.lua
index 57cbad2..3c37dad 100644
--- a/.vim/lua/internal/spell.lua
+++ b/.vim/lua/internal/spell.lua
@@ -1,8 +1,7 @@
-
 vim.opt_local.spell = true
 vim.opt.spellfile = vim.fn['spellfile#WritableSpellDir']() .. '/spellfile.utf-8.add'
 vim.opt.spellcapcheck = ''
-vim.opt.spelloptions = {'camel'}
+vim.opt.spelloptions = { 'camel' }
 vim.opt.spellsuggest = 'double'
 
 vim.keymap.set('n', '<C-l>', require('telescope.builtin').spell_suggest)
diff --git a/.vim/lua/internal/statusline.lua b/.vim/lua/internal/statusline.lua
index 97f5031..1c09271 100644
--- a/.vim/lua/internal/statusline.lua
+++ b/.vim/lua/internal/statusline.lua
@@ -5,28 +5,21 @@ function _G.statusline()
   local sl = hi
   -- sl = sl .. statusline_append([[ ⢷]], 'StatusLineIcon', hi)
 
-  sl = sl .. statusline_append(statusline_lightbulb(),
-    'StatusLineLightbulb', hi)
+  sl = sl .. statusline_append(statusline_lightbulb(), 'StatusLineLightbulb', hi)
 
-  sl = sl .. statusline_append(statusline_ts(),
-    'StatusLineTreesitter', hi)
+  sl = sl .. statusline_append(statusline_ts(), 'StatusLineTreesitter', hi)
 
-  sl = sl .. statusline_append(statusline_lsp_diagnostics(bufnr, hi),
-    'StatusLineDiagnostics', hi)
+  sl = sl .. statusline_append(statusline_lsp_diagnostics(bufnr, hi), 'StatusLineDiagnostics', hi)
 
-  sl = sl .. statusline_append(statusline_lspstatus(),
-    'StatusLineLsp', hi)
+  sl = sl .. statusline_append(statusline_lspstatus(), 'StatusLineLsp', hi)
 
-  sl = sl .. statusline_append(statusline_dap(),
-    'StatusLineDap', hi)
+  sl = sl .. statusline_append(statusline_dap(), 'StatusLineDap', hi)
 
   sl = sl .. [[ %= ]] -- spacer
 
-  sl = sl .. statusline_append(statusline_notify(hi),
-    'StatusLineNotify', hi)
+  sl = sl .. statusline_append(statusline_notify(hi), 'StatusLineNotify', hi)
 
-  sl = sl .. statusline_append(statusline_spinner(bufnr),
-    'StatusLineJobs', hi)
+  sl = sl .. statusline_append(statusline_spinner(bufnr), 'StatusLineJobs', hi)
 
   sl = sl .. statusline_append([[ %l:%v --%p%%-- %y]], hi, hi)
 
@@ -49,83 +42,123 @@ function _G.statusline_color(mode)
 end
 -- does item highlighting and conditionnal spacing
 function _G.statusline_append(element, hi, default_hi, opts)
-  if not element or element == '' then return '' end
+  if not element or element == '' then
+    return ''
+  end
   opts = opts or { append_space = true }
 
-  if hi ~= nil then hi = '%#' .. hi .. '#' end
-  if not (default_hi == '%*') then hi = default_hi end
+  if hi ~= nil then
+    hi = '%#' .. hi .. '#'
+  end
+  if not (default_hi == '%*') then
+    hi = default_hi
+  end
   local el = hi .. element .. default_hi
-  if opts.append_space then el = el .. ' ' end
+  if opts.append_space then
+    el = el .. ' '
+  end
   return el
 end
 function _G.statusline_combine_hi(outer_name, inner_name)
   local outer = vim.api.nvim_get_hl_by_id(vim.api.nvim_get_hl_id_by_name(outer_name), true)
   local inner = vim.api.nvim_get_hl_by_id(vim.api.nvim_get_hl_id_by_name(inner_name), true)
   local hi = 'auto' .. outer_name .. inner_name
-  if pcall(vim.api.nvim_get_hl_by_name, hi, true)  then return hi end
+  if pcall(vim.api.nvim_get_hl_by_name, hi, true) then
+    return hi
+  end
   local gui
   gui = inner.bold and 'bold'
   gui = inner.italic and 'italic'
   gui = inner.underline and 'underline'
-  vim.api.nvim_set_hl(0, hi, {bg = outer.background, fg = inner.foreground, gui = gui})
+  vim.api.nvim_set_hl(0, hi, { bg = outer.background, fg = inner.foreground, gui = gui })
   return hi
 end
 
 function _G.statusline_lsp_diagnostics(bufnr, default_hi)
-  local error_num = vim.diagnostic.get(bufnr, {severity=vim.diagnostic.severity.ERROR})
-  local warn_num = vim.diagnostic.get(bufnr, {severity=vim.diagnostic.severity.WARN})
+  local error_num = vim.diagnostic.get(bufnr, { severity = vim.diagnostic.severity.ERROR })
+  local warn_num = vim.diagnostic.get(bufnr, { severity = vim.diagnostic.severity.WARN })
 
   local s = ''
   if #error_num > 0 then
     local errs = vim.fn.sign_getdefined('DiagnosticSignError')[1].text .. #error_num
-    s = s .. statusline_append(errs, statusline_combine_hi('StatusLineDiagnostics', 'DiagnosticError'), default_hi)
+    s = s
+      .. statusline_append(
+        errs,
+        statusline_combine_hi('StatusLineDiagnostics', 'DiagnosticError'),
+        default_hi
+      )
   end
   if #warn_num > 0 then
     local warns = vim.fn.sign_getdefined('DiagnosticSignWarn')[1].text .. #warn_num
-    s = s .. statusline_append(warns, statusline_combine_hi('StatusLineDiagnostics', 'DiagnosticWarn'), default_hi)
+    s = s
+      .. statusline_append(
+        warns,
+        statusline_combine_hi('StatusLineDiagnostics', 'DiagnosticWarn'),
+        default_hi
+      )
   end
   return vim.trim(s)
 end
 function _G.statusline_ts()
   local navic = package.loaded['nvim-navic']
-  if not navic then return '' end
+  if not navic then
+    return ''
+  end
   local data = navic.get_data()
-  if not data then return '' end
+  if not data then
+    return ''
+  end
   local s = {}
   for i = 1, #data do
-    table.insert(s, string.format('%%#CmpItemKind%s#%s%%* %%#StatusLine#%s%%*', data[i].type, data[i].icon, data[i].name))
+    table.insert(
+      s,
+      string.format(
+        '%%#CmpItemKind%s#%s%%* %%#StatusLine#%s%%*',
+        data[i].type,
+        data[i].icon,
+        data[i].name
+      )
+    )
   end
   return table.concat(s, ' > ')
 end
 function _G.statusline_lspstatus()
   local lst = package.loaded['lsp-status']
-  if not lst then return '' end
+  if not lst then
+    return ''
+  end
   return vim.trim(lst.status())
 end
 function _G.statusline_lightbulb()
   local lb = package.loaded['nvim-lightbulb']
-  if not lb then return '' end
+  if not lb then
+    return ''
+  end
   return lb.get_status_text()
 end
 function _G.statusline_spinner(bufnr)
   local sp = package.loaded.spinner
-  if not sp then return '' end
+  if not sp then
+    return ''
+  end
   return sp.status(bufnr)
 end
 function _G.statusline_dap()
   local dap = package.loaded.dap
-  if not dap then return '' end
+  if not dap then
+    return ''
+  end
   local s = dap.status()
-  if s == '' then return s end
+  if s == '' then
+    return s
+  end
   return '[DAP: ' .. s .. ']'
 end
 
--- notifications cache
-_G.statusline_notifications = {}
-_G.statusline_notifications_archive = {}
-
 function _G.statusline_notify(default_hi)
-  if #_G.statusline_notifications == 0 then return '' end
+  if not _G.statusline_notifications or #_G.statusline_notifications == 0 then
+    return ''
+  end
   local n = _G.statusline_notifications[1]
   local timeout = (n.options and n.options.timeout) or 2000
   -- pop message after <timeout> and move to archive
@@ -140,110 +173,18 @@ function _G.statusline_notify(default_hi)
 
   local s = ''
   if n.hi then
-    s = s .. statusline_append(n.lvl_string .. ' ', statusline_combine_hi('StatusLineNotify', n.hi), default_hi, { append_space = false })
+    s = s
+      .. statusline_append(
+        n.lvl_string .. ' ',
+        statusline_combine_hi('StatusLineNotify', n.hi),
+        default_hi,
+        { append_space = false }
+      )
   end
-  s = s .. statusline_append(n.message, 'StatusLineNotify', default_hi)
+  s = s .. statusline_append(vim.inspect(n.message), 'StatusLineNotify', default_hi)
   return vim.trim(s)
 end
 
--- out vim.notify implementation
-local notify = function(m, l, o)
-  local lvl_string = l
-  local hi = nil
-  if l and type(l) == 'number' then
-    if l == vim.log.levels.TRACE then
-      hi = 'deEmph'
-    elseif l == vim.log.levels.DEBUG then
-      hi = 'DiagnosticHint'
-    elseif l == vim.log.levels.INFO then
-      hi = 'DiagnosticInfo'
-    elseif l == vim.log.levels.WARN then
-      hi = 'DiagnosticWarn'
-    elseif l == vim.log.levels.ERROR then
-      hi = 'DiagnosticError'
-    end
-    -- get level string
-    lvl_string = vim.lsp.log_levels[l]
-  end
-  local display = m
-  if lvl_string then display = lvl_string .. ' ' .. display end
-  table.insert(_G.statusline_notifications, {
-    message = m,
-    level = l,
-    options = o,
-    lvl_string = lvl_string,
-    hi = hi,
-    display = display,
-  })
-
-  if _G.statusline_enable_notifysend then
-    local args = {}
-    if lvl_string then
-      if lvl_string == 'ERROR' then
-        table.insert(args, '--category=error')
-      end
-      if lvl_string == 'WARN' then
-        table.insert(args, '--category=warning')
-      end
-    end
-    table.insert(args, 'nvim')
-    table.insert(args, display)
-    require('internal.job').jobstart { command = 'notify-send', args = args }
-  end
-end
-
--- overwrite vim.notify
-vim.notify = function( m, l, o)
-  if vim.in_fast_event() then
-    vim.schedule(function()
-      notify(m, l, o)
-    end)
-  else
-    return notify(m, l, o)
-  end
-end
-
-vim.keymap.set('n', '<leader>n', function()
-  local pickers = require('telescope.pickers')
-  local finders = require('telescope.finders')
-  local conf = require('telescope.config').values
-  local actions = require('telescope.actions')
-  -- local action_state = require('telescope.actions.state')
-  -- local previewers = require('telescope.previewers')
-
-  local opts = {}
-  pickers.new(opts, {
-    prompt_title = "Notifications",
-    finder = finders.new_dynamic {
-      fn = function()
-        return _G.statusline_notifications_archive
-      end,
-      entry_maker = function(n)
-        return {
-          value = n,
-          display = n.display,
-          ordinal = n.message,
-        }
-      end,
-    },
-    sorter = conf.generic_sorter(opts),
-    attach_mappings = function(prompt_bufnr, _)
-      actions.select_default:replace(function()
-        actions.close(prompt_bufnr)
-        -- noop
-        -- local sel = action_state.get_selected_entry()
-        -- vim.notify(sel.value.message, sel.value.level, sel.value.options)
-      end)
-      return true
-    end,
-    -- previewer = previewers.new_buffer_previewer {
-    --   define_preview = function(self, entry)
-    --     vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, {entry.value.display})
-    --   end,
-    -- },
-  }):find()
-end, {desc='notifications'})
-
 -- vim.opt.statusline = '%!luaeval("statusline()")'
 vim.opt.statusline = '%{%v:lua.statusline()%}'