commit bc8000f2376fb0b0754482b4777369346a18c4c2 from: vincent delft date: Sat Feb 14 18:03:21 2026 UTC initial import commit - /dev/null commit + bc8000f2376fb0b0754482b4777369346a18c4c2 blob - /dev/null blob + 2bbef8f489eef321e5d92c226404168b58103e18 (mode 644) --- /dev/null +++ README.md @@ -0,0 +1,122 @@ +# Installation + +pkg install neovim xclip +copy config/init.lua to ~/.config/nvim/ +mkdir -p ~/.config/nvim/sessions/ + +# Configuration + +start nvim and make sure lazy update all packages at 1st run + +# Maintenance + +regularely update modules by doing in nvim: Lazy update + +# Documentation + +This Neovim setup is designed for **Python development, shell scripting, HTML/CSS editing, and Markdown writing**. +It uses [lazy.nvim](https://github.com/folke/lazy.nvim) for plugin management and focuses on **LSP, autocompletion, Treesitter syntax highlighting, and session persistence**. + +--- + +## Features + +- 🚀 **Lazy.nvim** – fast plugin manager +- 🐍 **Python LSP** with `pylsp` + `pylint` integration +- 🐚 **ShellCheck** for inline shell script linting +- 🌐 **HTML/CSS/JS** improvements with Treesitter + autotagging +- 📝 **Markdown spell-check** for writing clean documentation +- 🎨 **Colors**: default scheme is `ron` (fallback `habamax`) +- 💾 **Sessions auto-save & restore** with `persistence.nvim` +- ⚡ **Completion engine** (`nvim-cmp`) with snippets, paths, buffer, emoji + +--- + +## Plugins + +### Core Editing +- **`nvim-treesitter`** → Syntax highlighting & smart indentation (bash, python, html, css, javascript, lua) +- **`nvim-ts-autotag`** → Auto-close and rename paired HTML/JSX tags +- **`ccc.nvim`** → Inline color preview and color picker for CSS/HTML + +### LSP & Autocompletion +- **`nvim-lspconfig`** → Manages language servers +- **`nvim-cmp`** + sources: + - LSP completions (`cmp-nvim-lsp`) + - Buffer words (`cmp-buffer`) + - Filesystem paths (`cmp-path`) + - Function signatures (`cmp-nvim-lsp-signature-help`) + - Emoji (`cmp-emoji`) +- **`LuaSnip`** → Snippet engine + +### Linting & Spell Checking +- **`shellcheck.nvim`** → Lint shell scripts directly in Neovim +- **Spell-check** → Enabled for Markdown (`*.md`) files to avoid typos + +### Sessions +- **`persistence.nvim`** → Save/restore sessions automatically in `~/.config/nvim/sessions/` + +## Language Configuration + +- **Python** + - LSP: [`pylsp`](https://github.com/python-lsp/python-lsp-server) + - `pylint` enabled (style warnings relaxed for line length & f-strings) + - Jedi completions + +- **Shell** + - `shellcheck.nvim` integrated for on-the-fly linting + +- **HTML/CSS/JS** + - 2-space indentation for HTML + - Treesitter-based highlighting + - Autotag for paired tags + +- **Markdown** + - Spell-check enabled to catch typos + + +## Keybindings + +Leader key: `` + +### LSP +- `gd` → Go to definition +- `K` → Hover documentation +- `ca` → Code action +- `e` → Show diagnostics in float +- `q` → List diagnostics + +### Sessions +- `ss` → Save session +- `sr` → Restore session +- `sl` → Restore last session + +### Completion (`nvim-cmp`) +- `` / `` → Scroll docs +- `` → Trigger completion +- `` → Abort completion +- `` → Confirm completion + + +## Diagnostics in Statusline + +Shows inline diagnostic messages for the **current line**, with icons: +- ⛔ Error +- âš ī¸ Warning +- â„šī¸ Info +- 💡 Hint + + +## Clipboard Tips + +For system clipboard integration (requires `xclip` on Linux/*BSD): +- In Visual mode: + - `"+y` → Yank to clipboard (paste with Ctrl+V) + - `"*y` → Yank to selection (paste with middle-click) + +Examples: +```vim +:.,.+5yank * " yank 5 lines → paste with middle click +:.,.+5yank + " yank 5 lines → paste with Ctrl+V + + blob - /dev/null blob + 40059b24081511de1651d5f613576d5755a1f398 (mode 644) --- /dev/null +++ config/init.lua @@ -0,0 +1,252 @@ +-- neovim config file build by vincent.delft@gmail.com + +-- Bootstrap Lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not vim.loop.fs_stat(lazypath) then + vim.fn.system({ + "git", + "clone", + "--filter=blob:none", + "https://github.com/folke/lazy.nvim.git", + "--branch=stable", + lazypath, + }) +end +vim.opt.rtp:prepend(lazypath) + +-- Set leader key +vim.g.mapleader = " " +vim.g.maplocalleader = " " + +-- Basic Neovim settings +vim.opt.number = true -- Show line numbers +vim.opt.tabstop = 4 -- 4 spaces for tabs +vim.opt.shiftwidth = 4 -- 4 spaces for indentation +vim.opt.expandtab = true -- Convert tabs to spaces +vim.opt.smartindent = true -- Smart indentation +vim.opt.termguicolors = true -- Enable true colors +vim.opt.signcolumn = "yes" -- show left column +vim.opt.ignorecase = true -- case-insensitive +vim.opt.smartcase = true -- case-sensitive if search pattern contains uppercase + +-- Show relative line numbers for all other lines +vim.opt.relativenumber = true + +-- Set colorscheme to ron +-- To list all colorscheme, just type :colorscheme +vim.cmd([[colorscheme ron]]) + +-- ensure sessionoptions has localoptions +vim.o.sessionoptions = "buffers,curdir,folds,help,tabpages,winsize,localoptions" + +-- Lazy.nvim setup +require("lazy").setup({ + { "neovim/nvim-lspconfig" }, + { "hrsh7th/nvim-cmp" }, + { "hrsh7th/cmp-nvim-lsp" }, + { "hrsh7th/cmp-buffer" }, + { "hrsh7th/cmp-path" }, + { "hrsh7th/cmp-nvim-lsp-signature-help" }, + { "L3MON4D3/LuaSnip" }, + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + config = function() + require("nvim-treesitter.configs").setup { + -- List of languages to install parsers for + ensure_installed = { "bash", "html", "css", "javascript", "python", "lua" }, + + -- Automatically install missing parsers when entering buffer + auto_install = true, + + highlight = { + enable = true, -- Enables syntax highlighting + additional_vim_regex_highlighting = false, + }, + + indent = { + enable = true, -- Enables Tree-sitter based indentation + }, + } + end, + }, + { + "pablos123/shellcheck.nvim", + config = function () require 'shellcheck-nvim'.setup {} end + }, + { + "windwp/nvim-ts-autotag", + config = function() + require("nvim-ts-autotag").setup({ + opts = { + enable_close = true, -- auto-close tags + enable_rename = true, -- auto-rename paired tags + enable_close_on_slash = false, + -- optionally, add per_filetype overrides here + }, + }) + end, + }, + { + "uga-rosa/ccc.nvim", + config = function() + require("ccc").setup({ + -- optional settings here + highlighter = { + auto_enable = true, -- highlight color codes automatically + -- lsp = true, -- enable LSP-based detection + }, + }) + end, + }, + { "hrsh7th/cmp-emoji" }, -- to enter emoticons, type : + + { + 'folke/persistence.nvim', + event = 'VimEnter', + opts = { + dir = vim.fn.expand('~/.config/nvim/sessions/') .. '/', -- to make sure it ends with a slah + options = { 'buffers', 'curdir', 'tabpages', 'winsize' }, + }, + keys = { + { 'ss', function() require('persistence').save() end, desc = 'Save session' }, + { 'sr', function() require('persistence').load() end, desc = 'Restore session' }, + { 'sl', function() require('persistence').load_last() end, desc = 'Restore last session' }, + }, + init = function() + -- Auto-restore session on startup + vim.api.nvim_create_autocmd('VimEnter', { + callback = function() + -- print('CWD: ' ..vim.fn.getcwd() .. ',argc: ' .. vim.fn.argc()) + if vim.fn.argc() == 0 then + require('persistence').load() + end + end, + nested = true, + }) + -- Auto-save session on buffer write or switch + vim.api.nvim_create_autocmd('BufWritePost', { + callback = function() + require('persistence').save() + -- print('Session saved for ' .. vim.fn.getcwd()) + end, + }) + + end, + }, + + + + +}, { + install = { colorscheme = { "ron", "habamax" } }, +}) + +-- LSP setup +local lspconfig = require("lspconfig") +-- Python LSP +lspconfig.pylsp.setup { + settings = { + pylsp = { + plugins = { + -- pycodestyle = { enabled = true, ignore = { "E501" }, }, + pycodestyle = { enabled = false }, + pylint = { + enabled = true, + args = { "--disable=C0301,C0209" }, -- line too long, use format + }, + jedi_completion = { enabled = true }, + }, + }, + }, +} + + +-- Autocompletion setup +local cmp = require("cmp") +cmp.setup({ + snippet = { + expand = function(args) + require("luasnip").lsp_expand(args.body) + end, + }, + mapping = cmp.mapping.preset.insert({ + [""] = cmp.mapping.scroll_docs(-4), + [""] = cmp.mapping.scroll_docs(4), + [""] = cmp.mapping.complete(), + [""] = cmp.mapping.abort(), + [""] = cmp.mapping.confirm({ select = true }), + }), + sources = cmp.config.sources({ + { name = "nvim_lsp" }, + { name = "luasnip" }, + { name = "buffer" }, + { name = "path" }, + { name = "nvim_lsp_signature_help" }, + { name = "emoji" }, + }), +}) + +-- Treesitter for syntax highlighting +require("nvim-treesitter.configs").setup({ + ensure_installed = { "python", "bash" }, + highlight = { enable = true }, + indent = { enable = true }, +}) + + + +-- Basic keybindings +vim.keymap.set("n", "e", vim.diagnostic.open_float, { desc = "Show diagnostics" }) +vim.keymap.set("n", "q", vim.diagnostic.setloclist, { desc = "Diagnostics list" }) +vim.keymap.set("n", "gd", vim.lsp.buf.definition, { desc = "Go to definition" }) +vim.keymap.set("n", "K", vim.lsp.buf.hover, { desc = "Hover documentation" }) +vim.keymap.set("n", "ca", vim.lsp.buf.code_action, { desc = "Code action" }) + +-- Diagnostic in statusline for current line +_G.DiagnosticStatus = function() + local diag = vim.diagnostic.get(0, { lnum = vim.fn.line('.') - 1 }) + if vim.tbl_isempty(diag) then return '' end + + -- Find most severe message on the line + table.sort(diag, function(a, b) return a.severity < b.severity end) + local d = diag[1] + + -- Severity icons + local severity_icons = { + [vim.diagnostic.severity.ERROR] = "⛔", + [vim.diagnostic.severity.WARN] = "âš ī¸", + [vim.diagnostic.severity.INFO] = "â„šī¸", + [vim.diagnostic.severity.HINT] = "💡", + } + + local icon = severity_icons[d.severity] or "" + local msg = d.message:gsub("\n", " ") + return string.format(" %s %s ", icon, msg) +end + +vim.o.statusline = "%f %h%m%r%=%{v:lua.DiagnosticStatus()} %l:%c" + +-- indent of 2 char for html file +-- the reste keeps 4 chars +-- use gg=G to re-indent the whole file. +-- or use =5j to re-indent next 5 lines +vim.api.nvim_create_autocmd("FileType", { + pattern = "html", + callback = function() + vim.bo.shiftwidth = 2 -- Indent size + vim.bo.tabstop = 2 -- Visual width of a tab character + vim.bo.softtabstop = 2 -- How many spaces inserts + vim.bo.expandtab = true -- Use spaces instead of real tabs + end, +}) + + + +-- tips: +-- to yank lines in the clipboard: doas pkg install xclip +-- 1st option) in V mode, select lines, then type "+y You can ctrl-v +-- 1st option) in V mode, select lines, then type "*y You can middle click +-- 2nd option) type :.,.+5yank * release by middle click +-- 2nd option) type :.,.+5yank + release by ctrl-v +--