adopt neovim 0.12 native editing features

This commit is contained in:
Ray Elliott 2026-10-28 15:43:13 +00:00
commit 282e5e0f0b
18 changed files with 125 additions and 215 deletions

13
lua/completion.lua Normal file
View file

@ -0,0 +1,13 @@
-- Neovim 0.12 native insert-mode completion.
if vim.fn.has("nvim-0.12") == 0 then
return
end
vim.opt.autocomplete = true
vim.opt.autocompletedelay = 150
vim.opt.completeopt = { "menu", "menuone", "noselect", "popup", "fuzzy" }
vim.opt.complete = { ".^10", "w^5", "b^5", "u^5" }
vim.keymap.set("i", "<C-Space>", function()
vim.lsp.completion.get()
end, { desc = "Completion: Trigger LSP suggestions", silent = true })

View file

@ -9,6 +9,11 @@
local map = vim.keymap.set
-- Neovim 0.12's optional native undo-tree viewer.
if vim.fn.has('nvim-0.12') == 1 then
map('n', '<leader>u', '<cmd>Undotree<cr>', { desc = 'Undotree: Toggle native undo tree', silent = true })
end
-- Fallback navigation keymaps for non-LSP buffers
-- When LSP attaches, buffer-local keymaps in lsp.lua override these
map('n', 'gd', function()

View file

@ -1,5 +1,5 @@
-- Paper Tonic Modern - Plugin Highlight Groups
-- Highlights for configured plugins (Telescope, Gitsigns, cmp, etc.)
-- Highlights for configured plugins (Telescope, Gitsigns, etc.)
local c = require('paper-tonic-modern.colors')
@ -58,44 +58,6 @@ return {
GitSignsChangeInline = { bg = c.bg_hl_special },
GitSignsDeleteInline = { bg = c.bg_error_weak },
-- ============================================================================
-- nvim-cmp (completion menu)
-- ============================================================================
-- Menu
CmpItemAbbr = { fg = c.fg },
CmpItemAbbrMatch = { fg = c.primary, bold = true },
CmpItemAbbrMatchFuzzy = { fg = c.primary_weak },
CmpItemAbbrDeprecated = { fg = c.fg_weak, strikethrough = true },
CmpItemMenu = { fg = c.fg_weak, italic = true },
-- Kind icons/labels
CmpItemKindDefault = { fg = c.fg },
CmpItemKindVariable = { fg = c.fg },
CmpItemKindFunction = { fg = c.primary_weak },
CmpItemKindMethod = { fg = c.primary_weak },
CmpItemKindConstructor = { fg = c.primary },
CmpItemKindClass = { fg = c.primary_strong },
CmpItemKindInterface = { fg = c.primary_strong },
CmpItemKindStruct = { fg = c.primary_strong },
CmpItemKindProperty = { fg = c.fg_strong },
CmpItemKindField = { fg = c.fg_strong },
CmpItemKindEnum = { fg = c.primary },
CmpItemKindEnumMember = { fg = c.fg_strong },
CmpItemKindModule = { fg = c.primary },
CmpItemKindKeyword = { fg = c.primary_weak },
CmpItemKindSnippet = { fg = c.modified },
CmpItemKindText = { fg = c.fg },
CmpItemKindFile = { fg = c.fg },
CmpItemKindFolder = { fg = c.fg_strong },
CmpItemKindColor = { fg = c.diag_warn },
CmpItemKindUnit = { fg = c.fg_weak },
CmpItemKindValue = { fg = c.fg_strong },
CmpItemKindConstant = { fg = c.fg_strong },
CmpItemKindReference = { fg = c.modified },
CmpItemKindOperator = { fg = c.fg },
CmpItemKindTypeParameter = { fg = c.primary },
-- ============================================================================
-- Comment.nvim
-- ============================================================================

View file

@ -130,7 +130,7 @@ function M.load()
local lsp = require('paper-tonic-modern.groups.lsp')
M.highlight_all(lsp)
-- Plugin highlights (Telescope, Gitsigns, cmp, etc.)
-- Plugin highlights (Telescope, Gitsigns, etc.)
local plugins = require('paper-tonic-modern.groups.plugins')
M.highlight_all(plugins)

View file

@ -25,9 +25,5 @@ return {
},
})
-- Integration with nvim-cmp
local cmp_autopairs = require('nvim-autopairs.completion.cmp')
local cmp = require('cmp')
cmp.event:on('confirm_done', cmp_autopairs.on_confirm_done())
end,
}

