Last active
March 9, 2025 15:03
-
-
Save protortyp/4b192123269e23ef55ca26e1e3f558bc to your computer and use it in GitHub Desktop.
nvim config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- always set leader first! | |
vim.keymap.set("n", "<Space>", "<Nop>", { silent = true }) | |
vim.g.mapleader = " " | |
------------------------------------------------------------------------------- | |
-- | |
-- preferences | |
-- | |
------------------------------------------------------------------------------- | |
-- never ever folding | |
vim.opt.foldenable = false | |
vim.opt.foldmethod = 'manual' | |
vim.opt.foldlevelstart = 99 | |
-- very basic "continue indent" mode (autoindent) is always on in neovim | |
-- could try smartindent/cindent, but meh. | |
-- vim.opt.cindent = true | |
-- XXX | |
-- vim.opt.cmdheight = 2 | |
-- vim.opt.completeopt = 'menuone,noinsert,noselect' | |
-- not setting updatedtime because I use K to manually trigger hover effects | |
-- and lowering it also changes how frequently files are written to swap. | |
-- vim.opt.updatetime = 300 | |
-- if key combos seem to be "lagging" | |
-- http://stackoverflow.com/questions/2158516/delay-before-o-opens-a-new-line | |
-- vim.opt.timeoutlen = 300 | |
-- keep more context on screen while scrolling | |
vim.opt.scrolloff = 2 | |
-- never show me line breaks if they're not there | |
vim.opt.wrap = false | |
-- always draw sign column. prevents buffer moving when adding/deleting sign | |
vim.opt.signcolumn = 'yes' | |
-- sweet sweet relative line numbers | |
vim.opt.relativenumber = true | |
-- and show the absolute line number for the current line | |
vim.opt.number = true | |
-- keep current content top + left when splitting | |
vim.opt.splitright = true | |
vim.opt.splitbelow = true | |
-- infinite undo! | |
-- NOTE: ends up in ~/.local/state/nvim/undo/ | |
vim.opt.undofile = true | |
--" Decent wildmenu | |
-- in completion, when there is more than one match, | |
-- list all matches, and only complete to longest common match | |
vim.opt.wildmode = 'list:longest' | |
-- when opening a file with a command (like :e), | |
-- don't suggest files like there: | |
vim.opt.wildignore = '.hg,.svn,*~,*.png,*.jpg,*.gif,*.min.js,*.swp,*.o,vendor,dist,_site' | |
-- tabs: go big or go home | |
vim.opt.shiftwidth = 8 | |
vim.opt.softtabstop = 8 | |
vim.opt.tabstop = 8 | |
vim.opt.expandtab = false | |
-- case-insensitive search/replace | |
vim.opt.ignorecase = true | |
-- unless uppercase in search term | |
vim.opt.smartcase = true | |
-- never ever make my terminal beep | |
vim.opt.vb = true | |
-- more useful diffs (nvim -d) | |
--- by ignoring whitespace | |
vim.opt.diffopt:append('iwhite') | |
--- and using a smarter algorithm | |
--- https://vimways.org/2018/the-power-of-diff/ | |
--- https://stackoverflow.com/questions/32365271/whats-the-difference-between-git-diff-patience-and-git-diff-histogram | |
--- https://luppeng.wordpress.com/2020/10/10/when-to-use-each-of-the-git-diff-algorithms/ | |
vim.opt.diffopt:append('algorithm:histogram') | |
vim.opt.diffopt:append('indent-heuristic') | |
-- show a column at 80 characters as a guide for long lines | |
vim.opt.colorcolumn = '80' | |
--- except in Rust where the rule is 100 characters | |
vim.api.nvim_create_autocmd('Filetype', { pattern = 'rust', command = 'set colorcolumn=100' }) | |
-- show more hidden characters | |
-- also, show tabs nicer | |
vim.opt.listchars = 'tab:^ ,nbsp:¬,extends:»,precedes:«,trail:•' | |
------------------------------------------------------------------------------- | |
-- | |
-- hotkeys | |
-- | |
------------------------------------------------------------------------------- | |
-- quick-open | |
vim.keymap.set('', '<C-p>', '<cmd>Files<cr>') | |
-- search buffers | |
vim.keymap.set('n', '<leader>;', '<cmd>Buffers<cr>') | |
-- quick-save | |
vim.keymap.set('n', '<leader>w', '<cmd>w<cr>') | |
-- make missing : less annoying | |
vim.keymap.set('n', ';', ':') | |
-- Ctrl+j and Ctrl+k as Esc | |
vim.keymap.set('n', '<C-j>', '<Esc>') | |
vim.keymap.set('i', '<C-j>', '<Esc>') | |
vim.keymap.set('v', '<C-j>', '<Esc>') | |
vim.keymap.set('s', '<C-j>', '<Esc>') | |
vim.keymap.set('x', '<C-j>', '<Esc>') | |
vim.keymap.set('c', '<C-j>', '<Esc>') | |
vim.keymap.set('o', '<C-j>', '<Esc>') | |
vim.keymap.set('l', '<C-j>', '<Esc>') | |
vim.keymap.set('t', '<C-j>', '<Esc>') | |
-- Ctrl-j is a little awkward unfortunately: | |
-- https://github.com/neovim/neovim/issues/5916 | |
-- So we also map Ctrl+k | |
vim.keymap.set('n', '<C-k>', '<Esc>') | |
vim.keymap.set('i', '<C-k>', '<Esc>') | |
vim.keymap.set('v', '<C-k>', '<Esc>') | |
vim.keymap.set('s', '<C-k>', '<Esc>') | |
vim.keymap.set('x', '<C-k>', '<Esc>') | |
vim.keymap.set('c', '<C-k>', '<Esc>') | |
vim.keymap.set('o', '<C-k>', '<Esc>') | |
vim.keymap.set('l', '<C-k>', '<Esc>') | |
vim.keymap.set('t', '<C-k>', '<Esc>') | |
-- Ctrl+h to stop searching | |
vim.keymap.set('v', '<C-h>', '<cmd>nohlsearch<cr>') | |
vim.keymap.set('n', '<C-h>', '<cmd>nohlsearch<cr>') | |
-- Jump to start and end of line using the home row keys | |
vim.keymap.set('', 'H', '^') | |
vim.keymap.set('', 'L', '$') | |
-- Neat X clipboard integration | |
-- <leader>p will paste clipboard into buffer | |
-- <leader>c will copy entire buffer into clipboard | |
vim.keymap.set('n', '<leader>p', '<cmd>read !wl-paste<cr>') | |
vim.keymap.set('n', '<leader>c', '<cmd>w !wl-copy<cr><cr>') | |
-- <leader><leader> toggles between buffers | |
vim.keymap.set('n', '<leader><leader>', '<c-^>') | |
-- <leader>, shows/hides hidden characters | |
vim.keymap.set('n', '<leader>,', ':set invlist<cr>') | |
-- always center search results | |
vim.keymap.set('n', 'n', 'nzz', { silent = true }) | |
vim.keymap.set('n', 'N', 'Nzz', { silent = true }) | |
vim.keymap.set('n', '*', '*zz', { silent = true }) | |
vim.keymap.set('n', '#', '#zz', { silent = true }) | |
vim.keymap.set('n', 'g*', 'g*zz', { silent = true }) | |
-- "very magic" (less escaping needed) regexes by default | |
vim.keymap.set('n', '?', '?\\v') | |
vim.keymap.set('n', '/', '/\\v') | |
vim.keymap.set('c', '%s/', '%sm/') | |
-- open new file adjacent to current file | |
vim.keymap.set('n', '<leader>o', ':e <C-R>=expand("%:p:h") . "/" <cr>') | |
-- no arrow keys --- force yourself to use the home row | |
--vim.keymap.set('n', '<up>', '<nop>') | |
--vim.keymap.set('n', '<down>', '<nop>') | |
--vim.keymap.set('i', '<up>', '<nop>') | |
--vim.keymap.set('i', '<down>', '<nop>') | |
--vim.keymap.set('i', '<left>', '<nop>') | |
--vim.keymap.set('i', '<right>', '<nop>') | |
-- let the left and right arrows be useful: they can switch buffers | |
--vim.keymap.set('n', '<left>', ':bp<cr>') | |
-- vim.keymap.set('n', '<right>', ':bn<cr>') | |
-- make j and k move by visual line, not actual line, when text is soft-wrapped | |
--vim.keymap.set('n', 'j', 'gj') | |
-- vim.keymap.set('n', 'k', 'gk') | |
-- handy keymap for replacing up to next _ (like in variable names) | |
vim.keymap.set('n', '<leader>_', 'ct_') | |
-- F1 is pretty close to Esc, so you probably meant Esc | |
vim.keymap.set('', '<F1>', '<Esc>') | |
vim.keymap.set('i', '<F1>', '<Esc>') | |
-- Map Option + Up/Down arrow to move lines | |
vim.keymap.set("n", "<A-Up>", ":m-2<CR>==", { silent = true }) | |
vim.keymap.set("n", "<A-Down>", ":m+<CR>==", { silent = true }) | |
-- move all selected liines up/Down | |
vim.keymap.set("v", "<A-Up>", ":m '<-2<CR>gv=gv", { silent = true }) | |
vim.keymap.set("v", "<A-Down>", ":m '>+1<CR>gv=gv", { silent = true }) | |
-- search for workspace symbols | |
vim.keymap.set('n', '<leader>s', vim.lsp.buf.workspace_symbol, {}) | |
-- toggle inlay hints | |
vim.keymap.set("n", "<Space>h", function() | |
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled()) | |
-- Optional: Display a message indicating the current state | |
if vim.lsp.inlay_hint.is_enabled() then | |
vim.notify("Inlay hints enabled") | |
else | |
vim.notify("Inlay hints disabled") | |
end | |
end, { silent = true }) | |
-- cut | |
vim.keymap.set({"n", "v"}, "<leader>x", '"+x') | |
------------------------------------------------------------------------------- | |
-- | |
-- autocommands | |
-- | |
------------------------------------------------------------------------------- | |
-- highlight yanked text | |
vim.api.nvim_create_autocmd( | |
'TextYankPost', | |
{ | |
pattern = '*', | |
command = 'silent! lua vim.highlight.on_yank({ timeout = 500 })' | |
} | |
) | |
-- jump to last edit position on opening file | |
vim.api.nvim_create_autocmd( | |
'BufReadPost', | |
{ | |
pattern = '*', | |
callback = function(ev) | |
if vim.fn.line("'\"") > 1 and vim.fn.line("'\"") <= vim.fn.line("$") then | |
-- except for in git commit messages | |
-- https://stackoverflow.com/questions/31449496/vim-ignore-specifc-file-in-autocommand | |
if not vim.fn.expand('%:p'):find('.git', 1, true) then | |
vim.cmd('exe "normal! g\'\\""') | |
end | |
end | |
end | |
} | |
) | |
-- prevent accidental writes to buffers that shouldn't be edited | |
vim.api.nvim_create_autocmd('BufRead', { pattern = '*.orig', command = 'set readonly' }) | |
vim.api.nvim_create_autocmd('BufRead', { pattern = '*.pacnew', command = 'set readonly' }) | |
-- leave paste mode when leaving insert mode (if it was on) | |
vim.api.nvim_create_autocmd('InsertLeave', { pattern = '*', command = 'set nopaste' }) | |
-- help filetype detection (add as needed) | |
--vim.api.nvim_create_autocmd('BufRead', { pattern = '*.ext', command = 'set filetype=someft' }) | |
-- correctly classify mutt buffers | |
local email = vim.api.nvim_create_augroup('email', { clear = true }) | |
vim.api.nvim_create_autocmd({ 'BufNewFile', 'BufRead' }, { | |
pattern = '/tmp/mutt*', | |
group = email, | |
command = 'setfiletype mail', | |
}) | |
-- also, produce "flowed text" wrapping | |
-- https://brianbuccola.com/line-breaks-in-mutt-and-vim/ | |
vim.api.nvim_create_autocmd('Filetype', { | |
pattern = 'mail', | |
group = email, | |
command = 'setlocal formatoptions+=w', | |
}) | |
-- shorter columns in text because it reads better that way | |
local text = vim.api.nvim_create_augroup('text', { clear = true }) | |
for _, pat in ipairs({'text', 'markdown', 'mail', 'gitcommit'}) do | |
vim.api.nvim_create_autocmd('Filetype', { | |
pattern = pat, | |
group = text, | |
command = 'setlocal spell tw=72 colorcolumn=73', | |
}) | |
end | |
--- tex has so much syntax that a little wider is ok | |
vim.api.nvim_create_autocmd('Filetype', { | |
pattern = 'tex', | |
group = text, | |
command = 'setlocal spell tw=80 colorcolumn=81', | |
}) | |
-- TODO: no autocomplete in text | |
------------------------------------------------------------------------------- | |
-- | |
-- plugin configuration | |
-- | |
------------------------------------------------------------------------------- | |
-- first, grab the manager | |
-- https://github.com/folke/lazy.nvim | |
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" | |
if not vim.loop.fs_stat(lazypath) then | |
vim.fn.system({ | |
"git", | |
"clone", | |
"--filter=blob:none", | |
"https://github.com/folke/lazy.nvim.git", | |
"--branch=stable", -- latest stable release | |
lazypath, | |
}) | |
end | |
vim.opt.rtp:prepend(lazypath) | |
-- then, setup! | |
require("lazy").setup({ | |
{ "hrsh7th/vim-vsnip" }, | |
-- main color scheme | |
{ | |
"tinted-theming/tinted-vim", | |
lazy = false, -- load at start | |
priority = 1000, -- load first | |
config = function() | |
vim.cmd([[colorscheme base16-gruvbox-dark-hard]]) | |
vim.o.background = 'dark' | |
-- XXX: hi Normal ctermbg=NONE | |
-- Make comments more prominent -- they are important. | |
local bools = vim.api.nvim_get_hl(0, { name = 'Boolean' }) | |
vim.api.nvim_set_hl(0, 'Comment', bools) | |
-- Make it clearly visible which argument we're at. | |
local marked = vim.api.nvim_get_hl(0, { name = 'PMenu' }) | |
vim.api.nvim_set_hl(0, 'LspSignatureActiveParameter', { fg = marked.fg, bg = marked.bg, ctermfg = marked.ctermfg, ctermbg = marked.ctermbg, bold = true }) | |
-- XXX | |
-- Would be nice to customize the highlighting of warnings and the like to make | |
-- them less glaring. But alas | |
-- https://github.com/nvim-lua/lsp_extensions.nvim/issues/21 | |
-- call Base16hi("CocHintSign", g:base16_gui03, "", g:base16_cterm03, "", "", "") | |
end | |
}, | |
-- nice bar at the bottom | |
{ | |
'itchyny/lightline.vim', | |
lazy = false, -- also load at start since it's UI | |
config = function() | |
-- no need to also show mode in cmd line when we have bar | |
vim.o.showmode = false | |
vim.g.lightline = { | |
active = { | |
left = { | |
{ 'mode', 'paste' }, | |
{ 'readonly', 'filename', 'modified' } | |
}, | |
right = { | |
{ 'lineinfo' }, | |
{ 'percent' }, | |
{ 'fileencoding', 'filetype' } | |
}, | |
}, | |
component_function = { | |
filename = 'LightlineFilename' | |
}, | |
} | |
function LightlineFilenameInLua(opts) | |
if vim.fn.expand('%:t') == '' then | |
return '[No Name]' | |
else | |
return vim.fn.getreg('%') | |
end | |
end | |
-- https://github.com/itchyny/lightline.vim/issues/657 | |
vim.api.nvim_exec( | |
[[ | |
function! g:LightlineFilename() | |
return v:lua.LightlineFilenameInLua() | |
endfunction | |
]], | |
true | |
) | |
end | |
}, | |
-- quick navigation | |
--{ | |
-- 'ggandor/leap.nvim', | |
-- config = function() | |
-- require('leap').create_default_mappings() | |
-- end | |
--}, | |
-- better % | |
{ | |
'andymass/vim-matchup', | |
config = function() | |
vim.g.matchup_matchparen_offscreen = { method = "popup" } | |
end | |
}, | |
-- auto-cd to root of git project | |
-- 'airblade/vim-rooter' | |
{ | |
'notjedi/nvim-rooter.lua', | |
config = function() | |
require('nvim-rooter').setup() | |
end | |
}, | |
-- fzf support for ^p | |
{ | |
'junegunn/fzf.vim', | |
dependencies = { | |
{ 'junegunn/fzf', build = './install --all' }, | |
}, | |
config = function() | |
-- stop putting a giant window over my editor | |
vim.g.fzf_layout = { down = '~20%' } | |
-- when using :Files, pass the file list through | |
-- | |
-- https://github.com/jonhoo/proximity-sort | |
-- | |
-- to prefer files closer to the current file. | |
function list_cmd() | |
local base = vim.fn.fnamemodify(vim.fn.expand('%'), ':h:.:S') | |
if base == '.' then | |
-- if there is no current file, | |
-- proximity-sort can't do its thing | |
return 'fd --type file --follow' | |
else | |
return vim.fn.printf('fd --type file --follow | proximity-sort %s', vim.fn.shellescape(vim.fn.expand('%'))) | |
end | |
end | |
vim.api.nvim_create_user_command('Files', function(arg) | |
vim.fn['fzf#vim#files'](arg.qargs, { source = list_cmd(), options = '--tiebreak=index' }, arg.bang) | |
end, { bang = true, nargs = '?', complete = "dir" }) | |
end | |
}, | |
{ | |
'mrcjkb/rustaceanvim', | |
version = '^5', -- Recommended | |
lazy = false, -- This plugin is already lazy | |
}, | |
-- LSP | |
{ | |
'neovim/nvim-lspconfig', | |
config = function() | |
-- Setup language servers. | |
local lspconfig = require('lspconfig') | |
-- Python LSP | |
require'lspconfig'.pyright.setup{} | |
require('lspconfig').ruff.setup{} | |
-- Bash LSP | |
local configs = require 'lspconfig.configs' | |
if not configs.bash_lsp and vim.fn.executable('bash-language-server') == 1 then | |
configs.bash_lsp = { | |
default_config = { | |
cmd = { 'bash-language-server', 'start' }, | |
filetypes = { 'sh' }, | |
root_dir = require('lspconfig').util.find_git_ancestor, | |
init_options = { | |
settings = { | |
args = {} | |
} | |
} | |
} | |
} | |
end | |
if configs.bash_lsp then | |
lspconfig.bash_lsp.setup {} | |
end | |
-- Global mappings. | |
-- See `:help vim.diagnostic.*` for documentation on any of the below functions | |
vim.keymap.set('n', '<leader>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', '<leader>q', vim.diagnostic.setloclist) | |
-- wrap error messages | |
vim.diagnostic.config({ | |
virtual_text = false, -- Disable inline diagnostics | |
float = { | |
source = "always", -- Include source in floating diagnostics | |
wrap = true, -- Ensure messages wrap in floating windows | |
}, | |
}) | |
-- 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', '<leader>wa', vim.lsp.buf.add_workspace_folder, opts) | |
vim.keymap.set('n', '<leader>wr', vim.lsp.buf.remove_workspace_folder, opts) | |
vim.keymap.set('n', '<leader>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', '<leader>r', vim.lsp.buf.rename, opts) | |
vim.keymap.set({ 'n', 'v' }, '<leader>a', vim.lsp.buf.code_action, opts) | |
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts) | |
vim.keymap.set('n', '<leader>f', function() | |
vim.lsp.buf.format { async = true } | |
end, opts) | |
local client = vim.lsp.get_client_by_id(ev.data.client_id) | |
-- When https://neovim.io/doc/user/lsp.html#lsp-inlay_hint stabilizes | |
-- *and* there's some way to make it only apply to the current line. | |
--if client.server_capabilities.inlayHintProvider then | |
-- vim.lsp.inlay_hint(ev.buf, true) | |
--end | |
-- | |
-- https://www.reddit.com/r/neovim/comments/143efmd/is_it_possible_to_disable_treesitter_completely/ | |
client.server_capabilities.semanticTokensProvider = nil | |
end, | |
}) | |
end | |
}, | |
-- LSP-based code-completion | |
{ | |
"hrsh7th/nvim-cmp", | |
-- load cmp on InsertEnter | |
event = "InsertEnter", | |
-- these dependencies will only be loaded when cmp loads | |
-- dependencies are always lazy-loaded unless specified otherwise | |
dependencies = { | |
'neovim/nvim-lspconfig', | |
"hrsh7th/cmp-nvim-lsp", | |
"hrsh7th/cmp-buffer", | |
"hrsh7th/cmp-path", | |
}, | |
config = function() | |
local cmp = require'cmp' | |
cmp.setup({ | |
snippet = { | |
-- REQUIRED by nvim-cmp. get rid of it once we can | |
expand = function(args) | |
vim.fn["vsnip#anonymous"](args.body) | |
end, | |
}, | |
mapping = cmp.mapping.preset.insert({ | |
['<C-b>'] = cmp.mapping.scroll_docs(-4), | |
['<C-f>'] = cmp.mapping.scroll_docs(4), | |
['<C-Space>'] = cmp.mapping.complete(), | |
['<C-e>'] = cmp.mapping.abort(), | |
-- Accept currently selected item. | |
-- Set `select` to `false` to only confirm explicitly selected items. | |
['<CR>'] = cmp.mapping.confirm({ select = true }), | |
}), | |
sources = cmp.config.sources({ | |
{ name = 'nvim_lsp' }, | |
}, { | |
{ name = 'path' }, | |
}), | |
experimental = { | |
ghost_text = true, | |
}, | |
}) | |
-- Enable completing paths in : | |
cmp.setup.cmdline(':', { | |
sources = cmp.config.sources({ | |
{ name = 'path' } | |
}) | |
}) | |
end | |
}, | |
-- inline function signatures | |
{ | |
"ray-x/lsp_signature.nvim", | |
event = "VeryLazy", | |
opts = {}, | |
config = function(_, opts) | |
-- Get signatures (and _only_ signatures) when in argument lists. | |
require "lsp_signature".setup({ | |
doc_lines = 0, | |
handler_opts = { | |
border = "none" | |
}, | |
}) | |
end | |
}, | |
-- language support | |
-- terraform | |
{ | |
'hashivim/vim-terraform', | |
ft = { "terraform" }, | |
}, | |
-- svelte | |
{ | |
'evanleck/vim-svelte', | |
ft = { "svelte" }, | |
}, | |
-- toml | |
'cespare/vim-toml', | |
-- yaml | |
{ | |
"cuducos/yaml.nvim", | |
ft = { "yaml" }, | |
dependencies = { | |
"nvim-treesitter/nvim-treesitter", | |
}, | |
}, | |
-- rust | |
{ | |
'rust-lang/rust.vim', | |
ft = { "rust" }, | |
config = function() | |
vim.g.rustfmt_autosave = 1 | |
vim.g.rustfmt_emit_files = 1 | |
vim.g.rustfmt_fail_silently = 0 | |
vim.g.rust_clip_command = 'wl-copy' | |
end | |
}, | |
-- fish | |
'khaveesh/vim-fish-syntax', | |
-- markdown | |
{ | |
'plasticboy/vim-markdown', | |
ft = { "markdown" }, | |
dependencies = { | |
'godlygeek/tabular', | |
}, | |
config = function() | |
-- never ever fold! | |
vim.g.vim_markdown_folding_disabled = 1 | |
-- support front-matter in .md files | |
vim.g.vim_markdown_frontmatter = 1 | |
-- 'o' on a list item should insert at same level | |
vim.g.vim_markdown_new_list_item_indent = 0 | |
-- don't add bullets when wrapping: | |
-- https://github.com/preservim/vim-markdown/issues/232 | |
vim.g.vim_markdown_auto_insert_bullets = 0 | |
end | |
}, | |
-- file explorer | |
{ | |
"nvim-tree/nvim-tree.lua", | |
version = "*", | |
dependencies = { | |
"nvim-tree/nvim-web-devicons" -- optional, for file icons | |
}, | |
config = function() | |
require'nvim-web-devicons'.get_icons() | |
require"nvim-tree".setup { | |
view = { | |
width = 30, -- Adjust width as needed | |
side = 'left', -- Position on the left | |
} | |
} | |
-- Toggle file browser with Ctrl+b | |
vim.keymap.set("n", "<C-b>", ":NvimTreeToggle<CR>") | |
end | |
}, | |
-- rust tools | |
{ | |
"folke/trouble.nvim", | |
opts = {}, -- for default options, refer to the configuration section for custom setup. | |
cmd = "Trouble", | |
keys = { | |
{ | |
"<leader>xx", | |
"<cmd>Trouble diagnostics toggle<cr>", | |
desc = "Diagnostics (Trouble)", | |
}, | |
{ | |
"<leader>xX", | |
"<cmd>Trouble diagnostics toggle filter.buf=0<cr>", | |
desc = "Buffer Diagnostics (Trouble)", | |
}, | |
{ | |
"<leader>cs", | |
"<cmd>Trouble symbols toggle focus=false<cr>", | |
desc = "Symbols (Trouble)", | |
}, | |
{ | |
"<leader>cl", | |
"<cmd>Trouble lsp toggle focus=false win.position=right<cr>", | |
desc = "LSP Definitions / references / ... (Trouble)", | |
}, | |
-- { | |
-- "<leader>xL", | |
-- "<cmd>Trouble loclist toggle<cr>", | |
-- desc = "Location List (Trouble)", | |
-- }, | |
-- { | |
-- "<leader>xQ", | |
-- "<cmd>Trouble qflist toggle<cr>", | |
-- desc = "Quickfix List (Trouble)", | |
-- }, | |
}, | |
}, | |
{ | |
'saecki/crates.nvim', | |
tag = 'stable', | |
config = function() | |
require('crates').setup() | |
end, | |
}, | |
-- keep function signatures in context | |
{"nvim-treesitter/nvim-treesitter-context"}, | |
-- screnwriting | |
{ "kblin/vim-fountain" }, | |
-- debugging tools | |
{ "theHamsta/nvim-dap-virtual-text"}, | |
{ "tnvim-neotest/nvim-nio"}, | |
{ "rcarriga/nvim-dap-ui", dependencies = {"mfussenegger/nvim-dap", "nvim-neotest/nvim-nio"} }, | |
{ | |
"mfussenegger/nvim-dap", | |
dependencies = { | |
"rcarriga/nvim-dap-ui", | |
"nvim-neotest/nvim-nio", | |
"williamboman/mason.nvim", | |
"nvim-dap-virtual-text", | |
}, | |
config = function() | |
local dap = require('dap') | |
local ui = require('dapui') | |
ui.setup() | |
dap.adapters.lldb = { | |
type = 'executable', | |
command = '/Library/Developer/CommandLineTools/usr/bin/lldb-dap', | |
name = 'lldb' | |
} | |
dap.configurations.cpp = { | |
{ | |
name = 'Launch', | |
type = 'lldb', | |
request = 'launch', | |
program = function() | |
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file') | |
end, | |
cwd = '${workspaceFolder}', | |
stopOnEntry = false, | |
args = {}, | |
}, | |
} | |
dap.configurations.c = dap.configurations.cpp | |
dap.configurations.rust = dap.configurations.cpp | |
vim.keymap.set('n', '<leader>b', dap.toggle_breakpoint) | |
vim.keymap.set('n', '<leader>gb', dap.run_to_cursor) | |
-- eval under cursor | |
vim.keymap.set("n", "<leader>?", function() | |
require("dapui").eval(nil, {enter = true}) | |
end) | |
vim.keymap.set("n", "<F1>", dap.continue) | |
vim.keymap.set("n", "<F2>", dap.step_into) | |
vim.keymap.set("n", "<F3>", dap.step_over) | |
vim.keymap.set("n", "<F4>", dap.step_out) | |
vim.keymap.set("n", "<F5>", dap.step_back) | |
vim.keymap.set("n", "<F13>", dap.restart) | |
-- ui listeners | |
dap.listeners.before.attach.dapui_config = function() | |
ui.open() | |
end | |
dap.listeners.before.launch.dapui_config = function() | |
ui.open() | |
end | |
dap.listeners.before.event_terminated.dapui_config = function() | |
ui.close() | |
end | |
dap.listeners.before.event_exited.dapui_config = function() | |
ui.close() | |
end | |
end, | |
}, | |
-- Find workspace symbols | |
{ | |
'nvim-telescope/telescope.nvim', | |
dependencies = {'nvim-lua/plenary.nvim'}, | |
config = function() | |
vim.keymap.set('n', '<leader>s', '<cmd>Telescope lsp_workspace_symbols<CR>') | |
end | |
}, | |
-- highlight the same word as the cursor + the function body | |
{"RRethy/vim-illuminate"}, | |
-- git signs in the gutter | |
{"lewis6991/gitsigns.nvim"}, | |
-- auto brackets | |
{ | |
'windwp/nvim-autopairs', | |
event = "InsertEnter", | |
config = true | |
-- use opts = {} for passing setup options | |
-- this is equivalent to setup({}) function | |
}, | |
-- auto indent lines | |
{ | |
"lukas-reineke/indent-blankline.nvim", | |
main = "ibl", | |
---@module "ibl" | |
---@type ibl.config | |
opts = {}, | |
}, | |
-- super friggin smooth cursor | |
{"sphamba/smear-cursor.nvim"}, | |
-- multi cursor | |
{ | |
'mg979/vim-visual-multi', | |
branch = 'master' | |
} | |
}) | |
require("ibl").setup() | |
require("smear_cursor").toggle() | |
require('gitsigns').setup({ | |
signs = { | |
add = { text = '│' }, | |
change = { text = '│' }, | |
delete = { text = '_' }, | |
topdelete = { text = '‾' }, | |
changedelete = { text = '~' }, | |
}, | |
current_line_blame = true, -- Toggle with `:Gitsigns toggle_current_line_blame` | |
on_attach = function(bufnr) | |
local gs = package.loaded.gitsigns | |
local function map(mode, l, r, opts) | |
opts = opts or {} | |
opts.buffer = bufnr | |
vim.keymap.set(mode, l, r, opts) | |
end | |
-- Navigation | |
map('n', ']c', function() | |
if vim.wo.diff then return ']c' end | |
vim.schedule(function() gs.next_hunk() end) | |
return '<Ignore>' | |
end, {expr=true}) | |
map('n', '[c', function() | |
if vim.wo.diff then return '[c' end | |
vim.schedule(function() gs.prev_hunk() end) | |
return '<Ignore>' | |
end, {expr=true}) | |
-- Actions | |
map('n', '<leader>hs', gs.stage_hunk) | |
map('n', '<leader>hr', gs.reset_hunk) | |
map('v', '<leader>hs', function() gs.stage_hunk {vim.fn.line('.'), vim.fn.line('v')} end) | |
map('v', '<leader>hr', function() gs.reset_hunk {vim.fn.line('.'), vim.fn.line('v')} end) | |
map('n', '<leader>hS', gs.stage_buffer) | |
map('n', '<leader>hu', gs.undo_stage_hunk) | |
map('n', '<leader>hR', gs.reset_buffer) | |
map('n', '<leader>hp', gs.preview_hunk) | |
map('n', '<leader>hb', function() gs.blame_line{full=true} end) | |
map('n', '<leader>tb', gs.toggle_current_line_blame) | |
map('n', '<leader>hd', gs.diffthis) | |
map('n', '<leader>hD', function() gs.diffthis('~') end) | |
map('n', '<leader>td', gs.toggle_deleted) | |
end | |
}) | |
--[[ | |
leftover things from init.vim that i may still end up wanting | |
" Completion | |
" Better completion | |
" menuone: popup even when there's only one match | |
" noinsert: Do not insert text until a selection is made | |
" noselect: Do not select, force user to select one from the menu | |
set completeopt=menuone,noinsert,noselect | |
" Settings needed for .lvimrc | |
set exrc | |
set secure | |
" Wrapping options | |
set formatoptions=tc " wrap text and comments using textwidth | |
set formatoptions+=r " continue comments when pressing ENTER in I mode | |
set formatoptions+=q " enable formatting of comments with gq | |
set formatoptions+=n " detect lists for formatting | |
set formatoptions+=b " auto-wrap in insert mode, and do not wrap old long lines | |
" <leader>s for Rg search | |
noremap <leader>s :Rg | |
let g:fzf_layout = { 'down': '~20%' } | |
command! -bang -nargs=* Rg | |
\ call fzf#vim#grep( | |
\ 'rg --column --line-number --no-heading --color=always '.shellescape(<q-args>), 1, | |
\ <bang>0 ? fzf#vim#with_preview('up:60%') | |
\ : fzf#vim#with_preview('right:50%:hidden', '?'), | |
\ <bang>0) | |
" <leader>q shows stats | |
nnoremap <leader>q g<c-g> | |
--]] | |
-- | |
-- vim.lsp.set_log_level("debug") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment