add borders around completion popups

This commit is contained in:
Ray Elliott 2025-12-19 20:16:21 +00:00
parent b473cc6d15
commit 9248cf468b
3 changed files with 149 additions and 144 deletions

View File

@ -1,102 +1,101 @@
-- Non-plugin autocommands (minimal placeholder for bootstrap) -- Non-plugin autocommands (minimal placeholder for bootstrap)
local aug = vim.api.nvim_create_augroup('UserDefaults', { clear = true }) local aug = vim.api.nvim_create_augroup("UserDefaults", { clear = true })
-- Phase 10.3: Templates (auto-populate new files from templates) -- Phase 10.3: Templates (auto-populate new files from templates)
local template_aug = vim.api.nvim_create_augroup('Templates', { clear = true }) local template_aug = vim.api.nvim_create_augroup("Templates", { clear = true })
vim.api.nvim_create_autocmd("BufNewFile", { vim.api.nvim_create_autocmd("BufNewFile", {
group = template_aug, group = template_aug,
pattern = "*.sh", pattern = "*.sh",
callback = function() callback = function()
-- Read template at top of file, then move to end -- Read template at top of file, then move to end
vim.cmd('0read ~/.config/nvim/templates/template.sh') vim.cmd("0read ~/.config/nvim/templates/template.sh")
vim.cmd('normal! G') vim.cmd("normal! G")
end, end,
}) })
-- Phase 9.4: Per-filetype indentation settings to match formatters -- Phase 9.4: Per-filetype indentation settings to match formatters
-- PHP: WordPress coding standards (tabs, displayed as 2 spaces) -- PHP: WordPress coding standards (tabs, displayed as 2 spaces)
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
group = aug, group = aug,
pattern = "php", pattern = "php",
callback = function() callback = function()
vim.opt_local.expandtab = false -- Use actual tabs (WordPress standard) vim.opt_local.expandtab = false -- Use actual tabs (WordPress standard)
vim.opt_local.tabstop = 2 -- Display tabs as 2 spaces wide vim.opt_local.tabstop = 2 -- Display tabs as 2 spaces wide
vim.opt_local.shiftwidth = 2 -- Indent/outdent by 2 columns (one tab) vim.opt_local.shiftwidth = 2 -- Indent/outdent by 2 columns (one tab)
vim.opt_local.softtabstop = 2 -- Tab key inserts 2 columns (one tab) vim.opt_local.softtabstop = 2 -- Tab key inserts 2 columns (one tab)
end, end,
}) })
-- JavaScript, TypeScript, JSON, CSS: Prettier defaults (2 spaces) -- JavaScript, TypeScript, JSON, CSS: Prettier defaults (2 spaces)
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
group = aug, group = aug,
pattern = { "javascript", "javascriptreact", "typescript", "typescriptreact", "json", "css", "scss", "html" }, pattern = { "javascript", "javascriptreact", "typescript", "typescriptreact", "json", "css", "scss", "html" },
callback = function() callback = function()
vim.opt_local.expandtab = true -- Use spaces (Prettier default) vim.opt_local.expandtab = true -- Use spaces (Prettier default)
vim.opt_local.tabstop = 2 -- Display as 2 spaces vim.opt_local.tabstop = 2 -- Display as 2 spaces
vim.opt_local.shiftwidth = 2 -- Indent by 2 vim.opt_local.shiftwidth = 2 -- Indent by 2
vim.opt_local.softtabstop = 2 vim.opt_local.softtabstop = 2
end, end,
}) })
-- Lua: stylua defaults (2 spaces) -- Lua: stylua defaults (2 spaces)
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
group = aug, group = aug,
pattern = "lua", pattern = "lua",
callback = function() callback = function()
vim.opt_local.expandtab = true -- Use spaces (common for Lua configs) vim.opt_local.expandtab = true -- Use spaces (common for Lua configs)
vim.opt_local.tabstop = 2 -- Display as 2 spaces vim.opt_local.tabstop = 2 -- Display as 2 spaces
vim.opt_local.shiftwidth = 2 -- Indent by 2 vim.opt_local.shiftwidth = 2 -- Indent by 2
vim.opt_local.softtabstop = 2 vim.opt_local.softtabstop = 2
end, end,
}) })
-- Markdown: Prettier defaults (2 spaces) -- Markdown: Prettier defaults (2 spaces)
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
group = aug, group = aug,
pattern = "markdown", pattern = "markdown",
callback = function() callback = function()
vim.opt_local.expandtab = true -- Use spaces vim.opt_local.expandtab = true -- Use spaces
vim.opt_local.tabstop = 2 -- Display as 2 spaces vim.opt_local.tabstop = 2 -- Display as 2 spaces
vim.opt_local.shiftwidth = 2 -- Indent by 2 vim.opt_local.shiftwidth = 2 -- Indent by 2
vim.opt_local.softtabstop = 2 vim.opt_local.softtabstop = 2
end, end,
}) })
-- Python: Black defaults (4 spaces) -- Python: Black defaults (4 spaces)
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
group = aug, group = aug,
pattern = "python", pattern = "python",
callback = function() callback = function()
vim.opt_local.expandtab = true -- Use spaces (PEP 8) vim.opt_local.expandtab = true -- Use spaces (PEP 8)
vim.opt_local.tabstop = 4 -- Display as 4 spaces vim.opt_local.tabstop = 4 -- Display as 4 spaces
vim.opt_local.shiftwidth = 4 -- Indent by 4 vim.opt_local.shiftwidth = 4 -- Indent by 4
vim.opt_local.softtabstop = 4 vim.opt_local.softtabstop = 4
end, end,
}) })
-- Phase 11.8: Colorize diagnostic severity in quickfix/location list -- Phase 11.8: Colorize diagnostic severity in quickfix/location list
vim.api.nvim_create_autocmd("FileType", { vim.api.nvim_create_autocmd("FileType", {
group = aug, group = aug,
pattern = "qf", -- Applies to both quickfix and location list pattern = "qf", -- Applies to both quickfix and location list
callback = function() callback = function()
-- Use matchadd() for higher priority highlighting -- Use matchadd() for higher priority highlighting
-- This will override the default qf syntax -- This will override the default qf syntax
vim.fn.matchadd('qfError', '\\<error\\>', 10) vim.fn.matchadd("qfError", "\\<error\\>", 10)
vim.fn.matchadd('qfWarning', '\\<warning\\>', 10) vim.fn.matchadd("qfWarning", "\\<warning\\>", 10)
vim.fn.matchadd('qfInfo', '\\<info\\>', 10) vim.fn.matchadd("qfInfo", "\\<info\\>", 10)
vim.fn.matchadd('qfHint', '\\<hint\\>', 10) vim.fn.matchadd("qfHint", "\\<hint\\>", 10)
vim.fn.matchadd('qfNote', '\\<note\\>', 10) vim.fn.matchadd("qfNote", "\\<note\\>", 10)
-- Also match uppercase variants -- Also match uppercase variants
vim.fn.matchadd('qfError', '\\<Error\\>', 10) vim.fn.matchadd("qfError", "\\<Error\\>", 10)
vim.fn.matchadd('qfWarning', '\\<Warning\\>', 10) vim.fn.matchadd("qfWarning", "\\<Warning\\>", 10)
vim.fn.matchadd('qfInfo', '\\<Info\\>', 10) vim.fn.matchadd("qfInfo", "\\<Info\\>", 10)
vim.fn.matchadd('qfHint', '\\<Hint\\>', 10) vim.fn.matchadd("qfHint", "\\<Hint\\>", 10)
vim.fn.matchadd('qfNote', '\\<Note\\>', 10) vim.fn.matchadd("qfNote", "\\<Note\\>", 10)
end, end,
}) })
return {} return {}

