Claude updates
This commit is contained in:
parent
831cd284aa
commit
47fcf0bef5
|
|
@ -0,0 +1,42 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## What this repo is
|
||||||
|
|
||||||
|
A personal Neovim config forked from [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim). Loaded by Neovim from `~/.config/nvim`. There is no build/test step — changes take effect by restarting `nvim` (or `:source %` / `:Lazy reload <plugin>` for some edits).
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- `init.lua` — entrypoint. Sets options, global keymaps, autocmds, bootstraps `lazy.nvim`, then loads every file under `lua/custom/plugins/` via `{ import = 'custom.plugins' }`. The kickstart single-file model has been broken out: only base options/keymaps live here; plugin specs live in their own files.
|
||||||
|
- `lua/custom/plugins/*.lua` — one file per plugin (or tightly related group). Each returns a lazy.nvim spec table (or list of specs). Adding a new plugin = create a new file here; it is picked up automatically. No central manifest to update.
|
||||||
|
- `lua/custom/zed-keymaps.lua` — mirrors Zed bindings (alt-j/k line move, F2 rename, `<leader>.` code action, `gb` blame, `<leader>x` close buffer, task spawners). Required directly from `init.lua` before lazy setup. Task spawner prefers a floating zellij pane (`$ZELLIJ` set) and falls back to an `nvim` split terminal.
|
||||||
|
- `lua/custom/health.lua` — backs `:checkhealth kickstart`.
|
||||||
|
- `lazy-lock.json` — committed; pin plugin versions. Update via `:Lazy update` then commit.
|
||||||
|
- `lua/kickstart/` does **not** exist in this fork (upstream kickstart had it). Don't add files there; everything custom lives under `lua/custom/`.
|
||||||
|
|
||||||
|
### Key conventions baked into the config
|
||||||
|
|
||||||
|
- **Leader = Space** (both `mapleader` and `maplocalleader`).
|
||||||
|
- **Window navigation** (`<C-h/j/k/l>`) is owned by `smart-splits.nvim` (`lua/custom/plugins/tmux.lua`) with `multiplexer_integration = 'zellij'` — at a split edge it forwards focus to the zellij pane. Don't re-bind these in `init.lua`.
|
||||||
|
- **LSP** is wired in `lua/custom/plugins/lsp.lua`. Servers configured: `clangd`, `gopls`, `pyright` (organize-imports disabled, lint suppressed — `ruff` handles both), `ruff` (hover disabled — `pyright` handles), `lua_ls`. Mason auto-installs them plus `stylua`, `jdtls`, `google-java-format`. Buffer-local LSP keymaps (`gd`, `gr`, `gI`, `<leader>rn`, `<leader>ca`, …) are set in the `LspAttach` autocmd — add new LSP keybindings there, not globally. Inlay hints are forced on for Go buffers.
|
||||||
|
- **Go imports** are organized on `BufWritePre` for `*.go` via a `source.organizeImports` code action (`lsp.lua`).
|
||||||
|
- **Formatting** is `conform.nvim` (`conform.lua`); `format_on_save` runs with `timeout_ms = 500` and LSP fallback (disabled for `c`/`cpp`). Per-ft formatters: `stylua` (lua), `ruff_organize_imports`+`ruff_format` (python), `google-java-format` (java), `terraform_fmt`, prettier (js/xml).
|
||||||
|
- **Per-filetype `colorcolumn`** is set by a `FileType` autocmd in `init.lua` (python 80, lua 100, go 120, rust 100, java 120). Other filetypes have no ruler.
|
||||||
|
- **Buffer switching**: `<A-1>`..`<A-9>` jump to `vim.t.bufs[i]` (populated by `mini.bufremove`/`mini.tabline` from `mini.lua`).
|
||||||
|
- **`;` is remapped to `:`** in normal mode. `<Esc>` clears search highlight.
|
||||||
|
|
||||||
|
## Formatting / lint for files in this repo
|
||||||
|
|
||||||
|
Lua files are formatted with **stylua** using `.stylua.toml` (2-space indent, single quotes preferred, 160-col width, no call parens). Run via `<leader>f` or `:Format`, or from a shell: `stylua .`. There is no test suite.
|
||||||
|
|
||||||
|
## Adding / modifying plugins
|
||||||
|
|
||||||
|
- New plugin → new file in `lua/custom/plugins/`, return a lazy spec. No need to edit `init.lua`.
|
||||||
|
- After edits: `:Lazy sync` (install/update/clean) or restart Neovim. Commit `lazy-lock.json` along with spec changes so the lock stays reproducible.
|
||||||
|
- Use `:checkhealth` and `:Mason` to verify tool installation.
|
||||||
|
|
||||||
|
## Repo-specific style notes
|
||||||
|
|
||||||
|
- `.stylua.toml` enforces single quotes and no call parens — keep `require 'foo'` style (not `require('foo')`) in plain calls; conform/lazy spec tables of course still use parens where required.
|
||||||
|
- Existing files have heavy kickstart-original tutorial comments. When editing those files, leave the surrounding teaching comments intact unless the user asks for cleanup; for new files, follow the global comment policy (terse, only when WHY is non-obvious).
|
||||||
380
README.md
380
README.md
|
|
@ -1,238 +1,208 @@
|
||||||
# kickstart.nvim
|
# nvim
|
||||||
|
|
||||||
## Introduction
|
Personal Neovim config, originally forked from [kickstart.nvim](https://github.com/nvim-lua/kickstart.nvim) and broken into per-plugin files. Lives at `~/.config/nvim`.
|
||||||
|
|
||||||
A starting point for Neovim that is:
|
## Layout
|
||||||
|
|
||||||
* Small
|
```
|
||||||
* Single-file
|
init.lua -- options, global keymaps, autocmds, lazy bootstrap
|
||||||
* Completely Documented
|
lua/custom/
|
||||||
|
├── zed-keymaps.lua -- Zed-parity bindings + task spawners
|
||||||
|
├── health.lua -- :checkhealth kickstart
|
||||||
|
└── plugins/*.lua -- one file per plugin; auto-imported by lazy
|
||||||
|
lazy-lock.json -- committed, pinned plugin versions
|
||||||
|
```
|
||||||
|
|
||||||
**NOT** a Neovim distribution, but instead a starting point for your configuration.
|
No build/test step. Changes take effect on `nvim` restart (or `:source %` / `:Lazy reload <plugin>`). Lua is formatted by `stylua` per `.stylua.toml` (2-space, single quotes, 160-col).
|
||||||
|
|
||||||
## Installation
|
## Install
|
||||||
|
|
||||||
### Install Neovim
|
Requires Neovim stable or nightly, plus: `git`, `make`, a C compiler, `ripgrep`, a clipboard tool, and a [Nerd Font](https://www.nerdfonts.com/). Optional: `npm`, `go`, `python`, `java` for the respective LSPs.
|
||||||
|
|
||||||
Kickstart.nvim targets *only* the latest
|
|
||||||
['stable'](https://github.com/neovim/neovim/releases/tag/stable) and latest
|
|
||||||
['nightly'](https://github.com/neovim/neovim/releases/tag/nightly) of Neovim.
|
|
||||||
If you are experiencing issues, please make sure you have the latest versions.
|
|
||||||
|
|
||||||
### Install External Dependencies
|
|
||||||
|
|
||||||
External Requirements:
|
|
||||||
- Basic utils: `git`, `make`, `unzip`, C Compiler (`gcc`)
|
|
||||||
- [ripgrep](https://github.com/BurntSushi/ripgrep#installation)
|
|
||||||
- Clipboard tool (xclip/xsel/win32yank or other depending on the platform)
|
|
||||||
- A [Nerd Font](https://www.nerdfonts.com/): optional, provides various icons
|
|
||||||
- if you have it set `vim.g.have_nerd_font` in `init.lua` to true
|
|
||||||
- Language Setup:
|
|
||||||
- If you want to write Typescript, you need `npm`
|
|
||||||
- If you want to write Golang, you will need `go`
|
|
||||||
- etc.
|
|
||||||
|
|
||||||
> **NOTE**
|
|
||||||
> See [Install Recipes](#Install-Recipes) for additional Windows and Linux specific notes
|
|
||||||
> and quick install snippets
|
|
||||||
|
|
||||||
### Install Kickstart
|
|
||||||
|
|
||||||
> **NOTE**
|
|
||||||
> [Backup](#FAQ) your previous configuration (if any exists)
|
|
||||||
|
|
||||||
Neovim's configurations are located under the following paths, depending on your OS:
|
|
||||||
|
|
||||||
| OS | PATH |
|
|
||||||
| :- | :--- |
|
|
||||||
| Linux, MacOS | `$XDG_CONFIG_HOME/nvim`, `~/.config/nvim` |
|
|
||||||
| Windows (cmd)| `%localappdata%\nvim\` |
|
|
||||||
| Windows (powershell)| `$env:LOCALAPPDATA\nvim\` |
|
|
||||||
|
|
||||||
#### Recommended Step
|
|
||||||
|
|
||||||
[Fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) this repo
|
|
||||||
so that you have your own copy that you can modify, then install by cloning the
|
|
||||||
fork to your machine using one of the commands below, depending on your OS.
|
|
||||||
|
|
||||||
> **NOTE**
|
|
||||||
> Your fork's URL will be something like this:
|
|
||||||
> `https://github.com/<your_github_username>/kickstart.nvim.git`
|
|
||||||
|
|
||||||
You likely want to remove `lazy-lock.json` from your fork's `.gitignore` file
|
|
||||||
too - it's ignored in the kickstart repo to make maintenance easier, but it's
|
|
||||||
[recommended to track it in version control](https://lazy.folke.io/usage/lockfile).
|
|
||||||
|
|
||||||
#### Clone kickstart.nvim
|
|
||||||
> **NOTE**
|
|
||||||
> If following the recommended step above (i.e., forking the repo), replace
|
|
||||||
> `nvim-lua` with `<your_github_username>` in the commands below
|
|
||||||
|
|
||||||
<details><summary> Linux and Mac </summary>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git clone https://github.com/nvim-lua/kickstart.nvim.git "${XDG_CONFIG_HOME:-$HOME/.config}"/nvim
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details><summary> Windows </summary>
|
|
||||||
|
|
||||||
If you're using `cmd.exe`:
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://github.com/nvim-lua/kickstart.nvim.git "%localappdata%\nvim"
|
|
||||||
```
|
|
||||||
|
|
||||||
If you're using `powershell.exe`
|
|
||||||
|
|
||||||
```
|
|
||||||
git clone https://github.com/nvim-lua/kickstart.nvim.git "${env:LOCALAPPDATA}\nvim"
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
|
|
||||||
### Post Installation
|
|
||||||
|
|
||||||
Start Neovim
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
git clone <your-fork> "${XDG_CONFIG_HOME:-$HOME/.config}"/nvim
|
||||||
nvim
|
nvim
|
||||||
```
|
```
|
||||||
|
|
||||||
That's it! Lazy will install all the plugins you have. Use `:Lazy` to view
|
On first launch `lazy.nvim` installs every plugin under `lua/custom/plugins/`, and Mason installs the LSPs/formatters listed in `lsp.lua`. Run `:Lazy`, `:Mason`, `:checkhealth` to verify.
|
||||||
the current plugin status. Hit `q` to close the window.
|
|
||||||
|
|
||||||
#### Read The Friendly Documentation
|
## Editor defaults (`init.lua`)
|
||||||
|
|
||||||
Read through the `init.lua` file in your configuration folder for more
|
- Leader and localleader are **Space**.
|
||||||
information about extending and exploring Neovim. That also includes
|
- `relativenumber`, `cursorline`, `signcolumn=yes`, `scrolloff=8`, `splitright`/`splitbelow`.
|
||||||
examples of adding popularly requested plugins.
|
- `spell` on (`en_us`); `undofile` on; `inccommand=split` for live substitution preview.
|
||||||
|
- `ignorecase` + `smartcase`; `timeoutlen=300`, `updatetime=250`.
|
||||||
|
- Per-filetype `colorcolumn`: python 80, lua 100, rust 100, go 120, java 120. Off everywhere else.
|
||||||
|
- Yank highlight on `TextYankPost`; clipboard synced to `unnamedplus` after UI ready.
|
||||||
|
|
||||||
> [!NOTE]
|
## Plugins
|
||||||
> For more information about a particular plugin check its repository's documentation.
|
|
||||||
|
|
||||||
|
| File | Plugin | Purpose |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| `lsp.lua` | `nvim-lspconfig` + Mason + `fidget.nvim` + `lazydev` | LSP for `clangd`, `gopls`, `pyright`, `ruff`, `lua_ls`; auto-installs `stylua`, `jdtls`, `google-java-format` |
|
||||||
|
| `cmp.lua` | `blink.cmp` | Completion (capabilities fed to LSP) |
|
||||||
|
| `conform.lua` | `conform.nvim` | Format on save (500ms timeout, LSP fallback; off for c/cpp/json/xml/html) |
|
||||||
|
| `lint.lua` | `nvim-lint` | Linting |
|
||||||
|
| `treesitter.lua` | `nvim-treesitter` (`main` branch) + textobjects | Highlight, indent, function/class/param motions |
|
||||||
|
| `treesitter-context.lua` | `nvim-treesitter-context` | Sticky context header |
|
||||||
|
| `telescope.lua` | `telescope.nvim` + `fzf-native` + `ui-select` | Fuzzy finder |
|
||||||
|
| `neo-tree.lua` | `neo-tree.nvim` | File tree (auto-opens on `nvim` / `nvim <dir>`) |
|
||||||
|
| `harpoon.lua` | `harpoon2` | Quick file marks |
|
||||||
|
| `gitsigns.lua` | `gitsigns.nvim` | Gutter signs, line blame (300ms), hunk actions |
|
||||||
|
| `lazygit.lua` | `lazygit.nvim` | Lazygit popup |
|
||||||
|
| `trouble.lua` | `trouble.nvim` | Diagnostics / refs / qflist panel |
|
||||||
|
| `todo.lua` | `todo-comments` | Highlight `TODO/FIX/HACK/...` |
|
||||||
|
| `toggleterm.lua` | `toggleterm.nvim` | Float / split terminals |
|
||||||
|
| `tmux.lua` | `smart-splits.nvim` | `<C-hjkl>` nav across nvim splits ↔ zellij panes |
|
||||||
|
| `mini.lua` | `mini.ai`, `mini.move`, `mini.notify`, `mini.starter`, `mini.statusline` | Misc utilities + statusline |
|
||||||
|
| `leap.lua` | `flash.nvim` | `s`/`S` motions, remote ops |
|
||||||
|
| `persistence.lua` | `persistence.nvim` | Per-cwd auto session |
|
||||||
|
| `which-key.lua` | `which-key.nvim` | Keybind popup |
|
||||||
|
| `copilot.lua` | `copilot.vim` | Inline suggestions (accept on `<M-Tab>`) |
|
||||||
|
| `copilot-chat.lua` | `CopilotChat.nvim` | In-editor chat |
|
||||||
|
| `render-markdown.lua` | `render-markdown.nvim` | Pretty markdown in buffer |
|
||||||
|
| `markdown-preview.lua` | `markdown-preview.nvim` | Browser preview |
|
||||||
|
| `gruvbox.lua` | gruvbox | Colorscheme |
|
||||||
|
| `neoscroll.lua` | `neoscroll.nvim` | Smooth scrolling |
|
||||||
|
| `illuminate.lua` | `vim-illuminate` | Highlight word under cursor |
|
||||||
|
| `indent_line.lua` | `indent-blankline` | Indent guides |
|
||||||
|
| `autopairs.lua` | `nvim-autopairs` | Bracket pairs |
|
||||||
|
| `nvim-surround.lua` | `nvim-surround` | Surround motions |
|
||||||
|
| `dressing.lua` | `dressing.nvim` | Better `vim.ui` prompts |
|
||||||
|
| `sleuth.lua` | `vim-sleuth` | Auto-detect indent |
|
||||||
|
| `java.lua` | `nvim-jdtls` | Java LSP wrapper |
|
||||||
|
| `debug.lua` | `nvim-dap` + UI | Debugger |
|
||||||
|
|
||||||
### Getting Started
|
## Keymaps
|
||||||
|
|
||||||
[The Only Video You Need to Get Started with Neovim](https://youtu.be/m8C0Cq9Uv9o)
|
### Movement & editing (`init.lua` / `zed-keymaps.lua`)
|
||||||
|
| Key | Mode | Action |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| `;` | n | `:` (command mode) |
|
||||||
|
| `<Esc>` | n | Clear search highlight |
|
||||||
|
| `oo` / `OO` | n | Open blank line below/above without entering insert |
|
||||||
|
| `<leader>p` | x | Paste without clobbering register |
|
||||||
|
| `<A-j>` / `<A-k>` | n/v | Move line/selection down/up |
|
||||||
|
| `<C-h/j/k/l>` | i | Arrow keys in insert |
|
||||||
|
| `<C-h/l/b/f/k/j>` | c | Word/char nav in command line |
|
||||||
|
| `<C-w>` | i | Delete previous word |
|
||||||
|
| `s` / `S` / `r` / `R` | n/x/o | flash.nvim jump / treesitter / remote |
|
||||||
|
|
||||||
### FAQ
|
### Windows, buffers, tasks
|
||||||
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `<C-h/j/k/l>` | Focus split — falls through to zellij pane |
|
||||||
|
| `<A-1>`..`<A-9>` | Jump to buffer slot 1..9 (`vim.t.bufs[i]`) |
|
||||||
|
| `<leader>x` | Close current buffer |
|
||||||
|
| `<leader>t` / `<leader>T` | Floating / horizontal toggleterm |
|
||||||
|
| `<C-\>` | Open mapping for toggleterm |
|
||||||
|
| `<leader>gh` | `gh dash` in floating pane |
|
||||||
|
| `<leader>kk` | `k9s` |
|
||||||
|
| `<leader>bb` | bruno tests |
|
||||||
|
| `<leader>uu` / `<leader>dd` | `make up` / `make down` in `restopay/` |
|
||||||
|
| `<leader>aa` | Refresh Athenz cert + AWS creds for `external-factory` |
|
||||||
|
|
||||||
* What should I do if I already have a pre-existing Neovim configuration?
|
### Finder (`<leader>f…`)
|
||||||
* You should back it up and then delete all associated files.
|
| Key | Action |
|
||||||
* This includes your existing init.lua and the Neovim files in `~/.local`
|
| :--- | :--- |
|
||||||
which can be deleted with `rm -rf ~/.local/share/nvim/`
|
| `<leader>ff` | Files |
|
||||||
* Can I keep my existing configuration in parallel to kickstart?
|
| `<leader>fg` | Live grep |
|
||||||
* Yes! You can use [NVIM_APPNAME](https://neovim.io/doc/user/starting.html#%24NVIM_APPNAME)`=nvim-NAME`
|
| `<leader>fw` | Grep current word |
|
||||||
to maintain multiple configurations. For example, you can install the kickstart
|
| `<leader>fd` | Diagnostics |
|
||||||
configuration in `~/.config/nvim-kickstart` and create an alias:
|
| `<leader>fh` | Help tags |
|
||||||
```
|
| `<leader>fk` | Keymaps |
|
||||||
alias nvim-kickstart='NVIM_APPNAME="nvim-kickstart" nvim'
|
| `<leader>fs` | Telescope builtins |
|
||||||
```
|
| `<leader>fr` | Resume last picker |
|
||||||
When you run Neovim using `nvim-kickstart` alias it will use the alternative
|
| `<leader>f.` | Recent files |
|
||||||
config directory and the matching local directory
|
| `<leader>fc` | Commands |
|
||||||
`~/.local/share/nvim-kickstart`. You can apply this approach to any Neovim
|
| `<leader>fe` | Workspace symbols |
|
||||||
distribution that you would like to try out.
|
| `<leader><leader>` | Buffers |
|
||||||
* What if I want to "uninstall" this configuration:
|
| `<leader>/` | Fuzzy find in current buffer |
|
||||||
* See [lazy.nvim uninstall](https://lazy.folke.io/usage#-uninstalling) information
|
| `<leader>s/` | Live grep in open buffers |
|
||||||
* Why is the kickstart `init.lua` a single file? Wouldn't it make sense to split it into multiple files?
|
| `<leader>sn` | Find files in nvim config |
|
||||||
* The main purpose of kickstart is to serve as a teaching tool and a reference
|
|
||||||
configuration that someone can easily use to `git clone` as a basis for their own.
|
|
||||||
As you progress in learning Neovim and Lua, you might consider splitting `init.lua`
|
|
||||||
into smaller parts. A fork of kickstart that does this while maintaining the
|
|
||||||
same functionality is available here:
|
|
||||||
* [kickstart-modular.nvim](https://github.com/dam9000/kickstart-modular.nvim)
|
|
||||||
* Discussions on this topic can be found here:
|
|
||||||
* [Restructure the configuration](https://github.com/nvim-lua/kickstart.nvim/issues/218)
|
|
||||||
* [Reorganize init.lua into a multi-file setup](https://github.com/nvim-lua/kickstart.nvim/pull/473)
|
|
||||||
|
|
||||||
### Install Recipes
|
### LSP (set on `LspAttach`, plus zed-parity)
|
||||||
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `gd` / `gr` / `gI` | Definitions / refs / implementations (telescope) |
|
||||||
|
| `gi` | Implementations (lowercase zed-style) |
|
||||||
|
| `gD` | Declaration |
|
||||||
|
| `<leader>D` | Type definition |
|
||||||
|
| `<leader>ds` / `<leader>ws` | Document / workspace symbols |
|
||||||
|
| `<leader>rn` or `F2` | Rename |
|
||||||
|
| `<leader>ca` or `<leader>.` | Code action |
|
||||||
|
| `<leader>th` | Toggle inlay hints (on by default for Go) |
|
||||||
|
| `<leader>q` | Diagnostics → loclist |
|
||||||
|
| `<leader>f` | Format buffer (conform) |
|
||||||
|
|
||||||
Below you can find OS specific install instructions for Neovim and dependencies.
|
### Git
|
||||||
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `]c` / `[c` | Next / prev hunk |
|
||||||
|
| `<leader>hs` / `<leader>hr` | Stage / reset hunk (works in visual) |
|
||||||
|
| `<leader>hS` / `<leader>hR` | Stage / reset buffer |
|
||||||
|
| `<leader>hu` | Undo stage hunk |
|
||||||
|
| `<leader>hp` | Preview hunk |
|
||||||
|
| `<leader>hb` | Blame current line |
|
||||||
|
| `<leader>hd` / `<leader>hD` | Diff vs index / last commit |
|
||||||
|
| `<leader>tb` / `<leader>tD` | Toggle inline blame / deleted markers |
|
||||||
|
| `gb` | Full-buffer blame |
|
||||||
|
|
||||||
After installing all the dependencies continue with the [Install Kickstart](#Install-Kickstart) step.
|
### Harpoon
|
||||||
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `<leader>ha` | Add current file |
|
||||||
|
| `<leader>hh` | Toggle harpoon menu |
|
||||||
|
| `<leader>1`..`<leader>4` | Jump to slot 1..4 |
|
||||||
|
| `[h` / `]h` | Prev / next entry |
|
||||||
|
|
||||||
#### Windows Installation
|
### Trouble (`<leader>x…`)
|
||||||
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `<leader>xx` | Workspace diagnostics |
|
||||||
|
| `<leader>xX` | Buffer diagnostics |
|
||||||
|
| `<leader>xs` | Symbols |
|
||||||
|
| `<leader>xr` | LSP refs/defs (right) |
|
||||||
|
| `<leader>xl` / `<leader>xq` | Loclist / quickfix |
|
||||||
|
|
||||||
<details><summary>Windows with Microsoft C++ Build Tools and CMake</summary>
|
### Neo-tree
|
||||||
Installation may require installing build tools and updating the run command for `telescope-fzf-native`
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `\` or `<leader>e` | Reveal file in tree |
|
||||||
|
| (inside tree) `h` / `l` / `<tab>` | Collapse / expand+open / smart-toggle |
|
||||||
|
| (inside tree) `T` | Trash file (via `trash` CLI) |
|
||||||
|
|
||||||
See `telescope-fzf-native` documentation for [more details](https://github.com/nvim-telescope/telescope-fzf-native.nvim#installation)
|
### Treesitter textobjects
|
||||||
|
`af`/`if` function, `ac`/`ic` class, `aa`/`ia` parameter, `al`/`il` loop; `]m`/`[m`/`]M`/`[M` move between functions.
|
||||||
|
|
||||||
This requires:
|
### Copilot / chat
|
||||||
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `<M-Tab>` (insert) | Accept Copilot suggestion |
|
||||||
|
| `<leader>cc` / `<leader>ce` / `<leader>cf` / `<leader>cr` / `<leader>ct` / `<leader>cm` | Chat / explain / fix / review / tests / commit-msg |
|
||||||
|
|
||||||
- Install CMake and the Microsoft C++ Build Tools on Windows
|
### Sessions (persistence.nvim)
|
||||||
|
| Key | Action |
|
||||||
|
| :--- | :--- |
|
||||||
|
| `<leader>qs` | Load session for cwd |
|
||||||
|
| `<leader>ql` | Load last session |
|
||||||
|
| `<leader>qd` | Stop saving current session |
|
||||||
|
|
||||||
```lua
|
## LSP & formatting notes
|
||||||
{'nvim-telescope/telescope-fzf-native.nvim', build = 'cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build' }
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
<details><summary>Windows with gcc/make using chocolatey</summary>
|
|
||||||
Alternatively, one can install gcc and make which don't require changing the config,
|
|
||||||
the easiest way is to use choco:
|
|
||||||
|
|
||||||
1. install [chocolatey](https://chocolatey.org/install)
|
- `gopls` uses `-tags=integration`, `gofumpt`, `staticcheck`, full inlay hints; `useany`/`unusedparams` on, `shadow` off.
|
||||||
either follow the instructions on the page or use winget,
|
- Go imports run as a `source.organizeImports` code action on `BufWritePre` for `*.go`.
|
||||||
run in cmd as **admin**:
|
- `pyright` lint is suppressed and its organize-imports disabled; `ruff` handles lint + organize + format. `ruff`'s hover is disabled — `pyright` provides hover.
|
||||||
```
|
- `lua_ls`: `callSnippet = 'Replace'`; `lazydev` loads `vim.uv` types.
|
||||||
winget install --accept-source-agreements chocolatey.chocolatey
|
- Per-ft formatters: `stylua` (lua), `ruff_organize_imports` + `ruff_format` (python), `google-java-format` (java), `terraform_fmt`, `prettier`/`xmlformatter` (xml), `prettierd`/`prettier` (js). Format-on-save off for `c`/`cpp`/`json`/`xml`/`html`.
|
||||||
```
|
|
||||||
|
|
||||||
2. install all requirements using choco, exit the previous cmd and
|
## Adding a plugin
|
||||||
open a new one so that choco path is set, and run in cmd as **admin**:
|
|
||||||
```
|
|
||||||
choco install -y neovim git ripgrep wget fd unzip gzip mingw make
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
<details><summary>WSL (Windows Subsystem for Linux)</summary>
|
|
||||||
|
|
||||||
```
|
Drop a new file in `lua/custom/plugins/` returning a lazy spec. No central manifest. After edits, run `:Lazy sync` (or restart) and commit `lazy-lock.json` alongside the spec.
|
||||||
wsl --install
|
|
||||||
wsl
|
|
||||||
sudo add-apt-repository ppa:neovim-ppa/unstable -y
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install make gcc ripgrep unzip git xclip neovim
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
#### Linux Install
|
## FAQ
|
||||||
<details><summary>Ubuntu Install Steps</summary>
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo add-apt-repository ppa:neovim-ppa/unstable -y
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install make gcc ripgrep unzip git xclip neovim
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
<details><summary>Debian Install Steps</summary>
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install make gcc ripgrep unzip git xclip curl
|
|
||||||
|
|
||||||
# Now we install nvim
|
|
||||||
curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linux64.tar.gz
|
|
||||||
sudo rm -rf /opt/nvim-linux64
|
|
||||||
sudo mkdir -p /opt/nvim-linux64
|
|
||||||
sudo chmod a+rX /opt/nvim-linux64
|
|
||||||
sudo tar -C /opt -xzf nvim-linux64.tar.gz
|
|
||||||
|
|
||||||
# make it available in /usr/local/bin, distro installs to /usr/bin
|
|
||||||
sudo ln -sf /opt/nvim-linux64/bin/nvim /usr/local/bin/
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
<details><summary>Fedora Install Steps</summary>
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo dnf install -y gcc make git ripgrep fd-find unzip neovim
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
<details><summary>Arch Install Steps</summary>
|
|
||||||
|
|
||||||
```
|
|
||||||
sudo pacman -S --noconfirm --needed gcc make git ripgrep fd unzip neovim
|
|
||||||
```
|
|
||||||
</details>
|
|
||||||
|
|
||||||
|
- **Where do LSP keymaps live?** In the `LspAttach` autocmd in `lsp.lua`. Add new buffer-local LSP bindings there, not globally.
|
||||||
|
- **Why doesn't `<C-h/j/k/l>` move splits in some configs?** They're owned by `smart-splits.nvim`; at a split edge they forward to the zellij pane (`multiplexer_integration = 'zellij'`).
|
||||||
|
- **Uninstall:** see [lazy.nvim uninstall](https://lazy.folke.io/usage#-uninstalling).
|
||||||
|
- **Run alongside another config:** `NVIM_APPNAME=nvim-other nvim`.
|
||||||
|
|
|
||||||
62
init.lua
62
init.lua
|
|
@ -4,13 +4,19 @@ vim.g.mapleader = ' '
|
||||||
vim.g.maplocalleader = ' '
|
vim.g.maplocalleader = ' '
|
||||||
vim.g.have_nerd_font = true
|
vim.g.have_nerd_font = true
|
||||||
|
|
||||||
|
-- Skip nvim's OSC 11/DSR terminal probe (zellij sometimes delays the response,
|
||||||
|
-- producing the "Did not detect DSR response" warning + 100ms slower startup).
|
||||||
|
-- Setting background explicitly tells defaults.lua to bypass the query.
|
||||||
|
vim.opt.background = 'dark'
|
||||||
|
|
||||||
vim.opt.relativenumber = true
|
vim.opt.relativenumber = true
|
||||||
vim.opt.mouse = 'a'
|
vim.opt.mouse = 'a'
|
||||||
vim.opt.showmode = false
|
vim.opt.showmode = false
|
||||||
vim.opt.smartindent = true
|
vim.opt.smartindent = true
|
||||||
vim.opt.spelllang = 'en_us'
|
vim.opt.spelllang = 'en_us'
|
||||||
vim.o.spell = true
|
vim.o.spell = true
|
||||||
vim.o.colorcolumn = '80'
|
-- colorcolumn set per-filetype (see autocmd below); default off.
|
||||||
|
vim.o.colorcolumn = ''
|
||||||
|
|
||||||
-- Sync clipboard between OS and Neovim.
|
-- Sync clipboard between OS and Neovim.
|
||||||
-- Schedule the setting after `UiEnter` because it can increase startup-time.
|
-- Schedule the setting after `UiEnter` because it can increase startup-time.
|
||||||
|
|
@ -97,18 +103,22 @@ vim.keymap.set('n', '<Esc>', '<cmd>nohlsearch<CR>')
|
||||||
-- Diagnostic keymaps
|
-- Diagnostic keymaps
|
||||||
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })
|
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, { desc = 'Open diagnostic [Q]uickfix list' })
|
||||||
|
|
||||||
-- Keybinds to make split navigation easier.
|
-- Window-nav Ctrl-h/j/k/l owned by smart-splits.nvim (custom/plugins/tmux.lua).
|
||||||
-- Use CTRL+<hjkl> to switch between windows
|
-- Falls through to zellij when at a split edge.
|
||||||
--
|
|
||||||
-- See `:help wincmd` for a list of all window commands
|
|
||||||
vim.keymap.set('n', '<C-h>', '<C-w><C-h>', { desc = 'Move focus to the left window' })
|
|
||||||
vim.keymap.set('n', '<C-l>', '<C-w><C-l>', { desc = 'Move focus to the right window' })
|
|
||||||
vim.keymap.set('n', '<C-j>', '<C-w><C-j>', { desc = 'Move focus to the lower window' })
|
|
||||||
vim.keymap.set('n', '<C-k>', '<C-w><C-k>', { desc = 'Move focus to the upper window' })
|
|
||||||
|
|
||||||
-- [[ Basic Autocommands ]]
|
-- [[ Basic Autocommands ]]
|
||||||
-- See `:help lua-guide-autocommands`
|
-- See `:help lua-guide-autocommands`
|
||||||
|
|
||||||
|
-- Per-filetype colorcolumn (Go allows long lines; markdown shouldn't have a ruler).
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
group = vim.api.nvim_create_augroup('per-ft-colorcolumn', { clear = true }),
|
||||||
|
callback = function(args)
|
||||||
|
local widths = { python = '80', lua = '100', go = '120', rust = '100', java = '120' }
|
||||||
|
vim.bo[args.buf].textwidth = 0
|
||||||
|
vim.wo.colorcolumn = widths[vim.bo[args.buf].filetype] or ''
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
-- Highlight when yanking (copying) text
|
-- Highlight when yanking (copying) text
|
||||||
-- Try it with `yap` in normal mode
|
-- Try it with `yap` in normal mode
|
||||||
-- See `:help vim.highlight.on_yank()`
|
-- See `:help vim.highlight.on_yank()`
|
||||||
|
|
@ -132,39 +142,7 @@ if not (vim.uv or vim.loop).fs_stat(lazypath) then
|
||||||
end ---@diagnostic disable-next-line: undefined-field
|
end ---@diagnostic disable-next-line: undefined-field
|
||||||
vim.opt.rtp:prepend(lazypath)
|
vim.opt.rtp:prepend(lazypath)
|
||||||
|
|
||||||
local floating_win = nil
|
require('custom.zed-keymaps')
|
||||||
|
|
||||||
function FloatingTerm()
|
|
||||||
if floating_win and vim.api.nvim_win_is_valid(floating_win) then
|
|
||||||
vim.api.nvim_win_close(floating_win, true)
|
|
||||||
floating_win = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local buf = vim.api.nvim_create_buf(false, true)
|
|
||||||
local width = math.floor(vim.o.columns * 0.8)
|
|
||||||
local height = math.floor(vim.o.lines * 0.8)
|
|
||||||
local row = math.floor((vim.o.lines - height) / 2)
|
|
||||||
local col = math.floor((vim.o.columns - width) / 2)
|
|
||||||
|
|
||||||
floating_win = vim.api.nvim_open_win(buf, true, {
|
|
||||||
relative = 'editor',
|
|
||||||
width = width,
|
|
||||||
height = height,
|
|
||||||
row = row,
|
|
||||||
col = col,
|
|
||||||
style = 'minimal',
|
|
||||||
border = 'rounded',
|
|
||||||
})
|
|
||||||
|
|
||||||
vim.fn.termopen(vim.o.shell)
|
|
||||||
vim.cmd 'startinsert'
|
|
||||||
|
|
||||||
-- Map <Esc> to close the floating terminal when inside it
|
|
||||||
vim.api.nvim_buf_set_keymap(buf, 't', '<Esc>', '<C-\\><C-n>:lua FloatingTerm()<CR>', { noremap = true, silent = true })
|
|
||||||
end
|
|
||||||
|
|
||||||
vim.api.nvim_set_keymap('n', '<leader>t', ':lua FloatingTerm()<CR>', { noremap = true, silent = true })
|
|
||||||
|
|
||||||
require('lazy').setup({ { import = 'custom.plugins' } }, {
|
require('lazy').setup({ { import = 'custom.plugins' } }, {
|
||||||
ui = {
|
ui = {
|
||||||
|
|
|
||||||
|
|
@ -1,115 +1,39 @@
|
||||||
return { -- Autocompletion
|
-- blink.cmp: faster Rust-based completion (replaces nvim-cmp).
|
||||||
'hrsh7th/nvim-cmp',
|
-- Provides LSP, path, snippet, and lazydev sources via single plugin.
|
||||||
event = 'InsertEnter',
|
return {
|
||||||
|
'saghen/blink.cmp',
|
||||||
|
version = '*',
|
||||||
|
event = { 'InsertEnter', 'CmdlineEnter' },
|
||||||
dependencies = {
|
dependencies = {
|
||||||
-- Snippet Engine & its associated nvim-cmp source
|
'rafamadriz/friendly-snippets',
|
||||||
{
|
|
||||||
'L3MON4D3/LuaSnip',
|
|
||||||
build = (function()
|
|
||||||
-- Build Step is needed for regex support in snippets.
|
|
||||||
-- This step is not supported in many windows environments.
|
|
||||||
-- Remove the below condition to re-enable on windows.
|
|
||||||
if vim.fn.has 'win32' == 1 or vim.fn.executable 'make' == 0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
return 'make install_jsregexp'
|
|
||||||
end)(),
|
|
||||||
dependencies = {
|
|
||||||
-- `friendly-snippets` contains a variety of premade snippets.
|
|
||||||
-- See the README about individual language/framework/plugin snippets:
|
|
||||||
-- https://github.com/rafamadriz/friendly-snippets
|
|
||||||
-- {
|
|
||||||
-- 'rafamadriz/friendly-snippets',
|
|
||||||
-- config = function()
|
|
||||||
-- require('luasnip.loaders.from_vscode').lazy_load()
|
|
||||||
-- end,
|
|
||||||
-- },
|
|
||||||
},
|
},
|
||||||
|
opts = {
|
||||||
|
-- Use the 'enter' preset: <CR> confirms, <Tab>/<S-Tab> cycle items.
|
||||||
|
keymap = {
|
||||||
|
preset = 'enter',
|
||||||
|
['<Tab>'] = { 'select_next', 'snippet_forward', 'fallback' },
|
||||||
|
['<S-Tab>'] = { 'select_prev', 'snippet_backward', 'fallback' },
|
||||||
|
['<C-Space>'] = { 'show', 'show_documentation', 'hide_documentation' },
|
||||||
},
|
},
|
||||||
'saadparwaiz1/cmp_luasnip',
|
appearance = {
|
||||||
|
use_nvim_cmp_as_default = true,
|
||||||
-- Adds other completion capabilities.
|
nerd_font_variant = 'mono',
|
||||||
-- nvim-cmp does not ship with all sources by default. They are split
|
|
||||||
-- into multiple repos for maintenance purposes.
|
|
||||||
'hrsh7th/cmp-nvim-lsp',
|
|
||||||
'hrsh7th/cmp-path',
|
|
||||||
},
|
},
|
||||||
config = function()
|
completion = {
|
||||||
-- See `:help cmp`
|
accept = { auto_brackets = { enabled = true } },
|
||||||
local cmp = require 'cmp'
|
documentation = { auto_show = true, auto_show_delay_ms = 200 },
|
||||||
local luasnip = require 'luasnip'
|
menu = { border = 'rounded' },
|
||||||
luasnip.config.setup {}
|
|
||||||
|
|
||||||
cmp.setup {
|
|
||||||
snippet = {
|
|
||||||
expand = function(args)
|
|
||||||
luasnip.lsp_expand(args.body)
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
completion = { completeopt = 'menu,menuone,noinsert' },
|
|
||||||
|
|
||||||
-- For an understanding of why these mappings were
|
|
||||||
-- chosen, you will need to read `:help ins-completion`
|
|
||||||
--
|
|
||||||
-- No, but seriously. Please read `:help ins-completion`, it is really good!
|
|
||||||
mapping = cmp.mapping.preset.insert {
|
|
||||||
-- Select the [n]ext item
|
|
||||||
-- ['<C-n>'] = cmp.mapping.select_next_item(),
|
|
||||||
-- Select the [p]revious item
|
|
||||||
-- ['<C-p>'] = cmp.mapping.select_prev_item(),
|
|
||||||
|
|
||||||
-- Scroll the documentation window [b]ack / [f]orward
|
|
||||||
['<C-b>'] = cmp.mapping.scroll_docs(-4),
|
|
||||||
['<C-f>'] = cmp.mapping.scroll_docs(4),
|
|
||||||
|
|
||||||
-- Accept ([y]es) the completion.
|
|
||||||
-- This will auto-import if your LSP supports it.
|
|
||||||
-- This will expand snippets if the LSP sent a snippet.
|
|
||||||
-- ['<C-y>'] = cmp.mapping.confirm { select = true },
|
|
||||||
|
|
||||||
-- If you prefer more traditional completion keymaps,
|
|
||||||
-- you can uncomment the following lines
|
|
||||||
['<CR>'] = cmp.mapping.confirm { select = true },
|
|
||||||
['<Tab>'] = cmp.mapping.select_next_item(),
|
|
||||||
['<S-Tab>'] = cmp.mapping.select_prev_item(),
|
|
||||||
|
|
||||||
-- Manually trigger a completion from nvim-cmp.
|
|
||||||
-- Generally you don't need this, because nvim-cmp will display
|
|
||||||
-- completions whenever it has completion options available.
|
|
||||||
['<C-Space>'] = cmp.mapping.complete {},
|
|
||||||
|
|
||||||
-- Think of <c-l> as moving to the right of your snippet expansion.
|
|
||||||
-- So if you have a snippet that's like:
|
|
||||||
-- function $name($args)
|
|
||||||
-- $body
|
|
||||||
-- end
|
|
||||||
--
|
|
||||||
-- <c-l> will move you to the right of each of the expansion locations.
|
|
||||||
-- <c-h> is similar, except moving you backwards.
|
|
||||||
['<C-l>'] = cmp.mapping(function()
|
|
||||||
if luasnip.expand_or_locally_jumpable() then
|
|
||||||
luasnip.expand_or_jump()
|
|
||||||
end
|
|
||||||
end, { 'i', 's' }),
|
|
||||||
['<C-h>'] = cmp.mapping(function()
|
|
||||||
if luasnip.locally_jumpable(-1) then
|
|
||||||
luasnip.jump(-1)
|
|
||||||
end
|
|
||||||
end, { 'i', 's' }),
|
|
||||||
|
|
||||||
-- For more advanced Luasnip keymaps (e.g. selecting choice nodes, expansion) see:
|
|
||||||
-- https://github.com/L3MON4D3/LuaSnip?tab=readme-ov-file#keymaps
|
|
||||||
},
|
},
|
||||||
|
signature = { enabled = true, window = { border = 'rounded' } },
|
||||||
sources = {
|
sources = {
|
||||||
{
|
default = { 'lsp', 'path', 'snippets', 'buffer', 'lazydev' },
|
||||||
name = 'lazydev',
|
providers = {
|
||||||
-- set group index to 0 to skip loading LuaLS completions as lazydev recommends it
|
lazydev = {
|
||||||
group_index = 0,
|
name = 'LazyDev',
|
||||||
|
module = 'lazydev.integrations.blink',
|
||||||
|
score_offset = 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{ name = 'nvim_lsp' },
|
|
||||||
{ name = 'luasnip' },
|
|
||||||
{ name = 'path' },
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ return { -- Autoformat
|
||||||
-- Disable "format_on_save lsp_fallback" for languages that don't
|
-- Disable "format_on_save lsp_fallback" for languages that don't
|
||||||
-- have a well standardized coding style. You can add additional
|
-- have a well standardized coding style. You can add additional
|
||||||
-- languages here or re-enable it for the disabled ones.
|
-- languages here or re-enable it for the disabled ones.
|
||||||
local disable_filetypes = { c = true, cpp = true }
|
local disable_filetypes = { c = true, cpp = true, json = true, xml = true, html = true }
|
||||||
local lsp_format_opt
|
local lsp_format_opt
|
||||||
if disable_filetypes[vim.bo[bufnr].filetype] then
|
if disable_filetypes[vim.bo[bufnr].filetype] then
|
||||||
lsp_format_opt = 'never'
|
lsp_format_opt = 'never'
|
||||||
|
|
@ -35,7 +35,7 @@ return { -- Autoformat
|
||||||
terraform = { 'terraform_fmt' },
|
terraform = { 'terraform_fmt' },
|
||||||
xml = { 'xmlformatter', 'prettier' },
|
xml = { 'xmlformatter', 'prettier' },
|
||||||
lua = { 'stylua' },
|
lua = { 'stylua' },
|
||||||
python = { 'isort', 'black' },
|
python = { 'ruff_organize_imports', 'ruff_format' },
|
||||||
javascript = { 'prettierd', 'prettier', stop_after_first = true },
|
javascript = { 'prettierd', 'prettier', stop_after_first = true },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
-- CopilotChat: in-nvim chat using your existing GitHub Copilot auth.
|
||||||
|
return {
|
||||||
|
'CopilotC-Nvim/CopilotChat.nvim',
|
||||||
|
dependencies = {
|
||||||
|
'github/copilot.vim',
|
||||||
|
'nvim-lua/plenary.nvim',
|
||||||
|
},
|
||||||
|
build = 'make tiktoken',
|
||||||
|
cmd = { 'CopilotChat', 'CopilotChatOpen', 'CopilotChatToggle', 'CopilotChatExplain', 'CopilotChatReview', 'CopilotChatFix', 'CopilotChatTests', 'CopilotChatCommit' },
|
||||||
|
opts = {
|
||||||
|
model = 'gpt-4o',
|
||||||
|
window = {
|
||||||
|
layout = 'float',
|
||||||
|
width = 0.8,
|
||||||
|
height = 0.8,
|
||||||
|
border = 'rounded',
|
||||||
|
},
|
||||||
|
show_help = true,
|
||||||
|
auto_follow_cursor = false,
|
||||||
|
},
|
||||||
|
keys = {
|
||||||
|
{ '<leader>cc', '<cmd>CopilotChatToggle<cr>', mode = { 'n', 'x' }, desc = '[C]opilot [C]hat' },
|
||||||
|
{ '<leader>ce', '<cmd>CopilotChatExplain<cr>', mode = { 'n', 'x' }, desc = '[C]opilot [E]xplain' },
|
||||||
|
{ '<leader>cf', '<cmd>CopilotChatFix<cr>', mode = { 'n', 'x' }, desc = '[C]opilot [F]ix' },
|
||||||
|
{ '<leader>cr', '<cmd>CopilotChatReview<cr>', mode = { 'n', 'x' }, desc = '[C]opilot [R]eview' },
|
||||||
|
{ '<leader>ct', '<cmd>CopilotChatTests<cr>', mode = { 'n', 'x' }, desc = '[C]opilot [T]ests' },
|
||||||
|
{ '<leader>cm', '<cmd>CopilotChatCommit<cr>', desc = '[C]opilot co[M]mit msg' },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
-- Replace the ugly default vim.ui.input/select with a floating UI.
|
||||||
|
return {
|
||||||
|
'stevearc/dressing.nvim',
|
||||||
|
event = 'VeryLazy',
|
||||||
|
opts = {},
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ return {
|
||||||
{
|
{
|
||||||
'lewis6991/gitsigns.nvim',
|
'lewis6991/gitsigns.nvim',
|
||||||
opts = {
|
opts = {
|
||||||
|
current_line_blame = true,
|
||||||
|
current_line_blame_opts = { delay = 300, virt_text_pos = 'eol' },
|
||||||
on_attach = function(bufnr)
|
on_attach = function(bufnr)
|
||||||
local gitsigns = require 'gitsigns'
|
local gitsigns = require 'gitsigns'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
return {
|
|
||||||
'ellisonleao/glow.nvim',
|
|
||||||
config = function()
|
|
||||||
require('glow').setup()
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
return {
|
||||||
|
'ThePrimeagen/harpoon',
|
||||||
|
branch = 'harpoon2',
|
||||||
|
dependencies = { 'nvim-lua/plenary.nvim' },
|
||||||
|
config = function()
|
||||||
|
local harpoon = require 'harpoon'
|
||||||
|
harpoon:setup()
|
||||||
|
|
||||||
|
vim.keymap.set('n', '<leader>ha', function() harpoon:list():add() end, { desc = '[H]arpoon [A]dd file' })
|
||||||
|
vim.keymap.set('n', '<leader>hh', function() harpoon.ui:toggle_quick_menu(harpoon:list()) end, { desc = '[H]arpoon toggle list' })
|
||||||
|
|
||||||
|
-- Jump to harpoon slots 1..4. (<C-h..> reserved for smart-splits pane nav.)
|
||||||
|
for i = 1, 4 do
|
||||||
|
vim.keymap.set('n', '<leader>' .. i, function() harpoon:list():select(i) end, { desc = 'Harpoon slot ' .. i })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Prev/next harpoon entries.
|
||||||
|
vim.keymap.set('n', '[h', function() harpoon:list():prev() end, { desc = 'Harpoon prev' })
|
||||||
|
vim.keymap.set('n', ']h', function() harpoon:list():next() end, { desc = 'Harpoon next' })
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
return {
|
||||||
|
-- 'mfussenegger/nvim-jdtls',
|
||||||
|
-- ft = { 'java' },
|
||||||
|
-- config = function()
|
||||||
|
-- local jdtls = require 'jdtls'
|
||||||
|
-- local home = os.getenv 'HOME'
|
||||||
|
-- local workspace_dir = home .. '~/.cache/jdtls/workspace/' .. vim.fn.fnamemodify(vim.fn.getcwd(), ':p:h:t')
|
||||||
|
--
|
||||||
|
-- require('jdtls').start_or_attach {
|
||||||
|
-- cmd = { 'jdtls' },
|
||||||
|
-- root_dir = require('jdtls.setup').find_root { '.git', 'mvnw', 'gradlew' },
|
||||||
|
-- settings = {
|
||||||
|
-- java = {
|
||||||
|
-- format = {
|
||||||
|
-- enabled = true,
|
||||||
|
-- settings = home .. '/.config/nvim/eclipse-java-style.xml', -- Use your exported formatter
|
||||||
|
-- },
|
||||||
|
-- },
|
||||||
|
-- },
|
||||||
|
-- workspace_dir = workspace_dir,
|
||||||
|
-- }
|
||||||
|
-- end,
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
|
-- flash.nvim: smarter `s`/`S` jump with treesitter-aware selection and
|
||||||
|
-- remote operations (e.g. `yr<motion>` to yank a remote region).
|
||||||
return {
|
return {
|
||||||
'ggandor/leap.nvim',
|
'folke/flash.nvim',
|
||||||
event = 'VeryLazy',
|
event = 'VeryLazy',
|
||||||
config = function()
|
opts = {},
|
||||||
vim.keymap.set({ 'n', 'x', 'o' }, 's', '<Plug>(leap-forward)', { noremap = true, silent = true })
|
keys = {
|
||||||
vim.keymap.set({ 'n', 'x', 'o' }, 'S', '<Plug>(leap-backward)', { noremap = true, silent = true })
|
{ 's', mode = { 'n', 'x', 'o' }, function() require('flash').jump() end, desc = 'Flash' },
|
||||||
vim.keymap.set({ 'n', 'x', 'o' }, 'gs', '<Plug>(leap-from-window)', { noremap = true, silent = true })
|
{ 'S', mode = { 'n', 'x', 'o' }, function() require('flash').treesitter() end, desc = 'Flash Treesitter' },
|
||||||
end,
|
{ 'r', mode = 'o', function() require('flash').remote() end, desc = 'Remote Flash' },
|
||||||
|
{ 'R', mode = { 'o', 'x' }, function() require('flash').treesitter_search() end, desc = 'Treesitter Search' },
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ return {
|
||||||
-- Useful status updates for LSP.
|
-- Useful status updates for LSP.
|
||||||
{ 'j-hui/fidget.nvim', opts = {} },
|
{ 'j-hui/fidget.nvim', opts = {} },
|
||||||
|
|
||||||
-- Allows extra capabilities provided by nvim-cmp
|
-- Completion capabilities from blink.cmp.
|
||||||
'hrsh7th/cmp-nvim-lsp',
|
'saghen/blink.cmp',
|
||||||
},
|
},
|
||||||
config = function()
|
config = function()
|
||||||
-- Brief aside: **What is LSP?**
|
-- Brief aside: **What is LSP?**
|
||||||
|
|
@ -114,7 +114,7 @@ return {
|
||||||
--
|
--
|
||||||
-- When you move your cursor, the highlights will be cleared (the second autocommand).
|
-- When you move your cursor, the highlights will be cleared (the second autocommand).
|
||||||
local client = vim.lsp.get_client_by_id(event.data.client_id)
|
local client = vim.lsp.get_client_by_id(event.data.client_id)
|
||||||
if client and client.supports_method(vim.lsp.protocol.Methods.textDocument_documentHighlight) then
|
if client and client:supports_method(vim.lsp.protocol.Methods.textDocument_documentHighlight) then
|
||||||
local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false })
|
local highlight_augroup = vim.api.nvim_create_augroup('kickstart-lsp-highlight', { clear = false })
|
||||||
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
|
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
|
||||||
buffer = event.buf,
|
buffer = event.buf,
|
||||||
|
|
@ -141,10 +141,32 @@ return {
|
||||||
-- code, if the language server you are using supports them
|
-- code, if the language server you are using supports them
|
||||||
--
|
--
|
||||||
-- This may be unwanted, since they displace some of your code
|
-- This may be unwanted, since they displace some of your code
|
||||||
if client and client.supports_method(vim.lsp.protocol.Methods.textDocument_inlayHint) then
|
if client and client:supports_method(vim.lsp.protocol.Methods.textDocument_inlayHint) then
|
||||||
map('<leader>th', function()
|
map('<leader>th', function()
|
||||||
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf })
|
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled { bufnr = event.buf })
|
||||||
end, '[T]oggle Inlay [H]ints')
|
end, '[T]oggle Inlay [H]ints')
|
||||||
|
-- Inlay hints on by default for Go.
|
||||||
|
if vim.bo[event.buf].filetype == 'go' then
|
||||||
|
vim.lsp.inlay_hint.enable(true, { bufnr = event.buf })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Go: organize imports on save via gopls code action.
|
||||||
|
vim.api.nvim_create_autocmd('BufWritePre', {
|
||||||
|
group = vim.api.nvim_create_augroup('go-organize-imports', { clear = true }),
|
||||||
|
pattern = '*.go',
|
||||||
|
callback = function()
|
||||||
|
local params = vim.lsp.util.make_range_params(0, 'utf-8')
|
||||||
|
params.context = { only = { 'source.organizeImports' } }
|
||||||
|
local result = vim.lsp.buf_request_sync(0, 'textDocument/codeAction', params, 1000)
|
||||||
|
for _, res in pairs(result or {}) do
|
||||||
|
for _, action in pairs(res.result or {}) do
|
||||||
|
if action.edit then
|
||||||
|
vim.lsp.util.apply_workspace_edit(action.edit, 'utf-8')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
@ -163,8 +185,7 @@ return {
|
||||||
-- By default, Neovim doesn't support everything that is in the LSP specification.
|
-- By default, Neovim doesn't support everything that is in the LSP specification.
|
||||||
-- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities.
|
-- When you add nvim-cmp, luasnip, etc. Neovim now has *more* capabilities.
|
||||||
-- So, we create new capabilities with nvim cmp, and then broadcast that to the servers.
|
-- So, we create new capabilities with nvim cmp, and then broadcast that to the servers.
|
||||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
local capabilities = require('blink.cmp').get_lsp_capabilities()
|
||||||
capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities())
|
|
||||||
|
|
||||||
-- Enable the following language servers
|
-- Enable the following language servers
|
||||||
-- Feel free to add/remove any LSPs that you want here. They will automatically be installed.
|
-- Feel free to add/remove any LSPs that you want here. They will automatically be installed.
|
||||||
|
|
@ -181,6 +202,8 @@ return {
|
||||||
filetypes = { 'go', 'go.mod', 'go.work' },
|
filetypes = { 'go', 'go.mod', 'go.work' },
|
||||||
settings = {
|
settings = {
|
||||||
gopls = {
|
gopls = {
|
||||||
|
-- Resolve files behind `//go:build integration`. Matches Zed's gopls config.
|
||||||
|
buildFlags = { '-tags=integration' },
|
||||||
completeUnimported = true,
|
completeUnimported = true,
|
||||||
usePlaceholders = true,
|
usePlaceholders = true,
|
||||||
analyses = {
|
analyses = {
|
||||||
|
|
@ -190,13 +213,38 @@ return {
|
||||||
},
|
},
|
||||||
gofumpt = true,
|
gofumpt = true,
|
||||||
staticcheck = true,
|
staticcheck = true,
|
||||||
|
hints = {
|
||||||
|
assignVariableTypes = true,
|
||||||
|
compositeLiteralFields = true,
|
||||||
|
compositeLiteralTypes = true,
|
||||||
|
constantValues = true,
|
||||||
|
functionTypeParameters = true,
|
||||||
|
parameterNames = true,
|
||||||
|
rangeVariableTypes = true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
env = {
|
|
||||||
GOEXPERIMENT = 'rangefunc',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pyright = {},
|
pyright = {
|
||||||
|
settings = {
|
||||||
|
pyright = {
|
||||||
|
-- Disable pyright's import organizer; let ruff handle it.
|
||||||
|
disableOrganizeImports = true,
|
||||||
|
},
|
||||||
|
python = {
|
||||||
|
analysis = {
|
||||||
|
-- ignore lint errors; ruff handles linting.
|
||||||
|
ignore = { '*' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ruff = {
|
||||||
|
-- Disable ruff's hover; pyright provides better hover.
|
||||||
|
on_attach = function(client, _)
|
||||||
|
client.server_capabilities.hoverProvider = false
|
||||||
|
end,
|
||||||
|
},
|
||||||
-- rust_analyzer = {},
|
-- rust_analyzer = {},
|
||||||
-- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs
|
-- ... etc. See `:help lspconfig-all` for a list of all the pre-configured LSPs
|
||||||
--
|
--
|
||||||
|
|
@ -239,8 +287,10 @@ return {
|
||||||
local ensure_installed = vim.tbl_keys(servers or {})
|
local ensure_installed = vim.tbl_keys(servers or {})
|
||||||
vim.list_extend(ensure_installed, {
|
vim.list_extend(ensure_installed, {
|
||||||
'stylua', -- Used to format Lua code
|
'stylua', -- Used to format Lua code
|
||||||
|
'jdtls', -- Java LSP
|
||||||
'gopls',
|
'gopls',
|
||||||
'pyright',
|
'pyright',
|
||||||
|
'ruff', -- Python linter/formatter LSP.
|
||||||
})
|
})
|
||||||
require('mason-tool-installer').setup { ensure_installed = ensure_installed }
|
require('mason-tool-installer').setup { ensure_installed = ensure_installed }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,17 @@
|
||||||
|
-- Live browser preview on `:MarkdownPreview`.
|
||||||
|
-- Build via the plugin's helper so it doesn't dirty yarn.lock and break Lazy updates.
|
||||||
return {
|
return {
|
||||||
'iamcco/markdown-preview.nvim',
|
'iamcco/markdown-preview.nvim',
|
||||||
build = 'cd app && npm install',
|
ft = { 'markdown' },
|
||||||
config = function()
|
build = function()
|
||||||
vim.g.mkdp_auto_start = 1
|
vim.fn['mkdp#util#install']()
|
||||||
end,
|
end,
|
||||||
|
cmd = { 'MarkdownPreview', 'MarkdownPreviewStop', 'MarkdownPreviewToggle' },
|
||||||
|
init = function()
|
||||||
|
vim.g.mkdp_auto_start = 0
|
||||||
|
vim.g.mkdp_filetypes = { 'markdown' }
|
||||||
|
end,
|
||||||
|
keys = {
|
||||||
|
{ '<leader>mp', '<cmd>MarkdownPreviewToggle<cr>', desc = '[M]arkdown [P]review' },
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ return { -- Collection of various small independent plugins/modules
|
||||||
require('mini.move').setup()
|
require('mini.move').setup()
|
||||||
require('mini.notify').setup()
|
require('mini.notify').setup()
|
||||||
require('mini.starter').setup()
|
require('mini.starter').setup()
|
||||||
require('mini.tabline').setup()
|
|
||||||
require('mini.statusline').setup {
|
require('mini.statusline').setup {
|
||||||
use_icons = vim.g.have_nerd_font,
|
use_icons = vim.g.have_nerd_font,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,56 +8,30 @@ return {
|
||||||
'saifulapm/neotree-file-nesting-config',
|
'saifulapm/neotree-file-nesting-config',
|
||||||
},
|
},
|
||||||
cmd = 'Neotree',
|
cmd = 'Neotree',
|
||||||
opts = {
|
-- Auto-open on startup when nvim is launched without a file or on a directory.
|
||||||
-- recommended config for better UI
|
init = function()
|
||||||
hide_root_node = true,
|
vim.api.nvim_create_autocmd('VimEnter', {
|
||||||
retain_hidden_root_indent = true,
|
group = vim.api.nvim_create_augroup('neo-tree-auto-open', { clear = true }),
|
||||||
filesystem = {
|
callback = function()
|
||||||
filtered_items = {
|
local argc = vim.fn.argc()
|
||||||
show_hidden_count = false,
|
local arg = argc > 0 and vim.fn.argv(0) or ''
|
||||||
never_show = {
|
if argc == 0 or vim.fn.isdirectory(arg) == 1 then
|
||||||
'.DS_Store',
|
vim.schedule(function()
|
||||||
},
|
-- `reveal_force_cwd` roots at cwd and avoids the
|
||||||
},
|
-- expand_to_node recursion that `show` can hit.
|
||||||
},
|
vim.cmd('Neotree reveal_force_cwd')
|
||||||
default_component_configs = {
|
end)
|
||||||
indent = {
|
end
|
||||||
with_expanders = true,
|
end,
|
||||||
expander_collapsed = '',
|
})
|
||||||
expander_expanded = '',
|
end,
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
keys = {
|
keys = {
|
||||||
{ '\\', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true },
|
{ '\\', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true },
|
||||||
{
|
{ '<leader>e', ':Neotree reveal<CR>', desc = 'NeoTree reveal', silent = true },
|
||||||
'<leader>b',
|
|
||||||
function()
|
|
||||||
require('neo-tree.command').execute { toggle = true, source = 'buffers', position = 'left' }
|
|
||||||
end,
|
|
||||||
desc = 'Buffers (root dir)',
|
|
||||||
},
|
},
|
||||||
{
|
config = function()
|
||||||
'<leader>e',
|
|
||||||
function()
|
|
||||||
require('neo-tree.command').execute { toggle = true, source = 'filesystem', position = 'left' }
|
|
||||||
end,
|
|
||||||
desc = 'Filesystem (root dir)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'<leader>g',
|
|
||||||
function()
|
|
||||||
require('neo-tree.command').execute { toggle = true, source = 'git_status', position = 'left' }
|
|
||||||
end,
|
|
||||||
desc = 'Filesystem (root dir)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
config = function(_, opts)
|
|
||||||
opts.nesting_rules = require('neotree-file-nesting-config').nesting_rules
|
|
||||||
require('neo-tree').setup(opts)
|
|
||||||
|
|
||||||
local inputs = require 'neo-tree.ui.inputs'
|
local inputs = require 'neo-tree.ui.inputs'
|
||||||
-- Trash the target
|
|
||||||
local function trash(state)
|
local function trash(state)
|
||||||
local node = state.tree:get_node()
|
local node = state.tree:get_node()
|
||||||
if node.type == 'message' then
|
if node.type == 'message' then
|
||||||
|
|
@ -74,7 +48,6 @@ return {
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Trash the selections (visual mode)
|
|
||||||
local function trash_visual(state, selected_nodes)
|
local function trash_visual(state, selected_nodes)
|
||||||
local paths_to_trash = {}
|
local paths_to_trash = {}
|
||||||
for _, node in ipairs(selected_nodes) do
|
for _, node in ipairs(selected_nodes) do
|
||||||
|
|
@ -95,6 +68,25 @@ return {
|
||||||
end
|
end
|
||||||
|
|
||||||
require('neo-tree').setup {
|
require('neo-tree').setup {
|
||||||
|
-- hide_root_node + follow_current_file used to cause an infinite
|
||||||
|
-- expand_to_node/restore recursion at startup; both disabled here.
|
||||||
|
nesting_rules = require('neotree-file-nesting-config').nesting_rules,
|
||||||
|
filesystem = {
|
||||||
|
filtered_items = {
|
||||||
|
show_hidden_count = false,
|
||||||
|
never_show = { '.DS_Store' },
|
||||||
|
},
|
||||||
|
follow_current_file = {
|
||||||
|
enabled = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
default_component_configs = {
|
||||||
|
indent = {
|
||||||
|
with_expanders = true,
|
||||||
|
expander_collapsed = '',
|
||||||
|
expander_expanded = '',
|
||||||
|
},
|
||||||
|
},
|
||||||
event_handlers = {
|
event_handlers = {
|
||||||
{
|
{
|
||||||
event = 'neo_tree_buffer_enter',
|
event = 'neo_tree_buffer_enter',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
-- Auto session per cwd. Run `:lua require('persistence').load()` to restore
|
||||||
|
-- the most recent session, or use the keymaps below.
|
||||||
|
return {
|
||||||
|
'folke/persistence.nvim',
|
||||||
|
event = 'BufReadPre',
|
||||||
|
opts = {},
|
||||||
|
keys = {
|
||||||
|
{ '<leader>qs', function() require('persistence').load() end, desc = 'Restore session for cwd' },
|
||||||
|
{ '<leader>ql', function() require('persistence').load({ last = true }) end, desc = 'Restore last session' },
|
||||||
|
{ '<leader>qd', function() require('persistence').stop() end, desc = "Don't save current session" },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
-- In-buffer markdown rendering (headings, lists, code blocks, tables).
|
||||||
|
-- Applies to markdown buffers, LSP hover docs, and noice popups.
|
||||||
|
return {
|
||||||
|
'MeanderingProgrammer/render-markdown.nvim',
|
||||||
|
dependencies = { 'nvim-treesitter/nvim-treesitter', 'nvim-tree/nvim-web-devicons' },
|
||||||
|
ft = { 'markdown', 'codecompanion' },
|
||||||
|
opts = {
|
||||||
|
file_types = { 'markdown', 'codecompanion' },
|
||||||
|
completions = { lsp = { enabled = true } },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -1,18 +1,16 @@
|
||||||
|
-- Seamless nvim-split + zellij-pane navigation.
|
||||||
|
-- Replaces vim-tmux-navigator. smart-splits owns Ctrl-h/j/k/l and falls
|
||||||
|
-- through to `zellij action move-focus` when at a vim split edge.
|
||||||
return {
|
return {
|
||||||
'christoomey/vim-tmux-navigator',
|
'mrjones2014/smart-splits.nvim',
|
||||||
event = 'VeryLazy',
|
lazy = false,
|
||||||
cmd = {
|
opts = {
|
||||||
'TmuxNavigateLeft',
|
multiplexer_integration = 'zellij',
|
||||||
'TmuxNavigateDown',
|
|
||||||
'TmuxNavigateUp',
|
|
||||||
'TmuxNavigateRight',
|
|
||||||
'TmuxNavigatePrevious',
|
|
||||||
},
|
},
|
||||||
keys = {
|
keys = {
|
||||||
{ '<c-h>', '<cmd><C-U>TmuxNavigateLeft<cr>' },
|
{ '<C-h>', function() require('smart-splits').move_cursor_left() end, desc = 'Focus left split/pane' },
|
||||||
{ '<c-j>', '<cmd><C-U>TmuxNavigateDown<cr>' },
|
{ '<C-j>', function() require('smart-splits').move_cursor_down() end, desc = 'Focus down split/pane' },
|
||||||
{ '<c-k>', '<cmd><C-U>TmuxNavigateUp<cr>' },
|
{ '<C-k>', function() require('smart-splits').move_cursor_up() end, desc = 'Focus up split/pane' },
|
||||||
{ '<c-l>', '<cmd><C-U>TmuxNavigateRight<cr>' },
|
{ '<C-l>', function() require('smart-splits').move_cursor_right() end, desc = 'Focus right split/pane' },
|
||||||
{ '<c-\\>', '<cmd><C-U>TmuxNavigatePrevious<cr>' },
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
-- Persistent floating/split terminals. Replaces the hand-rolled FloatingTerm.
|
||||||
|
return {
|
||||||
|
'akinsho/toggleterm.nvim',
|
||||||
|
version = '*',
|
||||||
|
cmd = { 'ToggleTerm', 'TermExec', 'ToggleTermSendCurrentLine', 'ToggleTermSendVisualLines' },
|
||||||
|
keys = {
|
||||||
|
{ '<leader>t', '<cmd>ToggleTerm direction=float<cr>', desc = 'Toggle floating terminal' },
|
||||||
|
{ '<leader>T', '<cmd>ToggleTerm direction=horizontal<cr>', desc = 'Toggle horizontal terminal' },
|
||||||
|
},
|
||||||
|
opts = {
|
||||||
|
size = function(term)
|
||||||
|
if term.direction == 'horizontal' then
|
||||||
|
return math.floor(vim.o.lines * 0.3)
|
||||||
|
else
|
||||||
|
return math.floor(vim.o.columns * 0.4)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
open_mapping = [[<c-\>]],
|
||||||
|
direction = 'float',
|
||||||
|
float_opts = { border = 'rounded' },
|
||||||
|
start_in_insert = true,
|
||||||
|
insert_mappings = true,
|
||||||
|
terminal_mappings = true,
|
||||||
|
persist_size = true,
|
||||||
|
persist_mode = true,
|
||||||
|
shade_terminals = true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
-- Sticky-scroll style context shown at the top of the buffer.
|
||||||
|
-- Mirrors Zed's `sticky_scroll` feature.
|
||||||
|
return {
|
||||||
|
'nvim-treesitter/nvim-treesitter-context',
|
||||||
|
event = 'BufReadPost',
|
||||||
|
opts = {
|
||||||
|
max_lines = 3,
|
||||||
|
min_window_height = 20,
|
||||||
|
mode = 'cursor',
|
||||||
|
trim_scope = 'outer',
|
||||||
|
},
|
||||||
|
keys = {
|
||||||
|
{
|
||||||
|
'[c',
|
||||||
|
function()
|
||||||
|
require('treesitter-context').go_to_context(vim.v.count1)
|
||||||
|
end,
|
||||||
|
desc = 'Jump to context',
|
||||||
|
silent = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -1,50 +1,70 @@
|
||||||
return { -- Highlight, edit, and navigate code
|
-- nvim-treesitter `main` branch (required for nvim 0.11+).
|
||||||
|
-- No more `require('nvim-treesitter.configs').setup{}`. Highlighting is
|
||||||
|
-- enabled per buffer via vim.treesitter.start() in a FileType autocmd.
|
||||||
|
return {
|
||||||
'nvim-treesitter/nvim-treesitter',
|
'nvim-treesitter/nvim-treesitter',
|
||||||
|
branch = 'main',
|
||||||
|
lazy = false,
|
||||||
build = ':TSUpdate',
|
build = ':TSUpdate',
|
||||||
main = 'nvim-treesitter.configs', -- Sets main module to use for opts
|
dependencies = {
|
||||||
-- [[ Configure Treesitter ]] See `:help nvim-treesitter`
|
{ 'nvim-treesitter/nvim-treesitter-textobjects', branch = 'main' },
|
||||||
opts = {
|
|
||||||
ensure_installed = {
|
|
||||||
'go',
|
|
||||||
'gowork',
|
|
||||||
'gomod',
|
|
||||||
'gosum',
|
|
||||||
'terraform',
|
|
||||||
'bash',
|
|
||||||
'c',
|
|
||||||
'diff',
|
|
||||||
'html',
|
|
||||||
'lua',
|
|
||||||
'luadoc',
|
|
||||||
'markdown',
|
|
||||||
'markdown_inline',
|
|
||||||
'query',
|
|
||||||
'vim',
|
|
||||||
'vimdoc',
|
|
||||||
'java',
|
|
||||||
'json',
|
|
||||||
'markdown',
|
|
||||||
'nginx',
|
|
||||||
'sql',
|
|
||||||
'tmux',
|
|
||||||
'typescript',
|
|
||||||
'yaml',
|
|
||||||
},
|
},
|
||||||
-- Autoinstall languages that are not installed
|
config = function()
|
||||||
auto_install = true,
|
-- Parsers we want installed.
|
||||||
highlight = {
|
local parsers = {
|
||||||
enable = true,
|
'go', 'gowork', 'gomod', 'gosum',
|
||||||
-- Some languages depend on vim's regex highlighting system (such as Ruby) for indent rules.
|
'terraform', 'bash', 'c', 'diff', 'html', 'lua', 'luadoc',
|
||||||
-- If you are experiencing weird indenting issues, add the language to
|
'markdown', 'markdown_inline', 'query', 'vim', 'vimdoc',
|
||||||
-- the list of additional_vim_regex_highlighting and disabled languages for indent.
|
'java', 'json', 'nginx', 'sql', 'tmux', 'typescript', 'yaml',
|
||||||
additional_vim_regex_highlighting = { 'ruby' },
|
'python', 'rust', 'toml',
|
||||||
},
|
}
|
||||||
indent = { enable = true, disable = { 'ruby' } },
|
require('nvim-treesitter').install(parsers)
|
||||||
},
|
|
||||||
-- There are additional nvim-treesitter modules that you can use to interact
|
-- Start treesitter highlighting + indent for any filetype with a parser.
|
||||||
-- with nvim-treesitter. You should go explore a few and see what interests you:
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
--
|
group = vim.api.nvim_create_augroup('ts-start', { clear = true }),
|
||||||
-- - Incremental selection: Included, see `:help nvim-treesitter-incremental-selection-mod`
|
callback = function(ev)
|
||||||
-- - Show your current context: https://github.com/nvim-treesitter/nvim-treesitter-context
|
local ft = vim.bo[ev.buf].filetype
|
||||||
-- - Treesitter + textobjects: https://github.com/nvim-treesitter/nvim-treesitter-textobjects
|
local lang = vim.treesitter.language.get_lang(ft)
|
||||||
|
if not lang then return end
|
||||||
|
local ok = pcall(vim.treesitter.start, ev.buf, lang)
|
||||||
|
if ok then
|
||||||
|
vim.bo[ev.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Treesitter-aware textobjects + motion.
|
||||||
|
local move = require('nvim-treesitter-textobjects.move')
|
||||||
|
local select = require('nvim-treesitter-textobjects.select')
|
||||||
|
|
||||||
|
-- Select: vif/vaf (function inner/outer), vac/vic (class), vaa/via (parameter).
|
||||||
|
local function map_select(key, query)
|
||||||
|
vim.keymap.set({ 'x', 'o' }, key, function()
|
||||||
|
select.select_textobject(query, 'textobjects')
|
||||||
|
end, { desc = 'TS select ' .. query })
|
||||||
|
end
|
||||||
|
map_select('af', '@function.outer')
|
||||||
|
map_select('if', '@function.inner')
|
||||||
|
map_select('ac', '@class.outer')
|
||||||
|
map_select('ic', '@class.inner')
|
||||||
|
map_select('aa', '@parameter.outer')
|
||||||
|
map_select('ia', '@parameter.inner')
|
||||||
|
map_select('al', '@loop.outer')
|
||||||
|
map_select('il', '@loop.inner')
|
||||||
|
|
||||||
|
-- Move: ]m / [m / ]M / [M between functions.
|
||||||
|
vim.keymap.set({ 'n', 'x', 'o' }, ']m',
|
||||||
|
function() move.goto_next_start('@function.outer', 'textobjects') end,
|
||||||
|
{ desc = 'TS next function start' })
|
||||||
|
vim.keymap.set({ 'n', 'x', 'o' }, ']M',
|
||||||
|
function() move.goto_next_end('@function.outer', 'textobjects') end,
|
||||||
|
{ desc = 'TS next function end' })
|
||||||
|
vim.keymap.set({ 'n', 'x', 'o' }, '[m',
|
||||||
|
function() move.goto_previous_start('@function.outer', 'textobjects') end,
|
||||||
|
{ desc = 'TS prev function start' })
|
||||||
|
vim.keymap.set({ 'n', 'x', 'o' }, '[M',
|
||||||
|
function() move.goto_previous_end('@function.outer', 'textobjects') end,
|
||||||
|
{ desc = 'TS prev function end' })
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
-- Pretty diagnostics / LSP refs / TODO / quickfix lists.
|
||||||
|
return {
|
||||||
|
'folke/trouble.nvim',
|
||||||
|
cmd = 'Trouble',
|
||||||
|
opts = {},
|
||||||
|
keys = {
|
||||||
|
{ '<leader>xx', '<cmd>Trouble diagnostics toggle<cr>', desc = '[T]rouble diagnostics' },
|
||||||
|
{ '<leader>xX', '<cmd>Trouble diagnostics toggle filter.buf=0<cr>', desc = '[T]rouble buffer diagnostics' },
|
||||||
|
{ '<leader>xs', '<cmd>Trouble symbols toggle focus=false<cr>', desc = '[T]rouble symbols' },
|
||||||
|
{ '<leader>xr', '<cmd>Trouble lsp toggle focus=false win.position=right<cr>', desc = '[T]rouble LSP refs/defs' },
|
||||||
|
{ '<leader>xl', '<cmd>Trouble loclist toggle<cr>', desc = '[T]rouble loclist' },
|
||||||
|
{ '<leader>xq', '<cmd>Trouble qflist toggle<cr>', desc = '[T]rouble quickfix' },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
-- Mirrors common Zed bindings for muscle-memory continuity.
|
||||||
|
-- Source from init.lua: require('custom.zed-keymaps').
|
||||||
|
|
||||||
|
-- Move lines (Zed: alt-j / alt-k).
|
||||||
|
vim.keymap.set('n', '<A-j>', ':m .+1<CR>==', { desc = 'Move line down', silent = true })
|
||||||
|
vim.keymap.set('n', '<A-k>', ':m .-2<CR>==', { desc = 'Move line up', silent = true })
|
||||||
|
vim.keymap.set('v', '<A-j>', ":m '>+1<CR>gv=gv", { desc = 'Move selection down', silent = true })
|
||||||
|
vim.keymap.set('v', '<A-k>', ":m '<-2<CR>gv=gv", { desc = 'Move selection up', silent = true })
|
||||||
|
|
||||||
|
-- Lowercase gi for implementation (Zed: g i; existing gI still works).
|
||||||
|
vim.keymap.set('n', 'gi', function()
|
||||||
|
require('telescope.builtin').lsp_implementations()
|
||||||
|
end, { desc = '[G]oto [I]mplementation' })
|
||||||
|
|
||||||
|
-- Zed-parity: F2 to rename, <leader>. for code action (mirrors cmd-.),
|
||||||
|
-- <leader>fc for command palette.
|
||||||
|
vim.keymap.set('n', '<F2>', vim.lsp.buf.rename, { desc = 'LSP rename' })
|
||||||
|
vim.keymap.set('n', '<leader>.', vim.lsp.buf.code_action, { desc = 'Code action' })
|
||||||
|
vim.keymap.set('n', '<leader>fc', function() require('telescope.builtin').commands() end, { desc = '[F]ind [C]ommand' })
|
||||||
|
|
||||||
|
-- Full-buffer git blame (Zed: g b).
|
||||||
|
vim.keymap.set('n', 'gb', function()
|
||||||
|
require('gitsigns').blame()
|
||||||
|
end, { desc = '[G]it [B]lame buffer' })
|
||||||
|
|
||||||
|
-- Close current buffer (Zed: space x).
|
||||||
|
vim.keymap.set('n', '<leader>x', '<cmd>bd<cr>', { desc = 'Close buffer' })
|
||||||
|
|
||||||
|
-- Workspace symbols (Zed: space f e).
|
||||||
|
vim.keymap.set('n', '<leader>fe', function()
|
||||||
|
require('telescope.builtin').lsp_dynamic_workspace_symbols()
|
||||||
|
end, { desc = '[F]ind workspace symbols' })
|
||||||
|
|
||||||
|
-- Task spawner: floating zellij pane when in zellij, fallback to nvim split term.
|
||||||
|
local function task(cmd)
|
||||||
|
return function()
|
||||||
|
if vim.env.ZELLIJ ~= nil and vim.env.ZELLIJ ~= '' then
|
||||||
|
vim.fn.jobstart({
|
||||||
|
'zellij', 'action', 'new-pane', '--floating',
|
||||||
|
'--close-on-exit', '--', '/bin/zsh', '-lc', cmd,
|
||||||
|
}, { detach = true })
|
||||||
|
else
|
||||||
|
vim.cmd('botright 15split | terminal ' .. cmd)
|
||||||
|
vim.cmd('startinsert')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Task bindings (mirror Zed's tasks.json).
|
||||||
|
vim.keymap.set('n', '<leader>gh', task('gh dash'), { desc = '[G]itHub das[H]board' })
|
||||||
|
vim.keymap.set('n', '<leader>kk', task('k9s'), { desc = '[K]9s' })
|
||||||
|
vim.keymap.set('n', '<leader>bb', task('cd bruno && bru run --env Local --insecure --tests-only'), { desc = '[B]runo tests' })
|
||||||
|
vim.keymap.set('n', '<leader>uu', task('cd restopay && make up'), { desc = 'Make [U]p' })
|
||||||
|
vim.keymap.set('n', '<leader>dd', task('cd restopay && make down'), { desc = 'Make Do[w]n' })
|
||||||
|
vim.keymap.set('n', '<leader>aa', task(
|
||||||
|
'hv athenz user-cert --system=public && awscreds -d vespa.external.factory -r admin -p external-factory -z public'
|
||||||
|
), { desc = 'Update certs for External-Factory' })
|
||||||
Loading…
Reference in New Issue