Jochen Sprickerhof
Last changed: 2024-09-27

Software

Vim Config

require("gitsigns").setup {}
require("lsp_signature").setup {}
require("undotree").setup()
require("outline").setup({
  symbols = {
    icons = {
      File = { icon = "F", hl = "Identifier" },
      Module = { icon = "M", hl = "Include" },
      Namespace = { icon = "ℕ", hl = "Include" },
      Package = { icon = "📦", hl = "Include" },
      Property = { icon = "P", hl = "Identifier" },
      Field = { icon = "f", hl = "Identifier" },
      Constructor = { icon = "", hl = "Special" },
      Interface = { icon = "I", hl = "Type" },
      Variable = { icon = "V", hl = "Constant" },
      Constant = { icon = "C", hl = "Constant" },
      Array = { icon = "A", hl = "Constant" },
    },
  },
})
require("nvim-treesitter.configs").setup { highlight = { enable = true } }
local cmp = require("cmp")
cmp.setup {
  mapping = cmp.mapping.preset.insert({["<CR>"] = cmp.mapping.confirm()}),
  sources = {
    {name = "nvim_lsp"},
    {name = "buffer", options = {keyword_pattern = [[\k\+]]}},
    {name = "path"},
    {name = "latex_symbols"},
    {name = "emoji"}
  }
}

local lspconfig = require("lspconfig")
local capabilities = require("cmp_nvim_lsp").default_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = false
lspconfig.debputy.setup {capabilities = capabilities}
lspconfig.clangd.setup {capabilities = capabilities}
lspconfig.pylsp.setup {
  capabilities = capabilities,
  settings = {pylsp = {plugins = {
    autopep8 = {enabled = false},
    pyflakes = {enabled = false},
    mccabe = {enabled = false},
    pycodestyle = {enabled = false},
    ruff = {extendSelect = {"I"}, lineLength = 120, targetVersion="py311"},
  }}}
}
lspconfig.efm.setup {
  cmd = {"efm-langserver", "-q"},
  filetypes = {"cmake", "json", "markdown", "rst", "sh", "tex", "yaml"},
  settings = {
    languages = {
      cmake = {
        {
          formatCommand = "cmake-format -",
          formatStdin = true
        },
        {
          lintCommand = "cmake-lint",
          lintFormats = {
            "%f:%l,%c: %m"
          }
        }
      },
      json = {
        {
          formatCommand = "python3 -m json.tool",
          formatStdin = true
        },
        {
          lintCommand = "python3 -m json.tool",
          lintStdin = true,
          lintIgnoreExitCode = true,
          lintFormats = {
            "%m: line %l column %c (char %r)"
          }
        }
      },
      markdown = {
        {
          formatCommand = "pandoc -f markdown -t gfm -sp --tab-stop=2",
          formatStdin = true
        }
      },
      rst = {
        {
          formatCommand = "pandoc -f rst -t rst -s --columns=79",
          formatStdin = true
        },
        {
          lintCommand = "rstcheck -",
          lintStdin = true,
          lintFormats = {
            "%f:%l: (%tNFO/1) %m",
            "%f:%l: (%tARNING/2) %m",
            "%f:%l: (%tRROR/3) %m",
            "%f:%l: (%tEVERE/4) %m"
          }
        }
      },
      sh = {
        {
          formatCommand = "shfmt",
          formatStdin = true
        },
        {
          lintCommand = "shellcheck -f gcc -x -",
          lintStdin = true,
          lintFormats = {
            "%f:%l:%c: %trror: %m",
            "%f:%l:%c: %tarning: %m",
            "%f:%l:%c: %tote: %m"
          }
        }
      },
      tex = {
        {
          lintCommand = "chktex -v0 -q",
          lintStdin = true,
          lintFormats = {
            "%f:%l:%c:%m"
          }
        }
      },
      yaml = {
        {
          lintCommand = "yamllint -f parsable -",
          lintStdin = true,
          lintIgnoreExitCode = true
        }
      }
    }
  }
}
local function goto_definition()
  return function(_, result, ctx)
    if result == nil or vim.tbl_isempty(result) then
      return
    end
    vim.cmd("vsplit")
    vim.cmd("wincmd p")
    if vim.tbl_islist(result) then
      vim.lsp.util.jump_to_location(result[1])
      if #result > 1 then
        vim.lsp.util.set_qflist(vim.lsp.util.locations_to_items(result))
        vim.cmd("copen")
        vim.cmd("wincmd p")
      end
    else
      vim.lsp.util.jump_to_location(result)
    end
  end
end
vim.lsp.handlers["textDocument/definition"] = goto_definition()
vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, {virtual_text = false})

vim.o.autoread = false
vim.o.autowrite = true
vim.o.colorcolumn = "101"
vim.o.foldenable = false
vim.o.ignorecase = true
vim.o.linebreak = true
vim.o.number = true
vim.o.pastetoggle = "<F11>"
vim.o.path = vim.o.path .. "**"
vim.o.scrolloff = 3
vim.o.shell = "sh"
vim.o.showmatch = true
vim.o.sidescrolloff = 10
vim.o.smartcase = true
vim.o.spell = not vim.o.diff
vim.o.termguicolors = true
vim.o.timeoutlen = 500
vim.o.title = true
vim.o.ttimeoutlen = 0
vim.o.updatetime = 250
vim.o.wildmode = "list:longest,full"