View File

@ -1,41 +1,44 @@
return { return {
"hrsh7th/nvim-cmp", "hrsh7th/nvim-cmp",
event = "InsertEnter", event = "InsertEnter",
dependencies = { dependencies = {
"hrsh7th/cmp-nvim-lsp", "hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer", "hrsh7th/cmp-buffer",
"hrsh7th/cmp-path", "hrsh7th/cmp-path",
"L3MON4D3/LuaSnip", "L3MON4D3/LuaSnip",
"zbirenbaum/copilot-cmp", -- Copilot completion source "zbirenbaum/copilot-cmp", -- Copilot completion source
}, },
opts = function() opts = function()
local cmp = require("cmp") local cmp = require("cmp")
local luasnip = require("luasnip") local luasnip = require("luasnip")
return { return {
snippet = { snippet = {
expand = function(args) expand = function(args)
luasnip.lsp_expand(args.body) luasnip.lsp_expand(args.body)
end, end,
}, },
mapping = cmp.mapping.preset.insert({ mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(), ["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = true }), -- Auto-select first item ["<CR>"] = cmp.mapping.confirm({ select = true }), -- Auto-select first item
["<C-n>"] = cmp.mapping.select_next_item(), ["<C-n>"] = cmp.mapping.select_next_item(),
["<C-p>"] = cmp.mapping.select_prev_item(), ["<C-p>"] = cmp.mapping.select_prev_item(),
["<C-e>"] = cmp.mapping.abort(), ["<C-e>"] = cmp.mapping.abort(),
}), }),
sources = cmp.config.sources({ sources = cmp.config.sources({
{ name = "copilot", group_index = 2 }, -- Copilot suggestions (priority 1) { name = "copilot", group_index = 2 }, -- Copilot suggestions (priority 1)
{ name = "nvim_lsp", group_index = 2 }, { name = "nvim_lsp", group_index = 2 },
{ name = "path", group_index = 2 }, { name = "path", group_index = 2 },
{ name = "buffer", group_index = 2 }, { name = "buffer", group_index = 2 },
}), }),
completion = { completeopt = "menu,menuone,noinsert" }, -- Auto-select first item completion = { completeopt = "menu,menuone,noinsert" }, -- Auto-select first item
} window = {
end, completion = cmp.config.window.bordered(),
config = function(_, opts) documentation = cmp.config.window.bordered(),
require("cmp").setup(opts) },
end, }
end,
config = function(_, opts)
require("cmp").setup(opts)
end,
} }

