-- [[ Setting options ]] -- See `:help vim.o` -- Set as the leader key vim.g.mapleader = " " vim.g.maplocalleader = " " vim.o.diffopt = "vertical,closeoff,filler" local opt = vim.opt vim.schedule(function() vim.opt.clipboard = 'unnamedplus' end) -- opt.shortmess:append({ W = true, I = true, c = true }) -- INFO: this control the format of some messages -- vim.o.exrc = true -- vim.opt.list = true -- Sets how neovim will display certain whitespace characters in the editor. -- vim.opt.listchars = { tab = '» ', trail = '·', nbsp = '␣' } opt.autowrite = true -- Enable auto write opt.breakindent = true -- Every wrapped line will continue visually indented opt.completeopt = "menu,menuone,noselect" opt.conceallevel = 2 -- Hide * markup for bold and italic opt.confirm = true -- Confirm to save changes before exiting modified buffer opt.cursorline = true -- Enable highlighting of the current line opt.expandtab = true -- Use spaces instead of tabs opt.formatoptions = "jcroqlnt" -- tcqj opt.grepformat = "%f:%l:%c:%m" opt.grepprg = "rg --vimgrep" opt.ignorecase = true -- Ignore case opt.inccommand = 'split' -- Preview substitutions live, as you type! opt.mouse = "a" -- Enable mouse mode opt.nrformats = 'blank,bin,hex' opt.number = true -- Print line number opt.pumblend = 10 -- Popup blend opt.pumheight = 10 -- Maximum number of entries in a popup -- opt.relativenumber = true -- Relative line numbers opt.scrolloff = 15 -- Lines of context opt.sidescrolloff = 25 -- Columns of context opt.sessionoptions = { "buffers", "curdir", "tabpages", "winsize" } opt.shiftround = true -- Round indent opt.shiftwidth = 2 -- Size of an indent opt.showmode = false -- Don't show mode since we have a statusline opt.sidescrolloff = 8 -- Columns of context opt.signcolumn = "yes" -- Always show the signcolumn, otherwise it would shift the text each time opt.smartcase = true -- Don't ignore case with capitals opt.smartindent = true -- Insert indents automatically opt.spelllang = { "en" } opt.splitbelow = true -- Put new windows below current opt.splitright = true -- Put new windows right of current opt.tabstop = 2 -- Number of spaces tabs count for opt.termguicolors = true -- True color support opt.undofile = true opt.undolevels = 10000 opt.updatetime = 200 -- Save swap file and trigger CursorHold opt.wildmode = "longest,list:full" -- Command-line completion mode opt.winminwidth = 5 -- Minimum window width opt.wrap = false -- Disable line wrap vim.o.completeopt = 'noselect,menu,menuone,noinsert,popup' vim.o.winborder = 'rounded' vim.o.sessionoptions = "blank,buffers,curdir,folds,help,tabpages,winsize,winpos,terminal,localoptions" -- Nice and simple folding: vim.o.foldenable = true vim.o.foldlevel = 99 vim.o.foldmethod = "expr" vim.o.foldexpr = "v:lua.vim.treesitter.foldexpr()" vim.opt.fillchars:append({ fold = " " }) local fn = vim.fn -- Quickfix customization function _G.qftf(info) local items local ret = {} -- The name of item in list is based on the directory of quickfix window. -- Change the directory for quickfix window make the name of item shorter. -- It's a good opportunity to change current directory in quickfixtextfunc :) -- -- local alterBufnr = fn.bufname('#') -- alternative buffer is the buffer before enter qf window -- local root = getRootByAlterBufnr(alterBufnr) -- vim.cmd(('noa lcd %s'):format(fn.fnameescape(root))) -- if info.quickfix == 1 then items = fn.getqflist({ id = info.id, items = 0 }).items else items = fn.getloclist(info.winid, { id = info.id, items = 0 }).items end local limit = 31 local fnameFmt1, fnameFmt2 = "%-" .. limit .. "s", "…%." .. (limit - 1) .. "s" local validFmt = "%s │%5d:%-3d│%s %s" for i = info.start_idx, info.end_idx do local e = items[i] local fname = "" local str if e.valid == 1 then if e.bufnr > 0 then fname = fn.bufname(e.bufnr) if fname == "" then fname = "[No Name]" else fname = fname:gsub("^" .. vim.env.HOME, "~") end -- char in fname may occur more than 1 width, ignore this issue in order to keep performance if #fname <= limit then fname = fnameFmt1:format(fname) else fname = fnameFmt2:format(fname:sub(1 - limit)) end end local lnum = e.lnum > 99999 and -1 or e.lnum local col = e.col > 999 and -1 or e.col local qtype = e.type == "" and "" or " " .. e.type:sub(1, 1):upper() str = validFmt:format(fname, lnum, col, qtype, e.text) else str = e.text end table.insert(ret, str) end return ret end -- TODO: how to customize? vim.o.qftf = "{info -> v:lua._G.qftf(info)}" vim.filetype.add({ -- Detect and assign filetype based on the extension of the filename extension = { mdx = "mdx", log = "log", conf = "conf", env = "dotenv", }, -- Detect and apply filetypes based on the entire filename filename = { [".env"] = "dotenv", ["env"] = "dotenv", ["tsconfig.json"] = "jsonc", }, -- Detect and apply filetypes based on certain patterns of the filenames pattern = { -- INFO: Match filenames like - ".env.example", ".env.local" and so on ["%.env%.[%w_.-]+"] = "dotenv", [".*%.blade%.php"] = "blade", [".*%.hurl.*"] = "hurl", [".*/hypr/.*%.conf"] = "hyprlang", }, }) -- ╭─────────────────────────────────────────────────────────╮ -- │ LSP │ -- ╰─────────────────────────────────────────────────────────╯ vim.lsp.config("rust-analyzer", { tools = { code_actions = { ui_select_fallback = true } } }) vim.lsp.enable({ "bashls", "biome", "fish_lsp", "gleam", "gopls", "hyprls", "intelephense", "jsonls", "kotlin_lsp", "lua_ls", "nushell", "pyright", "ruff", -- "rust_analyzer", -- managed by rustacean.nvim }) vim.lsp.inlay_hint.enable(true) vim.diagnostic.config({ virtual_lines = { current_line = true }, })