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 | 1 | +# Neovim Modern Workflow & Plugin Guide |
| 2 | - | 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. | 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 | - | 4 | + |
| 5 | -## Neovim Modes Overview | 5 | +--- |
| 6 | - | 6 | + |
| 7 | -Neovim operates in distinct modes, each serving specific purposes. Understanding these is essential for effective editing. | 7 | +## Modes Overview |
| 8 | - | 8 | + |
| 9 | -| Mode | Description | How to Enter | | 9 | +| Mode | Description | Enter From | |
| 10 | -|-----------------|--------------------------------------------------|----------------------------------| | 10 | +|-----------------|-----------------------------------------------|-----------------------| |
| 11 | -| **Normal Mode** | Default mode for navigation and commands | Press `Esc` from other modes | | 11 | +| **Normal** | Navigation, commands | `Esc` | |
| 12 | -| **Insert Mode** | For typing and inserting text | Press `i`, `a`, `o`, etc. from Normal Mode | | 12 | +| **Insert** | Insert/typing | `i`, `a`, `o`, `O` | |
| 13 | -| **Visual Mode** | For selecting text (line, block, or character) | Press `v`, `V`, or `Ctrl+v` from Normal Mode | | 13 | +| **Visual** | Select text (char, line, block) | `v`, `V`, `Ctrl+v` | |
| 14 | -| **Command Mode**| For entering Ex commands (e.g., saving, quitting)| Press `:` from Normal Mode | | 14 | +| **Command** | Ex commands (`:w`, `:q`) | `:` | |
| 15 | - | 15 | +| **Terminal** | Interactive terminal buffer | `:term`, `<C-`>` | |
| 16 | -## Navigation Keybindings | 16 | + |
| 17 | - | 17 | +--- |
| 18 | -These keybindings are primarily for **Normal Mode** and help you move around your editor efficiently. | 18 | + |
| 19 | - | 19 | +## Navigation Keybindings (Default) |
| 20 | -### Basic Movement | 20 | + |
| 21 | -| Keybind | Action | | 21 | +| Keybind | Action | |
| 22 | -|---------------|-----------------------------------| | 22 | +|------------|--------------------------------------| |
| 23 | -| `h` | Move left one character | | 23 | +| `h`/`l` | Left / right one character | |
| 24 | -| `j` | Move down one line | | 24 | +| `j`/`k` | Down / up one line | |
| 25 | -| `k` | Move up one line | | 25 | +| `w`/`e`/`b`| Next word / end word / back a word | |
| 26 | -| `l` | Move right one character | | 26 | +| `0` / `$` | Start / end of line | |
| 27 | -| `w` | Jump to start of next word | | 27 | +| `gg` / `G` | First / last line of file | |
| 28 | -| `b` | Jump to start of previous word | | 28 | +| `{n}G` | Jump to line n | |
| 29 | -| `e` | Jump to end of current/next word | | 29 | +| `Ctrl+u/d` | Scroll half screen up/down | |
| 30 | -| `0` | Jump to start of line | | 30 | +| `Ctrl+b/f` | Scroll full screen up/down | |
| 31 | -| `$` | Jump to end of line | | 31 | +| `%` | Match brackets/parentheses | |
| 32 | -| `gg` | Jump to first line of file | | 32 | +| `/text` | Search forward (n/N = next/prev) | |
| 33 | -| `G` | Jump to last line of file | | 33 | +| `?text` | Search backward (n/N = next/prev) | |
| 34 | -| `{number}G` | Jump to specific line number (e.g., `5G` for line 5) | | 34 | +| `*` / `#` | Next/prev word under cursor | |
| 35 | - | 35 | + |
| 36 | -### Scrolling and Larger Jumps | 36 | +--- |
| 37 | -| Keybind | Action | | 37 | + |
| 38 | -|---------------|-----------------------------------| | 38 | +## Editing Essentials |
| 39 | -| `Ctrl+u` | Scroll up half a screen | | 39 | + |
| 40 | -| `Ctrl+d` | Scroll down half a screen | | 40 | +| Keybind | Action | |
| 41 | -| `Ctrl+b` | Scroll up a full screen (backward)| | 41 | +|---------|------------------------------------------| |
| 42 | -| `Ctrl+f` | Scroll down a full screen (forward)| | 42 | +| `i`/`a` | Insert before / after cursor | |
| 43 | -| `%` | Jump to matching bracket/parenthesis | | 43 | +| `o`/`O` | New line below / above | |
| 44 | - | 44 | +| `x` | Delete character | |
| 45 | -### Search-Based Navigation | 45 | +| `dd` | Delete line | |
| 46 | -| Keybind | Action | | 46 | +| `yy` | Yank (copy) line | |
| 47 | -|---------------|-----------------------------------| | 47 | +| `p`/`P` | Paste after / before cursor | |
| 48 | -| `/` + `text` + `Enter` | Search forward for text; use `n` for next, `N` for previous | | 48 | +| `.` | Repeat last command | |
| 49 | -| `?` + `text` + `Enter` | Search backward for text; use `n` for next, `N` for previous | | 49 | +| `{n}{op}` | Repeat operation n times (`5dd`) | |
| 50 | -| `*` | Jump to next occurrence of word under cursor | | 50 | + |
| 51 | -| `#` | Jump to previous occurrence of word under cursor | | 51 | +### Visual Mode Tricks |
| 52 | - | 52 | +- `v`/`V`/`Ctrl+v` → char/line/block selections |
| 53 | -## Editing and Multi-Cursor Techniques | 53 | +- Block mode (`Ctrl+v` + `j/k`): |
| 54 | - | 54 | + - `I` insert before selection (applies to all lines) |
| 55 | -Neovim lacks native multi-cursor support, but Visual Mode and other features provide powerful alternatives. These are mostly **Normal Mode** commands unless noted. | 55 | + - `A` append after selection |
| 56 | - | 56 | + |
| 57 | -### Basic Editing | 57 | +--- |
| 58 | -| Keybind | Action | | 58 | + |
| 59 | -|---------------|-----------------------------------| | 59 | +## Custom Workflow Keymaps (from lazy config) |
| 60 | -| `i` | Enter Insert Mode before cursor | | 60 | + |
| 61 | -| `a` | Enter Insert Mode after cursor | | 61 | +| Keybind | Action | |
| 62 | -| `o` | Open new line below, enter Insert Mode | | 62 | +|-------------|-------------------------------------| |
| 63 | -| `O` | Open new line above, enter Insert Mode | | 63 | +| `<C-s>` | Save (normal/insert/visual) | |
| 64 | -| `x` | Delete character under cursor | | 64 | +| `<leader>q` | Quit | |
| 65 | -| `dd` | Delete current line | | 65 | +| `<leader>sv`| Vertical split | |
| 66 | -| `yy` | Yank (copy) current line | | 66 | +| `<leader>sh`| Horizontal split | |
| 67 | -| `p` | Paste after cursor | | 67 | +| `<leader>to`| New tab | |
| 68 | -| `P` | Paste before cursor | | 68 | +| `<leader>ff`| Telescope: find files | |
| 69 | - | 69 | +| `<leader>fg`| Telescope: live grep | |
| 70 | -### Visual Mode for Selections (Multi-Cursor Alternative) | 70 | +| `<leader>fb`| Telescope: buffers | |
| 71 | -| Keybind | Action | | 71 | +| `<leader>fh`| Telescope: help tags | |
| 72 | -|---------------|-----------------------------------| | 72 | +| `-` | Oil file manager float | |
| 73 | -| `v` | Start character-wise Visual Mode | | 73 | +| `<C-`>` | Toggle floating terminal | |
| 74 | -| `V` | Start line-wise Visual Mode | | 74 | +| `<leader>tr`| Run task (Overseer) | |
| 75 | -| `Ctrl+v` | Start block-wise Visual Mode (for columnar edits) | | 75 | +| `<leader>tt`| Task list toggle | |
| 76 | -| After selection, `I` | Insert at start of each selected line/block (block mode) | | 76 | +| `<leader>f` | Format buffer/file (Conform) | |
| 77 | -| After selection, `A` | Append at end of each selected line/block (block mode) | | 77 | + |
| 78 | - | 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. | 79 | + |
| 80 | - | 80 | +## LSP Workflow (Language Server Protocol) |
| 81 | -### Repeating Commands for Efficient Edits | 81 | + |
| 82 | -| Keybind | Action | | 82 | +Requires `mason.nvim` + `nvim-lspconfig`. |
| 83 | -|---------------|-----------------------------------| | 83 | + |
| 84 | -| `.` | Repeat the last command | | 84 | +| Keybind | Action | |
| 85 | -| `{number}{command}` | Repeat command a specific number of times (e.g., `5dd` deletes 5 lines) | | 85 | +|-------------|--------------------------------------| |
| 86 | - | 86 | +| `gd` | Goto definition | |
| 87 | -## Plugin for True Multi-Cursor Support | 87 | +| `gD` | Goto declaration | |
| 88 | - | 88 | +| `gi` | Goto implementation | |
| 89 | -For a modern multi-cursor experience (like VS Code), install the `vim-visual-multi` plugin. | 89 | +| `gr` | List references | |
| 90 | - | 90 | +| `K` | Hover docs | |
| 91 | -| Plugin | Keybind | Action | | 91 | +| `<leader>rn`| Rename symbol | |
| 92 | -|---------------|---------------|-----------------------------------| | 92 | +| `<leader>ca`| Code action | |
| 93 | -| `vim-visual-multi` | `Ctrl+n` | Start multi-cursor or add cursor at next word occurrence | | 93 | +| `<leader>fd`| Format buffer (LSP/formatter) | |
| 94 | -| `vim-visual-multi` | `Ctrl+p` | Add cursor at previous occurrence | | 94 | + |
| 95 | -| `vim-visual-multi` | `Ctrl+x` | Skip an occurrence | | 95 | +--- |
| 96 | - | 96 | + |
| 97 | -**Installation:** Add via plugin manager, e.g., `Plug 'mg979/vim-visual-multi'` with vim-plug. | 97 | +## Git Integration |
| 98 | - | 98 | + |
| 99 | -## Quick Tips for Efficiency | 99 | +- **Gitsigns.nvim** |
| 100 | -- **Practice Normal Mode:** Use it for navigation to minimize mode-switching. | 100 | + - Shows inline git diff signs, hunk navigation (`]c` / `[c`), staging hunks (`:Gitsigns stage_hunk`). |
| 101 | -- **Leverage `.` for Repetition:** Repeat edits quickly with the dot operator. | 101 | + |
| 102 | -- **Combine Commands:** Use motions with actions, e.g., `d2w` (delete 2 words) or `c$` (change to end of line). | 102 | +- **LazyGit.nvim** |
| 103 | -- **Use `:help`:** Type `:help key-notation` or `:help motion` in Neovim for detailed docs. | 103 | + - `:LazyGit` launches interactive TUI for Git inside Neovim. |
| 104 | - | 104 | + |
| 105 | -This tabulated guide focuses on default Neovim keybindings and practical workflows. For customizations or plugin setup help, let me know! | 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 | +--------------------------------------------------------------- | ||