feat(lua):introduce yank highlight autocmd and improve secure_env + LSP configs

This commit is contained in:
sankalp committed 2026-05-21 15:03:49 +05:45
1 parent d826fec47e
commit 36ab130e5a
2 files changed
+309 -286

No files matched your search

+172 -149
View File
@@ -1,7 +1,16 @@
local function augroup(name)
return vim.api.nvim_create_augroup("nvim_" .. name, { clear = true })
return vim.api.nvim_create_augroup('nvim_' .. name, { clear = true })
end
-- Yank highlight autocmd (built-in)
vim.api.nvim_create_autocmd('TextYankPost', {
group = vim.api.nvim_create_augroup('YankHighlight', { clear = true }),
pattern = '*',
callback = function()
vim.highlight.on_yank({ higroup = 'IncSearch', timeout = 150 })
end,
})
-- smart column only when needed
local smart_column_group = vim.api.nvim_create_augroup('SmartColumn', { clear = true })
vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI', 'BufEnter' }, {
@@ -25,197 +34,211 @@ vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI', 'BufEnter' }, {
})
-- Secure .env Masking
local env_ns = vim.api.nvim_create_namespace("secure_env")
local env_ns = vim.api.nvim_create_namespace('secure_env')
local function toggle_env(buf)
local is_mod = vim.bo[buf].modified
vim.bo[buf].modifiable = true
if vim.b[buf].env_cache then
vim.api.nvim_buf_set_lines(buf, 0, -1, false, vim.b[buf].env_cache)
vim.api.nvim_buf_clear_namespace(buf, env_ns, 0, -1)
vim.b[buf].env_cache = nil
else
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
vim.b[buf].env_cache = vim.deepcopy(lines)
for i, l in ipairs(lines) do
if not l:match("^%s*#") then
lines[i] = l:gsub("(=%s*[\"']?)(.-)([\"']?%s*)$", function(p, v, s)
return #v > 0 and (p .. string.rep("*", math.max(#v, 8)) .. s) or l
end)
end
end
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
vim.api.nvim_buf_set_extmark(buf, env_ns, 0, 0, { virt_text = {{" [Values Hidden]", "WarningMsg"}}, virt_text_pos = "eol" })
vim.bo[buf].modifiable = false
end
vim.bo[buf].modified = is_mod
local is_mod = vim.bo[buf].modified
vim.bo[buf].modifiable = true
if vim.b[buf].env_cache then
vim.api.nvim_buf_set_lines(buf, 0, -1, false, vim.b[buf].env_cache)
vim.api.nvim_buf_clear_namespace(buf, env_ns, 0, -1)
vim.b[buf].env_cache = nil
else
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
vim.b[buf].env_cache = vim.deepcopy(lines)
for i, l in ipairs(lines) do
if not l:match('^%s*#') then
lines[i] = l:gsub('(=%s*["\']?)(.-)(["\']?%s*)$', function(p, v, s)
return #v > 0 and (p .. string.rep('*', math.max(#v, 8)) .. s) or l
end)
end
end
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
vim.api.nvim_buf_set_extmark(
buf,
env_ns,
0,
0,
{ virt_text = { { ' [Values Hidden]', 'WarningMsg' } }, virt_text_pos = 'eol' }
)
vim.bo[buf].modifiable = false
end
vim.bo[buf].modified = is_mod
end
vim.api.nvim_create_autocmd({ "BufReadPost", "BufNewFile", "BufWriteCmd" }, {
group = augroup("secure_env"),
pattern = { ".env", ".env.*", "*.env" },
callback = function(args)
local ev, buf = args.event, args.buf
if ev == "BufReadPost" or ev == "BufNewFile" then
vim.keymap.set("n", "<leader>et", function() toggle_env(buf) end, { buffer = buf, desc = "Toggle env" })
if not vim.b[buf].env_cache then toggle_env(buf) end
elseif ev == "BufWriteCmd" then
local file = vim.api.nvim_buf_get_name(buf)
if file ~= "" then
local lines = vim.b[buf].env_cache or vim.api.nvim_buf_get_lines(buf, 0, -1, false)
if pcall(vim.fn.writefile, lines, file) then
vim.bo[buf].modified = false
else
vim.notify("Write failed!", vim.log.levels.ERROR)
end
end
end
end,
vim.api.nvim_create_autocmd({ 'BufReadPost', 'BufNewFile', 'BufWriteCmd' }, {
group = augroup('secure_env'),
pattern = { '.env', '.env.*', '*.env' },
callback = function(args)
local ev, buf = args.event, args.buf
if ev == 'BufReadPost' or ev == 'BufNewFile' then
vim.keymap.set('n', '<leader>et', function()
toggle_env(buf)
end, { buffer = buf, desc = 'Toggle env' })
if not vim.b[buf].env_cache then
toggle_env(buf)
end
elseif ev == 'BufWriteCmd' then
local file = vim.api.nvim_buf_get_name(buf)
if file ~= '' then
local lines = vim.b[buf].env_cache or vim.api.nvim_buf_get_lines(buf, 0, -1, false)
if pcall(vim.fn.writefile, lines, file) then
vim.bo[buf].modified = false
else
vim.notify('Write failed!', vim.log.levels.ERROR)
end
end
end
end,
})
-- Strip trailing spaces before write
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup("strip_space"),
pattern = "*",
callback = function()
local save = vim.fn.winsaveview()
vim.cmd([[keeppatterns %s/\s\+$//e]])
vim.fn.winrestview(save)
end,
vim.api.nvim_create_autocmd('BufWritePre', {
group = augroup('strip_space'),
pattern = '*',
callback = function()
local save = vim.fn.winsaveview()
vim.cmd([[keeppatterns %s/\s\+$//e]])
vim.fn.winrestview(save)
end,
})
-- Resize splits if window got resized
vim.api.nvim_create_autocmd("VimResized", {
group = augroup("resize_splits"),
callback = function()
vim.cmd("tabdo wincmd =")
end,
vim.api.nvim_create_autocmd('VimResized', {
group = augroup('resize_splits'),
callback = function()
vim.cmd('tabdo wincmd =')
end,
})
-- Close specific filetypes with <q>
vim.api.nvim_create_autocmd("FileType", {
group = augroup("close_with_q"),
pattern = {
"help", "lspinfo", "man", "notify", "qf", "query", "spectre_panel",
"startuptime", "tsplayground", "neotest-output", "checkhealth",
},
callback = function(event)
vim.bo[event.buf].buflisted = false
vim.keymap.set("n", "q", "<cmd>close<cr>", { buffer = event.buf, silent = true })
end,
vim.api.nvim_create_autocmd('FileType', {
group = augroup('close_with_q'),
pattern = {
'help',
'lspinfo',
'man',
'notify',
'qf',
'query',
'spectre_panel',
'startuptime',
'tsplayground',
'neotest-output',
'checkhealth',
},
callback = function(event)
vim.bo[event.buf].buflisted = false
vim.keymap.set('n', 'q', '<cmd>close<cr>', { buffer = event.buf, silent = true })
end,
})
-- Auto-create directories on save
vim.api.nvim_create_autocmd("BufWritePre", {
group = augroup("auto_create_dir"),
callback = function(event)
if event.match:match("^%w%w+://") then
return
end
local file = vim.loop.fs_realpath(event.match) or event.match
vim.fn.mkdir(vim.fn.fnamemodify(file, ":p:h"), "p")
end,
vim.api.nvim_create_autocmd('BufWritePre', {
group = augroup('auto_create_dir'),
callback = function(event)
if event.match:match('^%w%w+://') then
return
end
local file = vim.loop.fs_realpath(event.match) or event.match
vim.fn.mkdir(vim.fn.fnamemodify(file, ':p:h'), 'p')
end,
})
-- LSP Attach Features
vim.api.nvim_create_autocmd("LspAttach", {
group = augroup("lsp_attach_autocmds"),
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
-- Document Highlight
if client and client:supports_method("textDocument/documentHighlight") then
vim.api.nvim_create_autocmd({ "CursorHold" }, {
buffer = args.buf,
callback = vim.lsp.buf.document_highlight,
})
vim.api.nvim_create_autocmd({ "CursorMoved", "CursorMovedI" }, {
buffer = args.buf,
callback = vim.lsp.buf.clear_references,
})
end
vim.api.nvim_create_autocmd('LspAttach', {
group = augroup('lsp_attach_autocmds'),
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
-- Inlay Hints
if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
vim.lsp.inlay_hint.enable(true, { bufnr = args.buf })
end
end,
-- Document Highlight
if client and client:supports_method('textDocument/documentHighlight') then
vim.api.nvim_create_autocmd({ 'CursorHold' }, {
buffer = args.buf,
callback = vim.lsp.buf.document_highlight,
})
vim.api.nvim_create_autocmd({ 'CursorMoved', 'CursorMovedI' }, {
buffer = args.buf,
callback = vim.lsp.buf.clear_references,
})
end
-- Inlay Hints
if client and client.server_capabilities.inlayHintProvider and vim.lsp.inlay_hint then
vim.lsp.inlay_hint.enable(true, { bufnr = args.buf })
end
end,
})
-- Wrap and spellcheck in text filetypes
vim.api.nvim_create_autocmd("FileType", {
group = augroup("wrap_spell"),
pattern = { "gitcommit", "markdown", "text" },
callback = function()
vim.opt_local.wrap = true
vim.opt_local.spell = true
end,
vim.api.nvim_create_autocmd('FileType', {
group = augroup('wrap_spell'),
pattern = { 'gitcommit', 'markdown', 'text' },
callback = function()
vim.opt_local.wrap = true
vim.opt_local.spell = true
end,
})
-- Disable auto-commenting on new lines
vim.api.nvim_create_autocmd("FileType", {
group = augroup("no_auto_comment"),
callback = function()
vim.opt_local.formatoptions:remove({ "c", "r", "o" })
end,
vim.api.nvim_create_autocmd('FileType', {
group = augroup('no_auto_comment'),
callback = function()
vim.opt_local.formatoptions:remove({ 'c', 'r', 'o' })
end,
})
-- Manual Treesitter Installation command
vim.api.nvim_create_user_command("TSInstallAll", function()
local parsers = require("extensions").ts_parsers
vim.notify("Installing all configured Tree-sitter parsers...", vim.log.levels.INFO, { title = "Tree-sitter" })
require("nvim-treesitter.install").install(parsers)
end, { desc = "Install all configured Tree-sitter parsers" })
vim.api.nvim_create_user_command('TSInstallAll', function()
local parsers = require('extensions').ts_parsers
vim.notify('Installing all configured Tree-sitter parsers...', vim.log.levels.INFO, { title = 'Tree-sitter' })
require('nvim-treesitter.install').install(parsers)
end, { desc = 'Install all configured Tree-sitter parsers' })
-- Macro Notifications
vim.api.nvim_create_autocmd("RecordingEnter", {
callback = function()
vim.notify("Recording macro...", vim.log.levels.INFO, { title = "Macro", timeout = 1000 })
end,
vim.api.nvim_create_autocmd('RecordingEnter', {
callback = function()
vim.notify('Recording macro...', vim.log.levels.INFO, { title = 'Macro', timeout = 1000 })
end,
})
vim.api.nvim_create_autocmd("RecordingLeave", {
callback = function()
local reg = vim.v.recording
vim.notify("Stopped recording @" .. reg, vim.log.levels.INFO, { title = "Macro", timeout = 1000 })
end,
vim.api.nvim_create_autocmd('RecordingLeave', {
callback = function()
local reg = vim.v.recording
vim.notify('Stopped recording @' .. reg, vim.log.levels.INFO, { title = 'Macro', timeout = 1000 })
end,
})
-- Auto-Save on InsertLeave with 3s Debounce
local save_timer = nil
local function clear_timer()
if save_timer then
save_timer:stop()
save_timer = nil
end
if save_timer then
save_timer:stop()
save_timer = nil
end
end
vim.api.nvim_create_autocmd({ "InsertEnter" }, {
group = augroup("autosave_cancel"),
callback = clear_timer,
vim.api.nvim_create_autocmd({ 'InsertEnter' }, {
group = augroup('autosave_cancel'),
callback = clear_timer,
})
vim.api.nvim_create_autocmd({ "InsertLeave" }, {
group = augroup("autosave"),
callback = function(args)
clear_timer()
if vim.api.nvim_buf_is_valid(args.buf) and vim.bo[args.buf].modified and vim.bo[args.buf].buftype == "" then
save_timer = vim.defer_fn(function()
if vim.api.nvim_buf_is_valid(args.buf) and vim.bo[args.buf].modified then
vim.api.nvim_buf_call(args.buf, function()
vim.cmd("silent! write")
vim.notify("Autosaved " .. vim.fn.expand("%:t"), vim.log.levels.INFO, { title = "Auto-Save" })
end)
end
end, 3000)
end
end,
vim.api.nvim_create_autocmd({ 'InsertLeave' }, {
group = augroup('autosave'),
callback = function(args)
clear_timer()
if vim.api.nvim_buf_is_valid(args.buf) and vim.bo[args.buf].modified and vim.bo[args.buf].buftype == '' then
save_timer = vim.defer_fn(function()
if vim.api.nvim_buf_is_valid(args.buf) and vim.bo[args.buf].modified then
vim.api.nvim_buf_call(args.buf, function()
vim.cmd('silent! write')
vim.notify('Autosaved ' .. vim.fn.expand('%:t'), vim.log.levels.INFO, { title = 'Auto-Save' })
end)
end
end, 3000)
end
end,
})
-- Autoinstall missing plugins on startup
+137 -137
View File
@@ -2,152 +2,152 @@
-- LSP
--------------------------------------------------------------------------------
vim.api.nvim_create_autocmd("User", {
pattern = "PackerComplete", -- Fallback or custom event if needed, but let's use a more standard one
callback = function()
-- This is where we would put it if we had a specific event.
-- Since we're using VimEnter, let's use that instead.
end,
vim.api.nvim_create_autocmd('User', {
pattern = 'PackerComplete', -- Fallback or custom event if needed, but let's use a more standard one
callback = function()
-- This is where we would put it if we had a specific event.
-- Since we're using VimEnter, let's use that instead.
end,
})
-- Let's use a simple function and schedule it to run after plugins
vim.schedule(function()
vim.lsp.config("*", {
capabilities = require("blink.cmp").get_lsp_capabilities(),
})
vim.lsp.config('*', {
capabilities = require('blink.cmp').get_lsp_capabilities(),
})
-- ts_ls
vim.lsp.config("ts_ls", {
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = "all",
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
})
vim.lsp.enable("ts_ls")
-- ts_ls
vim.lsp.config('ts_ls', {
settings = {
typescript = {
inlayHints = {
includeInlayParameterNameHints = 'all',
includeInlayParameterNameHintsWhenArgumentMatchesName = false,
includeInlayFunctionParameterTypeHints = true,
includeInlayVariableTypeHints = true,
includeInlayPropertyDeclarationTypeHints = true,
includeInlayFunctionLikeReturnTypeHints = true,
includeInlayEnumMemberValueHints = true,
},
},
},
})
vim.lsp.enable('ts_ls')
vim.lsp.enable("html")
vim.lsp.enable("cssls")
vim.lsp.config("tailwindcss", {
filetypes = {
"astro",
"blade",
"edge",
"ejs",
"erb",
"gohtml",
"gohtmltmpl",
"handlebars",
"hbs",
"html",
"jade",
"leaf",
"liquid",
"markdown",
"mdx",
"mustache",
"nunjucks",
"php",
"razor",
"slim",
"twig",
"css",
"less",
"postcss",
"sass",
"scss",
"stylus",
"sugarss",
"javascript",
"javascriptreact",
"rescript",
"typescript",
"typescriptreact",
"vue",
"svelte",
"templ",
},
})
vim.lsp.enable("tailwindcss")
vim.lsp.enable('html')
vim.lsp.enable('cssls')
vim.lsp.config('tailwindcss', {
filetypes = {
'astro',
'blade',
'edge',
'ejs',
'erb',
'gohtml',
'gohtmltmpl',
'handlebars',
'hbs',
'html',
'jade',
'leaf',
'liquid',
'markdown',
'mdx',
'mustache',
'nunjucks',
'php',
'razor',
'slim',
'twig',
'css',
'less',
'postcss',
'sass',
'scss',
'stylus',
'sugarss',
'javascript',
'javascriptreact',
'rescript',
'typescript',
'typescriptreact',
'vue',
'svelte',
'templ',
},
})
vim.lsp.enable('tailwindcss')
-- rust
vim.lsp.config("rust_analyzer", {
settings = {
["rust-analyzer"] = {
diagnostics = {
enable = true,
experimental = { enable = true },
},
},
},
})
vim.lsp.enable("rust_analyzer")
-- rust
vim.lsp.config('rust_analyzer', {
settings = {
['rust-analyzer'] = {
diagnostics = {
enable = true,
experimental = { enable = true },
},
},
},
})
vim.lsp.enable('rust_analyzer')
-- lua
vim.lsp.config("lua_ls", {
settings = {
Lua = {
diagnostics = {
disable = {
"missing-fields",
"undefined-global",
},
},
},
},
})
vim.lsp.enable("lua_ls")
-- lua
vim.lsp.config('lua_ls', {
settings = {
Lua = {
diagnostics = {
disable = {
'missing-fields',
'undefined-global',
},
},
},
},
})
vim.lsp.enable('lua_ls')
-- python
vim.lsp.config("basedpyright", {
settings = {
basedpyright = {
inlayHints = true,
analysis = {
diagnosticSeverityOverrides = {
reportUnusedImport = "none",
reportUnusedVariable = "none",
reportAttributeAccessIssue = "none",
reportUnusedClass = "none",
reportUnusedFunction = "none",
reportDuplicateImport = "none",
reportArgumentType = "error",
},
typeCheckingMode = "standard",
},
},
},
})
vim.lsp.enable("basedpyright")
-- python
vim.lsp.config('basedpyright', {
settings = {
basedpyright = {
inlayHints = true,
analysis = {
diagnosticSeverityOverrides = {
reportUnusedImport = 'none',
reportUnusedVariable = 'none',
reportAttributeAccessIssue = 'none',
reportUnusedClass = 'none',
reportUnusedFunction = 'none',
reportDuplicateImport = 'none',
reportArgumentType = 'error',
},
typeCheckingMode = 'standard',
},
},
},
})
vim.lsp.enable('basedpyright')
-- bash
vim.lsp.config("bashls", {
settings = {
bashIde = {
shellcheckArguments = {
"--exclude=SC1090,SC1091,SC2076,SC2164",
},
},
},
})
vim.lsp.enable("bashls")
-- bash
vim.lsp.config('bashls', {
settings = {
bashIde = {
shellcheckArguments = {
'--exclude=SC1090,SC1091,SC2076,SC2164',
},
},
},
})
vim.lsp.enable('bashls')
-- cpp
vim.lsp.config("clangd", {
cmd = {
"clangd",
"--fallback-style=llvm",
"--header-insertion=iwyu",
"-j=4",
},
})
vim.lsp.enable("clangd")
-- cpp
vim.lsp.config('clangd', {
cmd = {
'clangd',
'--fallback-style=llvm',
'--header-insertion=iwyu',
'-j=4',
},
})
vim.lsp.enable('clangd')
end)