View file

@ -1,69 +0,0 @@
return {
"hrsh7th/nvim-cmp",
event = "InsertEnter",
dependencies = {
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/cmp-buffer",
"hrsh7th/cmp-path",
"L3MON4D3/LuaSnip",
"zbirenbaum/copilot-cmp", -- Copilot completion source
},
opts = function()
local cmp = require("cmp")
local luasnip = require("luasnip")
return {
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = false }),
["<C-n>"] = cmp.mapping.select_next_item(),
["<C-p>"] = cmp.mapping.select_prev_item(),
["<C-e>"] = cmp.mapping.abort(),
}),
sources = cmp.config.sources({
{ name = "copilot", group_index = 2 }, -- Copilot suggestions (priority 1)
{ name = "nvim_lsp", group_index = 2 },
{ name = "path", group_index = 2 },
{ name = "buffer", group_index = 2 },
}),
preselect = cmp.PreselectMode.None,
completion = { completeopt = "menu,menuone,noinsert,noselect" },
window = {
completion = cmp.config.window.bordered({
border = {
{ "🭽", "FloatBorder" },
{ "▔", "FloatBorder" },
{ "🭾", "FloatBorder" },
{ "▕", "FloatBorder" },
{ "🭿", "FloatBorder" },
{ "▁", "FloatBorder" },
{ "🭼", "FloatBorder" },
{ "▏", "FloatBorder" },
},
winhighlight = "Normal:Normal,FloatBorder:FloatBorder,CursorLine:PmenuSel",
}),
documentation = cmp.config.window.bordered({
border = {
{ "🭽", "FloatBorder" },
{ "▔", "FloatBorder" },
{ "🭾", "FloatBorder" },
{ "▕", "FloatBorder" },
{ "🭿", "FloatBorder" },
{ "▁", "FloatBorder" },
{ "🭼", "FloatBorder" },
{ "▏", "FloatBorder" },
},
winhighlight = "Normal:Normal,FloatBorder:FloatBorder",
}),
},
}
end,
config = function(_, opts)
require("cmp").setup(opts)
end,
}

View file