vim.g.netrw_chgwin = 2
vim.g.vimtex_view_method = "zathura"

vim.filetype.add({extension = {launch = "xml"}, filename = {["debputy.manifest"] = "yaml"}})

vim.api.nvim_create_autocmd("BufRead", {pattern = "/tmp/mutt*", callback = function() vim.cmd("normal :g/^> -- $/,/^$/-1d^M/^$^M^L") end})
vim.api.nvim_create_autocmd("CursorHold", {pattern = "*", callback = function() vim.diagnostic.open_float(nil, {focus = false, scope = "cursor"}) end})
vim.api.nvim_create_autocmd("CursorHoldI", {pattern = "*", callback = function() vim.diagnostic.open_float(nil, {focus = false, scope = "cursor"}) end})
vim.api.nvim_create_autocmd("DiagnosticChanged", {pattern = "*", callback = function() vim.diagnostic.setqflist({open = false}) end})
vim.api.nvim_create_autocmd("FileType", {pattern = "qf,git,gitAnnotate,Outline,diff,help", callback = function() vim.opt_local.spell = false end})
vim.api.nvim_create_autocmd("FileType", {pattern = "remind", callback = function() vim.opt_local.spelllang = "de" end})
vim.api.nvim_create_autocmd("FileType", {
  pattern = "mail",
  callback = function()
    vim.opt_local.expandtab = true
    vim.opt_local.tabstop = 2
    vim.opt_local.shiftwidth = 2
    vim.opt_local.colorcolumn = "80"
  end
})

vim.api.nvim_set_hl(0, "ColorColumn", {bg = "Gray20"})
vim.api.nvim_set_hl(0, "GitSignsAdd", {bg = "Green"})
vim.api.nvim_set_hl(0, "GitSignsDelete", {bg = "Red"})
vim.api.nvim_set_hl(0, "SignColumn", {})
vim.api.nvim_set_hl(0, "SpellBad", {fg = "Red", underline = true})
vim.api.nvim_set_hl(0, "Pmenu", {bg = "Gray20"})

vim.cmd[[command DiffOrig vert new | set buftype=nofile | read ++edit # | 0d_ | diffthis | wincmd p | diffthis]]

-- https://wiki.ubuntuusers.de/VIM/Tipps
-- https://ftp.nluug.nl/pub/vim/runtime/spell/{de,en}.utf-8.{spl,sug}
-- :mkspell! ~/.local/share/nvim/site/spell/en.utf-8.add
function togglespell()
  if vim.o.spell then
    if vim.o.spelllang == "de" then
      vim.o.spelllang = "en"
      print("toggle spell " .. vim.o.spelllang)
    else
      vim.o.spell = false
      print("toggle spell off")
    end
  else
    vim.o.spell = true
    vim.o.spelllang = "de"
    print("toggle spell " .. vim.o.spelllang)
  end
end

vim.keymap.set("", "<F1>", togglespell)
vim.keymap.set("i", "<F1>", togglespell)
vim.keymap.del("", "Y")
vim.api.nvim_set_keymap("", "<space>o", "<Cmd>Outline<CR>", {silent = true})
vim.keymap.set("", "<space>t", require("undotree").toggle, { noremap = true, silent = true })
vim.keymap.set("", "<Space>l", function() vim.lsp.stop_client(vim.lsp.get_active_clients()) end)
-- Global mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
vim.keymap.set("n", "<space>e", vim.diagnostic.open_float)
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev)
vim.keymap.set("n", "]d", vim.diagnostic.goto_next)
vim.keymap.set("n", "<space>q", vim.diagnostic.setloclist)

-- Use LspAttach autocommand to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd("LspAttach", {
  group = vim.api.nvim_create_augroup("UserLspConfig", {}),
  callback = function(ev)
    -- Enable completion triggered by <c-x><c-o>
    vim.bo[ev.buf].omnifunc = "v:lua.vim.lsp.omnifunc"

    -- Buffer local mappings.
    -- See `:help vim.lsp.*` for documentation on any of the below functions
    local opts = { buffer = ev.buf }
    vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
    vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts)
    vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
    vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
    vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, opts)
    vim.keymap.set("n", "<space>wa", vim.lsp.buf.add_workspace_folder, opts)
    vim.keymap.set("n", "<space>wr", vim.lsp.buf.remove_workspace_folder, opts)
    vim.keymap.set("n", "<space>wl", function()
      print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
    end, opts)
    vim.keymap.set("n", "<space>D", vim.lsp.buf.type_definition, opts)
    vim.keymap.set("n", "<space>rn", vim.lsp.buf.rename, opts)
    vim.keymap.set({ "n", "v" }, "<space>ca", vim.lsp.buf.code_action, opts)
    vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
    vim.keymap.set("n", "<space>f", function()
      vim.lsp.buf.format { async = true }
    end, opts)
  end,
})