diff --git a/modules/base/default.nix b/modules/base/default.nix index 4d5d811..ef3cbc4 100644 --- a/modules/base/default.nix +++ b/modules/base/default.nix @@ -17,6 +17,6 @@ ./sudo.nix ./syncthing.nix ./users.nix - ./vim + ./vim.nix ]; } diff --git a/modules/base/vim.nix b/modules/base/vim.nix new file mode 100644 index 0000000..a19c88c --- /dev/null +++ b/modules/base/vim.nix @@ -0,0 +1,728 @@ +{pkgs, ...}: { + # NixOS + # https://wiki.nixos.org/wiki/Neovim + # https://wiki.nixos.org/wiki/Vim + # https://nix-community.github.io/home-manager/options.xhtml#opt-programs.neovim.enable + # https://github.com/nix-community/nixvim + # + # Popular plugins + # https://neovimcraft.com/ + # https://dotfyle.com/neovim/plugins/top + # https://github.com/rockerBOO/awesome-neovim + # + # Distros + # https://docs.astronvim.com/ + # https://nvchad.com/docs/ + # https://www.lazyvim.org/ + # https://www.lunarvim.org/docs/ + # + # Inspiration + # https://github.com/nvim-lua/kickstart.nvim + home-manager.users.caspervk = { + programs.neovim = { + enable = true; + defaultEditor = true; + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + extraLuaConfig = + /* + lua + */ + '' + -- Use as the leader key + vim.g.mapleader = " " + + -- Show (relative) line numbers + vim.opt.number = true + vim.opt.relativenumber = true + + -- Highlight the cursor line + vim.opt.cursorline = true + vim.opt.cursorlineopt = {"line", "number"} + + -- Don't show the mode ("-- INSERT --") since it's already in the + -- status line (plugin). + vim.opt.showmode = false + + -- Preserve undo history across restarts + vim.opt.undofile = true + + -- Case-insensitive search -- unless a capital letter is used + vim.opt.ignorecase = true + vim.opt.smartcase = true + + -- Always show sign column. Avoids buffer jumping left and right on + -- gitsigns or LSP diagnostics. + vim.opt.signcolumn = "yes" + + -- Send CursorHold autocommend event after 100ms (instead of 4000ms + -- by default). Used, among other things, to highlight definitions + -- with treesitter faster. + vim.opt.updatetime = 100 + + -- Open new splits on the right and below + vim.opt.splitright = true + vim.opt.splitbelow = true + + -- Visualise whitespace characters + vim.opt.list = true + vim.opt.listchars = { tab="▸ ", trail="·", nbsp="␣" } + + -- Show search-replace preview live + vim.opt.inccommand = "split" + + -- Keep a minimum of 10 lines of context above and below the cursor + vim.opt.scrolloff = 10 + vim.opt.sidescrolloff = 10 + + -- Enable spell cheking + vim.opt.spell = true + vim.opt.spelllang = {"en", "da"} + vim.opt.spelloptions = "camel" + + -- Set better defaults for . The guess-indent plugin will + -- automatically detect indentation style and change these. + vim.opt.tabstop = 4 + vim.opt.softtabstop = 4 + vim.opt.shiftwidth = 4 + vim.opt.expandtab = true + + -- Automatically round indent to multiple of 'shiftwidth' + vim.opt.shiftround = true + + -- Show statusline at the bottom only, instead of in each window + vim.opt.laststatus = 3 + + -- Move cursor to the first non-blank of the line on CTRL-D, CTRL-U, G, + -- gg, etc. + vim.opt.startofline = true + + -- Keep visual selection after indenting + vim.keymap.set("v", "<", "", ">gv") + + -- Use CTRL-{JK} to navigate dropdowns, like CTRL-{NP}, in insert and + -- command mode. + vim.keymap.set({"c", "i"}, "", "") + vim.keymap.set({"c", "i"}, "", "") + + -- Use CTRL-{HJKL} to navigate windows + vim.keymap.set("n", "", "") + vim.keymap.set("n", "", "") + vim.keymap.set("n", "", "") + vim.keymap.set("n", "", "") + + -- Use to clear search highlight. This is normally bound to + -- CTRL-L, but we use that to navigate windows instead. + vim.keymap.set("n", "", vim.cmd.noh) + + -- Restore cursor position when opening a file + -- https://github.com/neovim/neovim/issues/16339#issuecomment-1457394370 + vim.api.nvim_create_autocmd('BufRead', { + callback = function(opts) + vim.api.nvim_create_autocmd('BufWinEnter', { + once = true, + buffer = opts.buf, + callback = function() + local ft = vim.bo[opts.buf].filetype + local last_known_line = vim.api.nvim_buf_get_mark(opts.buf, '"')[1] + if + not (ft:match('commit') and ft:match('rebase')) + and last_known_line > 1 + and last_known_line <= vim.api.nvim_buf_line_count(opts.buf) + then + vim.api.nvim_feedkeys([[g`"]], 'nx', false) + end + end, + }) + end, + }) + ''; + plugins = with pkgs.vimPlugins; [ + # NeoVim dark colorscheme inspired by the colors of the famous painting + # by Katsushika Hokusai. + # https://github.com/rebelot/kanagawa.nvim + { + plugin = kanagawa-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("kanagawa").setup({ + commentStyle = { italic = false }, + keywordStyle = { italic = false }, + dimInactive = true, + colors = { + theme = { + all = { + ui = { + -- Don't use a special background for the gutter + bg_gutter = "none", + }, + }, + }, + }, + overrides = function(colors) + local theme = colors.theme + return { + -- Less pronounced cursorline + CursorLine = { bg = theme.ui.bg_p1 }, + -- More pronounced window borders + WinSeparator = { fg = theme.ui.nontext }, + -- Less pronounced indent lines + IblIndent = { fg = theme.ui.bg_p2 }, + IblScope = { fg = theme.ui.whitespace }, + } + end, + }) + vim.cmd("colorscheme kanagawa") + ''; + } + + # Adds file type icons to Vim plugins. + # https://github.com/nvim-tree/nvim-web-devicons + { + plugin = nvim-web-devicons; + } + + # Rearrange window layout using sway-like bindings. + # https://github.com/sindrets/winshift.nvim + { + plugin = winshift-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("winshift").setup({}) + vim.keymap.set("n", "", function() vim.cmd.WinShift("left") end) + vim.keymap.set("n", "", function() vim.cmd.WinShift("down") end) + vim.keymap.set("n", "", function() vim.cmd.WinShift("up") end) + vim.keymap.set("n", "", function() vim.cmd.WinShift("right") end) + ''; + } + + # Tree sitter is a parsing system that provides improved syntax + # highlighting compared to the default regex-based grammars built into + # Vim. + # https://github.com/nvim-treesitter/nvim-treesitter + # https://github.com/nvim-treesitter/nvim-treesitter/wiki/Extra-modules-and-plugins + { + plugin = nvim-treesitter.withAllGrammars; + type = "lua"; + config = + /* + lua + */ + '' + require("nvim-treesitter.configs").setup({ + -- Consistent syntax highlighting + highlight = { + enable = true, + }, + -- Indentation based on treesitter + indent = { + enable = true, + }, + }) + ''; + } + # Refactor module for nvim-treesitter. + # https://github.com/nvim-treesitter/nvim-treesitter-refactor + { + plugin = nvim-treesitter-refactor; + type = "lua"; + config = + /* + lua + */ + '' + require("nvim-treesitter.configs").setup({ + refactor = { + -- Highlight definition and usages of the current symbol under + -- the cursor. + highlight_definitions = { + enable = true, + -- Don't redraw (blink) highlight when moving cursor inside a word + clear_on_cursor_move = false, + }, + -- Renames the symbol under the cursor within the current scope + -- (and current file). + smart_rename = { + enable = true, + keymaps = { + -- This keymap will be overwritten in LspAttach + smart_rename = "grn", + }, + }, + -- Provides "go to definition" for the symbol under the cursor, + -- and lists the definitions from the current file. + navigation = { + enable = true, + keymaps = { + -- This keymap will be overwritten in LspAttach + goto_definition = "gd", + }, + }, + }, + }) + ''; + } + # Code context module for nvim-treesitter. + # https://github.com/nvim-treesitter/nvim-treesitter-context + { + plugin = nvim-treesitter-context; + type = "lua"; + config = + /* + lua + */ + '' + require("treesitter-context").setup({ + -- Show one line of context at the top of the screen + max_lines = 1, + }) + ''; + } + + # A completion engine plugin for neovim written in Lua. Completion + # sources are installed from external repositories and "sourced". + # https://github.com/hrsh7th/nvim-cmp + { + plugin = cmp-nvim-lsp; + } + { + plugin = nvim-cmp; + type = "lua"; + config = + /* + lua + */ + '' + local cmp = require("cmp") + cmp.setup({ + snippet = { + -- Configuring a snippet engine is required. Configure + -- neovom's native one. + expand = function(args) + vim.snippet.expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + -- Use CTRL-{JK} to navigate and CTRL-L to confirm like + -- telescope. + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping.select_prev_item(), + [""] = cmp.mapping.confirm({ select = true }), + -- Scroll documentatiion + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + -- Close completion menu + [""] = cmp.mapping.abort(), + -- Manually trigger completion dropdown. This is not + -- generally needed because nvim-cmp will display completions + -- whenever it has completion options available. + [""] = cmp.mapping.complete(), + }), + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + }) + }) + + -- Add parentheses after selecting function or method item (nvim-autopairs). + -- https://github.com/hrsh7th/nvim-cmp/wiki/Advanced-techniques#add-parentheses-after-selecting-function-or-method-item + local cmp_autopairs = require("nvim-autopairs.completion.cmp") + cmp.event:on( + "confirm_done", + cmp_autopairs.on_confirm_done() + ) + ''; + } + + # Language Server Protocol (LSP). LSP facilitates features like + # go-to-definition, find references, hover, completion, rename, format, + # refactor, etc, using semantic whole-project analysis. + # > :checkhealth lsp + # https://github.com/neovim/nvim-lspconfig + { + plugin = nvim-lspconfig; + type = "lua"; + config = + /* + lua + */ + '' + local ts = require("telescope.builtin") + + -- The LspAttach event is fired after an LSP client attaches to a buffer. + -- https://neovim.io/doc/user/lsp.html + -- https://microsoft.github.io/language-server-protocol/specifications/specification-current + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local client = vim.lsp.get_client_by_id(args.data.client_id) + local buf = args.buf + + -- Overwrite treesitter-refactor's basic go-to-definition and + -- smart_rename keymaps if supported by the server. + if client.supports_method("textDocument/definition") then + vim.keymap.set("n", "gd", ts.lsp_definitions, { buffer = args.buf }) + end + if client.supports_method("textDocument/rename") then + vim.keymap.set("n", "grn", vim.lsp.buf.rename, { buffer = args.buf }) + end + end, + }) + + -- The following keymaps are defined irregardless of the LSP + -- server's capabilities since we would rather receive an error + -- that the action is unsupported by the LSP server instead of doing + -- some other random action. + vim.keymap.set("n", "grr", ts.lsp_references) + vim.keymap.set("n", "gD", vim.lsp.buf.declaration) + vim.keymap.set("n", "gy", vim.lsp.buf.type_definition) + vim.keymap.set("n", "gI", ts.lsp_implementations) + vim.keymap.set("n", "gq", vim.lsp.buf.format) + + -- TODO: This becomes default in newer neovim? + vim.keymap.set("n", "gra", vim.lsp.buf.code_action) + + -- CTRL-S is mapped to signature help in insert mode by default. + -- Add it to normal mode as well. + vim.keymap.set({"i", "n"}, "", vim.lsp.buf.signature_help) + + -- LSP servers and clients communicate what features they support. + -- By default, neovim does not support everything in the LSP + -- specification. When we add plugins such as nvim-cmp, neovim now + -- has more capabilities, so we must add these to the capabilities + -- that are broadcast to each server. + -- https://github.com/nvim-lua/kickstart.nvim/blob/master/init.lua + local capabilities = vim.lsp.protocol.make_client_capabilities() + capabilities = vim.tbl_deep_extend("force", capabilities, require("cmp_nvim_lsp").default_capabilities()) + + local lspconfig = require("lspconfig") + + -- https://github.com/nix-community/nixd + lspconfig.nixd.setup({ + capabilities = capabilities, + settings = { + nixd = { + formatting = { + command = {"${pkgs.alejandra}/bin/alejandra"}, + }, + }, + }, + }) + + -- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.txt#pylsp + lspconfig.pylsp.setup({ + capabilities = capabilities, + -- https://github.com/NixOS/nixpkgs/issues/229337 + cmd = {"${pkgs.python3.withPackages (ps: [ps.python-lsp-server ps.pyls-isort ps.pylsp-mypy ps.pylsp-rope ps.python-lsp-ruff])}/bin/python", "-m", "pylsp"}, + settings = { + pylsp = { + plugins = { + rope = { + ropeFolder = {".ropefolder/"}, + }, + -- TODO + rope_autoimport = { + enabled = true, + memory = true, + }, + }, + }, + }, + }) + + -- https://docs.basedpyright.com + -- lspconfig.basedpyright.setup({ + -- capabilities = capabilities, + -- settings = { + -- basedpyright = { + -- analysis = { + -- -- https://docs.basedpyright.com/#/configuration?id=diagnostic-settings-defaults + -- typeCheckingMode = "standard", + -- }, + -- }, + -- }, + -- }) + ''; + } + + # Telescope is a highly extendable fuzzy finder. + # https://github.com/nvim-telescope/telescope.nvim + # https://github.com/nvim-telescope/telescope.nvim/wiki/Extensions + { + plugin = telescope-nvim; + type = "lua"; + config = + /* + lua + */ + '' + local actions = require("telescope.actions") + require("telescope").setup({ + defaults = { + mappings = { + i = { + -- Quit telescope directly from insert mode, instead of + -- entering normal mode. + -- https://github.com/nvim-telescope/telescope.nvim/wiki/Configuration-Recipes + [""] = actions.close, + + -- Use CTRL-{JK} to navigate dropdowns like CTRL-{NP} + [""] = actions.move_selection_next, + [""] = actions.move_selection_previous, + -- Use CTRL-L to confirm selection + [""] = actions.select_default, + }, + }, + }, + }) + + -- Keymaps mostly inspired by the popular distros. + -- NOTE: Some mappings are done conditionally on LspAttach. + -- https://github.com/nvim-telescope/telescope.nvim?tab=readme-ov-file#vim-pickers + local ts = require("telescope.builtin") + vim.keymap.set("n", "fb", ts.buffers) + vim.keymap.set("n", "fc", ts.commands) + vim.keymap.set("n", "fd", ts.diagnostics) + vim.keymap.set("n", "fF", function() ts.find_files({hidden=true, no_ignore=true}) end) + vim.keymap.set("n", "ff", ts.find_files) + vim.keymap.set("n", "fh", ts.help_tags) + vim.keymap.set("n", "fk", ts.keymaps) + vim.keymap.set("n", "fm", ts.marks) + vim.keymap.set("n", "fo", ts.oldfiles) + vim.keymap.set("n", "fr", ts.registers) + vim.keymap.set("n", "f/", ts.current_buffer_fuzzy_find) + vim.keymap.set("n", "F", ts.resume) + vim.keymap.set("n", "fW", function() ts.live_grep({additional_args={"--hidden", "--no-ignore"}}) end) + vim.keymap.set("n", "fw", ts.live_grep) + ''; + } + # It's suggested to install one native sorter for telescope for better + # performance. + # https://github.com/nvim-telescope/telescope-fzf-native.nvim + { + plugin = telescope-fzf-native-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("telescope").load_extension("fzf") + ''; + } + # Replace `vim.ui.select` to Telescope. That means for example that + # neovim core stuff can fill the telescope picker. Example would be lua + # `vim.lsp.buf.code_action()`. + # https://github.com/nvim-telescope/telescope-ui-select.nvim + { + plugin = telescope-ui-select-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("telescope").load_extension("ui-select") + ''; + } + + # Buffer list that lives in the tabline. + # https://github.com/akinsho/bufferline.nvim + { + plugin = bufferline-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("bufferline").setup({}) + -- Use and to go to previous/next buffer + vim.keymap.set("n", "", vim.cmd.BufferLineCyclePrev); + vim.keymap.set("n", "", vim.cmd.BufferLineCycleNext); + -- Use to select a buffer. selects the rightmost + -- buffer like tabs in Firefox. + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(1) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(2) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(3) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(4) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(5) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(6) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(7) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(8) end); + vim.keymap.set("n", "", function() vim.cmd.BufferLineGoToBuffer(-1) end); + -- Use to close current buffer + vim.keymap.set("n", "", vim.cmd.bd); + ''; + } + + # Indentation guides. + # https://github.com/lukas-reineke/indent-blankline.nvim + { + plugin = indent-blankline-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("ibl").setup({ + indent = { + -- Thinner indent line + char = "▏", + }, + scope = { + -- Don't show start/end of scope horizontal lines + show_start = false, + show_end = false, + }, + }) + ''; + } + + # Automatic indentation style detection for Neovim. + # https://github.com/NMAC427/guess-indent.nvim + { + plugin = guess-indent-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("guess-indent").setup({}) + ''; + } + + # A super powerful autopair plugin for Neovim that supports multiple + # characters; automatically closes brackets etc. + # https://github.com/windwp/nvim-ts-autotag + { + plugin = nvim-autopairs; + type = "lua"; + config = + /* + lua + */ + '' + require("nvim-autopairs").setup({}) + ''; + } + + # Add/change/delete surrounding delimiter pairs with ease; cs, ds, ys. + # https://github.com/kylechui/nvim-surround + { + plugin = nvim-surround; + type = "lua"; + config = + /* + lua + */ + '' + require("nvim-surround").setup({}) + ''; + } + + # Use treesitter to autoclose and autorename html tags. + # https://github.com/windwp/nvim-ts-autotag + { + plugin = nvim-ts-autotag; + type = "lua"; + config = + /* + lua + */ + '' + require("nvim-ts-autotag").setup({}) + ''; + } + + # Git integration for buffers. + # https://github.com/lewis6991/gitsigns.nvim + { + plugin = gitsigns-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("gitsigns").setup({}) + -- TODO: keybinds + ''; + } + + # Single tabpage interface for easily cycling through diffs for all + # modified files for any git rev. + # https://github.com/sindrets/diffview.nvim + { + plugin = diffview-nvim; + type = "lua"; + config = + /* + lua + */ + '' + vim.keymap.set("n", "gd", vim.cmd.DiffviewOpen) + ''; + } + + # TODO + ######################## + + # A blazing fast and easy to configure statusline written in Lua. + # https://github.com/nvim-lualine/lualine.nvim + { + plugin = lualine-nvim; + type = "lua"; + config = + /* + lua + */ + '' + require("lualine").setup({}) + ''; + } + + # TODO! + vim-fugitive + + # mini-nvim + + # TODO: popup file-tree/viewer?? + + # nvim-colorizer-lua # show colours in colours + # vim-matchup # better % + # nvim-dap # debug adapter protocol + # nvim-dap-virtual-text # show variable values in-line + # salt-vim # salt syntax-highlighting + # https://github.com/JoosepAlviste/nvim-ts-context-commentstring + ]; + extraPackages = [ + # nixpkgs-unstable.legacyPackages.${pkgs.system}.basedpyright + pkgs.nixd + ]; + extraLuaPackages = ps: []; + extraPython3Packages = ps: []; + # withNodeJs = true; + }; + + # https://wiki.nixos.org/wiki/Vim#Vim_Spell_Files + home.file.".config/nvim/spell/da.utf-8.spl".source = builtins.fetchurl { + url = "http://ftp.vim.org/vim/runtime/spell/da.utf-8.spl"; + sha256 = "0cl9q1ln7y4ihbpgawl3rc86zw8xynq9hg4hl8913dbmpcl2nslj"; + }; + home.file.".config/nvim/spell/da.utf-8.sug".source = builtins.fetchurl { + url = "http://ftp.vim.org/vim/runtime/spell/da.utf-8.sug"; + sha256 = "1pdnp0hq3yll65z6rlmq0l6axvn5450jw5y081vyb4x5850czdxm"; + }; + }; +} diff --git a/modules/base/vim/config.lua b/modules/base/vim/config.lua deleted file mode 100644 index 9f52477..0000000 --- a/modules/base/vim/config.lua +++ /dev/null @@ -1,98 +0,0 @@ --- https://github.com/rebelot/kanagawa.nvim -require('kanagawa').setup({ - undercurl = true, - commentStyle = {italic = false}, - keywordStyle = {italic = false}, - theme = "dragon", - background = { - dark = "dragon", - light = "lotus" - } -}) - --- https://github.com/lukas-reineke/indent-blankline.nvim -require('ibl').setup() - --- https://github.com/numToStr/Comment.nvim -require("Comment").setup() - --- https://github.com/ggandor/leap.nvim/ -require("leap").add_default_mappings() - --- https://github.com/NvChad/nvim-colorizer.lua -require('colorizer').setup({user_default_options = {names = false}}) - --- https://github.com/nvim-treesitter/nvim-treesitter -require('nvim-treesitter.configs').setup({ - highlight = { - enable = true - }, - refactor = { - highlight_definitions = { - enable = true, - clear_on_cursor_move = true, - }, - smart_rename = { - enable = true, - keymaps = { - smart_rename = "grr" - } - }, - navigation = { - enable = true, - keymaps = { - goto_definition = "gnd", - list_definitions = "gnD", - list_definitions_toc = "gO", - goto_next_usage = "", - goto_previous_usage = "", - } - }, - }, - incremental_selection = { - enable = true, - keymaps = { - init_selection = "", - node_incremental = "", - node_decremental = "", - scope_incremental = false, - } - }, - matchup = { - enable = true, - }, - textobjects = { - swap = { - enable = true, - swap_next = {["a"] = "@parameter.inner"}, - swap_previous = {["A"] = "@parameter.inner"} - } - }, -}) - --- https://github.com/nvim-treesitter/nvim-treesitter-context -require('treesitter-context').setup({ - mode = "topline", -}) - - --- https://github.com/nvim-tree/nvim-tree.lua -require("nvim-tree").setup({ - -- Automatically show tree from the project root - -- https://github.com/ahmedkhalf/project.nvim - sync_root_with_cwd = true, - respect_buf_cwd = true, - update_focused_file = { - enable = true, - update_root = true, - }, -}) - - --- https://github.com/ahmedkhalf/project.nvim -require("project_nvim").setup() - - --- TODO -require("nvim-dap-virtual-text").setup() - diff --git a/modules/base/vim/config.vim b/modules/base/vim/config.vim deleted file mode 100644 index 8c607da..0000000 --- a/modules/base/vim/config.vim +++ /dev/null @@ -1,44 +0,0 @@ -" Colour scheme -colorscheme kanagawa -set termguicolors - -" Show relative line numbers and highlight the current one -set number -set relativenumber -set cursorline -set cursorlineopt=number - -" Keep some context above and below the cursor -set scrolloff=3 -set sidescrolloff=3 - -" Tabs are spaces -set tabstop=4 -set softtabstop=4 -set shiftwidth=4 -set expandtab - -" Better search -set ignorecase -set smartcase - -" Jump to new splits automatically -set splitbelow -set splitright - -" Visualise trailing whitespace -set list -set listchars=tab:▸\ ,trail:·,nbsp:␣ - -" Spelling -set spell -set spelllang=en_us,en_gb,da_dk - -" Use space as leader key -nnoremap -let mapleader = "\" - -" Keep visual selection after indenting -vnoremap > >gv -vnoremap <