@ -1,22 +1,23 @@
-- GitHub Copilot: AI-powered code completion
-- GitHub Copilot inline suggestions, separate from the native completion menu.
return {
{
'zbirenbaum/copilot.lua',
cmd = 'Copilot',
event = 'InsertEnter', -- Lazy load on first insert mode entry
opts = {
suggestion = { enabled = false }, -- Disable inline suggestions (use cmp instead)
panel = { enabled = false }, -- Disable panel (use cmp instead)
filetypes = {
['*'] = true, -- Enable for all filetypes
'zbirenbaum/copilot.lua',
cmd = 'Copilot',
event = 'InsertEnter',
opts = {
suggestion = {
enabled = true,
auto_trigger = true,
hide_during_completion = true,
keymap = {
accept = '<M-l>',
next = '<M-]>',
prev = '<M-[>',
dismiss = '<C-]>',
},
},
},
{
'zbirenbaum/copilot-cmp',
dependencies = { 'zbirenbaum/copilot.lua' },
config = function()
require('copilot_cmp').setup()
end,
panel = { enabled = false },
filetypes = {
['*'] = true,
},
},
}

View file

@ -1,12 +1,7 @@
return {
"neovim/nvim-lspconfig",
event = { "BufReadPre", "BufNewFile" },
dependencies = {
"hrsh7th/cmp-nvim-lsp",
},
config = function()
local capabilities = require("cmp_nvim_lsp").default_capabilities()
-- Load trusted project-local LSP settings from .nvim.lua.
local function load_project_lsp_settings(server_name, root_dir)
if not root_dir then
@ -66,6 +61,13 @@ return {
-- Setup keymaps for this buffer
setup_keymaps(args.buf)
if client:supports_method("textDocument/completion") then
vim.lsp.completion.enable(true, client.id, args.buf)
if vim.fn.has("nvim-0.12") == 1 then
vim.bo[args.buf].complete = "o^20"
end
end
-- Load and send project-specific settings
local project_settings = load_project_lsp_settings(client.name, client.root_dir)
if project_settings.settings then
@ -88,13 +90,8 @@ return {
local function configure(server_name, opts)
opts = opts or {}
-- Merge with defaults
local config = vim.tbl_deep_extend("force", {
capabilities = capabilities,
}, opts)
-- Configure the server using the new API
vim.lsp.config(server_name, config)
vim.lsp.config(server_name, opts)
end
-- Configure all servers

View file

@ -131,19 +131,19 @@ return {
-- Setup autotag
require("nvim-ts-autotag").setup({
opts = {
enable_close = true, -- Auto close tags
enable_rename = true, -- Auto rename pairs of tags
enable_close_on_slash = true, -- Auto close on trailing </
enable_close = false,
enable_rename = false,
enable_close_on_slash = false,
},
-- Limit to relevant filetypes
-- Enable only in filetypes that can contain HTML-style tags.
per_filetype = {
["html"] = { enable_close = true },
["php"] = { enable_close = true },
["javascript"] = { enable_close = true },
["javascriptreact"] = { enable_close = true },
["typescript"] = { enable_close = true },
["typescriptreact"] = { enable_close = true },
["vue"] = { enable_close = true },
["html"] = { enable_close = true, enable_rename = true, enable_close_on_slash = true },
["php"] = { enable_close = true, enable_rename = true, enable_close_on_slash = true },
["javascript"] = { enable_close = true, enable_rename = true, enable_close_on_slash = true },
["javascriptreact"] = { enable_close = true, enable_rename = true, enable_close_on_slash = true },
["typescript"] = { enable_close = true, enable_rename = true, enable_close_on_slash = true },
["typescriptreact"] = { enable_close = true, enable_rename = true, enable_close_on_slash = true },
["vue"] = { enable_close = true, enable_rename = true, enable_close_on_slash = true },
},
})
end,

View file

@ -1,15 +0,0 @@
-- Phase 6.8: undotree for visual undo history
return {
'mbbill/undotree',
cmd = 'UndotreeToggle', -- Lazy load on command
keys = {
{ '<leader>u', '<cmd>UndotreeToggle<cr>', desc = 'Undotree: Toggle undo tree' },
},
config = function()
-- Configure undotree
vim.g.undotree_WindowLayout = 2 -- Layout: diff at bottom
vim.g.undotree_ShortIndicators = 1 -- Use short time indicators
vim.g.undotree_SetFocusWhenToggle = 1 -- Focus undotree when toggled
vim.g.undotree_DiffAutoOpen = 1 -- Auto open diff window
end,
}

View file

@ -65,14 +65,8 @@ vim.opt.tabline = '%!v:lua.require("utils").custom_tabline()'
vim.opt.showtabline = 1 -- Show tabline only when there are 2+ tabs
-- Phase 3.2: non-plugin settings (legacy values where specified)
-- Completion UI for nvim-cmp
vim.opt.completeopt = { "menu", "menuone", "noselect" }
-- Built-in completion popup style (for Ctrl-X Ctrl-N/F completions)
-- Use floating window with border for native completion
-- Native completion popup style
vim.opt.pumblend = 0 -- No transparency
-- Note: Native completion (pumvisible) doesn't support custom borders like LSP floats
-- The Pmenu* highlight groups control its appearance
-- Spelling
vim.opt.spell = true