neovim
Authored by
mfwolffe <wolffemf@dukes.jmu.edu>
- SHA
76a2ea1a3f3b326de5800206315dea5aff884fdd- Parents
-
f20affe - Tree
81330ea
76a2ea1
76a2ea1a3f3b326de5800206315dea5aff884fddf20affe
81330ea| Status | File | + | - |
|---|---|---|---|
| M |
notes/neovim.md
|
168 | 105 |
| A |
nvim/init.lua
|
267 | 0 |
notes/neovim.mdmodified@@ -1,105 +1,168 @@ | ||
| 1 | -# Neovim Keybind Guide for Modern Usage | |
| 2 | - | |
| 3 | -This guide provides a concise reference for keybindings in Neovim (version 0.7 or later), focusing on quick navigation, jumping between words and lines, and handling multiple cursors or selections. Master these to enhance your productivity in this powerful text editor. | |
| 4 | - | |
| 5 | -## Neovim Modes Overview | |
| 6 | - | |
| 7 | -Neovim operates in distinct modes, each serving specific purposes. Understanding these is essential for effective editing. | |
| 8 | - | |
| 9 | -| Mode | Description | How to Enter | | |
| 10 | -|-----------------|--------------------------------------------------|----------------------------------| | |
| 11 | -| **Normal Mode** | Default mode for navigation and commands | Press `Esc` from other modes | | |
| 12 | -| **Insert Mode** | For typing and inserting text | Press `i`, `a`, `o`, etc. from Normal Mode | | |
| 13 | -| **Visual Mode** | For selecting text (line, block, or character) | Press `v`, `V`, or `Ctrl+v` from Normal Mode | | |
| 14 | -| **Command Mode**| For entering Ex commands (e.g., saving, quitting)| Press `:` from Normal Mode | | |
| 15 | - | |
| 16 | -## Navigation Keybindings | |
| 17 | - | |
| 18 | -These keybindings are primarily for **Normal Mode** and help you move around your editor efficiently. | |
| 19 | - | |
| 20 | -### Basic Movement | |
| 21 | -| Keybind | Action | | |
| 22 | -|---------------|-----------------------------------| | |
| 23 | -| `h` | Move left one character | | |
| 24 | -| `j` | Move down one line | | |
| 25 | -| `k` | Move up one line | | |
| 26 | -| `l` | Move right one character | | |
| 27 | -| `w` | Jump to start of next word | | |
| 28 | -| `b` | Jump to start of previous word | | |
| 29 | -| `e` | Jump to end of current/next word | | |
| 30 | -| `0` | Jump to start of line | | |
| 31 | -| `$` | Jump to end of line | | |
| 32 | -| `gg` | Jump to first line of file | | |
| 33 | -| `G` | Jump to last line of file | | |
| 34 | -| `{number}G` | Jump to specific line number (e.g., `5G` for line 5) | | |
| 35 | - | |
| 36 | -### Scrolling and Larger Jumps | |
| 37 | -| Keybind | Action | | |
| 38 | -|---------------|-----------------------------------| | |
| 39 | -| `Ctrl+u` | Scroll up half a screen | | |
| 40 | -| `Ctrl+d` | Scroll down half a screen | | |
| 41 | -| `Ctrl+b` | Scroll up a full screen (backward)| | |
| 42 | -| `Ctrl+f` | Scroll down a full screen (forward)| | |
| 43 | -| `%` | Jump to matching bracket/parenthesis | | |
| 44 | - | |
| 45 | -### Search-Based Navigation | |
| 46 | -| Keybind | Action | | |
| 47 | -|---------------|-----------------------------------| | |
| 48 | -| `/` + `text` + `Enter` | Search forward for text; use `n` for next, `N` for previous | | |
| 49 | -| `?` + `text` + `Enter` | Search backward for text; use `n` for next, `N` for previous | | |
| 50 | -| `*` | Jump to next occurrence of word under cursor | | |
| 51 | -| `#` | Jump to previous occurrence of word under cursor | | |
| 52 | - | |
| 53 | -## Editing and Multi-Cursor Techniques | |
| 54 | - | |
| 55 | -Neovim lacks native multi-cursor support, but Visual Mode and other features provide powerful alternatives. These are mostly **Normal Mode** commands unless noted. | |
| 56 | - | |
| 57 | -### Basic Editing | |
| 58 | -| Keybind | Action | | |
| 59 | -|---------------|-----------------------------------| | |
| 60 | -| `i` | Enter Insert Mode before cursor | | |
| 61 | -| `a` | Enter Insert Mode after cursor | | |
| 62 | -| `o` | Open new line below, enter Insert Mode | | |
| 63 | -| `O` | Open new line above, enter Insert Mode | | |
| 64 | -| `x` | Delete character under cursor | | |
| 65 | -| `dd` | Delete current line | | |
| 66 | -| `yy` | Yank (copy) current line | | |
| 67 | -| `p` | Paste after cursor | | |
| 68 | -| `P` | Paste before cursor | | |
| 69 | - | |
| 70 | -### Visual Mode for Selections (Multi-Cursor Alternative) | |
| 71 | -| Keybind | Action | | |
| 72 | -|---------------|-----------------------------------| | |
| 73 | -| `v` | Start character-wise Visual Mode | | |
| 74 | -| `V` | Start line-wise Visual Mode | | |
| 75 | -| `Ctrl+v` | Start block-wise Visual Mode (for columnar edits) | | |
| 76 | -| After selection, `I` | Insert at start of each selected line/block (block mode) | | |
| 77 | -| After selection, `A` | Append at end of each selected line/block (block mode) | | |
| 78 | - | |
| 79 | -**Note:** For block edits, select with `Ctrl+v`, move with `j`/`k`, then use `I` or `A` to edit multiple lines at once. Press `Esc` to apply changes. | |
| 80 | - | |
| 81 | -### Repeating Commands for Efficient Edits | |
| 82 | -| Keybind | Action | | |
| 83 | -|---------------|-----------------------------------| | |
| 84 | -| `.` | Repeat the last command | | |
| 85 | -| `{number}{command}` | Repeat command a specific number of times (e.g., `5dd` deletes 5 lines) | | |
| 86 | - | |
| 87 | -## Plugin for True Multi-Cursor Support | |
| 88 | - | |
| 89 | -For a modern multi-cursor experience (like VS Code), install the `vim-visual-multi` plugin. | |
| 90 | - | |
| 91 | -| Plugin | Keybind | Action | | |
| 92 | -|---------------|---------------|-----------------------------------| | |
| 93 | -| `vim-visual-multi` | `Ctrl+n` | Start multi-cursor or add cursor at next word occurrence | | |
| 94 | -| `vim-visual-multi` | `Ctrl+p` | Add cursor at previous occurrence | | |
| 95 | -| `vim-visual-multi` | `Ctrl+x` | Skip an occurrence | | |
| 96 | - | |
| 97 | -**Installation:** Add via plugin manager, e.g., `Plug 'mg979/vim-visual-multi'` with vim-plug. | |
| 98 | - | |
| 99 | -## Quick Tips for Efficiency | |
| 100 | -- **Practice Normal Mode:** Use it for navigation to minimize mode-switching. | |
| 101 | -- **Leverage `.` for Repetition:** Repeat edits quickly with the dot operator. | |
| 102 | -- **Combine Commands:** Use motions with actions, e.g., `d2w` (delete 2 words) or `c$` (change to end of line). | |
| 103 | -- **Use `:help`:** Type `:help key-notation` or `:help motion` in Neovim for detailed docs. | |
| 104 | - | |
| 105 | -This tabulated guide focuses on default Neovim keybindings and practical workflows. For customizations or plugin setup help, let me know! | |
| 1 | +# Neovim Modern Workflow & Plugin Guide | |
| 2 | + | |
| 3 | +This guide extends the default Neovim keybinds with **modern workflows** (LSP, Telescope, Treesitter, Git, terminals) for Neovim ≥ 0.8. Designed for productivity on Wayland/Hyprland with lazy.nvim config. | |
| 4 | + | |
| 5 | +--- | |
| 6 | + | |
| 7 | +## Modes Overview | |
| 8 | + | |
| 9 | +| Mode | Description | Enter From | | |
| 10 | +|-----------------|-----------------------------------------------|-----------------------| | |
| 11 | +| **Normal** | Navigation, commands | `Esc` | | |
| 12 | +| **Insert** | Insert/typing | `i`, `a`, `o`, `O` | | |
| 13 | +| **Visual** | Select text (char, line, block) | `v`, `V`, `Ctrl+v` | | |
| 14 | +| **Command** | Ex commands (`:w`, `:q`) | `:` | | |
| 15 | +| **Terminal** | Interactive terminal buffer | `:term`, `<C-`>` | | |
| 16 | + | |
| 17 | +--- | |
| 18 | + | |
| 19 | +## Navigation Keybindings (Default) | |
| 20 | + | |
| 21 | +| Keybind | Action | | |
| 22 | +|------------|--------------------------------------| | |
| 23 | +| `h`/`l` | Left / right one character | | |
| 24 | +| `j`/`k` | Down / up one line | | |
| 25 | +| `w`/`e`/`b`| Next word / end word / back a word | | |
| 26 | +| `0` / `$` | Start / end of line | | |
| 27 | +| `gg` / `G` | First / last line of file | | |
| 28 | +| `{n}G` | Jump to line n | | |
| 29 | +| `Ctrl+u/d` | Scroll half screen up/down | | |
| 30 | +| `Ctrl+b/f` | Scroll full screen up/down | | |
| 31 | +| `%` | Match brackets/parentheses | | |
| 32 | +| `/text` | Search forward (n/N = next/prev) | | |
| 33 | +| `?text` | Search backward (n/N = next/prev) | | |
| 34 | +| `*` / `#` | Next/prev word under cursor | | |
| 35 | + | |
| 36 | +--- | |
| 37 | + | |
| 38 | +## Editing Essentials | |
| 39 | + | |
| 40 | +| Keybind | Action | | |
| 41 | +|---------|------------------------------------------| | |
| 42 | +| `i`/`a` | Insert before / after cursor | | |
| 43 | +| `o`/`O` | New line below / above | | |
| 44 | +| `x` | Delete character | | |
| 45 | +| `dd` | Delete line | | |
| 46 | +| `yy` | Yank (copy) line | | |
| 47 | +| `p`/`P` | Paste after / before cursor | | |
| 48 | +| `.` | Repeat last command | | |
| 49 | +| `{n}{op}` | Repeat operation n times (`5dd`) | | |
| 50 | + | |
| 51 | +### Visual Mode Tricks | |
| 52 | +- `v`/`V`/`Ctrl+v` → char/line/block selections | |
| 53 | +- Block mode (`Ctrl+v` + `j/k`): | |
| 54 | + - `I` insert before selection (applies to all lines) | |
| 55 | + - `A` append after selection | |
| 56 | + | |
| 57 | +--- | |
| 58 | + | |
| 59 | +## Custom Workflow Keymaps (from lazy config) | |
| 60 | + | |
| 61 | +| Keybind | Action | | |
| 62 | +|-------------|-------------------------------------| | |
| 63 | +| `<C-s>` | Save (normal/insert/visual) | | |
| 64 | +| `<leader>q` | Quit | | |
| 65 | +| `<leader>sv`| Vertical split | | |
| 66 | +| `<leader>sh`| Horizontal split | | |
| 67 | +| `<leader>to`| New tab | | |
| 68 | +| `<leader>ff`| Telescope: find files | | |
| 69 | +| `<leader>fg`| Telescope: live grep | | |
| 70 | +| `<leader>fb`| Telescope: buffers | | |
| 71 | +| `<leader>fh`| Telescope: help tags | | |
| 72 | +| `-` | Oil file manager float | | |
| 73 | +| `<C-`>` | Toggle floating terminal | | |
| 74 | +| `<leader>tr`| Run task (Overseer) | | |
| 75 | +| `<leader>tt`| Task list toggle | | |
| 76 | +| `<leader>f` | Format buffer/file (Conform) | | |
| 77 | + | |
| 78 | +--- | |
| 79 | + | |
| 80 | +## LSP Workflow (Language Server Protocol) | |
| 81 | + | |
| 82 | +Requires `mason.nvim` + `nvim-lspconfig`. | |
| 83 | + | |
| 84 | +| Keybind | Action | | |
| 85 | +|-------------|--------------------------------------| | |
| 86 | +| `gd` | Goto definition | | |
| 87 | +| `gD` | Goto declaration | | |
| 88 | +| `gi` | Goto implementation | | |
| 89 | +| `gr` | List references | | |
| 90 | +| `K` | Hover docs | | |
| 91 | +| `<leader>rn`| Rename symbol | | |
| 92 | +| `<leader>ca`| Code action | | |
| 93 | +| `<leader>fd`| Format buffer (LSP/formatter) | | |
| 94 | + | |
| 95 | +--- | |
| 96 | + | |
| 97 | +## Git Integration | |
| 98 | + | |
| 99 | +- **Gitsigns.nvim** | |
| 100 | + - Shows inline git diff signs, hunk navigation (`]c` / `[c`), staging hunks (`:Gitsigns stage_hunk`). | |
| 101 | + | |
| 102 | +- **LazyGit.nvim** | |
| 103 | + - `:LazyGit` launches interactive TUI for Git inside Neovim. | |
| 104 | + | |
| 105 | +--- | |
| 106 | + | |
| 107 | +## Telescope (Fuzzy Finder) | |
| 108 | + | |
| 109 | +- `<leader>ff` → Files | |
| 110 | +- `<leader>fg` → Live grep | |
| 111 | +- `<leader>fb` → Buffers | |
| 112 | +- `<leader>fh` → Help tags | |
| 113 | + | |
| 114 | +Extra: type `/` inside Telescope for fuzzy-in-list filtering. | |
| 115 | + | |
| 116 | +--- | |
| 117 | + | |
| 118 | +## Treesitter (Syntax Engine) | |
| 119 | + | |
| 120 | +- Auto-installs parsers for `bash`, `c/cpp`, `lua`, `python`, `rust`, `json`, `yaml`, `toml`, `html/css/js/ts`, `markdown`, `fish`, **fortran**. | |
| 121 | +- Provides better highlighting + indenting. | |
| 122 | + | |
| 123 | +--- | |
| 124 | + | |
| 125 | +## Formatting (Conform.nvim) | |
| 126 | + | |
| 127 | +| Language | Formatter(s) | | |
| 128 | +|--------------|--------------------------------------| | |
| 129 | +| Lua | stylua | | |
| 130 | +| Python | ruff_format, black | | |
| 131 | +| Shell/Fish | shfmt, fish_indent | | |
| 132 | +| C/C++ | clang-format | | |
| 133 | +| JS/TS/HTML | prettier | | |
| 134 | +| JSON/YAML | jq / prettier | | |
| 135 | +| TOML | taplo | | |
| 136 | +| Markdown | prettier | | |
| 137 | +| Fortran | fprettify | | |
| 138 | + | |
| 139 | +--- | |
| 140 | + | |
| 141 | +## Debugging (nvim-dap + dap-ui) | |
| 142 | + | |
| 143 | +- `:DapToggleBreakpoint` → set/clear breakpoint | |
| 144 | +- `:DapContinue` → run/start | |
| 145 | +- `:DapStepOver` / `:DapStepInto` / `:DapStepOut` | |
| 146 | +- DAP UI auto-opens on session start. | |
| 147 | + | |
| 148 | +--- | |
| 149 | + | |
| 150 | +## Bonus: Multi-Cursor | |
| 151 | + | |
| 152 | +- Native block selections: `Ctrl+v` + `I`/`A` | |
| 153 | +- True multi-cursor: install **vim-visual-multi** | |
| 154 | + - `Ctrl+n` → add cursor to next occurrence | |
| 155 | + - `Ctrl+p` → add cursor to prev | |
| 156 | + - `Ctrl+x` → skip | |
| 157 | + | |
| 158 | +--- | |
| 159 | + | |
| 160 | +## Quick Efficiency Tips | |
| 161 | +- Use `.` to repeat edits, `:noh` to clear highlights | |
| 162 | +- Combine motions: `d2w` (delete 2 words), `c$` (change to end of line) | |
| 163 | +- Use **Overseer** for project build/run/test integration | |
| 164 | +- Map `-` (Oil) for directory browsing like a mini file manager | |
| 165 | +- Use `<C-`>` as a popup shell without leaving Neovim | |
| 166 | +- Keep `<leader>` easy (`<Space>` in this config) for speed | |
| 167 | + | |
| 168 | +--- | |
nvim/init.luaadded@@ -0,0 +1,267 @@ | ||
| 1 | +-- smooth editing, LSP, Treesitter, Telescope, formatting, Git, terminals, and a few QoL boosts. | |
| 2 | + | |
| 3 | +--------------------------------------------------------------- | |
| 4 | +-- 0) Bootstrap lazy.nvim (plugin manager) | |
| 5 | +--------------------------------------------------------------- | |
| 6 | +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" | |
| 7 | +if not vim.loop.fs_stat(lazypath) then | |
| 8 | + vim.fn.system({ | |
| 9 | + "git", "clone", "--filter=blob:none", | |
| 10 | + "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath, | |
| 11 | + }) | |
| 12 | +end | |
| 13 | +vim.opt.rtp:prepend(lazypath) | |
| 14 | + | |
| 15 | +--------------------------------------------------------------- | |
| 16 | +-- 1) Core settings (Wayland-safe clipboard, sensible defaults) | |
| 17 | +--------------------------------------------------------------- | |
| 18 | +vim.g.mapleader = " " | |
| 19 | +vim.g.maplocalleader = "," | |
| 20 | + | |
| 21 | +local opt = vim.opt | |
| 22 | +opt.number = true | |
| 23 | +opt.relativenumber = true | |
| 24 | +opt.signcolumn = "yes" | |
| 25 | +opt.termguicolors = true | |
| 26 | +opt.cursorline = true | |
| 27 | +opt.wrap = false | |
| 28 | +opt.scrolloff = 5 | |
| 29 | +opt.sidescrolloff = 8 | |
| 30 | +opt.expandtab = true | |
| 31 | +opt.shiftwidth = 2 | |
| 32 | +opt.tabstop = 2 | |
| 33 | +opt.smartindent = true | |
| 34 | +opt.ignorecase = true | |
| 35 | +opt.smartcase = true | |
| 36 | +opt.incsearch = true | |
| 37 | +opt.splitbelow = true | |
| 38 | +opt.splitright = true | |
| 39 | +opt.updatetime = 300 | |
| 40 | +opt.timeoutlen = 400 | |
| 41 | +opt.undofile = true | |
| 42 | +opt.clipboard = "unnamedplus" -- uses wl-clipboard on Wayland if installed | |
| 43 | + | |
| 44 | +--------------------------------------------------------------- | |
| 45 | +-- 2) Plugins via lazy.nvim | |
| 46 | +--------------------------------------------------------------- | |
| 47 | +require("lazy").setup({ | |
| 48 | + -- UI + UX --------------------------------------------------- | |
| 49 | + { "folke/tokyonight.nvim", lazy = false, priority = 1000, opts = { style = "night" } }, | |
| 50 | + { "nvim-lualine/lualine.nvim", dependencies = { "nvim-tree/nvim-web-devicons" }, | |
| 51 | + opts = { options = { theme = "auto", globalstatus = true } } }, | |
| 52 | + { "folke/which-key.nvim", event = "VeryLazy", opts = {} }, | |
| 53 | + { "stevearc/dressing.nvim", event = "VeryLazy", opts = {} }, | |
| 54 | + { "rcarriga/nvim-notify", opts = { timeout = 2000 } }, | |
| 55 | + { "folke/noice.nvim", event = "VeryLazy", dependencies = { "MunifTanjim/nui.nvim", "rcarriga/nvim-notify" }, | |
| 56 | + opts = { presets = { command_palette = true, long_message_to_split = true } } }, | |
| 57 | + { "lukas-reineke/indent-blankline.nvim", main = "ibl", opts = {} }, | |
| 58 | + { "numToStr/Comment.nvim", opts = {} }, | |
| 59 | + { "kylechui/nvim-surround", event = "VeryLazy", opts = {} }, | |
| 60 | + | |
| 61 | + -- Files, search, projects ---------------------------------- | |
| 62 | + { "nvim-telescope/telescope.nvim", dependencies = { "nvim-lua/plenary.nvim" } }, | |
| 63 | + { "nvim-telescope/telescope-fzf-native.nvim", build = "make", cond = function() return vim.fn.executable("make") == 1 end }, | |
| 64 | + { "ahmedkhalf/project.nvim", opts = { detection_methods = { "pattern", "lsp" }, patterns = { ".git", "pyproject.toml", "package.json", "Makefile" } } }, | |
| 65 | + { "stevearc/oil.nvim", opts = { view_options = { show_hidden = true } } }, | |
| 66 | + | |
| 67 | + -- Git ------------------------------------------------------- | |
| 68 | + { "lewis6991/gitsigns.nvim", opts = {} }, | |
| 69 | + { "kdheepak/lazygit.nvim", cmd = { "LazyGit" } }, | |
| 70 | + | |
| 71 | + -- Terminal & task runner ----------------------------------- | |
| 72 | + { "akinsho/toggleterm.nvim", version = "*", opts = { open_mapping = [[<C-`>]], direction = "float" } }, | |
| 73 | + { "stevearc/overseer.nvim", opts = {} }, | |
| 74 | + | |
| 75 | + -- Treesitter ------------------------------------------------ | |
| 76 | + { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate", opts = { | |
| 77 | + ensure_installed = { | |
| 78 | + "bash", "c", "cpp", "lua", "python", "rust", "json", "yaml", "toml", | |
| 79 | + "html", "css", "javascript", "typescript", "markdown", "markdown_inline", | |
| 80 | + "make", "fish", "fortran" | |
| 81 | + }, | |
| 82 | + highlight = { enable = true }, | |
| 83 | + indent = { enable = true }, | |
| 84 | + } | |
| 85 | + }, | |
| 86 | + | |
| 87 | + -- LSP, format, lint ---------------------------------------- | |
| 88 | + { "williamboman/mason.nvim", opts = { ui = { border = "rounded" } } }, | |
| 89 | + { "williamboman/mason-lspconfig.nvim" }, | |
| 90 | + { "neovim/nvim-lspconfig" }, | |
| 91 | + { "stevearc/conform.nvim", opts = { | |
| 92 | + notify_on_error = false, | |
| 93 | + format_on_save = function(buf) | |
| 94 | + -- Disable on big files | |
| 95 | + local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(buf)) | |
| 96 | + if ok and stats and stats.size > 512 * 1024 then return end | |
| 97 | + return { timeout_ms = 2000, lsp_fallback = true } | |
| 98 | + end, | |
| 99 | + formatters_by_ft = { | |
| 100 | + lua = { "stylua" }, | |
| 101 | + python = { "ruff_format", "black" }, | |
| 102 | + sh = { "shfmt" }, bash = { "shfmt" }, zsh = { "shfmt" }, fish = { "fish_indent" }, | |
| 103 | + c = { "clang_format" }, cpp = { "clang_format" }, | |
| 104 | + javascript = { "prettier" }, typescript = { "prettier" }, | |
| 105 | + json = { "jq", "prettier" }, yaml = { "prettier" }, toml = { "taplo" }, | |
| 106 | + html = { "prettier" }, css = { "prettier" }, markdown = { "prettier" }, | |
| 107 | + fortran = { "fprettify" }, | |
| 108 | + }, | |
| 109 | + } | |
| 110 | + }, | |
| 111 | + | |
| 112 | + -- Debugging (optional, light defaults) --------------------- | |
| 113 | + { "mfussenegger/nvim-dap" }, | |
| 114 | + { "rcarriga/nvim-dap-ui", dependencies = { "mfussenegger/nvim-dap" } }, | |
| 115 | +}, { | |
| 116 | + install = { colorscheme = { "tokyonight" } }, | |
| 117 | + change_detection = { notify = false }, | |
| 118 | +}) | |
| 119 | + | |
| 120 | +--------------------------------------------------------------- | |
| 121 | +-- 3) Post-plugin config (LSP, Telescope, keymaps, etc.) | |
| 122 | +--------------------------------------------------------------- | |
| 123 | +-- Colorscheme | |
| 124 | +vim.cmd.colorscheme("tokyonight") | |
| 125 | + | |
| 126 | +-- Lualine | |
| 127 | +require("lualine").setup({}) | |
| 128 | + | |
| 129 | +-- Telescope | |
| 130 | +local telescope = require("telescope") | |
| 131 | +telescope.setup({ defaults = { mappings = { i = { ["<C-j>"] = "move_selection_next", ["<C-k>"] = "move_selection_previous" } } } }) | |
| 132 | +pcall(telescope.load_extension, "fzf") | |
| 133 | + | |
| 134 | +-- Oil: simple file manager toggle | |
| 135 | +vim.keymap.set("n", "-", function() require("oil").toggle_float() end, { desc = "Oil file manager" }) | |
| 136 | + | |
| 137 | +-- ToggleTerm: float terminal with <C-`> | |
| 138 | +-- (Already mapped via opts. Add extra terminals if desired.) | |
| 139 | + | |
| 140 | +-- Overseer: tasks (build, run, test) | |
| 141 | +vim.keymap.set("n", "<leader>tt", ":OverseerToggle<CR>", { desc = "Toggle task list" }) | |
| 142 | +vim.keymap.set("n", "<leader>tr", ":OverseerRun<CR>", { desc = "Run a task" }) | |
| 143 | + | |
| 144 | +-- Gitsigns | |
| 145 | +require("gitsigns").setup() | |
| 146 | + | |
| 147 | +-- Treesitter | |
| 148 | +require("nvim-treesitter.configs").setup({}) | |
| 149 | + | |
| 150 | +-- Mason + LSPConfig | |
| 151 | +require("mason").setup() | |
| 152 | +local mlsp = require("mason-lspconfig") | |
| 153 | +mlsp.setup({ ensure_installed = { | |
| 154 | + "pyright", "ruff_lsp", "lua_ls", "clangd", "rust_analyzer", "bashls", | |
| 155 | + "jsonls", "yamlls", "html", "cssls", "ts_ls", "marksman", "taplo", "fortls" | |
| 156 | +}}) | |
| 157 | + | |
| 158 | +local lspconfig = require("lspconfig") | |
| 159 | +local capabilities = vim.lsp.protocol.make_client_capabilities() | |
| 160 | +local ok_cmp, cmp_lsp = pcall(require, "cmp_nvim_lsp") | |
| 161 | +if ok_cmp then capabilities = cmp_lsp.default_capabilities(capabilities) end | |
| 162 | + | |
| 163 | +-- Pretty borders | |
| 164 | +local handlers = { | |
| 165 | + ["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = "rounded" }), | |
| 166 | + ["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = "rounded" }), | |
| 167 | +} | |
| 168 | + | |
| 169 | +-- on_attach: buffer-local mappings | |
| 170 | +local on_attach = function(_, bufnr) | |
| 171 | + local nmap = function(keys, func, desc) | |
| 172 | + vim.keymap.set("n", keys, func, { buffer = bufnr, desc = desc }) | |
| 173 | + end | |
| 174 | + nmap("gd", vim.lsp.buf.definition, "Goto Definition") | |
| 175 | + nmap("gr", vim.lsp.buf.references, "References") | |
| 176 | + nmap("gD", vim.lsp.buf.declaration, "Goto Declaration") | |
| 177 | + nmap("gi", vim.lsp.buf.implementation, "Goto Implementation") | |
| 178 | + nmap("K", vim.lsp.buf.hover, "Hover") | |
| 179 | + nmap("<leader>rn", vim.lsp.buf.rename, "Rename symbol") | |
| 180 | + nmap("<leader>ca", vim.lsp.buf.code_action, "Code Action") | |
| 181 | + nmap("<leader>fd", function() vim.lsp.buf.format({ async = true }) end, "Format buffer") | |
| 182 | +end | |
| 183 | + | |
| 184 | +mlsp.setup_handlers({ function(server) | |
| 185 | + lspconfig[server].setup({ capabilities = capabilities, on_attach = on_attach, handlers = handlers }) | |
| 186 | +end }) | |
| 187 | + | |
| 188 | +-- Lua LS: tuned for Neovim config dev | |
| 189 | +lspconfig.lua_ls.setup({ | |
| 190 | + capabilities = capabilities, | |
| 191 | + on_attach = on_attach, | |
| 192 | + settings = { Lua = { diagnostics = { globals = { "vim" } }, workspace = { checkThirdParty = false } } } | |
| 193 | +}) | |
| 194 | + | |
| 195 | +-- Ruff: prefer as linter + fixer with Pyright for types | |
| 196 | +lspconfig.ruff_lsp.setup({ capabilities = capabilities, on_attach = on_attach }) | |
| 197 | + | |
| 198 | +-- DAP minimal sugar | |
| 199 | +local dap_ok, dapui = pcall(require, "dapui") | |
| 200 | +if dap_ok then | |
| 201 | + dapui.setup() | |
| 202 | + local dap = require("dap") | |
| 203 | + dap.listeners.after.event_initialized["dapui_config"] = function() dapui.open() end | |
| 204 | + dap.listeners.before.event_terminated["dapui_config"] = function() dapui.close() end | |
| 205 | + dap.listeners.before.event_exited["dapui_config"] = function() dapui.close() end | |
| 206 | +end | |
| 207 | + | |
| 208 | +--------------------------------------------------------------- | |
| 209 | +-- 4) Keymaps you’ll actually use (and remember) | |
| 210 | +--------------------------------------------------------------- | |
| 211 | +local map = vim.keymap.set | |
| 212 | +-- Save, quit | |
| 213 | +map({"n","i","v"}, "<C-s>", function() vim.cmd("silent w") end, { desc = "Save" }) | |
| 214 | +map("n", "<leader>q", ":q<CR>", { desc = "Quit" }) | |
| 215 | + | |
| 216 | +-- Windows and tabs | |
| 217 | +map("n", "<leader>sv", ":vsplit<CR>", { desc = "Split vertical" }) | |
| 218 | +map("n", "<leader>sh", ":split<CR>", { desc = "Split horizontal" }) | |
| 219 | +map("n", "<leader>to", ":tabnew<CR>", { desc = "New tab" }) | |
| 220 | + | |
| 221 | +-- Telescope | |
| 222 | +map("n", "<leader>ff", function() require("telescope.builtin").find_files() end, { desc = "Find files" }) | |
| 223 | +map("n", "<leader>fg", function() require("telescope.builtin").live_grep() end, { desc = "Live grep" }) | |
| 224 | +map("n", "<leader>fb", function() require("telescope.builtin").buffers() end, { desc = "Buffers" }) | |
| 225 | +map("n", "<leader>fh", function() require("telescope.builtin").help_tags() end, { desc = "Help tags" }) | |
| 226 | + | |
| 227 | +-- Move lines (visual) | |
| 228 | +map("v", "J", ":m '>+1<CR>gv=gv") | |
| 229 | +map("v", "K", ":m '<-2<CR>gv=gv") | |
| 230 | + | |
| 231 | +-- Clear search | |
| 232 | +map("n", "<Esc>", ":noh<CR>", { silent = true }) | |
| 233 | + | |
| 234 | +-- Format | |
| 235 | +map("n", "<leader>f", function() require("conform").format({ lsp_fallback = true }) end, { desc = "Format file" }) | |
| 236 | + | |
| 237 | +--------------------------------------------------------------- | |
| 238 | +-- 5) Small QoL autocommands | |
| 239 | +--------------------------------------------------------------- | |
| 240 | +-- Restore cursor to last position | |
| 241 | +vim.api.nvim_create_autocmd("BufReadPost", { | |
| 242 | + callback = function() | |
| 243 | + local mark = vim.api.nvim_buf_get_mark(0, '"') | |
| 244 | + local lcount = vim.api.nvim_buf_line_count(0) | |
| 245 | + if mark[1] > 0 and mark[1] <= lcount then | |
| 246 | + pcall(vim.api.nvim_win_set_cursor, 0, mark) | |
| 247 | + end | |
| 248 | + end | |
| 249 | +}) | |
| 250 | + | |
| 251 | +-- Highlight on yank | |
| 252 | +vim.api.nvim_create_autocmd("TextYankPost", { | |
| 253 | + callback = function() vim.highlight.on_yank({ higroup = "IncSearch", timeout = 120 }) end | |
| 254 | +}) | |
| 255 | + | |
| 256 | +-- Wayland clipboard fix hint (if clipboard missing) | |
| 257 | +if vim.env.WAYLAND_DISPLAY and vim.o.clipboard ~= "unnamedplus" then | |
| 258 | + vim.notify("Tip: install 'wl-clipboard' and set clipboard=unnamedplus for system clipboard.", vim.log.levels.INFO) | |
| 259 | +end | |
| 260 | + | |
| 261 | +--------------------------------------------------------------- | |
| 262 | +-- 6) Add language tools via Mason: :Mason | |
| 263 | +-- Choose servers/formatters: pyright, ruff, lua_ls, clangd, rust_analyzer, bashls, | |
| 264 | +-- jsonls, yamlls, html, cssls, tsserver/ts_ls, marksman, taplo, fortls, etc. | |
| 265 | +-- Then enjoy: <leader>ff (files), <leader>fg (grep), <C-`> (terminal), - (Oil), | |
| 266 | +-- <leader>f (format), gd/gr/K, and :OverseerRun for project tasks. | |
| 267 | +--------------------------------------------------------------- | |