View File

@ -6,64 +6,67 @@ vim.g.loaded_perl_provider = 0
vim.g.loaded_node_provider = 0 vim.g.loaded_node_provider = 0
-- Enable project-local configuration files -- Enable project-local configuration files
vim.opt.exrc = true -- Load .nvim.lua from project root vim.opt.exrc = true -- Load .nvim.lua from project root
vim.opt.secure = true -- Prompt before loading untrusted files vim.opt.secure = true -- Prompt before loading untrusted files
-- Phase 3.2: non-plugin settings (legacy values where specified) -- Phase 3.2: non-plugin settings (legacy values where specified)
-- Completion UI for nvim-cmp -- Completion UI for nvim-cmp
vim.opt.completeopt = { 'menu', 'menuone', 'noselect' } vim.opt.completeopt = { "menu", "menuone", "noselect" }
-- Spelling -- Spelling
vim.opt.spelllang = { 'en_gb' } vim.opt.spelllang = { "en_gb" }
-- Keyword characters (add $ for PHP/shell variables, - for CSS/HTML/config files) -- Keyword characters (add $ for PHP/shell variables, - for CSS/HTML/config files)
vim.opt.iskeyword:append('$') vim.opt.iskeyword:append("$")
vim.opt.iskeyword:append('-') vim.opt.iskeyword:append("-")
-- Visuals -- Visuals
vim.opt.showbreak = '' vim.opt.showbreak = ""
vim.opt.listchars = { vim.opt.listchars = {
eol = '¬', eol = "¬",
tab = '', tab = "",
trail = '~', trail = "~",
extends = '>', extends = ">",
precedes = '<', precedes = "<",
space = '·', space = "·",
} }
-- Enable line numbers and relative line numbers -- Enable line numbers and relative line numbers
vim.opt.number = true vim.opt.number = true
vim.opt.relativenumber = true vim.opt.relativenumber = true
-- Scrolloff settings
vim.opt.scrolloff = 4
-- Phase 6.2: UX settings -- Phase 6.2: UX settings
vim.opt.signcolumn = 'yes' -- Always show sign column (for LSP diagnostics, git signs, etc.) vim.opt.signcolumn = "yes" -- Always show sign column (for LSP diagnostics, git signs, etc.)
vim.opt.cursorline = true -- Highlight current line vim.opt.cursorline = true -- Highlight current line
vim.opt.colorcolumn = '80,120' -- Visual guides at 80 and 120 characters vim.opt.colorcolumn = "80,120" -- Visual guides at 80 and 120 characters
-- Phase 9.4: Default indentation (per-filetype overrides in after/ftplugin/) -- Phase 9.4: Default indentation (per-filetype overrides in after/ftplugin/)
vim.opt.tabstop = 4 -- Display tabs as 4 spaces vim.opt.tabstop = 4 -- Display tabs as 4 spaces
vim.opt.shiftwidth = 4 -- Indent by 4 vim.opt.shiftwidth = 4 -- Indent by 4
vim.opt.softtabstop = 4 -- Backspace removes 4 spaces vim.opt.softtabstop = 4 -- Backspace removes 4 spaces
vim.opt.expandtab = true -- Use spaces by default (overridden per-filetype) vim.opt.expandtab = true -- Use spaces by default (overridden per-filetype)
-- LSP diagnostics configuration -- LSP diagnostics configuration
vim.diagnostic.config({ vim.diagnostic.config({
virtual_text = { virtual_text = {
spacing = 4, spacing = 4,
prefix = '', prefix = "",
-- Show severity (ERROR, WARN, INFO, HINT) -- Show severity (ERROR, WARN, INFO, HINT)
format = function(diagnostic) format = function(diagnostic)
return string.format("%s: %s", diagnostic.source or "", diagnostic.message) return string.format("%s: %s", diagnostic.source or "", diagnostic.message)
end, end,
}, },
signs = false, -- Disable signs (redundant with background highlights and virtual text) signs = false, -- Disable signs (redundant with background highlights and virtual text)
underline = true, -- Use background highlights on problematic text underline = true, -- Use background highlights on problematic text
update_in_insert = false, -- Don't update diagnostics while typing update_in_insert = false, -- Don't update diagnostics while typing
severity_sort = true, -- Sort by severity (errors first) severity_sort = true, -- Sort by severity (errors first)
float = { float = {
border = 'rounded', border = "rounded",
source = 'always', -- Show diagnostic source source = "always", -- Show diagnostic source
header = '', header = "",
prefix = '', prefix = "",
}, },
}) })