---@diagnostic disable: missing-fields -- vim:foldmethod=marker vim.g.loaded_netrw = 1 vim.g.loaded_netrwPlugin = 1 local function get_python_venv_path() --{{{1 return vim.fn.stdpath('config') .. '/.venv/bin/python' end do vim.g.python3_host_prog = get_python_venv_path() end -- GENERAL SETTINGS {{{1 vim.cmd [[ set exrc set secure set clipboard=unnamedplus set cursorline set tabstop=4 set shiftwidth=0 set rnu set nu set nowrap set shiftround set expandtab set nohlsearch set incsearch set scrolloff=8 nnoremap zz nnoremap zz nnoremap ,co :copen nnoremap ,cc :cclose nnoremap ,cq :call setqflist([]):cclose nnoremap ,ct :call setqflist([{'filename': expand('%'), 'lnum': line('.'), 'col': col('.'), 'text': 'TODO'}], 'a') nnoremap ,cf :cfirst nnoremap ,cl :clast nnoremap :cnext nnoremap :cprevious nnoremap ,cd :cd %:p:h nnoremap ,cu :colder nnoremap ,cr :cnewer nnoremap ,cD :call setqflist(filter(getqflist(), 'v:val != getqflist()[getqflist({"idx": 0}).idx - 1]')) nnoremap ,t vl:terminala " Don't include curdir, it just causes pain. set viewoptions=folds,cursor autocmd BufWinLeave *.* silent! mkview autocmd BufWinEnter *.* silent! loadview nnoremap h nnoremap j nnoremap k nnoremap l nnoremap ,v v tnoremap h tnoremap j tnoremap k tnoremap l tnoremap c c autocmd TextYankPost * silent! lua vim.highlight.on_yank {higroup='Visual', timeout=100} autocmd BufEnter *__virtual* setlocal buftype=nofile bufhidden=hide noswapfile let g:rustfmt_autosave = 1 " remove annoying and bad indentation autocmd FileType * setlocal indentexpr= ]] local function file_exists(name) --{{{1 local f = io.open(name,"r") if f~=nil then f:close() return true else return false end end -- LAZY.NVIM BOOTSTRAP {{{1 local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if not (vim.uv or 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) require'lazy'.setup{ --{{{1 { 'unblevable/quick-scope', --{{{2 init = function() vim.cmd [[ let g:qs_highlight_on_keys = ['f', 'F', 't', 'T'] ]] end, }, { 'michaeljsmith/vim-indent-object', --{{{2 }, { 'kylechui/nvim-surround', --{{{2 version = '*', -- Use for stability; omit to use `main` branch for the latest features event = 'VeryLazy', config = function() require('nvim-surround').setup{} end }, { 'echasnovski/mini.align', --{{{2 version = false, config = function() require'mini.align'.setup() end, }, { 'nvim-tree/nvim-tree.lua', --{{{2 dependencies = {"nvim-tree/nvim-web-devicons"}, config = function () local function map_toggle(bufnr) bufnr = bufnr or nil local api = require("nvim-tree.api") vim.keymap.set( "n", "-", api.tree.toggle, { desc = "nvim-tree: Toggle", buffer = bufnr, noremap = true, silent = true, nowait = true, } ) end local function my_on_attach(bufnr) local api = require("nvim-tree.api") api.config.mappings.default_on_attach(bufnr) map_toggle(bufnr) end require'nvim-tree'.setup{ on_attach = my_on_attach, update_focused_file = { enable = true, } } map_toggle() end }, { 'sainnhe/everforest', --{{{2 lazy = false, priority = 1000, config = function() vim.o.termguicolors = true vim.g.everforest_enable_italic = true vim.cmd.colorscheme('everforest') end, }, { 'folke/zen-mode.nvim', --{{{2 dependencies = {"folke/twilight.nvim"}, config = function () vim.keymap.set( 'n', ",z", vim.cmd.ZenMode, { silent = true } ) end }, { 'seblyng/roslyn.nvim', --{{{2 --WARN: requires html-lsp, roslyn and rzls installed via Mason dependencies = { 'tris203/rzls.nvim', }, ft = {'cs', 'razor'}, config = function() require'rzls'.setup{} require'roslyn'.setup{ args = { '--stdio', '--logLevel=Information', '--extensionLogDirectory=' .. vim.fs.dirname(vim.lsp.get_log_path()), '--razorSourceGenerator=' .. vim.fs.joinpath( vim.fn.stdpath'data' --[[@as string]], 'mason', 'packages', 'roslyn', 'libexec', 'Microsoft.CodeAnalysis.Razor.Compiler.dll' ), '--razorDesignTimePath=' .. vim.fs.joinpath( vim.fn.stdpath'data' --[[@as string]], 'mason', 'packages', 'rzls', 'libexec', 'Targets', 'Microsoft.NET.Sdk.Razor.DesignTime.targets' ), }, config = { handlers = require 'rzls.roslyn_handlers', ['csharp|code_lens'] = { dotnet_enable_references_code_lens = true, } }, } end, init = function() vim.filetype.add{ extension = { razor = 'razor', cshtml = 'razor' } } end, opts = { exe = { 'dotnet', vim.fs.joinpath( vim.fn.stdpath'data' --[[@as string]], 'mason', 'packages', 'roslyn', 'libexec', 'Microsoft.CodeAnalysis.LanguageServer.dll' ) }, }, }, { "folke/lazydev.nvim", --{{{2 ft = "lua", -- only load on lua files opts = { library = { { path = "${3rd}/luv/library", words = { "vim%.uv" } }, { path = "${3rd}/love2d/library", words = { "love" } }, }, }, }, { 'neovim/nvim-lspconfig', --{{{2 dependencies = { 'williamboman/mason.nvim', 'williamboman/mason-lspconfig.nvim', }, config = function() require'mason'.setup{ registries = { 'github:mason-org/mason-registry', 'github:crashdummyy/mason-registry', }, } do --it seems like mason-lspconfig's ensure_installed field does not work for lsps in 3rd-party registries local is_installed = require'mason-registry'.is_installed local c_sharp_requirements = { 'html-lsp', 'roslyn', 'rzls', } for _, requirement in ipairs(c_sharp_requirements) do if not is_installed(requirement) then vim.cmd('MasonInstall '..requirement) end end end require'mason-lspconfig'.setup() require'mason-lspconfig'.setup_handlers{ function (server_name) require'lspconfig'[server_name].setup{} end, zls = function() require'lspconfig'.zls.setup{ enable_autofix = false } vim.g.zig_fmt_autosave = false end, lua_ls = function() require'lspconfig'.lua_ls.setup{ Lua = { runtime = { version = "LuaJIT" } } } end } require'lspconfig'.gdscript.setup{} function JumpToDefinition() local tag_jump_success = pcall(vim.cmd, "tag " .. vim.fn.expand("")) if not tag_jump_success then vim.lsp.buf.definition() end end vim.cmd [[ noremap ,rn :lua vim.lsp.buf.rename() noremap ,fd :lua JumpToDefinition() noremap ,ft :lua vim.lsp.buf.type_definition() noremap ,fr :lua vim.lsp.buf.references() noremap ,ca :lua vim.lsp.buf.code_action() noremap ,oe :lua vim.diagnostic.open_float() noremap ,ea :lua vim.diagnostic.setqflist() noremap ,ee :lua vim.diagnostic.setqflist{severity="ERROR"} noremap ,ew :lua vim.diagnostic.setqflist{severity="WARN"} noremap ,ei :lua vim.diagnostic.setqflist{severity="INFO"} noremap ,eh :lua vim.diagnostic.setqflist{severity="HINT"} ]] end }, { 'nvim-treesitter/nvim-treesitter', --{{{2 config = function() require'nvim-treesitter.configs'.setup{ ensure_installed = "all", sync_install = false, auto_install = true, indent = { enable = true, }, highlight = { enable = true, additional_vim_regex_highlighting = false, }, } end, }, { "kdheepak/lazygit.nvim", --{{{2 lazy = true, cmd = { "LazyGit", "LazyGitConfig", "LazyGitCurrentFile", "LazyGitFilter", "LazyGitFilterCurrentFile", }, dependencies = { "nvim-lua/plenary.nvim", }, keys = { { ",g", "LazyGit", desc = "LazyGit" }, }, }, { 'mfussenegger/nvim-dap', --{{{2 dependencies = { 'nvim-treesitter/nvim-treesitter', 'theHamsta/nvim-dap-virtual-text', 'leoluz/nvim-dap-go', 'mfussenegger/nvim-dap-python', }, config = function() require'nvim-dap-virtual-text'.setup{ commented = true, } require'dap-go'.setup() require'dap-python'.setup(get_python_venv_path()) local dap = require'dap' dap.adapters.godot = { type = 'server', host = '127.0.0.1', port = 6006, } dap.configurations.gdscript = { {type = 'godot', request = 'launch', name = 'Launch scene', project = "${workspaceFolder}",} } dap.adapters.lldb = { type = 'executable', command = vim.fn.exepath('lldb-dap'), name = 'lldb' } dap.configurations.c = { { 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 = {}, runInTerminal = true, }, } dap.configurations.cpp = dap.configurations.c dap.configurations.rust = dap.configurations.c vim.cmd [[ nnoremap ,b :DapToggleBreakpoint nnoremap ,B :DapClearBreakpoints nnoremap nnoremap ,db :DapContinue nnoremap :DapStepInto nnoremap :DapStepOut nnoremap :DapStepOver ]] end }, { 'dcampos/nvim-snippy', --{{{2 config = function() require'snippy'.setup{ enable_auto = true, } vim.cmd [[ imap '(snippy-next)' imap '(snippy-previous)' smap '(snippy-next)' smap '(snippy-previous)' nmap g; (snippy-cut-text) xmap g; (snippy-cut-text) ]] vim.api.nvim_create_user_command( 'S', function () ---@type string local snippets_path = vim.fn.stdpath('config') .. '/snippets/' .. vim.bo.filetype .. '.snippets' if not file_exists(snippets_path) then local file = io.open( snippets_path, 'w' ) assert( file ~= nil, ("io.open('%s', 'w') returned nil.\n"):format(snippets_path) .. "Make sure the snippets folder in the above path exists." ) file:close() print('created file: ', snippets_path) end vim.api.nvim_command(('SnippyEdit %s'):format(snippets_path)) end, { nargs = 0 } ) end }, { 'hrsh7th/nvim-cmp', --{{{2 dependencies = { 'hrsh7th/cmp-nvim-lsp', 'hrsh7th/cmp-path', 'dcampos/nvim-snippy', 'dcampos/cmp-snippy', 'quangnguyen30192/cmp-nvim-tags', }, config = function() local cmp = require'cmp' cmp.setup{ snippet = { expand = function(args) require'snippy'.expand_snippet(args.body) end, }, mapping = { [''] = cmp.mapping.confirm{ select = true }, [''] = cmp.mapping.select_next_item(), [''] = cmp.mapping.select_prev_item(), }, sources = cmp.config.sources( { { name = 'snippy', priority = 100000000000000000000 }, { name = 'nvim_lsp', priority = 1000000000}, { name = 'tags', priority = 100 }, { name = 'path', priority = 1}, } ), preselect = cmp.PreselectMode.None, } end, }, { 'nvim-telescope/telescope.nvim', --{{{2 tag = '0.1.8', dependencies = { 'nvim-lua/plenary.nvim', 'nvim-telescope/telescope-ui-select.nvim', }, config = function() local a = require'telescope.actions' require'telescope'.setup{ defaults = { file_ignore_patterns = {'%__virtual.cs$'}, mappings = { i = { [""] = a.smart_send_to_qflist + a.open_qflist, [""] = a.select_default, }, n = { [""] = a.smart_send_to_qflist + a.open_qflist, [""] = a.select_default, }, } }, extensions = { ['ui-select'] = { require'telescope.themes'.get_dropdown{}, }, }, } vim.cmd [[ noremap ,ff :lua require'telescope.builtin'.find_files() noremap ,fo :lua require'telescope.builtin'.oldfiles() noremap ,fg :lua require'telescope.builtin'.live_grep() noremap ,fz :lua require'telescope.builtin'.current_buffer_fuzzy_find() noremap ,fh :lua require'telescope.builtin'.help_tags() noremap ,fm :lua require'telescope.builtin'.marks() noremap ,fb :lua require'telescope.builtin'.buffers() noremap ,fcm :lua require'telescope.builtin'.commands() noremap ,fct :lua require'telescope.builtin'.tags() noremap ,fea :lua require'telescope.builtin'.diagnostics() noremap ,fee :lua require'telescope.builtin'.diagnostics{severity="ERROR"} noremap ,few :lua require'telescope.builtin'.diagnostics{severity="WARN"} noremap ,fei :lua require'telescope.builtin'.diagnostics{severity="INFO"} noremap ,feh :lua require'telescope.builtin'.diagnostics{severity="HINT"} ]] require'telescope'.load_extension'ui-select' end, }, } do -- split line {{{1 local SPLIT_DELIMETERS = { -- single characters only [','] = true, [';'] = true, } local SPLIT_BETWEEN = { -- single characters only ['('] = ')', ['['] = ']', ['{'] = '}', ['<'] = '>', } local SPLIT_IGNORE_BETWEEN = { --single characters only ['"'] = '"', ["'"] = "'", } local split_line = function() local SPLIT_WHITESPACE = ' ' if vim.o.expandtab then SPLIT_WHITESPACE = '' for _ = 1, vim.o.tabstop do SPLIT_WHITESPACE = SPLIT_WHITESPACE .. ' ' end end local line = vim.api.nvim_get_current_line() local _, col = unpack(vim.api.nvim_win_get_cursor(0)) col = col + 1 -- Doing this to make it 1-indexed ---@type integer? local first_bracket_i = nil for i = col, #line do local char = line:sub(i, i) if SPLIT_BETWEEN[char] ~= nil then first_bracket_i = i break end end if not first_bracket_i then print('No opening brackets found after cursor on this line.') return end ---@type integer[] local split_indexes = {} -- Populate this array ---@type integer? local last_bracket_i = nil -- And find this index do ---@type string[] local closing_bracket_stack = {} local icon_to_close_ignore = '' local in_ignore = false for i = first_bracket_i, #line do local char = line:sub(i,i) if in_ignore then in_ignore = not (char == icon_to_close_ignore) goto continue end if SPLIT_IGNORE_BETWEEN[char] ~= nil then icon_to_close_ignore = SPLIT_IGNORE_BETWEEN[char] in_ignore = true goto continue end -- string handling complete if SPLIT_BETWEEN[char] ~= nil then table.insert( closing_bracket_stack, SPLIT_BETWEEN[char] ) end if char == closing_bracket_stack[#closing_bracket_stack] then table.remove(closing_bracket_stack) end if #closing_bracket_stack == 1 and SPLIT_DELIMETERS[char] then table.insert(split_indexes, i) end if #closing_bracket_stack == 0 then last_bracket_i = i break end ::continue:: end end if not last_bracket_i then print("The first opening bracket found after the cursor was not closed on this line.") return end if #split_indexes == 0 then print('No comma separated items within brackets that were opened and closed after the cursor.') return end ---@type string local leading_whitespace = string.match(line, "^%s*") local first_line = line:sub(1, first_bracket_i) local last_line = leading_whitespace .. line:sub(last_bracket_i, #line) local middle_lines = {} table.insert( middle_lines, line:sub(first_bracket_i+1, split_indexes[1]) ) for i = 1, #split_indexes-1 do table.insert( middle_lines, line:sub(split_indexes[i], split_indexes[i+1]) ) end table.insert( middle_lines, line:sub(split_indexes[#split_indexes], last_bracket_i-1) ) local leading_pattern = "^[%s" for k, _ in pairs(SPLIT_DELIMETERS) do leading_pattern = leading_pattern .. k end leading_pattern = leading_pattern .. "]*" -- Cleanup step for i, middle_line in ipairs(middle_lines) do middle_line = middle_line:gsub(leading_pattern, leading_whitespace .. SPLIT_WHITESPACE, 1) middle_line = middle_line:gsub("[%s]*$", '', 1) middle_lines[i] = middle_line end if middle_lines[#middle_lines]:match("^%s*$") ~= nil then table.remove(middle_lines) end local row, _ = unpack(vim.api.nvim_win_get_cursor(0)) vim.api.nvim_buf_set_lines(0, row-1, row, false, {first_line}) vim.api.nvim_buf_set_lines(0, row, row, false, {last_line}) vim.api.nvim_buf_set_lines(0, row, row, false, middle_lines) end vim.keymap.set( 'n', ",s", split_line, { silent = true } ) end