Nvim change and sway update
This commit is contained in:
@@ -0,0 +1,843 @@
|
||||
-- phill Neovim config (nightly)
|
||||
|
||||
vim.g.mapleader = " "
|
||||
vim.g.maplocalleader = " "
|
||||
|
||||
local opt = vim.opt
|
||||
local map = vim.keymap.set
|
||||
|
||||
-- ============================================================================
|
||||
-- Core options
|
||||
-- ============================================================================
|
||||
|
||||
opt.number = true
|
||||
opt.relativenumber = true
|
||||
opt.mouse = "a"
|
||||
opt.clipboard = "unnamedplus"
|
||||
|
||||
opt.swapfile = false
|
||||
opt.backup = false
|
||||
opt.writebackup = false
|
||||
opt.undofile = true
|
||||
|
||||
opt.ignorecase = true
|
||||
opt.smartcase = true
|
||||
opt.incsearch = true
|
||||
opt.hlsearch = false
|
||||
|
||||
opt.termguicolors = true
|
||||
opt.signcolumn = "yes"
|
||||
opt.cursorline = true
|
||||
opt.splitbelow = true
|
||||
opt.splitright = true
|
||||
opt.wrap = false
|
||||
opt.linebreak = true
|
||||
opt.breakindent = true
|
||||
opt.scrolloff = 8
|
||||
opt.sidescrolloff = 8
|
||||
opt.updatetime = 200
|
||||
opt.timeoutlen = 300
|
||||
opt.confirm = true
|
||||
opt.showmode = false
|
||||
opt.laststatus = 3
|
||||
opt.pumheight = 12
|
||||
-- opt.cmdheight = 0
|
||||
|
||||
opt.expandtab = true
|
||||
opt.smartindent = true
|
||||
opt.shiftround = true
|
||||
opt.tabstop = 2
|
||||
opt.softtabstop = 2
|
||||
opt.shiftwidth = 2
|
||||
|
||||
opt.list = true
|
||||
opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" }
|
||||
opt.fillchars = { eob = " " }
|
||||
|
||||
opt.completeopt = { "menu", "menuone", "noselect", "popup", "fuzzy" }
|
||||
opt.winborder = "single"
|
||||
opt.pumborder = "single"
|
||||
|
||||
opt.winbar = "%=%m %t %="
|
||||
opt.showtabline = 0
|
||||
|
||||
-- ============================================================================
|
||||
-- Basic keymaps
|
||||
-- ============================================================================
|
||||
|
||||
map("n", "<Esc>", "<cmd>nohlsearch<cr><Esc>", { silent = true, desc = "Clear search highlight" })
|
||||
|
||||
-- j/k over display lines when no count is given
|
||||
map({ "n", "x" }, "j", "v:count == 0 ? 'gj' : 'j'", {
|
||||
expr = true,
|
||||
silent = true,
|
||||
desc = "Down (display line)",
|
||||
})
|
||||
map({ "n", "x" }, "k", "v:count == 0 ? 'gk' : 'k'", {
|
||||
expr = true,
|
||||
silent = true,
|
||||
desc = "Up (display line)",
|
||||
})
|
||||
|
||||
-- Save on Ctrl-s
|
||||
map("n", "<C-s>", "<cmd>update<cr>", { silent = true, desc = "Save" })
|
||||
map("i", "<C-s>", "<Esc><cmd>update<cr>gi", { silent = true, desc = "Save" })
|
||||
map("v", "<C-s>", "<Esc><cmd>update<cr>gv", { silent = true, desc = "Save" })
|
||||
|
||||
-- Window navigation on Ctrl-hjkl
|
||||
map("n", "<C-h>", "<C-w>h", { silent = true, desc = "Window left" })
|
||||
map("n", "<C-j>", "<C-w>j", { silent = true, desc = "Window down" })
|
||||
map("n", "<C-k>", "<C-w>k", { silent = true, desc = "Window up" })
|
||||
map("n", "<C-l>", "<C-w>l", { silent = true, desc = "Window right" })
|
||||
|
||||
map("t", "<C-h>", [[<C-\><C-n><C-w>h]], { silent = true, desc = "Window left" })
|
||||
map("t", "<C-j>", [[<C-\><C-n><C-w>j]], { silent = true, desc = "Window down" })
|
||||
map("t", "<C-k>", [[<C-\><C-n><C-w>k]], { silent = true, desc = "Window up" })
|
||||
map("t", "<C-l>", [[<C-\><C-n><C-w>l]], { silent = true, desc = "Window right" })
|
||||
|
||||
-- Buffer cycling
|
||||
map("n", "H", "<cmd>bprevious<cr>", { silent = true, desc = "Previous buffer" })
|
||||
map("n", "L", "<cmd>bnext<cr>", { silent = true, desc = "Next buffer" })
|
||||
|
||||
-- ============================================================================
|
||||
-- Buffer helpers
|
||||
-- ============================================================================
|
||||
|
||||
local function listed_buffers()
|
||||
return vim.tbl_filter(function(buf)
|
||||
return vim.api.nvim_buf_is_valid(buf) and vim.bo[buf].buflisted
|
||||
end, vim.api.nvim_list_bufs())
|
||||
end
|
||||
|
||||
local function delete_buffer(buf, opts)
|
||||
opts = opts or {}
|
||||
if not buf or buf == 0 then
|
||||
buf = vim.api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
local cmd = opts.wipe
|
||||
and (opts.force and "bwipeout!" or "bwipeout")
|
||||
or (opts.force and "bdelete!" or "bdelete")
|
||||
|
||||
pcall(vim.cmd, cmd .. " " .. buf)
|
||||
end
|
||||
|
||||
local function delete_other_buffers(force)
|
||||
local current = vim.api.nvim_get_current_buf()
|
||||
for _, buf in ipairs(listed_buffers()) do
|
||||
if buf ~= current then
|
||||
delete_buffer(buf, { force = force })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function delete_all_buffers(force)
|
||||
for _, buf in ipairs(listed_buffers()) do
|
||||
delete_buffer(buf, { force = force })
|
||||
end
|
||||
end
|
||||
|
||||
map("n", "<leader>bb", "<cmd>buffer #<cr>", { silent = true, desc = "Last buffer" })
|
||||
map("n", "<leader>bd", function() delete_buffer(0, { force = false }) end, { desc = "Delete buffer" })
|
||||
map("n", "<leader>bD", function() delete_buffer(0, { force = true }) end, { desc = "Force delete buffer" })
|
||||
map("n", "<leader>bw", function() delete_buffer(0, { wipe = true }) end, { desc = "Wipe buffer" })
|
||||
map("n", "<leader>bo", function() delete_other_buffers(false) end, { desc = "Delete other buffers" })
|
||||
map("n", "<leader>ba", function() delete_all_buffers(false) end, { desc = "Delete all buffers" })
|
||||
|
||||
-- ============================================================================
|
||||
-- netrw stays the default file browser
|
||||
-- ============================================================================
|
||||
|
||||
vim.g.netrw_banner = 1
|
||||
vim.g.netrw_liststyle = 3
|
||||
vim.g.netrw_winsize = 30
|
||||
vim.g.netrw_keepdir = 0
|
||||
|
||||
map("n", "<leader>E", "<cmd>Ex<cr>", { silent = true, desc = "Open netrw" })
|
||||
|
||||
vim.api.nvim_create_autocmd("VimEnter", {
|
||||
callback = function()
|
||||
if vim.fn.argc() == 0 then
|
||||
vim.cmd("Neotree position=current")
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- Built-in package manager (nightly)
|
||||
-- ============================================================================
|
||||
|
||||
-- Optional post-install hooks for plugins that usually need one-time setup.
|
||||
vim.api.nvim_create_autocmd("PackChanged", {
|
||||
callback = function(ev)
|
||||
local data = ev.data or {}
|
||||
local spec = data.spec or {}
|
||||
local name = spec.name
|
||||
local kind = data.kind
|
||||
|
||||
if kind ~= "install" and kind ~= "update" then
|
||||
return
|
||||
end
|
||||
|
||||
if name == "nvim-treesitter" then
|
||||
vim.schedule(function()
|
||||
pcall(vim.cmd.packadd, "nvim-treesitter")
|
||||
pcall(function()
|
||||
require("nvim-treesitter.install").update({ with_sync = true })()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
if name == "markdown-preview.nvim" then
|
||||
vim.schedule(function()
|
||||
pcall(vim.cmd.packadd, "markdown-preview.nvim")
|
||||
pcall(function()
|
||||
vim.fn["mkdp#util#install"]()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
vim.pack.add({
|
||||
|
||||
{ src = "https://github.com/nvim-lua/plenary.nvim" },
|
||||
{ src = "https://github.com/MunifTanjim/nui.nvim" },
|
||||
{ src = "https://github.com/nvim-tree/nvim-web-devicons" },
|
||||
|
||||
-- Themes
|
||||
{ src = "https://github.com/oskarnurm/koda.nvim" },
|
||||
{ src = "https://github.com/vague-theme/vague.nvim" },
|
||||
{ src = "https://github.com/nendix/zen.nvim" },
|
||||
{ src = "https://github.com/rebelot/kanagawa.nvim" },
|
||||
|
||||
-- Editing / syntax / completion
|
||||
{ src = "https://github.com/nvim-treesitter/nvim-treesitter" },
|
||||
|
||||
{ src = "https://github.com/saghen/blink.lib" },
|
||||
{ src = "https://github.com/saghen/blink.cmp" },
|
||||
|
||||
{ src = "https://github.com/L3MON4D3/LuaSnip" },
|
||||
{ src = "https://github.com/rafamadriz/friendly-snippets" },
|
||||
{ src = "https://gitlab.com/repetitivesin/madol.nvim" },
|
||||
|
||||
-- LSP configs (for vim.lsp.enable)
|
||||
{ src = "https://github.com/neovim/nvim-lspconfig" },
|
||||
|
||||
-- Navigation / search
|
||||
{ src = "https://github.com/ibhagwan/fzf-lua" },
|
||||
{ src = "https://github.com/nvim-neo-tree/neo-tree.nvim" },
|
||||
{ src = "https://github.com/folke/flash.nvim" },
|
||||
{ src = "https://github.com/leath-dub/snipe.nvim" },
|
||||
{ src = "https://github.com/folke/which-key.nvim" },
|
||||
{ src = "https://github.com/mikavilpas/yazi.nvim" },
|
||||
{ src = "https://github.com/christoomey/vim-tmux-navigator"},
|
||||
|
||||
-- Git
|
||||
{ src = "https://github.com/tpope/vim-fugitive" },
|
||||
{ src = "https://github.com/lewis6991/gitsigns.nvim" },
|
||||
{ src = "https://github.com/kdheepak/lazygit.nvim" },
|
||||
|
||||
-- Text objects / editing
|
||||
{ src = "https://github.com/kylechui/nvim-surround" },
|
||||
{ src = "https://github.com/windwp/nvim-autopairs" },
|
||||
{ src = "https://github.com/abecodes/tabout.nvim" },
|
||||
|
||||
-- UI
|
||||
{ src = "https://github.com/nvim-lualine/lualine.nvim" },
|
||||
{ src = "https://github.com/chentoast/marks.nvim" },
|
||||
|
||||
-- Writing / docs
|
||||
{ src = "https://github.com/chomosuke/typst-preview.nvim" },
|
||||
{ src = "https://github.com/iamcco/markdown-preview.nvim" },
|
||||
{ src = "https://github.com/MeanderingProgrammer/render-markdown.nvim" },
|
||||
|
||||
-- AI
|
||||
{ src = "https://github.com/nickjvandyke/opencode.nvim" },
|
||||
{ src = "https://github.com/zbirenbaum/copilot.lua" },
|
||||
|
||||
}, { confirm = false, load = true })
|
||||
|
||||
-- ============================================================================
|
||||
-- Plugin globals before setup
|
||||
-- ============================================================================
|
||||
|
||||
vim.g.mkdp_auto_start = 0
|
||||
vim.g.mkdp_auto_close = 1
|
||||
vim.g.mkdp_filetypes = { "markdown" }
|
||||
|
||||
-- Let native LSP own LSP features; opencode still works for its own UI/actions.
|
||||
vim.g.opencode_opts = {
|
||||
lsp = {
|
||||
enabled = false,
|
||||
},
|
||||
}
|
||||
|
||||
vim.o.autoread = true
|
||||
|
||||
-- ============================================================================
|
||||
-- Themes
|
||||
-- ============================================================================
|
||||
|
||||
require("koda").setup({})
|
||||
require("vague").setup({})
|
||||
require("kanagawa").setup({
|
||||
compile = false,
|
||||
background = {
|
||||
dark = "wave",
|
||||
light = "lotus",
|
||||
},
|
||||
})
|
||||
require("zen").setup({})
|
||||
|
||||
vim.cmd.colorscheme("vague")
|
||||
|
||||
-- ============================================================================
|
||||
-- which-key
|
||||
-- ============================================================================
|
||||
|
||||
local wk = require("which-key")
|
||||
wk.setup({ preset = "helix" })
|
||||
|
||||
wk.add({
|
||||
{ "<leader>b", group = "buffer" },
|
||||
{ "<leader>f", group = "find" },
|
||||
{ "<leader>g", group = "git" },
|
||||
{ "<leader>h", group = "hunks" },
|
||||
{ "<leader>l", group = "lsp" },
|
||||
{ "<leader>m", group = "marks" },
|
||||
{ "<leader>o", group = "opencode" },
|
||||
{ "<leader>t", group = "tree" },
|
||||
{ "<leader>p", group = "preview" },
|
||||
{ "<leader>u", group = "toggles" },
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- vim-tmux-navigator
|
||||
-- ============================================================================
|
||||
|
||||
map("n", "<C-h>", "<cmd>TmuxNavigateLeft<CR>", { silent = true })
|
||||
map("n", "<C-j>", "<cmd>TmuxNavigateDown<CR>", { silent = true })
|
||||
map("n", "<C-k>", "<cmd>TmuxNavigateUp<CR>", { silent = true })
|
||||
map("n", "<C-l>", "<cmd>TmuxNavigateRight<CR>", { silent = true })
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
-- Treesitter
|
||||
-- ============================================================================
|
||||
|
||||
require("nvim-treesitter.configs").setup({
|
||||
ensure_installed = {
|
||||
"go",
|
||||
"gomod",
|
||||
"gowork",
|
||||
"gosum",
|
||||
"bash",
|
||||
"c",
|
||||
"cpp",
|
||||
"css",
|
||||
"diff",
|
||||
"html",
|
||||
"javascript",
|
||||
"json",
|
||||
"json5",
|
||||
"latex",
|
||||
"lua",
|
||||
"luadoc",
|
||||
"markdown",
|
||||
"markdown_inline",
|
||||
"python",
|
||||
"query",
|
||||
"regex",
|
||||
"rust",
|
||||
"toml",
|
||||
"tsx",
|
||||
"typst",
|
||||
"typescript",
|
||||
"vim",
|
||||
"vimdoc",
|
||||
"yaml",
|
||||
},
|
||||
auto_install = true,
|
||||
highlight = { enable = true },
|
||||
indent = { enable = true },
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- LuaSnip
|
||||
-- ============================================================================
|
||||
|
||||
local ls = require("luasnip")
|
||||
|
||||
ls.config.setup({
|
||||
history = true,
|
||||
update_events = "TextChanged,TextChangedI",
|
||||
delete_check_events = "TextChanged",
|
||||
enable_autosnippets = true,
|
||||
})
|
||||
|
||||
require("luasnip.loaders.from_vscode").lazy_load()
|
||||
|
||||
require("madol").setup({
|
||||
rmarkdown = {
|
||||
snippets = {
|
||||
["greek-tex"] = true,
|
||||
["greek-unicode"] = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
map({ "i", "s" }, "<C-j>", function()
|
||||
if ls.choice_active() then
|
||||
ls.change_choice(1)
|
||||
end
|
||||
end, { desc = "LuaSnip next choice" })
|
||||
|
||||
map({ "i", "s" }, "<C-k>", function()
|
||||
if ls.choice_active() then
|
||||
ls.change_choice(-1)
|
||||
end
|
||||
end, { desc = "LuaSnip previous choice" })
|
||||
|
||||
-- ============================================================================
|
||||
-- blink.cmp
|
||||
-- ============================================================================
|
||||
--
|
||||
|
||||
require("blink.cmp").build():pwait()
|
||||
|
||||
require("blink.cmp").setup({
|
||||
snippets = {
|
||||
preset = "luasnip",
|
||||
},
|
||||
completion = {
|
||||
menu = { auto_show = true },
|
||||
ghost_text = { enabled = false },
|
||||
documentation = {
|
||||
auto_show = true,
|
||||
auto_show_delay_ms = 200,
|
||||
},
|
||||
list = {
|
||||
selection = {
|
||||
preselect = false,
|
||||
auto_insert = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
keymap = {
|
||||
preset = "none",
|
||||
["<C-space>"] = { "show", "show_documentation", "hide_documentation" },
|
||||
["<C-e>"] = { "hide" },
|
||||
|
||||
["<C-up>"] = { "scroll_documentation_up" },
|
||||
["<C-down>"] = { "scroll_documentation_down" },
|
||||
|
||||
["<CR>"] = { "accept", "fallback" },
|
||||
|
||||
["<C-n>"] = { "select_next", "fallback" },
|
||||
["<C-p>"] = { "select_prev", "fallback" },
|
||||
|
||||
["<C-l>"] = { "snippet_forward", "fallback" },
|
||||
["<C-h>"] = { "snippet_backward", "fallback" },
|
||||
|
||||
|
||||
},
|
||||
sources = {
|
||||
default = { "lsp", "path", "snippets", "buffer" },
|
||||
},
|
||||
fuzzy = {
|
||||
implementation = "rust"
|
||||
},
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- Copilot
|
||||
-- Included, but practically "off by default" because auto_trigger = false.
|
||||
-- Toggle it on/off with <leader>uc.
|
||||
-- ============================================================================
|
||||
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "BlinkCmpMenuOpen",
|
||||
callback = function()
|
||||
vim.b.copilot_suggestion_hidden = true
|
||||
end,
|
||||
})
|
||||
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "BlinkCmpMenuClose",
|
||||
callback = function()
|
||||
vim.b.copilot_suggestion_hidden = false
|
||||
end,
|
||||
})
|
||||
|
||||
require("copilot").setup({
|
||||
panel = {
|
||||
enabled = false,
|
||||
},
|
||||
suggestion = {
|
||||
enabled = true,
|
||||
auto_trigger = false,
|
||||
hide_during_completion = true,
|
||||
keymap = {
|
||||
accept = "<M-l>",
|
||||
next = "<M-]>",
|
||||
prev = "<M-[>",
|
||||
dismiss = "<C-]>",
|
||||
toggle_auto_trigger = false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
map("n", "<leader>ac", function()
|
||||
require("copilot.suggestion").toggle_auto_trigger()
|
||||
end, { desc = "Toggle Copilot auto-trigger" })
|
||||
|
||||
map("n", "<leader>ap", function()
|
||||
require("copilot.panel").toggle()
|
||||
end, { desc = "Toggle Copilot panel" })
|
||||
|
||||
-- ============================================================================
|
||||
-- autopairs / tabout / surround
|
||||
-- ============================================================================
|
||||
|
||||
require("nvim-autopairs").setup({
|
||||
check_ts = true,
|
||||
})
|
||||
|
||||
require("tabout").setup({
|
||||
tabkey = "<Tab>",
|
||||
backwards_tabkey = "<S-Tab>",
|
||||
act_as_tab = true,
|
||||
act_as_shift_tab = true,
|
||||
default_tab = "<C-t>",
|
||||
default_shift_tab = "<C-d>",
|
||||
enable_backwards = true,
|
||||
completion = false,
|
||||
ignore_beginning = true,
|
||||
tabouts = {
|
||||
{ open = "'", close = "'" },
|
||||
{ open = '"', close = '"' },
|
||||
{ open = "`", close = "`" },
|
||||
{ open = "(", close = ")" },
|
||||
{ open = "[", close = "]" },
|
||||
{ open = "{", close = "}" },
|
||||
{ open = "$", close = "$" },
|
||||
},
|
||||
})
|
||||
|
||||
require("nvim-surround").setup({})
|
||||
|
||||
-- ============================================================================
|
||||
-- flash.nvim
|
||||
-- ============================================================================
|
||||
|
||||
require("flash").setup({})
|
||||
|
||||
map({ "n", "x", "o" }, "s", function() require("flash").jump() end, { desc = "Flash" })
|
||||
map({ "n", "x", "o" }, "S", function() require("flash").treesitter() end, { desc = "Flash Treesitter" })
|
||||
map("o", "r", function() require("flash").remote() end, { desc = "Remote Flash" })
|
||||
map({ "o", "x" }, "R", function() require("flash").treesitter_search() end, { desc = "Treesitter Search" })
|
||||
map("c", "<C-s>", function() require("flash").toggle() end, { desc = "Toggle Flash Search" })
|
||||
|
||||
-- ============================================================================
|
||||
-- marks.nvim
|
||||
-- ============================================================================
|
||||
|
||||
require("marks").setup({
|
||||
default_mappings = true,
|
||||
builtin_marks = { ".", "<", ">", "^" },
|
||||
cyclic = true,
|
||||
force_write_shada = false,
|
||||
refresh_interval = 250,
|
||||
})
|
||||
|
||||
map("n", "<leader>mb", "<cmd>MarksListBuf<cr>", { silent = true, desc = "Marks in buffer" })
|
||||
map("n", "<leader>ma", "<cmd>MarksListAll<cr>", { silent = true, desc = "All marks" })
|
||||
|
||||
-- ============================================================================
|
||||
-- snipe.nvim
|
||||
-- ============================================================================
|
||||
|
||||
require("snipe").setup({
|
||||
ui = {
|
||||
position = "center",
|
||||
preselect_current = true,
|
||||
text_align = "file-first",
|
||||
},
|
||||
hints = {
|
||||
dictionary = "sadflewcmpghio",
|
||||
},
|
||||
navigate = {
|
||||
cancel_snipe = "<Esc>",
|
||||
close_buffer = "D",
|
||||
open_vsplit = "V",
|
||||
open_split = "H",
|
||||
},
|
||||
sort = "last",
|
||||
})
|
||||
|
||||
map("n", "<leader><leader>", function() require("snipe").open_buffer_menu() end, { desc = "Snipe buffers" })
|
||||
|
||||
-- ============================================================================
|
||||
-- Markdown / Typst
|
||||
-- ============================================================================
|
||||
|
||||
require("render-markdown").setup({
|
||||
file_types = { "markdown" },
|
||||
render_modes = { "n", "c", "t" },
|
||||
})
|
||||
|
||||
require("typst-preview").setup({
|
||||
follow_cursor = true,
|
||||
})
|
||||
|
||||
-- Typst
|
||||
map("n", "<leader>ptp", "<cmd>TypstPreview<cr>", { silent = true, desc = "Typst preview" })
|
||||
map("n", "<leader>ptP", "<cmd>TypstPreviewToggle<cr>", { silent = true, desc = "Toggle Typst preview" })
|
||||
|
||||
-- Markdown
|
||||
map("n", "<leader>pmp", "<cmd>MarkdownPreview<cr>", { silent = true, desc = "Markdown preview" })
|
||||
map("n", "<leader>pmr", "<cmd>RenderMarkdown toggle<cr>", { silent = true, desc = "Toggle render-markdown" })
|
||||
|
||||
-- ============================================================================
|
||||
-- fzf-lua
|
||||
-- ============================================================================
|
||||
|
||||
require("fzf-lua").setup({
|
||||
actions = {
|
||||
files = {
|
||||
["enter"] = require("fzf-lua.actions").file_edit,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
map("n", "<leader>ff", function() require("fzf-lua").files() end, { desc = "Files" })
|
||||
map("n", "<leader>db", function() require("fzf-lua").buffers() end, { desc = "Buffers" })
|
||||
map("n", "<leader>bl", function() require("fzf-lua").buffers() end, { desc = "List buffers" })
|
||||
map("n", "<leader>ft", function() require("fzf-lua").live_grep() end, { desc = "Live grep" })
|
||||
map("n", "<leader>fs", function() require("fzf-lua").lsp_document_symbols() end, { desc = "Document symbols" })
|
||||
map("n", "<leader>/", function() require("fzf-lua").grep_curbuf() end, { desc = "Grep current buffer" })
|
||||
map("n", "<leader>fh", function() require("fzf-lua").help_tags() end, { desc = "Help tags" })
|
||||
|
||||
-- useful extras
|
||||
map("n", "<leader>fr", function() require("fzf-lua").oldfiles() end, { desc = "Recent files" })
|
||||
map("n", "<leader>fg", function() require("fzf-lua").git_files() end, { desc = "Git files" })
|
||||
map("n", "<leader>fc", function() require("fzf-lua").commands() end, { desc = "Commands" })
|
||||
map("n", "<leader>fk", function() require("fzf-lua").keymaps() end, { desc = "Keymaps" })
|
||||
map("n", "<leader>fd", function() require("fzf-lua").diagnostics_document() end, { desc = "Document diagnostics" })
|
||||
map("n", "<leader>fD", function() require("fzf-lua").diagnostics_workspace() end, { desc = "Workspace diagnostics" })
|
||||
map("n", "<leader>fw", function() require("fzf-lua").grep_cword() end, { desc = "Grep word under cursor" })
|
||||
|
||||
-- ============================================================================
|
||||
-- neo-tree
|
||||
-- netrw remains default; neo-tree is opt-in on <leader>n
|
||||
-- ============================================================================
|
||||
|
||||
require("neo-tree").setup({
|
||||
close_if_last_window = true,
|
||||
enable_git_status = true,
|
||||
enable_diagnostics = true,
|
||||
filesystem = {
|
||||
hijack_netrw_behavior = "disabled",
|
||||
follow_current_file = { enabled = true },
|
||||
use_libuv_file_watcher = true,
|
||||
},
|
||||
window = {
|
||||
width = 80,
|
||||
},
|
||||
})
|
||||
|
||||
map("n", "<leader>e", "<cmd>Neotree position=right toggle<cr>", {
|
||||
silent = true,
|
||||
desc = "Neo-tree",
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- Git
|
||||
-- ============================================================================
|
||||
|
||||
require("gitsigns").setup({
|
||||
signs = {
|
||||
add = { text = "▎" },
|
||||
change = { text = "▎" },
|
||||
delete = { text = "" },
|
||||
topdelete = { text = "" },
|
||||
changedelete = { text = "▎" },
|
||||
untracked = { text = "▎" },
|
||||
},
|
||||
on_attach = function(bufnr)
|
||||
local gs = package.loaded.gitsigns
|
||||
|
||||
local function bufmap(mode, lhs, rhs, desc)
|
||||
vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, silent = true, desc = desc })
|
||||
end
|
||||
|
||||
bufmap("n", "]h", gs.next_hunk, "Next hunk")
|
||||
bufmap("n", "[h", gs.prev_hunk, "Prev hunk")
|
||||
bufmap("n", "<leader>hs", gs.stage_hunk, "Stage hunk")
|
||||
bufmap("n", "<leader>hr", gs.reset_hunk, "Reset hunk")
|
||||
bufmap("n", "<leader>hS", gs.stage_buffer, "Stage buffer")
|
||||
bufmap("n", "<leader>hR", gs.reset_buffer, "Reset buffer")
|
||||
bufmap("n", "<leader>hp", gs.preview_hunk, "Preview hunk")
|
||||
bufmap("n", "<leader>hb", function() gs.blame_line({ full = true }) end, "Blame line")
|
||||
bufmap("n", "<leader>hd", gs.diffthis, "Diff this")
|
||||
bufmap("n", "<leader>hQ", gs.setqflist, "Hunks to quickfix")
|
||||
end,
|
||||
})
|
||||
|
||||
map("n", "<leader>gg", "<cmd>LazyGit<cr>", { silent = true, desc = "LazyGit" })
|
||||
map("n", "<leader>gs", "<cmd>Git<cr>", { silent = true, desc = "Git status" })
|
||||
map("n", "<leader>gb", "<cmd>Git blame<cr>", { silent = true, desc = "Git blame" })
|
||||
map("n", "<leader>gp", "<cmd>Git push<cr>", { silent = true, desc = "Git push" })
|
||||
map("n", "<leader>gl", "<cmd>Git pull<cr>", { silent = true, desc = "Git pull" })
|
||||
map("n", "<leader>gc", "<cmd>Git commit<cr>", { silent = true, desc = "Git commit" })
|
||||
|
||||
-- ============================================================================
|
||||
-- opencode.nvim
|
||||
-- ============================================================================
|
||||
|
||||
map({ "n", "x" }, "<leader>oa", function()
|
||||
require("opencode").ask("@this: ", { submit = true })
|
||||
end, { desc = "Ask opencode" })
|
||||
|
||||
map({ "n", "x" }, "<leader>os", function()
|
||||
require("opencode").select()
|
||||
end, { desc = "Select opencode action" })
|
||||
|
||||
map({ "n", "t" }, "<leader>oo", function()
|
||||
require("opencode").toggle()
|
||||
end, { desc = "Toggle opencode" })
|
||||
|
||||
map({ "n", "x" }, "<leader>or", function()
|
||||
return require("opencode").operator("@this ")
|
||||
end, { expr = true, desc = "Send range to opencode" })
|
||||
|
||||
map("n", "<leader>ol", function()
|
||||
return require("opencode").operator("@this ") .. "_"
|
||||
end, { expr = true, desc = "Send line to opencode" })
|
||||
|
||||
map("n", "<leader>ou", function()
|
||||
require("opencode").command("session.half.page.up")
|
||||
end, { desc = "Opencode scroll up" })
|
||||
|
||||
map("n", "<leader>od", function()
|
||||
require("opencode").command("session.half.page.down")
|
||||
end, { desc = "Opencode scroll down" })
|
||||
|
||||
-- ============================================================================
|
||||
-- LSP (native nightly flow)
|
||||
-- No Mason. Install server binaries yourself and keep them on PATH.
|
||||
-- ============================================================================
|
||||
|
||||
local capabilities = require("blink.cmp").get_lsp_capabilities()
|
||||
|
||||
vim.diagnostic.config({
|
||||
underline = true,
|
||||
severity_sort = true,
|
||||
update_in_insert = false,
|
||||
virtual_text = {
|
||||
spacing = 2,
|
||||
source = "if_many",
|
||||
},
|
||||
float = {
|
||||
border = "rounded",
|
||||
source = "if_many",
|
||||
},
|
||||
})
|
||||
|
||||
-- Global defaults for all enabled servers
|
||||
vim.lsp.config("*", {
|
||||
capabilities = capabilities,
|
||||
root_markers = { ".git" },
|
||||
})
|
||||
|
||||
-- Per-server overrides
|
||||
vim.lsp.config("lua_ls", {
|
||||
settings = {
|
||||
Lua = {
|
||||
diagnostics = {
|
||||
globals = { "vim" },
|
||||
},
|
||||
workspace = {
|
||||
checkThirdParty = false,
|
||||
},
|
||||
telemetry = {
|
||||
enable = false,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
-- Adjust this list to the servers you actually have installed.
|
||||
local servers = {
|
||||
"gopls",
|
||||
"lua_ls",
|
||||
"tinymist",
|
||||
"marksman",
|
||||
"pyright",
|
||||
}
|
||||
|
||||
for _, server in ipairs(servers) do
|
||||
vim.lsp.enable(server)
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
callback = function(ev)
|
||||
local bufnr = ev.buf
|
||||
|
||||
local function lmap(lhs, rhs, desc, mode)
|
||||
vim.keymap.set(mode or "n", lhs, rhs, { buffer = bufnr, silent = true, desc = desc })
|
||||
end
|
||||
|
||||
lmap("gd", vim.lsp.buf.definition, "Goto definition")
|
||||
lmap("gD", vim.lsp.buf.declaration, "Goto declaration")
|
||||
lmap("gi", vim.lsp.buf.implementation, "Goto implementation")
|
||||
lmap("gt", vim.lsp.buf.type_definition, "Goto type definition")
|
||||
lmap("gr", function() require("fzf-lua").lsp_references() end, "References")
|
||||
lmap("K", vim.lsp.buf.hover, "Hover")
|
||||
lmap("gK", vim.lsp.buf.signature_help, "Signature help")
|
||||
|
||||
lmap("<leader>la", vim.lsp.buf.code_action, "Code action", { "n", "x" })
|
||||
lmap("<leader>lr", vim.lsp.buf.rename, "Rename")
|
||||
lmap("<leader>lf", function() vim.lsp.buf.format({ async = true }) end, "Format")
|
||||
lmap("<leader>ld", vim.diagnostic.open_float, "Line diagnostics")
|
||||
lmap("<leader>ls", function() require("fzf-lua").lsp_document_symbols() end, "Document symbols")
|
||||
lmap("<leader>lS", function() require("fzf-lua").lsp_live_workspace_symbols() end, "Workspace symbols")
|
||||
|
||||
lmap("[d", function() vim.diagnostic.jump({ count = -1, float = true }) end, "Prev diagnostic")
|
||||
lmap("]d", function() vim.diagnostic.jump({ count = 1, float = true }) end, "Next diagnostic")
|
||||
end,
|
||||
})
|
||||
|
||||
-- ============================================================================
|
||||
-- lualine
|
||||
-- ============================================================================
|
||||
|
||||
local function opencode_statusline()
|
||||
local ok, opencode = pcall(require, "opencode")
|
||||
if ok and opencode.statusline then
|
||||
return opencode.statusline()
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
require("lualine").setup({
|
||||
options = {
|
||||
section_separators = "",
|
||||
component_separators = "",
|
||||
globalstatus = true,
|
||||
theme = "auto",
|
||||
},
|
||||
|
||||
sections = {
|
||||
lualine_a = { "mode" },
|
||||
lualine_b = { { "branch", icon = "" }, "diff" },
|
||||
lualine_c = {
|
||||
{ "diagnostics" },
|
||||
{ "filename", path = 1, symbols = { modified = " ●", readonly = " " } },
|
||||
},
|
||||
lualine_x = { "encoding", "fileformat", "filetype", opencode_statusline },
|
||||
lualine_y = { "progress" },
|
||||
lualine_z = { "location" },
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user