From 4c8248f32337fe1c877e7b3ad939e8914abdc4a5 Mon Sep 17 00:00:00 2001 From: inorishio Date: Tue, 10 Feb 2026 16:13:55 +0100 Subject: [PATCH] poggers --- lua/config/blink.lua | 177 +++++++++++++++++++++++++ lua/config/copilot.lua | 2 +- lua/config/lspconfig.lua | 210 ++++++++++++++--------------- lua/config/neoformat.lua | 219 ------------------------------- lua/config/prettier.lua | 19 +++ lua/mappings.lua | 10 ++ lua/plugins/init.lua | 11 +- scripts/windows_dependencies.ps1 | 4 +- 8 files changed, 318 insertions(+), 334 deletions(-) create mode 100644 lua/config/blink.lua create mode 100644 lua/config/prettier.lua diff --git a/lua/config/blink.lua b/lua/config/blink.lua new file mode 100644 index 0000000..4b2d066 --- /dev/null +++ b/lua/config/blink.lua @@ -0,0 +1,177 @@ +local M = {} + +local icons = require("assets.icons").icons.kinds + +local devicons = { + default_icon = { icon = "󰈚", name = "Default" }, + js = { icon = "󰌞", name = "js" }, + ts = { icon = "󰛦", name = "ts" }, + lock = { icon = "󰌾", name = "lock" }, + ["robots.txt"] = { icon = "󰚩", name = "robots" }, +} + +M.components = { + kind_icon = { + text = function(ctx) + local icon = (icons[ctx.kind] or "󰈚") + + return icon .. " " + end, + }, + + kind = { + highlight = function(ctx) + return ctx.kind + end, + }, +} + +local opts = { + "saghen/blink.cmp", + dependencies = { + "rafamadriz/friendly-snippets", + { + "fang2hou/blink-copilot", + config = function() + require "config.blink-copilot" + end, + }, + }, + + version = "1.*", + + opts = { + keymap = { + [""] = { + function(cmp) + if cmp.is_visible() then + return cmp.select_next() + end + + if cmp.snippet_active() then + return cmp.snippet_forward() + end + end, + "fallback", + }, + [""] = { + function(cmp) + if cmp.is_visible() then + return cmp.select_prev() + end + + if cmp.snippet_active() then + return cmp.snippet_backward() + end + end, + "fallback", + }, + [""] = { "accept", "fallback" }, + ["Up"] = {}, + ["Down"] = {}, + }, + + appearance = { + nerd_font_variant = "mono", + }, + + cmdline = { + completion = { + menu = { auto_show = true }, + list = { selection = { preselect = false } }, + }, + + keymap = { + [""] = { + function(cmp) + if cmp.is_visible() then + return cmp.select_next() + end + end, + "fallback", + }, + [""] = { + function(cmp) + if cmp.is_visible() then + return cmp.select_prev() + end + end, + "fallback", + }, + [""] = { "accept", "fallback" }, + ["Up"] = {}, + ["Down"] = {}, + }, + }, + + completion = { + documentation = { auto_show = true, auto_show_delay_ms = 50 }, + keyword = { range = "full" }, + accept = { auto_brackets = { enabled = true } }, + ghost_text = { enabled = true }, + list = { + selection = { + -- preselect = false, + auto_insert = false, + }, + }, + + menu = { + scrollbar = false, + border = "single", + draw = { + padding = 1, + columns = { + { "kind_icon" }, + { "label", "label_description", gap = 1 }, + { "kind" }, + }, + components = M.components, + }, + }, + }, + + signature = { enabled = true }, + + sources = { + default = { "lsp", "path", "snippets", "buffer", "copilot" }, + providers = { + lsp = { + score_offset = 50, + }, + + path = { + opts = { + get_cwd = function() + return vim.fn.getcwd() + end, + }, + }, + + buffer = { + score_offset = -10, + }, + + snippets = { + score_offset = 0, + }, + + copilot = { + name = "copilot", + module = "blink-copilot", + score_offset = 100, + async = true, + }, + }, + }, + + snippets = { + preset = "default", + }, + + fuzzy = { implementation = "prefer_rust_with_warning" }, + }, + opts_extend = { "sources.default" }, +} + +return opts diff --git a/lua/config/copilot.lua b/lua/config/copilot.lua index 5092bd2..a730264 100644 --- a/lua/config/copilot.lua +++ b/lua/config/copilot.lua @@ -20,7 +20,7 @@ require("copilot").setup({ hide_during_completion = true, debounce = 75, keymap = { - accept = "", + accept = "", accept_word = false, accept_line = false, next = "", diff --git a/lua/config/lspconfig.lua b/lua/config/lspconfig.lua index 65625fb..449b29d 100644 --- a/lua/config/lspconfig.lua +++ b/lua/config/lspconfig.lua @@ -1,43 +1,28 @@ -local cmp = require("cmp") -local cmp_lsp = require("cmp_nvim_lsp") +local function flatten_to_array(t) + local res = {} + local function _flatten(tbl) + for _, v in ipairs(tbl) do + if type(v) == "table" then + _flatten(v) + else + table.insert(res, v) + end + end + end + _flatten(t) + return res +end + local capabilities = vim.tbl_deep_extend( "force", {}, vim.lsp.protocol.make_client_capabilities(), - cmp_lsp.default_capabilities() + require("blink.cmp").get_lsp_capabilities() ) -local cmp_kinds = { - Text = ' ', - Method = ' ', - Function = ' ', - Constructor = ' ', - Field = ' ', - Variable = ' ', - Class = ' ', - Interface = ' ', - Module = ' ', - Property = ' ', - Unit = ' ', - Value = ' ', - Enum = ' ', - Keyword = ' ', - Snippet = ' ', - Color = ' ', - File = ' ', - Reference = ' ', - Folder = ' ', - EnumMember = ' ', - Constant = ' ', - Struct = ' ', - Event = ' ', - Operator = ' ', - TypeParameter = ' ', -} - -require("fidget").setup({}) +require("fidget").setup {} require("mason").setup() -require("mason-lspconfig").setup({ +require("mason-lspconfig").setup { automatic_enable = true, ensure_installed = { "lua_ls", @@ -52,24 +37,28 @@ require("mason-lspconfig").setup({ end, ["tailwindcss"] = function() - local lspconfig = require("lspconfig") + local lspconfig = require "lspconfig" lspconfig.tailwindcss.setup { capabilities = capabilities, } end, ["css-lsp"] = function() - local lspconfig = require("lspconfig") + local lspconfig = require "lspconfig" lspconfig.cssls.setup { capabilities = capabilities, } end, zls = function() - local lspconfig = require("lspconfig") - lspconfig.zls.setup({ + local lspconfig = require "lspconfig" + lspconfig.zls.setup { capabilities = capabilities, - root_dir = lspconfig.util.root_pattern(".git", "build.zig", "zls.json"), + root_dir = lspconfig.util.root_pattern( + ".git", + "build.zig", + "zls.json" + ), settings = { zls = { enable_inlay_hints = true, @@ -77,89 +66,35 @@ require("mason-lspconfig").setup({ warn_style = true, }, }, - }) + } vim.g.zig_fmt_parse_errors = 0 vim.g.zig_fmt_autosave = 0 - end, ["lua_ls"] = function() - local lspconfig = require("lspconfig") + local lspconfig = require "lspconfig" lspconfig.lua_ls.setup { capabilities = capabilities, settings = { Lua = { runtime = { version = "Lua 5.1" }, diagnostics = { - globals = { "bit", "vim", "it", "describe", "before_each", "after_each" }, - } - } - } + globals = { + "bit", + "vim", + "it", + "describe", + "before_each", + "after_each", + }, + }, + }, + }, } end, - } -}) - -cmp.setup { - preselect = 'None', - formatting = { - fields = { 'kind', 'abbr' }, - format = function(entry, vim_item) - vim_item.kind = cmp_kinds[vim_item.kind] or '' - if entry.completion_item.detail then - vim_item.menu = entry.completion_item.detail - end - return vim_item - end, }, - completion = { completeopt = "menu,menuone" }, - snippet = { - expand = function(args) - require("luasnip").lsp_expand(args.body) - end, - }, - - mapping = { - [""] = cmp.mapping.select_prev_item(), - [""] = cmp.mapping.select_next_item(), - [""] = cmp.mapping.scroll_docs(-4), - [""] = cmp.mapping.scroll_docs(4), - [""] = cmp.mapping.complete(), - [""] = cmp.mapping.close(), - [""] = cmp.mapping.confirm { - behavior = cmp.ConfirmBehavior.Insert, - select = true, - }, - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_next_item() - elseif require("luasnip").expand_or_jumpable() then - require("luasnip").expand_or_jump() - else - fallback() - end - end, { "i", "s" }), - [""] = cmp.mapping(function(fallback) - if cmp.visible() then - cmp.select_prev_item() - elseif require("luasnip").jumpable(-1) then - require("luasnip").jump(-1) - else - fallback() - end - end, { "i", "s" }), - }, - - sources = cmp.config.sources({ - { name = "path" }, - { name = "nvim_lsp" }, - { name = "luasnip" }, - { name = "buffer" }, - { name = "nvim_lua" }, - }), } -vim.diagnostic.config({ - -- update_in_insert = true, +vim.diagnostic.config { virtual_text = false, virtual_lines = false, signs = true, @@ -172,20 +107,32 @@ vim.diagnostic.config({ header = "", prefix = "", }, -}) +} local lspconfig = vim.lsp.config lspconfig("texlab", { cmd = { "texlab" }, filetypes = { "tex", "bib", "plaintex" }, - root_markers = { ".git", ".latexmkrc", "latexmkrc", ".texlabroot", "texlabroot", "Tectonic.toml" }, + root_markers = { + ".git", + ".latexmkrc", + "latexmkrc", + ".texlabroot", + "texlabroot", + "Tectonic.toml", + }, settings = { texlab = { rootDirectory = nil, build = { executable = "latexmk", - args = { "-pdf", "-interaction=nonstopmode", "-synctex=1", "%f" }, + args = { + "-pdf", + "-interaction=nonstopmode", + "-synctex=1", + "%f", + }, onSave = true, forwardSearchAfter = true, }, @@ -193,7 +140,8 @@ lspconfig("texlab", { executable = "zathura", args = { "--synctex-editor-command", - [[ nvim-texlabconfig -file '%%%{input}' -line %%%{line} -server ]] .. vim.v.servername, + [[ nvim-texlabconfig -file '%%%{input}' -line %%%{line} -server ]] + .. vim.v.servername, "--synctex-forward", "%l:1:%f", "%p", @@ -206,7 +154,7 @@ lspconfig("texlab", { diagnosticsDelay = 300, latexFormatter = "latexindent", latexindent = { - ['local'] = nil, + ["local"] = nil, modifyLineBreaks = false, }, bibtexFormatter = "texlab", @@ -219,6 +167,27 @@ lspconfig("qmlls", { cmd = { "qmlls6" }, }) +lspconfig("jsonls", { + settings = { + json = { + schemas = require("schemastore").json.schemas(), + validate = { enable = true }, + }, + }, +}) + +lspconfig("yamlls", { + settings = { + yaml = { + schemaStore = { + enable = false, + url = "", + }, + schemas = require("schemastore").yaml.schemas(), + }, + }, +}) + local lspenable = vim.lsp.enable local servers = { "html", @@ -229,8 +198,25 @@ local servers = { "sourcekit", "qmlls", "tailwindcss", + "systemd-lsp", + require("mason-lspconfig").get_installed_servers(), } -for _, server in ipairs(servers) do +local flat_servers = flatten_to_array(servers) + +for _, server in ipairs(flat_servers) do + lspconfig(server, { + on_attach = function(client, bufnr) + if client.name == "typos_lsp" or client.name == "copilot" then + return + end + + require("workspace-diagnostics").populate_workspace_diagnostics( + client, + bufnr + ) + end, + capabilities = capabilities, + }) lspenable(server) end diff --git a/lua/config/neoformat.lua b/lua/config/neoformat.lua index 59caffd..bfbf05e 100644 --- a/lua/config/neoformat.lua +++ b/lua/config/neoformat.lua @@ -2,9 +2,7 @@ local M = {} M.plugin = { "sbdchd/neoformat", - event = { "BufReadPre", "BufNewFile" }, config = function() - -- === formatter enablement (order = priority) === vim.g.neoformat_enabled_lua = { "stylua" } vim.g.neoformat_enabled_python = { "black" } vim.g.neoformat_enabled_javascript = { "prettier" } @@ -15,223 +13,6 @@ M.plugin = { vim.g.neoformat_enabled_bash = { "shfmt" } vim.g.neoformat_enabled_zsh = { "shfmt" } vim.g.neoformat_enabled_powershell = { "pwshfmt" } -- experimental - - -- === helper to prefer local prettier in cwd/node_modules/.bin === - local function prefer_local_prettier() - local cwd = vim.fn.getcwd() - local local_path = cwd .. "/node_modules/.bin/prettier" - if vim.loop.fs_stat(local_path) then - return local_path - end - local global = vim.fn.exepath("prettier") - if global ~= "" then - return global - end - return "prettier" - end - - -- === neoformatters definitions === - vim.g.neoformatters_javascript = { - prettier = { - exe = prefer_local_prettier(), - args = { "--stdin-filepath", "%:p" }, - stdin = 1, - }, - } - vim.g.neoformatters_typescript = vim.g.neoformatters_javascript - vim.g.neoformatters_json = vim.g.neoformatters_javascript - vim.g.neoformatters_markdown = vim.g.neoformatters_javascript - - vim.g.neoformatters_lua = { - stylua = { - exe = "stylua", - args = { "-", "--stdin-filepath", "%:p" }, - stdin = 1, - }, - } - - vim.g.neoformatters_python = { - black = { - exe = "black", - args = { "-" }, - stdin = 1, - }, - } - - vim.g.neoformatters_qml = { - qmlformat = { - exe = "qmlformat", - args = { "-" }, - stdin = 1, - }, - } - - vim.g.neoformatters_go = { - gofmt = { - exe = "gofmt", - args = {}, - stdin = 1, - }, - } - - vim.g.neoformatters_sh = { - shfmt = { - exe = "shfmt", - args = { "-i", "2", "-ci" }, - stdin = 1, - }, - } - vim.g.neoformatters_bash = vim.g.neoformatters_sh - vim.g.neoformatters_zsh = vim.g.neoformatters_sh - - vim.g.neoformatters_powershell = { - pwshfmt = { - exe = "pwsh", - args = { - "-NoProfile", - "-Command", - [[ - $in = [Console]::In.ReadToEnd(); - if (Get-Command Invoke-Formatter -ErrorAction SilentlyContinue) { - Invoke-Formatter -ScriptDefinition $in | Out-String - } else { - $in - } - ]], - }, - stdin = 1, - }, - } - - -- === utility: check whether a path/exe exists === - local function is_executable(path) - if not path or path == "" then - return false - end - -- if it contains a slash or backslash, treat as path - if path:match("[/\\]") then - local stat = vim.loop.fs_stat(path) - return stat and stat.type == "file" - end - -- otherwise check PATH - return vim.fn.exepath(path) ~= "" - end - - local function resolve_exe_field(exe_field) - if type(exe_field) == "function" then - local ok, res = pcall(exe_field) - if ok then - return res - else - return nil - end - end - if type(exe_field) == "string" then - return exe_field - end - return nil - end - - -- === determine whether any configured formatter for ft is available === - local function has_formatter_for_ft(ft) - if not ft or ft == "" then - return false - end - - -- 1) check explicit enabled list first - local enabled_var = "neoformat_enabled_" .. ft - local enabled = vim.g[enabled_var] - local candidates = {} - - if enabled then - if type(enabled) == "string" then - candidates = { enabled } - elseif type(enabled) == "table" then - candidates = enabled - end - else - -- 2) fallback to any entries defined in vim.g.neoformatters_ - local table_var = "neoformatters_" .. ft - local tbl = vim.g[table_var] - if type(tbl) == "table" then - for name, _ in pairs(tbl) do - table.insert(candidates, name) - end - end - end - - if #candidates == 0 then - return false - end - - -- table of custom formatter definitions - local formatter_table = vim.g["neoformatters_" .. ft] - - for _, name in ipairs(candidates) do - -- if we have a definition with exe, check that exe - if formatter_table and formatter_table[name] and formatter_table[name].exe then - local exe_field = formatter_table[name].exe - local exe = resolve_exe_field(exe_field) - if exe and is_executable(exe) then - return true - end - else - -- otherwise, try to find a system executable by the formatter name - if is_executable(name) then - return true - end - end - end - - return false - end - - -- === safe format wrapper that no-ops when no formatter found === - local function neoformat_if_available(bufnr) - bufnr = bufnr or 0 - local ft = vim.bo[bufnr].filetype - if not has_formatter_for_ft(ft) then - -- silent fallback: do nothing if no formatter is available - return - end - -- run Neoformat in protected call to avoid blocking save on errors - pcall(vim.cmd, "Neoformat") - end - - -- === keymap and command using the safe wrapper === - vim.keymap.set("n", "f", function() - neoformat_if_available() - end, { noremap = true, silent = true }) - - vim.api.nvim_create_user_command("NeoformatIfAvailable", function() - neoformat_if_available() - end, {}) - - -- === autoreformat on save (uses safe wrapper) === - local format_on_save_filetypes = { - lua = true, - python = true, - javascript = true, - typescript = true, - qml = true, - go = true, - sh = true, - bash = true, - zsh = true, - powershell = false, -- keep off by default (experimental) - } - - vim.api.nvim_create_autocmd("BufWritePre", { - group = vim.api.nvim_create_augroup("NeoformatOnSave", { clear = true }), - callback = function(args) - local ft = vim.bo[args.buf].filetype - if format_on_save_filetypes[ft] then - neoformat_if_available(args.buf) - end - end, - }) - - -- === end config === end, } diff --git a/lua/config/prettier.lua b/lua/config/prettier.lua new file mode 100644 index 0000000..d96c585 --- /dev/null +++ b/lua/config/prettier.lua @@ -0,0 +1,19 @@ +local prettier = require("prettier") + +prettier.setup({ + bin = 'prettier', + filetypes = { + "css", + "graphql", + "html", + "javascript", + "javascriptreact", + "json", + "less", + "markdown", + "scss", + "typescript", + "typescriptreact", + "yaml", + }, +}) diff --git a/lua/mappings.lua b/lua/mappings.lua index 5046aa4..1c32999 100644 --- a/lua/mappings.lua +++ b/lua/mappings.lua @@ -63,3 +63,13 @@ map("n", "", function() Snacks.terminal.toggle() end, { desc = "Toggle Term -- Gitbrowse map("n", "gb", function() Snacks.gitbrowse.open() end ) + +-- Notif history +map("n", "n", function() + Snacks.notifier.show_history() +end) + +-- Actions Previewer +map({ "n", "v" }, "ap", require("actions-preview").code_actions) + +map("n", "K", require("pretty_hover").hover) diff --git a/lua/plugins/init.lua b/lua/plugins/init.lua index 6851a6f..fb906ac 100644 --- a/lua/plugins/init.lua +++ b/lua/plugins/init.lua @@ -102,7 +102,6 @@ return { }, { "zbirenbaum/copilot.lua", - lazy = true, cmd = "Copilot", event = "InsertEnter", config = function() @@ -161,6 +160,8 @@ return { "L3MON4D3/LuaSnip", "saadparwaiz1/cmp_luasnip", "j-hui/fidget.nvim", + "b0o/schemastore.nvim", + "saghen/blink.cmp", }, config = function() require("config.lspconfig") @@ -269,4 +270,12 @@ return { require("config.zterm-navigator") end, }, + { + "Fildo7525/pretty_hover", + event = "LspAttach", + opts = {}, + }, + { + "artemave/workspace-diagnostics.nvim", + }, } diff --git a/scripts/windows_dependencies.ps1 b/scripts/windows_dependencies.ps1 index 831d25c..bb1e420 100644 --- a/scripts/windows_dependencies.ps1 +++ b/scripts/windows_dependencies.ps1 @@ -11,6 +11,8 @@ $packages = @( "Ninja-build.Ninja" ) +# cargo install --locked tree-sitter-cli + foreach ( $package in $packages ) { Write-Host "Installing $package..." -foregroundcolor yellow # winget install $package @@ -18,7 +20,7 @@ foreach ( $package in $packages ) { $list = @( "Git.Git", - "ajeetdsouza.zoxide", + "ajeetdsouza.zoxide" ) Write-Host "Module list" -ForegroundColor Magenta