Initial commit: nvim-minimal
A small, fast, portable Neovim config built on bare lazy.nvim (no LazyVim, no LSPs, no Mason). Vendored `based` colorscheme (GPLv3, self-authored, derived from vim-vividchalk) so the config loads on any machine with just nvim + git — the listed treesitter parsers ship prebuilt, so no compiler is needed for the configured languages. Plugins: snacks.nvim (picker/explorer/buffers), nvim-treesitter (pinned to master for the declarative ensure_installed/highlight/indent API), blink.cmp (buffer+path completion, prebuilt binary), lualine, gitsigns, mini.align/ comment/surround. Personal keymaps ported: jj/jk/kj/чя escape, ж -> :, Russian langmap, arrow disables, bracket-return expansions, gc/sa-sd-sr/gz-gZ.
This commit is contained in:
commit
97a90cc1e5
16 files changed
+575
No files matched your search
@@ -0,0 +1 @@
|
||||
-- Autocmds. Currently empty; add vim.api.nvim_create_autocmd groups here as needed.
|
||||
@@ -0,0 +1,52 @@
|
||||
-- Personal keymaps (plugin-agnostic). Plugin-bound keys live in their specs.
|
||||
|
||||
local function map(mode, lhs, rhs, opts)
|
||||
local options = { noremap = true, silent = true }
|
||||
if opts then
|
||||
options = vim.tbl_extend('force', options, opts)
|
||||
end
|
||||
vim.keymap.set(mode, lhs, rhs, options)
|
||||
end
|
||||
|
||||
local function no(lhs, rhs) map('n', lhs, rhs, { silent = false }) end
|
||||
local function no_s(lhs, rhs) map('n', lhs, rhs) end
|
||||
local function no_r(lhs, rhs) map('n', lhs, rhs, { noremap = false, silent = false }) end
|
||||
local function i(lhs, rhs) map('i', lhs, rhs, { silent = false }) end
|
||||
local function i_s(lhs, rhs) map('i', lhs, rhs) end
|
||||
local function v_s(lhs, rhs) map('v', lhs, rhs) end
|
||||
|
||||
-- disable arrow keys and middle-click (muscle memory from the old config)
|
||||
no_s('<up>', '<nop>')
|
||||
no_s('<down>', '<nop>')
|
||||
no_s('<left>', '<nop>')
|
||||
no_s('<right>', '<nop>')
|
||||
no_s('<c-left>', '<nop>')
|
||||
no_s('<c-right>', '<nop>')
|
||||
v_s('<up>', '<nop>')
|
||||
v_s('<down>', '<nop>')
|
||||
v_s('<left>', '<nop>')
|
||||
v_s('<right>', '<nop>')
|
||||
v_s('<c-left>', '<nop>')
|
||||
v_s('<c-right>', '<nop>')
|
||||
|
||||
-- escape from insert mode on home-row bigrams
|
||||
i_s('jj', '<esc>')
|
||||
i_s('jk', '<esc>')
|
||||
i_s('kj', '<esc>')
|
||||
i_s('чя', '<esc>')
|
||||
|
||||
i_s('<esc>', '<nop>')
|
||||
i_s('<C-c>', '<nop>')
|
||||
|
||||
-- bracket-return expansions: open a line between the delimiters, indented
|
||||
i('[<CR>', '[<CR>]<Esc>O<BS><Tab>')
|
||||
i('{<CR>', '{<CR>}<Esc>O<BS><Tab>')
|
||||
i('(<CR>', '(<CR>)<Esc>O<BS><Tab>')
|
||||
|
||||
vim.keymap.set({ 'n', 'i', 'v' }, '<LeftMouse>', '<nop>')
|
||||
|
||||
-- Russian-layout fixes: `ж` types `:`, `W`/`E`/`w'` expand in cmdline
|
||||
no_r('ж', ':')
|
||||
vim.cmd.cnoreabbrev({ "<expr> W", "((getcmdtype() is# ':' && getcmdline() is# 'W')?('w'):('W'))" })
|
||||
vim.cmd.cnoreabbrev({ "<expr> E", "((getcmdtype() is# ':' && getcmdline() is# 'E')?('e'):('E'))" })
|
||||
vim.cmd.cnoreabbrev({ "<expr> w'", "(getcmdtype() == \":\" && getcmdline() == \"w'\" ? \"w\" : \"w'\")" })
|
||||
@@ -0,0 +1,37 @@
|
||||
-- Bootstrap lazy.nvim on a fresh machine (needs only git + internet).
|
||||
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
||||
if not (vim.uv or vim.loop).fs_stat(lazypath) then
|
||||
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
|
||||
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
|
||||
if vim.v.shell_error ~= 0 then
|
||||
vim.api.nvim_echo({
|
||||
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
|
||||
{ out, "WarningMsg" },
|
||||
{ "\nPress any key to exit..." },
|
||||
}, true, {})
|
||||
vim.fn.getchar()
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
vim.opt.rtp:prepend(lazypath)
|
||||
|
||||
require("lazy").setup({
|
||||
spec = { { import = "plugins" } },
|
||||
defaults = {
|
||||
lazy = false,
|
||||
version = false, -- use latest git commit; lazy-lock.json pins the exact SHAs
|
||||
},
|
||||
install = { colorscheme = { "based" } },
|
||||
checker = { enabled = true, notify = false },
|
||||
performance = {
|
||||
rtp = {
|
||||
disabled_plugins = {
|
||||
"gzip",
|
||||
"tarPlugin",
|
||||
"tohtml",
|
||||
"tutor",
|
||||
"zipPlugin",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,56 @@
|
||||
-- Options are set before lazy.nvim startup.
|
||||
|
||||
vim.opt.termguicolors = true
|
||||
vim.opt.encoding = "utf8"
|
||||
vim.opt.hidden = true
|
||||
vim.opt.incsearch = true
|
||||
vim.opt.langmap =
|
||||
"ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ;ABCDEFGHIJKLMNOPQRSTUVWXYZ,фисвуапршолдьтщзйкыегмцчня;abcdefghijklmnopqrstuvwxyz"
|
||||
vim.opt.maxmempattern = 5000
|
||||
|
||||
-- completion
|
||||
vim.opt.wildignorecase = true
|
||||
vim.opt.smartcase = true
|
||||
vim.opt.wildmenu = true
|
||||
vim.opt.path:append("**")
|
||||
-- `gf` will try these extensions on a bare word under the cursor.
|
||||
vim.opt.suffixesadd = { ".lua", ".vim", ".md", ".json", ".ts", ".tsx", ".js", ".py", ".rs" }
|
||||
vim.opt.wildignore:append("**/node_modules/**")
|
||||
vim.opt.completeopt = { "menu", "menuone", "preview", "noinsert" }
|
||||
|
||||
-- backups and recovery
|
||||
vim.opt.backup = true
|
||||
vim.opt.backupdir = os.getenv("HOME") .. "/.local/state/nvim/backup"
|
||||
vim.opt.swapfile = true
|
||||
vim.opt.undofile = true
|
||||
vim.opt.updatetime = 800
|
||||
|
||||
-- misc
|
||||
vim.opt.wrap = false
|
||||
vim.opt.whichwrap:append("<,>,[,]")
|
||||
vim.opt.timeoutlen = 500
|
||||
vim.opt.ttimeoutlen = 50
|
||||
|
||||
-- indentation/tabulation
|
||||
vim.opt.tabstop = 4
|
||||
vim.opt.softtabstop = 4
|
||||
vim.opt.expandtab = true
|
||||
vim.opt.shiftwidth = 4
|
||||
vim.opt.smartindent = true
|
||||
vim.opt.autoindent = true
|
||||
|
||||
-- layout
|
||||
vim.opt.signcolumn = "yes"
|
||||
vim.opt.colorcolumn = { 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 80, 99 }
|
||||
vim.opt.cmdheight = 1
|
||||
vim.opt.number = true
|
||||
vim.opt.relativenumber = true
|
||||
vim.opt.scrolloff = 10
|
||||
|
||||
-- folds (treesitter-based; no nvim-ufo needed)
|
||||
vim.opt.foldcolumn = "1"
|
||||
vim.opt.foldlevel = 99
|
||||
vim.opt.foldlevelstart = 99
|
||||
vim.opt.foldenable = true
|
||||
vim.opt.foldmethod = "expr"
|
||||
vim.opt.foldexpr = "v:lua.vim.treesitter.foldexpr()"
|
||||
@@ -0,0 +1,47 @@
|
||||
-- saghen/blink.cmp: fast completion (Rust-backed, prebuilt binary).
|
||||
-- Sources are buffer words + file paths only (no LSP). Filename completion
|
||||
-- comes from the `path` source, triggered by typing `/` or `./`.
|
||||
-- `version = "*"` pulls a release tag, which ships a prebuilt `libblink`
|
||||
-- binary (x86_64/arm64, linux/mac) — no Rust toolchain needed on those arches.
|
||||
return {
|
||||
{
|
||||
"saghen/blink.cmp",
|
||||
event = "InsertEnter",
|
||||
version = "*",
|
||||
opts = {
|
||||
sources = {
|
||||
default = { "buffer", "path" },
|
||||
},
|
||||
completion = {
|
||||
ghost_text = { enabled = false },
|
||||
list = { selection = { preselect = false, auto_insert = false } },
|
||||
},
|
||||
keymap = {
|
||||
preset = "super-tab",
|
||||
["<C-space>"] = { "show", "show_documentation", "hide_documentation" },
|
||||
["<C-e>"] = { "hide", "fallback" },
|
||||
["<Tab>"] = {
|
||||
"select_next",
|
||||
function(cmp)
|
||||
if cmp.snippet_active() then
|
||||
return cmp.accept()
|
||||
else
|
||||
return cmp.select_and_accept()
|
||||
end
|
||||
end,
|
||||
"snippet_forward",
|
||||
"fallback",
|
||||
},
|
||||
["<S-Tab>"] = { "select_prev", "snippet_backward", "fallback" },
|
||||
["<cr>"] = { "select_and_accept", "fallback_to_mappings" },
|
||||
["<Up>"] = { "select_prev", "fallback" },
|
||||
["<Down>"] = { "select_next", "fallback" },
|
||||
["<C-p>"] = { "select_prev", "fallback_to_mappings" },
|
||||
["<C-n>"] = { "select_next", "fallback_to_mappings" },
|
||||
["<C-b>"] = { "scroll_documentation_up", "fallback" },
|
||||
["<C-f>"] = { "scroll_documentation_down", "fallback" },
|
||||
["<C-k>"] = { "show_signature", "hide_signature", "fallback" },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
-- echasnovski/mini.*: small, dependency-free editing utilities.
|
||||
return {
|
||||
{
|
||||
"echasnovski/mini.align",
|
||||
keys = {
|
||||
{ "gz", mode = { "n", "x" } },
|
||||
{ "gZ", mode = { "n", "x" } },
|
||||
},
|
||||
opts = {
|
||||
mappings = {
|
||||
start = "gz",
|
||||
start_with_preview = "gZ",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"echasnovski/mini.comment",
|
||||
event = "VeryLazy",
|
||||
opts = {},
|
||||
},
|
||||
{
|
||||
"echasnovski/mini.surround",
|
||||
event = "VeryLazy",
|
||||
opts = {},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
-- folke/snacks.nvim: picker, explorer, buffers.
|
||||
-- The familiar `gb` / `<leader>F` / `<leader>t` entry points live here as
|
||||
-- lazy `keys`, so the global `Snacks` is guaranteed to exist before any call.
|
||||
return {
|
||||
{
|
||||
"folke/snacks.nvim",
|
||||
priority = 1000,
|
||||
lazy = false,
|
||||
keys = {
|
||||
{
|
||||
"gb",
|
||||
function()
|
||||
Snacks.picker.buffers({ hidden = false, nofile = false, sort_lastused = true, current = false })
|
||||
end,
|
||||
desc = "Buffers",
|
||||
},
|
||||
{
|
||||
"<leader>F",
|
||||
function()
|
||||
Snacks.picker.files({ exclude = { "node_modules/", ".git/" }, hidden = true, auto_close = true })
|
||||
end,
|
||||
desc = "Find Files",
|
||||
},
|
||||
{
|
||||
"<leader>t",
|
||||
function()
|
||||
Snacks.picker.explorer({ exclude = { "node_modules/", ".git/" }, hidden = true, auto_close = true })
|
||||
end,
|
||||
desc = "Explorer",
|
||||
},
|
||||
},
|
||||
opts = {},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
-- nvim-treesitter: highlighting, indentation, and treesitter-based folds.
|
||||
-- All listed parsers ship PREBUILT in the plugin repo, so no compiler is needed
|
||||
-- for the configured languages. A C toolchain (base-devel) is only required if
|
||||
-- you add parsers that aren't prebuilt or force `:TSInstall` to recompile.
|
||||
-- Pinned to the legacy `master` branch, which keeps the declarative
|
||||
-- ensure_installed/highlight/indent API the old config used. The new `main`
|
||||
-- branch dropped this API in favor of do-it-yourself autocommands.
|
||||
return {
|
||||
{
|
||||
"nvim-treesitter/nvim-treesitter",
|
||||
branch = "master",
|
||||
event = "VeryLazy",
|
||||
build = ":TSUpdate",
|
||||
opts = {
|
||||
ensure_installed = {
|
||||
"bash",
|
||||
"css",
|
||||
"html",
|
||||
"javascript",
|
||||
"json",
|
||||
"lua",
|
||||
"markdown",
|
||||
"markdown_inline",
|
||||
"python",
|
||||
"query",
|
||||
"regex",
|
||||
"rust",
|
||||
"scss",
|
||||
"svelte",
|
||||
"tsx",
|
||||
"typescript",
|
||||
"vim",
|
||||
"yaml",
|
||||
},
|
||||
highlight = { enable = true },
|
||||
indent = { enable = true },
|
||||
},
|
||||
config = function(_, opts)
|
||||
require("nvim-treesitter.configs").setup(opts)
|
||||
end,
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
-- UI: statusline, git gutter signs, file icons.
|
||||
-- The `based` colorscheme is vendored at ../../colors/based.vim and set in
|
||||
-- init.lua, so it needs no lazy spec here.
|
||||
return {
|
||||
{
|
||||
"nvim-lualine/lualine.nvim",
|
||||
event = "VeryLazy",
|
||||
dependencies = { "nvim-tree/nvim-web-devicons" },
|
||||
opts = {
|
||||
options = {
|
||||
theme = "auto",
|
||||
component_separators = { left = "│", right = "│" },
|
||||
section_separators = {},
|
||||
globalstatus = true,
|
||||
},
|
||||
sections = {
|
||||
lualine_a = { "mode" },
|
||||
lualine_b = { "branch", "diff" },
|
||||
lualine_c = { { "filename", path = 1 } },
|
||||
lualine_x = { "encoding", "fileformat", "filetype" },
|
||||
lualine_y = { "progress" },
|
||||
lualine_z = { "location" },
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"lewis6991/gitsigns.nvim",
|
||||
event = { "BufReadPre", "BufNewFile" },
|
||||
opts = {},
|
||||
},
|
||||
{ "nvim-tree/nvim-web-devicons", lazy = true },
|
||||
}
|
||||
Reference in new issue
Block a user