local vim = vim local Plug = vim.fn['plug#'] local o = vim.opt local g = vim.g o.title = true g.mapleader = ' ' g.maplocalleader = ' ' g.toggle_theme_icon = "  " g.have_nerd_font = true -- Line numbers o.number = true -- o.spell = true o.spelllang="en_us,es" -- Configure how new splits should be opened o.splitright = true o.splitbelow = true o.inccommand = 'split' -- Tabs o.shiftwidth = 2 o.tabstop = 2 o.undofile = true o.undodir = vim.fn.stdpath("data") .. "/undo//" -- https://www.reddit.com/r/neovim/comments/wlkq0e/neovim_configuration_to_backup_files_with/ o.backup = true o.backupdir = vim.fn.stdpath("data") .. "/backup//" -- o.clipboard = "unnamedplus" -- Statuscolumn -- Set sign column to be 4. -- So, if I have a new diff, It'll not feel weird, by the signcolumn expanding o.signcolumn = "yes:1" -- Statusline o.cmdheight = 0 o.laststatus = 3 -- Folds o.foldcolumn = "1" o.foldlevel = 99 o.foldlevelstart = 99 o.foldenable = true -- Enable break indent o.breakindent = true o.list = true o.listchars = { tab = '» ', trail = '·', nbsp = '␣' } -- Scrolloff o.scrolloff = 15 -- Show which line your cursor is on o.cursorline = true -- Searching o.ignorecase = true o.smartcase = true o.pumblend = 10 -- Popup blend o.pumheight = 10 -- Maximum number of entries in a popup vim.opt.hlsearch = true vim.keymap.set('n', '', 'nohlsearch') local map = vim.keymap.set map('v', "y", '"+y') map('n', '', ':Treewalker Down', { noremap = true }) map('n', '', ':Treewalker Up', { noremap = true }) map('n', '', ':Treewalker Left', { noremap = true }) map('n', '', ':Treewalker Right', { noremap = true }) -- Diagnostic keymaps map('n', '[d', vim.diagnostic.goto_prev, { desc = 'Go to previous [D]iagnostic message' }) map('n', ']d', vim.diagnostic.goto_next, { desc = 'Go to next [D]iagnostic message' }) map('n', 'e', vim.diagnostic.open_float, { desc = 'Show diagnostic [E]rror messages' }) map('v', 'q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' }) -- Prevent CapsLock from interfering with movement keys map('n', 'J', 'j', { noremap = true }) map('n', 'K', 'k', { noremap = true }) map('n', 'H', 'h', { noremap = true }) map('n', 'L', 'l', { noremap = true }) map('n', 'U', 'u', { noremap = true }) -- Better window navigation (works across splits) map('n', '', 'h', { desc = 'Move to left window' }) map('n', '', 'j', { desc = 'Move to lower window' }) map('n', '', 'k', { desc = 'Move to upper window' }) map('n', '', 'l', { desc = 'Move to right window' }) -- Keep cursor centered during searches and jumps map('n', 'n', 'nzzzv', { desc = 'Next search result (centered)' }) map('n', 'N', 'Nzzzv', { desc = 'Prev search result (centered)' }) map('n', 'G', 'Gzz', { desc = 'Jump to line (centered)' }) -- Clear last search highlight map('n', 'nh', ':nohlsearch', { desc = 'Clear search highlights' }) -- Half-page jumping with centered cursor map('n', '', 'zz') map('n', '', 'zz') -- Move lines up/down in visual mode map('v', 'J', ":m '>+1gv=gv", { desc = 'Move selection down' }) map('v', 'K', ":m '<-2gv=gv", { desc = 'Move selection up' }) -- Quick fix list navigation map('n', '', ':cnext', { desc = 'Next quickfix item' }) map('n', '', ':cprev', { desc = 'Previous quickfix item' }) -- System clipboard integration map('n', 'p', '"+p', { desc = 'Paste from system clipboard' }) map('n', 'P', '"+P', { desc = 'Paste from system clipboard (before)' }) -- Better indentation map('v', '<', '', '>gv', { desc = 'Indent and stay in visual mode' }) -- Buffer navigation map('n', 'bn', ':bnext', { desc = 'Next buffer' }) map('n', 'bp', ':bprevious', { desc = 'Previous buffer' }) map('n', 'bd', ':bdelete', { desc = 'Delete buffer' }) -- Replace current word map('n', 's', [[:%s/\<\>//gI]], { desc = 'Replace current word' }) -- Keep search matches in middle map('n', '*', '*zz', { desc = 'Search word under cursor (centered)' }) map('n', '#', '#zz', { desc = 'Search backward word (centered)' }) -- Quick save/quit map('n', 'w', ':w', { desc = 'Save file' }) map('n', 'q', ':q', { desc = 'Quit window' }) -- Disable hell map('n', 'Q', 'gq') -- Toggle terminal map('n', 'tt', ':terminal', { desc = '[T]oggle [T]erminal' }) -- Escape terminal mode map('t', '', '', { desc = 'Exit terminal mode' }) -- Open chad tree map('n', '.', ':CHADopen', { noremap = true }) -- Quick escape from insert mode map('i', 'jk', '', { desc = 'Exit insert mode' }) -- Clear search highlights map('n', '', 'nohlsearch', { desc = 'Clear search highlights' }) -- Toggle spellcheck map('n', 'ts', ':set spell!', { desc = '[T]oggle [S]pellcheck' }) -- Epic Golang JSON metadata macro, piss off pussies map('n', 'j', '_ywApbeld$bguwciw"pA"F"ijson:bi`A`_j', { noremap = true }) map('n', '_', 'ebcw_', { noremap = true, desc = 'Replace word with _ (to ignore variable)' }) vim.call('plug#begin') -- Style Plug 'folke/tokyonight.nvim' Plug 'olimorris/onedarkpro.nvim' Plug 'xiyaowong/transparent.nvim' Plug 'alexblackie/lunarised' Plug 'starryleo/starry-vim-colorschemes' -- lsp Plug('williamboman/mason.nvim') Plug('williamboman/mason-lspconfig.nvim') -- more lsp Plug('neovim/nvim-lspconfig') Plug('L3MON4D3/LuaSnip', { ['tag'] = 'v2.*', }) Plug 'marilari88/twoslash-queries.nvim' Plug 'neovim/nvim-lspconfig' -- auto complete Plug 'hrsh7th/cmp-nvim-lsp' Plug 'hrsh7th/cmp-buffer' Plug 'hrsh7th/cmp-path' Plug 'hrsh7th/cmp-cmdline' Plug 'hrsh7th/nvim-cmp' Plug 'zbirenbaum/copilot-cmp' -- copilot Plug 'L3MON4D3/LuaSnip' Plug 'saadparwaiz1/cmp_luasnip' -- useful stuff Plug 'echasnovski/mini.nvim' Plug 'zbirenbaum/copilot.lua' Plug 'ms-jpq/chadtree' Plug 'ryanoasis/vim-devicons' Plug 'kyazdani42/nvim-web-devicons' Plug 'jetzig-framework/zmpl.vim' Plug 'folke/which-key.nvim' -- Personalization Plug 'nvim-lualine/lualine.nvim' Plug 'goolord/alpha-nvim' Plug 'lukas-reineke/indent-blankline.nvim' Plug 'karb94/neoscroll.nvim' Plug 'folke/noice.nvim' Plug 'MunifTanjim/nui.nvim' -- More stuff Plug 'SmiteshP/nvim-navic' Plug 'kr40/nvim-macros' -- tree sitter Plug 'nvim-treesitter/nvim-treesitter' Plug('aaronik/treewalker.nvim', { opts = { highlight = true } }) vim.call('plug#end') vim.cmd('set background=dark') -- Better Around/Inside textobjects -- -- Examples: -- - va) - [V]isually select [A]round [)]paren -- - yinq - [Y]ank [I]nside [N]ext [']quote -- - ci' - [C]hange [I]nside [']quote require('mini.ai').setup { n_lines = 500 } -- Add/delete/replace surroundings (brackets, quotes, etc.) -- -- - saiw) - [S]urround [A]dd [I]nner [W]ord [)]Paren -- - sd' - [S]urround [D]elete [']quotes -- - sr)' - [S]urround [R]eplace [)] ['] require('mini.surround').setup() -- Simple and easy statusline. -- You could remove this setup call if you don't like it, -- and try some other statusline plugin local statusline = require 'mini.statusline' -- set use_icons to true if you have a Nerd Font statusline.setup { use_icons = vim.g.have_nerd_font } -- You can configure sections in the statusline by overriding their -- default behavior. For example, here we set the section for -- cursor location to LINE:COLUMN ---@diagnostic disable-next-line: duplicate-set-field statusline.section_location = function() return '%2l:%-2v' end -- ... and there is more! -- Check out: https://github.com/echasnovski/mini.nvim require('mini.pairs').setup() require('nvim-treesitter.configs').setup({ -- A list of parser names, or "all" (the listed parsers MUST always be installed) ensure_installed = {'bash', 'c', 'html', 'lua', 'luadoc', 'markdown', 'vim', 'vimdoc'}, sync_install = false, highlight = { enable = true, additional_vim_regex_highlighting = false, }, }) require("mason").setup() local lspconfig = require('lspconfig') lspconfig.zls.setup({ {cmd = '~/.zig/zls'} }) local lsp_cmds = vim.api.nvim_create_augroup('lsp_cmds', {clear = true}) vim.api.nvim_create_autocmd('LspAttach', { group = lsp_cmds, desc = 'LSP actions', callback = function() local bufmap = function(mode, lhs, rhs) vim.keymap.set(mode, lhs, rhs, {buffer = true}) end bufmap('n', 'K', 'lua vim.lsp.buf.hover()') bufmap('n', 'gd', 'lua vim.lsp.buf.definition()') bufmap('n', 'gD', 'lua vim.lsp.buf.declaration()') bufmap('n', 'gi', 'lua vim.lsp.buf.implementation()') bufmap('n', 'go', 'lua vim.lsp.buf.type_definition()') bufmap('n', 'gr', 'lua vim.lsp.buf.references()') bufmap('n', 'gs', 'lua vim.lsp.buf.signature_help()') bufmap('n', '', 'lua vim.lsp.buf.rename()') bufmap({'n', 'x'}, '', 'lua vim.lsp.buf.format({async = true})') bufmap('n', '', 'lua vim.lsp.buf.code_action()') bufmap('n', 'gl', 'lua vim.diagnostic.open_float()') bufmap('n', '[d', 'lua vim.diagnostic.goto_prev()') bufmap('n', ']d', 'lua vim.diagnostic.goto_next()') end }) require('mason-lspconfig').setup({ ensure_installed = {}, handlers = { function(server) lspconfig[server].setup({ capabilities = lsp_capabilities, }) end, } }) vim.opt.completeopt = {'menu', 'menuone', 'noselect'} require("copilot").setup({ suggestion = { enabled = false }, panel = { enabled = false }, }) require("copilot_cmp").setup() local cmp = require('cmp') local luasnip = require('luasnip') local select_opts = {behavior = cmp.SelectBehavior.Select} local has_words_before = function() if vim.api.nvim_buf_get_option(0, "buftype") == "prompt" then return false end local line, col = unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0 and vim.api.nvim_buf_get_text(0, line-1, 0, line-1, col, {})[1]:match("^%s*$") == nil end -- See :help cmp-config cmp.setup({ snippet = { expand = function(args) luasnip.lsp_expand(args.body) end }, sources = { {name = 'path'}, {name = 'nvim_lsp', keyword_length = 3}, {name = 'buffer', keyword_length = 3}, {name = 'luasnip', keyword_length = 2}, {name = 'copilot', group_index = 2} }, window = { documentation = cmp.config.window.bordered() }, formatting = { fields = {'menu', 'abbr', 'kind'}, format = function(entry, item) local menu_icon = { nvim_lsp = 'λ', luasnip = '⋗', buffer = 'Ω', path = '🖫', } item.menu = menu_icon[entry.source.name] return item end, }, -- See :help cmp-mapping mapping = { [''] = cmp.mapping.select_prev_item(select_opts), [''] = cmp.mapping.select_next_item(select_opts), [''] = cmp.mapping.select_prev_item(select_opts), [''] = cmp.mapping.select_next_item(select_opts), [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.abort(), [''] = cmp.mapping.confirm({select = false}), [''] = cmp.mapping(function(fallback) if luasnip.jumpable(1) then luasnip.jump(1) else fallback() end end, {'i', 's'}), [''] = cmp.mapping(function(fallback) if luasnip.jumpable(-1) then luasnip.jump(-1) else fallback() end end, {'i', 's'}), [''] = cmp.mapping(function(fallback) local col = vim.fn.col('.') - 1 if cmp.visible() and has_words_before() then cmp.select_next_item({ behavior = cmp.SelectBehavior.Select }) elseif cmp.visible() then cmp.select_next_item(select_opts) elseif col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') then fallback() else cmp.complete() end end, {'i', 's'}), [''] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_prev_item(select_opts) else fallback() end end, {'i', 's'}), }, }) -- auto save vim.api.nvim_create_autocmd("BufWritePost", { pattern = "hyprland.conf", callback = function() os.execute("hyprctl reload") vim.cmd.edit() end }) vim.api.nvim_create_autocmd("BufWritePost", { pattern = "init.lua", callback = function() -- Reload config without restarting Neovim vim.cmd("source $MYVIMRC") end }) -- Execute go tidy on save because nico told me so vim.api.nvim_create_autocmd("BufWritePost", { pattern = "*.go", callback = function() vim.cmd("silent! !go mod tidy") vim.cmd("silent! edit") end }) -- Format on save vim.api.nvim_create_autocmd('BufWritePre', { pattern = '*', callback = function() vim.lsp.buf.format() end }) -- Code actions menu map('n', 'ca', vim.lsp.buf.code_action, { desc = '[C]ode [A]ctions' }) -- Find references map('n', 'gr', vim.lsp.buf.references, { desc = '[G]oto [R]eferences' }) -- files to the right local chadtree_settings = { ['view.open_direction'] = "right", ['view.width'] = 20 } vim.api.nvim_set_var("chadtree_settings", chadtree_settings) -- Customization require('lualine').setup { options = { theme = 'tokyonight', component_separators = { left = '', right = ''}, section_separators = { left = '', right = ''}, globalstatus = true, icons_enabled = true }, sections = { lualine_a = {'mode'}, lualine_b = {'branch', 'diff', 'diagnostics'}, lualine_c = { { 'filename', path = 1, -- Show relative path symbols = { modified = '  ', readonly = '  ' } } }, lualine_x = { 'encoding', { 'fileformat', symbols = { unix = ' LF' } }, { 'filetype', icons_enabled = true, icon = { align = 'right' } } }, lualine_y = {'progress'}, lualine_z = {'location'} }, extensions = {'chadtree', 'fugitive'} } local alpha = require'alpha' local dashboard = require'alpha.themes.dashboard' dashboard.section.header.val = { [[ __ __ __ __ ______ __ __ ______ __ __ ]], [[/\ \_\ \ /\ \/\ \ /\___ \ /\ \/\ \ /\ == \ /\ \/\ \ ]], [[\ \____ \\ \ \_\ \\/_/ /__\ \ \_\ \\ \ __- \ \ \_\ \ ]], [[ \/\_____\\ \_____\ /\_____\\ \_____\\ \_\ \_\\ \_____\]], [[ \/_____/ \/_____/ \/_____/ \/_____/ \/_/ /_/ \/_____/]] } dashboard.section.buttons.val = { dashboard.button("e", " New file", ":ene startinsert "), dashboard.button("f", "󰈞 Find file", ":CHADopen"), dashboard.button("c", " Config", ":e ~/.config/nvim/init.lua"), dashboard.button("q", " Quit", ":qa"), } alpha.setup(dashboard.config) local highlight = { "CursorColumn", -- "Whitespace", } -- Indent guides require('ibl').setup { indent = { highlight = highlight, char = "" }, scope = { enabled = false }, } -- Smooth scrolling require('neoscroll').setup { mappings = {'', '', 'zz', 'zt', 'zb'}, hide_cursor = true, stop_eof = true, respect_scrolloff = false, } require('nvim-navic').setup { icons = { File = "󰈙 ", Module = " ", Namespace = "󰌗 ", Package = " ", Class = "󰌗 ", Method = "󰆧 ", Property = " ", Field = " ", Constructor = " ", Enum = "󰕘", Interface = "󰕘", Function = "󰊕 ", Variable = "󰆧 ", Constant = "󰏿 ", String = "󰀬 ", Number = "󰎠 ", Boolean = "◩ ", Array = "󰅪 ", Object = "󰅩 ", Key = "󰌋 ", Null = "󰟢 ", EnumMember = " ", Struct = "󰌗 ", Event = " ", Operator = "󰆕 ", TypeParameter = "󰊄 ", } } vim.o.winbar = "%{%v:lua.require'nvim-navic'.get_location()%}" map('n', 'tt', function() local height = math.ceil(vim.o.lines * 0.3) vim.api.nvim_command('botright split | resize ' .. height) vim.api.nvim_command('terminal') end, { desc = 'Open floating terminal' }) -- Better theme configuration require('tokyonight').setup { style = 'night', transparent = true, styles = { floats = 'transparent', sidebars = 'transparent' }, on_highlights = function(hl, c) hl.TelescopeBorder = { fg = c.bg_dark, bg = c.bg_dark } hl.TelescopePromptBorder = { fg = c.orange, bg = c.bg } end } vim.cmd.colorscheme('tokyonight') -- Etc require('noice').setup { cmdline = { view = 'cmdline_popup', format = { cmdline = { pattern = '^:', icon = '', lang = 'vim' }, search_down = { kind = 'search', pattern = '^/', icon = ' ', lang = 'regex' }, search_up = { kind = 'search', pattern = '^%?', icon = ' ', lang = 'regex' }, } }, popupmenu = { backend = 'nui', }, views = { cmdline_popup = { position = { row = 5, col = '50%' }, size = { width = 60, height = 'auto' }, } } } require('which-key').setup { plugins = { marks = true, registers = true, spelling = { enabled = true }, presets = { operators = true, motions = true, text_objects = true, windows = true, nav = true, z = true, g = true } }, }