mirror of
https://github.com/dwinkler1/nvimConfig.git
synced 2026-08-22 17:43:13 -04:00
Compare commits
21 changed files with 349 additions and 614 deletions
14
.github/workflows/check.yml
vendored
14
.github/workflows/check.yml
vendored
|
|
@ -5,20 +5,12 @@ on:
|
||||||
paths:
|
paths:
|
||||||
- 'flake.lock'
|
- 'flake.lock'
|
||||||
- 'flake.nix'
|
- 'flake.nix'
|
||||||
- 'modules/**'
|
- 'modules'
|
||||||
- 'plugin/**'
|
|
||||||
- 'lua/**'
|
|
||||||
- 'overlays/**'
|
|
||||||
- 'ftplugin/**'
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'flake.lock'
|
- 'flake.lock'
|
||||||
- 'flake.nix'
|
- 'flake.nix'
|
||||||
- 'modules/**'
|
- 'modules'
|
||||||
- 'plugin/**'
|
|
||||||
- 'lua/**'
|
|
||||||
- 'overlays/**'
|
|
||||||
- 'ftplugin/**'
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
@ -43,5 +35,5 @@ jobs:
|
||||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||||
extraPullNames: rstats-on-nix, nix-community
|
extraPullNames: rstats-on-nix, nix-community
|
||||||
- run: nix build
|
- run: nix build
|
||||||
- run: nix develop -c echo ok
|
- run: nix develop
|
||||||
- run: nix flake check
|
- run: nix flake check
|
||||||
|
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
# CodeCompanion Revamp Plan
|
|
||||||
|
|
||||||
## Context
|
|
||||||
|
|
||||||
- Current: CodeCompanion **19.18.0** via nixpkgs `vimPlugins.codecompanion-nvim` (nixpkgs input lastModified ~2026-05-15).
|
|
||||||
- Latest: **19.20.0**. Key changes since 19.18.0:
|
|
||||||
- v19.19.0: `claude-sonnet-5` support, async/dynamic model fetching, copilot `top_p` fixes, inline orphaned-keymap fix, background command deregistration.
|
|
||||||
- v19.20.0: `gemini_interactions` adapter, PDF support for http adapters (`/file` on Anthropic/Copilot/OpenAI/OpenRouter), env vars from files, prompt-library items auto-receive default rule groups, copilot schema options removed.
|
|
||||||
- **Bug in current setup:** config sets `model = "claude-sonnet-5"` but 19.18.0 predates its support; the model name may not resolve. The nixpkgs bump fixes this.
|
|
||||||
- Files involved:
|
|
||||||
- `plugin/24_completion.lua` — `get_codecompanion_config()`, setup, blink integration.
|
|
||||||
- `plugin/10_keymap.lua` — `<leader>a*` keymaps (lines 69–84, contains duplicates/commented cruft).
|
|
||||||
- `overlays/plugins.nix` — codecompanion overlay (nvimSkipModules); likely unchanged.
|
|
||||||
- `modules/module/specs/plugins.nix` — plugin spec; unchanged.
|
|
||||||
|
|
||||||
## Decisions (confirmed with user)
|
|
||||||
|
|
||||||
1. **Version bump:** `nix flake update nixpkgs` (accepts wider plugin bump; do NOT override src).
|
|
||||||
2. **Adopt:** agent-mode keymaps, one workflow prompt, minor slash-command config (`/share` token). **No MCP.**
|
|
||||||
3. **Models:** `claude-sonnet-5` (copilot) for **chat only**; cheaper copilot model for **inline** and **background** (title generation) — use `gpt-5-mini` as placeholder; verify exact model id via `ga` model picker in a chat buffer after the bump and adjust.
|
|
||||||
4. **Codex (ChatGPT Edu) = heavy agent lane.** Copilot stays the default chat adapter; Codex ACP is launched explicitly for heavy autonomous tasks. Auth via ChatGPT login only (no API key) — user's existing `auth_method = "chatgpt"` is correct per the v19.20.0 adapter source (`"openai-api-key"|"codex-api-key"|"chatgpt"`; the docs page comment `"chat-gpt"` is stale).
|
|
||||||
|
|
||||||
## Tasks
|
|
||||||
|
|
||||||
1. **Bump nixpkgs**
|
|
||||||
- Run `nix flake update nixpkgs`.
|
|
||||||
- Verify: `nix eval --raw nixpkgs#vimPlugins.codecompanion-nvim.version` reports ≥ 19.20.0.
|
|
||||||
- Rebuild the wrapped Neovim per this repo's normal build (`nix build` / the repo's usual package target) and smoke-test that the editor starts.
|
|
||||||
|
|
||||||
2. **`plugin/24_completion.lua` — `get_codecompanion_config()`**
|
|
||||||
- Keep `interactions.chat.adapter = { name = "copilot", model = "claude-sonnet-5" }`.
|
|
||||||
- Change `interactions.inline.adapter` to `{ name = "copilot", model = "gpt-5-mini" }` (cheap/fast).
|
|
||||||
- Add a background adapter so title generation doesn't use Sonnet: set the background chat adapter to copilot/`gpt-5-mini` (config lives under `interactions.background.chat`; confirm exact key against `:h codecompanion` / `:checkhealth codecompanion` after the bump — the docs page "Generating Titles" says an adapter must be configured for background interactions).
|
|
||||||
- Keep existing context_management, rules, display, shared keymaps unchanged.
|
|
||||||
- Add `interactions.chat.slash_commands["share"].opts.token = os.getenv("GITHUB_GIST_TOKEN")`.
|
|
||||||
- **Prompt library additions** (keep `expert`, `fixer`, `suggest`):
|
|
||||||
- `["agent"]`: interaction "chat", alias `agent`, first user prompt starts with `@{agent}` plus selected code block, so Copilot/Claude gets the file-editing tool group (read_file, insert_edit_into_file, grep_search, run_command, etc., with approvals).
|
|
||||||
- `["tdd"]` (name flexible): interaction "chat", `opts = { is_workflow = true, alias = "tdd" }` — 3-stage workflow: (1) plan/understand `#buffer`, (2) `@{agent}` implement, (3) `@{run_command}` run the test suite (leverages run_command's test-flag for agentic workflows).
|
|
||||||
|
|
||||||
3. **`plugin/10_keymap.lua` — clean up + add**
|
|
||||||
- Remove duplicated/commented lines (70–71, 77, 81).
|
|
||||||
- Add:
|
|
||||||
- `nmap_leader("aa", "<cmd>CodeCompanionChat<CR>", "Agent chat (use @{agent})")` or directly `<cmd>CodeCompanion /agent<CR>`.
|
|
||||||
- `xmap_leader("aa", "<cmd>CodeCompanion /agent<CR>", "Agent on selection")`.
|
|
||||||
- `nmap_leader("aw", "<cmd>CodeCompanion /tdd<CR>", "Workflow: plan→implement→test")`.
|
|
||||||
- `nmap_leader("aC", "<cmd>CodeCompanion /compact<CR>", "Compact chat")` (verify `<leader>aC` doesn't clash).
|
|
||||||
- Keep existing mappings unchanged.
|
|
||||||
|
|
||||||
4. **No changes** to `overlays/plugins.nix` or `modules/module/specs/plugins.nix` unless the new version introduces new lazy-module load failures (re-run the build's check phase; `doCheck = false` is already set on the spec entry).
|
|
||||||
|
|
||||||
5. **Codex ACP lane (ChatGPT Edu)**
|
|
||||||
- **Resolved prerequisite:** user has installed `codex-acp` at `~/.nix-profile/bin/codex-acp` (verified on PATH 2026-07-24). The preset adapter's default command (`codex-acp`) now works as-is — **no `commands` override in the Lua config**. Fallback only if the binary misbehaves: override with `commands = { default = { "codex", "acp" } }` (requires the codex CLI's built-in `acp` subcommand; verify with `codex acp --help`).
|
|
||||||
- **Config change (small):** none strictly required — the existing `extend("codex", { defaults = { auth_method = "chatgpt" } })` block in `plugin/24_completion.lua` is correct. Keep it.
|
|
||||||
- Auth: prereq is an active `codex login` session with the ChatGPT Edu account (`~/.codex/auth.json` exists — user confirms validity; if expired, re-run `codex login`, browser/ChatGPT-app flow, no API key).
|
|
||||||
- Keep codex on-demand (do NOT make it the default chat adapter):
|
|
||||||
- Keep `<leader>ak` (`:CodeCompanionChat adapter=codex`).
|
|
||||||
- Add comment documenting ACP-only slash commands for this lane: `/resume` (restore past codex session, fresh chat only), `/mode` (switch agent mode), `/command`, `/acp_session_options`, plus `\`-triggered ACP command completion in the chat buffer.
|
|
||||||
- Do not set a default codex model in config; pick per-session via `ga` / `/acp_session_options` (avoids hardcoding model ids that change with the Edu plan).
|
|
||||||
- PATH note: Neovim must inherit a PATH containing `~/.nix-profile/bin` so the spawned `codex-acp` resolves — true when nvim is launched from the user's normal shell; call it out if validation fails with "command not found".
|
|
||||||
|
|
||||||
6. **Docs/habit notes** (add as comment block above the codecompanion setup, no separate docs file): `/compact`, `/fork`, `/symbols`, `/share`, `/resume`+`/mode` (codex ACP), `gm` (btw), `gty` (YOLO), `gba`/`gbd` (buffer sync), `gd` (debug window).
|
|
||||||
|
|
||||||
## Validation
|
|
||||||
|
|
||||||
- `nix flake update nixpkgs` then repo build succeeds.
|
|
||||||
- In Neovim: `:checkhealth codecompanion` clean.
|
|
||||||
- `:CodeCompanionChat`, press `ga` → copilot adapter lists `claude-sonnet-5`; send a trivial message and confirm response + auto title generation.
|
|
||||||
- In chat: type `@` → completion shows `agent`, `files`, `memory`, etc.; run `@{agent}` task on a scratch repo and confirm the approval prompt flow works.
|
|
||||||
- `:CodeCompanion /tdd` starts the workflow stages in order.
|
|
||||||
- Inline: visual-select code, `:CodeCompanion` prompt → confirm diff shows and `ga`/`gr` accept/reject still work on the cheap model.
|
|
||||||
- `:CodeCompanion /share` prompts/errors sensibly if `GITHUB_GIST_TOKEN` unset.
|
|
||||||
- **Codex lane:** `<leader>ak` opens a chat with the codex ACP adapter; the spawned `codex-acp` process initializes without auth errors (ChatGPT method), a trivial prompt gets a response, and `/mode` lists codex session modes. If it fails with command-not-found, check that Neovim inherited `~/.nix-profile/bin` in PATH (`:echo $PATH` inside nvim).
|
|
||||||
|
|
||||||
## Risks
|
|
||||||
|
|
||||||
- `nix flake update nixpkgs` bumps **all** vimPlugins and Neovim itself; other plugins may break. If the blast radius is too large, fall back to overriding codecompanion `src` to tag `v19.20.0` in `overlays/plugins.nix` (fetchFromGitHub, `doCheck = false`).
|
|
||||||
- Model ids (`claude-sonnet-5`, `gpt-5-mini`) must match the copilot adapter's choices post-bump; verify via `ga` picker and adjust literals.
|
|
||||||
- `gpt-5-mini` may not support tool use on copilot — fine, since inline/background don't use tools.
|
|
||||||
- `codex-acp` lives in the user's nix profile (outside this flake). If the profile is rebuilt/removed, the codex lane breaks — long-term consider adding `codex-acp` to this flake's runtime deps so it's pinned with the rest of the setup (optional follow-up, not required now).
|
|
||||||
- ChatGPT Edu accounts authenticate codex via browser/ChatGPT-app login; token expiry will surface as ACP auth errors → re-run `codex login`.
|
|
||||||
|
|
||||||
## Out of scope
|
|
||||||
|
|
||||||
- MCP server integration.
|
|
||||||
- Custom rules parsers, custom tools, extensions (mcphub/history/vectorcode).
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
# Neovim + Nix setup review
|
|
||||||
|
|
||||||
Scope: `flake.nix`, `overlays/`, `modules/`, `plugin/*.lua`, `lua/*`, `ftplugin/*`, CI/workflows, and cross-check against the pinned versions in `flake.lock` (nixpkgs weekly `241313f4`).
|
|
||||||
|
|
||||||
## Pinned package versions (from current lock)
|
|
||||||
- neovim `0.12.2`
|
|
||||||
- blink-cmp `1.10.2`
|
|
||||||
- codecompanion-nvim `19.13.0`
|
|
||||||
- nvim-treesitter `0.10.0-unstable-2026-04-03` (main-branch rewrite)
|
|
||||||
- nvim-treesitter-textobjects `0-unstable-2026-04-07` (main-branch rewrite)
|
|
||||||
- copilot-lua `2.0.3`
|
|
||||||
- render-markdown-nvim `8.12.0-unstable-2026-05-07`
|
|
||||||
- zk-nvim `0.4.7-unstable-2026-03-13`
|
|
||||||
- mini.nvim `0.17.0-unstable-2026-05-12`
|
|
||||||
- quarto-nvim `2.1.0`
|
|
||||||
- otter-nvim `2.14.5`
|
|
||||||
- lspconfig `2.9.0`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CRITICAL: Treesitter is currently non-functional
|
|
||||||
|
|
||||||
### Finding
|
|
||||||
The nixpkgs `nvim-treesitter` package is the **main-branch rewrite** — there is no `lua/nvim-treesitter/configs.lua`. The whole module in `plugin/20_startup.lua` lines 212-294 is dead code:
|
|
||||||
|
|
||||||
```lua
|
|
||||||
local ok_configs, configs = pcall(require, "nvim-treesitter.configs") -- fails
|
|
||||||
```
|
|
||||||
|
|
||||||
The working tree already removed the fallback `vim.treesitter.start()` FileType autocmd (the "fixed treesitter" commit deleted it). Net result: **no treesitter highlighting, indentexpr, foldexpr, or textobjects are configured**.
|
|
||||||
|
|
||||||
### Impact
|
|
||||||
- Syntax highlighting falls back to Neovim's regex-only engine.
|
|
||||||
- All textobject keymaps (`]a`, `[a`, `]f`, `[f`, `]e`/`[e`, `<leader>x`/`X`, lsp_interop `<leader>lm`) are inert.
|
|
||||||
- `foldexpr`/`indentexpr` based folding does nothing.
|
|
||||||
|
|
||||||
### Fix direction
|
|
||||||
Rewrite `plugin/20_startup.lua` for main-branch API:
|
|
||||||
1. FileType autocmd → `vim.treesitter.start()` (and optionally `indentexpr`/`foldexpr`).
|
|
||||||
2. `require("nvim-treesitter-textobjects").setup({ move = { set_jumps = true } })` + explicit keymaps using `move.goto_next_start(query, "textobjects")` and `swap.swap_next(...)`.
|
|
||||||
3. The non-Nix `ensure_installed` block should set `opts.ensure_installed` BEFORE the filter (line 278 reads it before line 286 defines it).
|
|
||||||
|
|
||||||
Also remove duplicate `vim.treesitter.language.register("markdown", ...)` between `plugin/20_startup.lua` and `plugin/21_datascience.lua`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CodeCompanion version mismatch
|
|
||||||
|
|
||||||
### Finding
|
|
||||||
Config targets features absent in `19.13.0` (present only in `≥19.19.0`/main):
|
|
||||||
|
|
||||||
| Config usage | Present in 19.13? | Present in main (`v19.20.0`) |
|
|
||||||
|---|---|---|
|
|
||||||
| `interactions.chat.opts.context_management.editing` | No (flat `trigger`/`enabled` only) | Yes |
|
|
||||||
| `interactions.chat.opts.context_management.compaction` | No | Yes |
|
|
||||||
| `<leader>aC` requiring `codecompanion.interactions.chat.context_management.compaction` | **RUNTIME ERROR** | Works |
|
|
||||||
| `slash_commands.share` (`opts.token = ...`) | No (absent from defaults) | Yes |
|
|
||||||
| `adapters.acp.codex.defaults.auth_method = "chatgpt"` | Yes | Yes |
|
|
||||||
| `interactions.chat.adapter = { name = ..., model = ... }` table form | Yes | Yes |
|
|
||||||
|
|
||||||
### Risk
|
|
||||||
On today's lock (`19.13.0`): `/share` is inert, compaction-only keymap throws module-not-found, and `editing`/`compaction` tuning is silently ignored. On `≥19.19.0`/main: everything works.
|
|
||||||
|
|
||||||
### Decision needed (BLOCKING)
|
|
||||||
Choose **exactly one**:
|
|
||||||
|
|
||||||
- **A — Upgrade the plugin pin** (`overlays/plugins.nix` fetch to `v19.20.0` or `main`, bump the lock, and keep the current config). Riskiest change but matches what the config is written for.
|
|
||||||
- **B — Downgrade config call sites** to match `19.13.0`: remove `slash_commands.share`, remove `editing`/`compaction` keys (or collapse to flat `trigger: 0.75`), remove or gate `<leader>aC` on "newer" version.
|
|
||||||
- **C — Version-gate the config**: keep current code, read the installed version at startup and skip the new features when < 19.19.
|
|
||||||
|
|
||||||
I recommend A (the config clearly intends to track upstream main-ish behavior; `nix flake update` already bumped it to `19.18.0` in a prior session and you only reverted because the nightly was still too old — `v19.20.0` is now available).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## DEAD / DUPLICATE code
|
|
||||||
|
|
||||||
- `plugin/20_startup.lua` — the entire `configs.setup(opts)` block is dead (see Treesitter finding above).
|
|
||||||
- `plugin/10_keymap.lua`:
|
|
||||||
- `nmap_leader('od', '<Cmd>Neogen<CR>', ...)` — `neogen` plugin is **not shipped** in `specs/plugins.nix`. Mapping errors on press.
|
|
||||||
- `nmap_leader('fp', '<Cmd>Pick projects<CR>', ...)` — `MiniExtra.pickers.projects` doesn't exist in mini.extra; would error.
|
|
||||||
- `nmap_leader('oS', '<Cmd>lua Config.insert_section()<CR>', ...)` — `Config.insert_section` is never defined.
|
|
||||||
- `vim.lsp.buf.definition()` is bound to `grd`; Neovim 0.11+ defaults include `gr` aliases. Cosmetic, but `]d`/`[d` exist on modern LSP config and would be more idiomatic.
|
|
||||||
- `plugin/23_editor.lua`:
|
|
||||||
- `my_styler` formatter (calls `R -s -e styler::...`) is defined but never referenced — dead.
|
|
||||||
- `plugin/24_completion.lua`:
|
|
||||||
- `providers.cmp_r` is defined in the blink source list but never enabled in `default` or `per_filetype`; inert.
|
|
||||||
- `BLINK_VERSION = "v1.4.1"` — only consulted in the non-Nix install path; nixpkgs is `1.10.2`. Pin it to current or drop.
|
|
||||||
- `get_blink_fuzzy_setting().prebuilt_binary = { force_version = BLINK_VERSION }` — singular key is wrong; blink option is `fuzzy.prebuilt_binaries` (plural). Being skipped in-Nix anyway, but still wrong key.
|
|
||||||
- `modules/module/specs/plugins.nix` — `specs.utils-lazy` ships `nvim-dap*` and `nvim-lint` but there is zero config/tooling that references them in this repo.
|
|
||||||
- `ftplugin/quarto.lua`:
|
|
||||||
- Second top-level `require('quarto').setup()` with **no args** runs _after_ `21_datascience.lua`'s setup and **resets** it to defaults (no `lspFeatures`, no `codeRunner`).
|
|
||||||
- Top-level `require('quarto')` at FileType load also crashes if the quarto plugin isn't installed (e.g. cats off and a `.qmd`/`.quarto` file is opened): Neovim detects `quarto` ft natively in 0.10+.
|
|
||||||
- `plugin/00_options.lua`:
|
|
||||||
- Lines 146-163: two back-to-back FileType autocmds that both remove `r`/`o` from `formatoptions`. The second references an undefined `augroup` variable (nil → autocmd is global, happens to still work).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## STALE / WRONG options
|
|
||||||
|
|
||||||
- `plugin/10_keymap.lua` line 174:
|
|
||||||
```lua
|
|
||||||
require("conform").format({ lsp_fallback = true })
|
|
||||||
```
|
|
||||||
`lsp_fallback` is the **deprecated** boolean form of `conform.nvim`; should be `lsp_format = "fallback"` (the form already used in `plugin/23_editor.lua` and `ftplugin/python.lua`). In newer conform this may warn or error.
|
|
||||||
- `ftplugin/quarto.lua`:
|
|
||||||
- Sets `<Plug>RDSendLine` and R-style keymaps on _all_ quarto buffers, including Python/Julia chunks. This collides with quarto-runner mappings set in `21_datascience.lua`. Should gate on `vim.bo.filetype == "r"` (the ftplugin already imports quarto.runner for python, but the R keys leak).
|
|
||||||
- `.github/dependapot.yml` — filename typo. GitHub expects `dependabot.yml`; Dependabot won't run.
|
|
||||||
- `.github/workflows/check.yml`:
|
|
||||||
- `nix develop` without a `-c` command just launches an interactive shell. In CI it does nothing useful (or hangs). Replace with `nix develop -c echo ok` or drop.
|
|
||||||
- Path filter `'modules'` only matches the root directory itself; should be `modules/**` (or `'modules/**'`).
|
|
||||||
- Changing `plugin/`, `lua/`, `overlays/`, `ftplugin/`, etc. does **not** trigger CI.
|
|
||||||
- `flake.nix` / `.envrc` shellHook:
|
|
||||||
```sh
|
|
||||||
export R_LIBS_SITE=$(strings "$(command -v R)" | grep -oP '/nix/store/[^:]+/library' ...)
|
|
||||||
```
|
|
||||||
`grep -oP` (PCRE) is **not available in macOS BSD grep**. On `aarch64-darwin` this silently fails → `R_LIBS_SITE` is empty. Either depend on `ripgrep` regex (`strings ... | rg -o '...'`) or use `gsed` (GNU sed).
|
|
||||||
- `overlays/plugins.nix` — `zk-nvim` skip list contains `zk.pickers.fzf_lua`; current zk-nvim package likely doesn't load that regardless, but harmless.
|
|
||||||
- `modules/module/settings/core.nix` — `config.settings.nvim_lua_env` references `lp.tiktoken_core` but `tiktoken_core` is **not in `catPkgs.general` or anywhere else** in these files. If there's an extra Lua/tiktoken module, fine; otherwise this option is placeholder dead code.
|
|
||||||
- `modules/module/settings/hosts.nix` — host `m` (marimo) is defined with `enable = false` but also configured with `package`, `argv0`, `addFlag`. Dead block.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PORTABILITY / DARWIN issues
|
|
||||||
|
|
||||||
- Shell hook `grep -oP` (above) fails on macOS.
|
|
||||||
- `mkdir -p "$R_LIBS_USER"` fine; but `command -v R` on macOS returns the wrapper; the wrapper path injection still works.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## DEAD WEIGHT (shipped but unused)
|
|
||||||
|
|
||||||
- `catPkgs.r` includes `pkgs.rnvimserver` — `rnvimserver` is needed by R.nvim only when using the _socket_ transport; `21_datascience.lua` only uses vim-slime. Acceptable, but `rnvimserver` adds to build time. Include if you actually use it? Currently not used.
|
|
||||||
- `specs.utils-lazy` ships `nvim-dap`, `nvim-dap-ui`, `nvim-dap-virtual-text`, `nvim-lint` — none of these are referenced anywhere in `plugin/` or `lua/`. Consider moving them to a devShell-only cat, or drop them.
|
|
||||||
- `.gitignore` `*.R` — prevents tracking any new `.R` files. `tests/test.R` is already committed so it isn't actively harmful, but it's surprising for a repo whose default cats include R.
|
|
||||||
- `.commandcode/` dir is listed in `.gitignore` but is in the worktree; fine, but worth cleaning up if it's an artifact.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## IMPROVEMENTS given updated packages
|
|
||||||
|
|
||||||
- `catPkgs.markdown` — add `marksman` (it's the LSP used by `render-markdown.nvim` wiki links and configured in LSP). Same binary is needed by `render-markdown` for wiki link ISP.
|
|
||||||
- `vim.lsp.enable` servers configured but binaries missing in PATH:
|
|
||||||
- `marksman` (LSP + render-markdown wiki integration).
|
|
||||||
- `r_ls` (new R language server — package name in nixpkgs is likely `r-languageserver` or `r_ls`; current `catPkgs.r` doesn't ship either).
|
|
||||||
- `clangd` — not required for this data-science setup; either drop or add to `external`.
|
|
||||||
- `julials` — require `LanguageServer.jl` in `settings.lang_packages.julia` for it to be useful.
|
|
||||||
- `blink.cmp` is `1.10.2` but config pins `BLINK_VERSION = "v1.4.1"` for the non-Nix path. Either drop the `BLINK_VERSION` constant (let MiniDeps track HEAD or the tag pinned in flake) or update it to `v1.10.2`.
|
|
||||||
- `conform.nvim` already uses `lsp_format = "fallback"` in `23_editor.lua` and `ftplugin/python.lua`, but `10_keymap.lua` still calls the deprecated `lsp_fallback = true`. Align to `lsp_format = "fallback"`.
|
|
||||||
- `.github/workflows/check.yml` — add path filters for `plugin/**`, `lua/**`, `overlays/**`, `ftplugin/**`, `modules/**`.
|
|
||||||
- `tests/init.lua` smoke-test and `tests/test.R` are present but **not wired into `nix flake check`**. Add a trivial check that runs `lua tests/init.lua` via `nix-shell -A ...`.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CONFLICTS
|
|
||||||
|
|
||||||
- `<leader>up` (terminal bracketed paste toggle in `10_keymap.lua`) conflicts with `mini.basics.mappings.option_toggle_prefix = "<leader>u"` (paste toggle), which is set up later in `20_startup.lua` via `now()`. Result: the user's `<leader>up` mapping gets overwritten. Portable workaround: remap to `<leader>tp` (terminal namespace) and keep `<leader>tb` as alternative — both already mapped in 10_keymap.
|
|
||||||
- `ftplugin/quarto.lua` resets quarto-nvim config (kills `lspFeatures`/`codeRunner` set in `21_datascience.lua`) and injects R plug mappings into non-R quarto chunks.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CLEAN summary for implementer
|
|
||||||
|
|
||||||
### Immediate (not version-dependent)
|
|
||||||
1. Restore treesitter highlighting + textobjects in `plugin/20_startup.lua` using main-branch API.
|
|
||||||
2. Remove duplicate `vim.treesitter.language.register` in `21_datascience.lua`.
|
|
||||||
3. Fix `plugin/10_keymap.lua`: remove/resolve `Neogen`, `Pick projects`, `Config.insert_section` dangling mappings.
|
|
||||||
4. Replace deprecated `lsp_fallback = true` with `lsp_format = "fallback"` in `plugin/10_keymap.lua`.
|
|
||||||
5. Gate `ftplugin/quarto.lua` to not reset config and to not leak R keys into non-R chunks; guard against missing `quarto` plugin.
|
|
||||||
6. Remove duplicate `formatoptions` autocmds (or at least dedupe).
|
|
||||||
7. Dedupe `RNVIM_COMPLDIR` / `TMPDIR` setup (do it in one place).
|
|
||||||
8. Rename `.github/dependapot.yml` to `.github/dependabot.yml`.
|
|
||||||
9. Remove or gate dead host `m` in `hosts.nix`.
|
|
||||||
10. Remove unused `rsplit`? no, irrelevant.
|
|
||||||
11. Add `marksman` to `catPkgs.markdown` and remove orphan LSP entries or ship the binaries.
|
|
||||||
12. Remove dead `conform` formatter `my_styler` and dead blink `cmp_r` provider, or wire them up.
|
|
||||||
|
|
||||||
### Version-dependent (BLOCKED)
|
|
||||||
- **Reset the CodeCompanion version decision**: either pin to `v19.20.0` (keep config, fix `slash_commands.share`, drop the `<leader>aC` compatibility shim, keep `editing`/`compaction`) OR downgrade config to match `19.13.0` (remove `share`, collapse `context_management`).
|
|
||||||
|
|
||||||
### CI / packaging
|
|
||||||
- Fix `nix develop` usage and path filters in `.github/workflows/check.yml`.
|
|
||||||
- Replace `grep -oP` in `flake.nix` shellHook with portable `rg -o` or add `gnused` to `catPkgs.always` and use `gsed`.
|
|
||||||
- Wire `tests/init.lua` into `flake check`.
|
|
||||||
|
|
||||||
### Verification
|
|
||||||
- `nix flake check` on both `aarch64-darwin` and `x86_64-linux`.
|
|
||||||
- `nix build .#packages.<system>.default` succeeds (already does).
|
|
||||||
- Start nvim, verify :TSContext works, treesitter highlighting is on, and `]f`/`[f` textobjects move.
|
|
||||||
- Open a `.qmd` file with cats off → no ftplugin crash.
|
|
||||||
- Confirm `<leader>up` still toggles bracketed paste.
|
|
||||||
- Confirm `:Pick projects` and `:Neogen` and `Config.insert_section` no longer error (or are mapped to valid handlers).
|
|
||||||
34
flake.lock
generated
34
flake.lock
generated
|
|
@ -7,11 +7,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1781337902,
|
"lastModified": 1776413584,
|
||||||
"narHash": "sha256-QjXxUvpOBbnlpSskBOZJ9nUbpYyFRD4cBo4s1aHniGs=",
|
"narHash": "sha256-xqqv46MTveuT4yJH2YihmbHGy5mdLnnLFDebVmUws/E=",
|
||||||
"owner": "dwinkler1",
|
"owner": "dwinkler1",
|
||||||
"repo": "fran",
|
"repo": "fran",
|
||||||
"rev": "30ab141871ede23b245a90afea58e076ef83b515",
|
"rev": "da09626e4dd8f0f57078b3a04e0443a8c20defa1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -22,11 +22,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784796856,
|
"lastModified": 1778869304,
|
||||||
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
|
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
|
"rev": "d233902339c02a9c334e7e593de68855ad26c4cb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -60,16 +60,16 @@
|
||||||
"rnvimsrc": "rnvimsrc"
|
"rnvimsrc": "rnvimsrc"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1784867506,
|
"lastModified": 1781392459,
|
||||||
"narHash": "sha256-5zXVJLG7+Gi9sgb4Dn7P6O/ywQQxpvcjjoHSJXZEuVo=",
|
"narHash": "sha256-9CMG+trBd9AX7cWiGPrMr0eJwuZaql+pj2WVGyT417I=",
|
||||||
"owner": "dwinkler1",
|
"owner": "dwinkler1",
|
||||||
"repo": "r_nvim_nix",
|
"repo": "r_nvim_nix",
|
||||||
"rev": "1d26452e3c940153271fc57fbad0b295fcb0e04f",
|
"rev": "03d7872d7702db37ede41f3c6e4d4ce4c129e862",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "dwinkler1",
|
"owner": "dwinkler1",
|
||||||
"ref": "v1.0.0",
|
"ref": "v0.99.5",
|
||||||
"repo": "r_nvim_nix",
|
"repo": "r_nvim_nix",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
@ -93,16 +93,16 @@
|
||||||
"rnvimsrc": {
|
"rnvimsrc": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1783264911,
|
"lastModified": 1780759435,
|
||||||
"narHash": "sha256-FywUL3mV2+kfu+rO6uUFyUv80EflbdgSkYuSnW965UE=",
|
"narHash": "sha256-VxgKMOP1hseQre3cas2dmMXZu4PVyl05INla2OdHTU4=",
|
||||||
"owner": "R-nvim",
|
"owner": "R-nvim",
|
||||||
"repo": "R.nvim",
|
"repo": "R.nvim",
|
||||||
"rev": "c56ebe0f8445e251673981c40ac2d74659ecd6ed",
|
"rev": "6ca306191531c3e3d501ee1609c84a5d29059386",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "R-nvim",
|
"owner": "R-nvim",
|
||||||
"ref": "v1.0.0",
|
"ref": "v0.99.5",
|
||||||
"repo": "R.nvim",
|
"repo": "R.nvim",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|
@ -124,11 +124,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1782135443,
|
"lastModified": 1779297405,
|
||||||
"narHash": "sha256-vAmbArdCyjqpVW+37aCy/PMBOLIqukUXLQuEKLwUhA4=",
|
"narHash": "sha256-VFoBwH7ZjVxCnvZTb5ODRXt70sLtWMxstive0N+RS50=",
|
||||||
"owner": "BirdeeHub",
|
"owner": "BirdeeHub",
|
||||||
"repo": "nix-wrapper-modules",
|
"repo": "nix-wrapper-modules",
|
||||||
"rev": "6e7f66fa2cdf4d63162580b438f7fcf87c28a46f",
|
"rev": "e7ed7a1205945befdf2e0d73ba7df91d935e5af1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
15
flake.nix
15
flake.nix
|
|
@ -12,7 +12,7 @@
|
||||||
rixpkgs.url = "github:dwinkler1/rixpkgs/nixpkgs";
|
rixpkgs.url = "github:dwinkler1/rixpkgs/nixpkgs";
|
||||||
|
|
||||||
r-nvim-nix = {
|
r-nvim-nix = {
|
||||||
url = "github:dwinkler1/r_nvim_nix/v1.0.0";
|
url = "github:dwinkler1/r_nvim_nix/v0.99.5";
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.follows = "rixpkgs";
|
nixpkgs.follows = "rixpkgs";
|
||||||
};
|
};
|
||||||
|
|
@ -69,7 +69,7 @@
|
||||||
''
|
''
|
||||||
+ nixpkgs.lib.optionalString (config.cats.r or false) ''
|
+ nixpkgs.lib.optionalString (config.cats.r or false) ''
|
||||||
export R_HOME=$(R RHOME)
|
export R_HOME=$(R RHOME)
|
||||||
export R_LIBS_SITE=$(strings "$(command -v R)" | rg -o '/nix/store/[^:]+/library' | sort -u | paste -sd: -)
|
export R_LIBS_SITE=$(strings "$(command -v R)" | grep -oP '/nix/store/[^:]+/library' | sort -u | paste -sd: -)
|
||||||
export R_LIBS_USER="$PWD/.r-libs"
|
export R_LIBS_USER="$PWD/.r-libs"
|
||||||
mkdir -p "$R_LIBS_USER"
|
mkdir -p "$R_LIBS_USER"
|
||||||
'';
|
'';
|
||||||
|
|
@ -224,23 +224,18 @@
|
||||||
fi
|
fi
|
||||||
echo "Downstream override assertions passed" > $out
|
echo "Downstream override assertions passed" > $out
|
||||||
'';
|
'';
|
||||||
lua-test = pkgs.runCommand "lua-test" {
|
|
||||||
buildInputs = [ pkgs.neovim-unwrapped ];
|
|
||||||
} ''
|
|
||||||
nvim --headless -u NONE -c "set runtimepath+=${./.}" -l ${./tests/init.lua}
|
|
||||||
touch $out
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
nixosModules.default = wrappers.lib.getInstallModule {
|
nixosModules.default = wrappers.lib.mkInstallModule {
|
||||||
name = "vModule";
|
name = "vModule";
|
||||||
value = module;
|
value = module;
|
||||||
};
|
};
|
||||||
|
|
||||||
homeModules.default = wrappers.lib.getInstallModule {
|
homeModules.default = wrappers.lib.mkInstallModule {
|
||||||
name = "vModule";
|
name = "vModule";
|
||||||
value = module;
|
value = module;
|
||||||
|
loc = ["home" "packages"];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
local quarto_ok, quarto = pcall(require, 'quarto')
|
local quarto = require('quarto')
|
||||||
if quarto_ok then
|
quarto.setup()
|
||||||
vim.keymap.set('n', '<leader>qp', quarto.quartoPreview, { silent = true, noremap = true, buffer = true })
|
vim.keymap.set('n', '<leader>qp', quarto.quartoPreview, { silent = true, noremap = true })
|
||||||
end
|
|
||||||
|
|
||||||
if vim.bo.filetype == "r" then
|
|
||||||
vim.keymap.set("n", "<Enter>", "<Plug>RDSendLine", { buffer = true })
|
vim.keymap.set("n", "<Enter>", "<Plug>RDSendLine", { buffer = true })
|
||||||
vim.keymap.set("v", "<Enter>", "<Plug>RSendSelection", { buffer = true })
|
vim.keymap.set("v", "<Enter>", "<Plug>RSendSelection", { buffer = true })
|
||||||
|
|
||||||
|
|
@ -14,15 +12,12 @@ if vim.bo.filetype == "r" then
|
||||||
|
|
||||||
-- Pipe operator (;;)
|
-- Pipe operator (;;)
|
||||||
vim.keymap.set("i", ";;", "<Cmd>lua MiniTrailspace.trim()<CR><Plug>RInsertPipe<CR>", { buffer = true, noremap = true })
|
vim.keymap.set("i", ";;", "<Cmd>lua MiniTrailspace.trim()<CR><Plug>RInsertPipe<CR>", { buffer = true, noremap = true })
|
||||||
end
|
|
||||||
|
|
||||||
local runner_ok, runner = pcall(require, "quarto.runner")
|
local runner = require("quarto.runner")
|
||||||
if runner_ok then
|
vim.keymap.set("n", "<localleader>a", runner.run_cell, { desc = "run cell", silent = true })
|
||||||
vim.keymap.set("n", "<localleader>a", runner.run_cell, { desc = "run cell", silent = true, buffer = true })
|
vim.keymap.set("n", "<localleader>A", runner.run_all, { desc = "run all cells", silent = true })
|
||||||
vim.keymap.set("n", "<localleader>A", runner.run_all, { desc = "run all cells", silent = true, buffer = true })
|
|
||||||
vim.keymap.set("n", "<localleader>RA", function()
|
vim.keymap.set("n", "<localleader>RA", function()
|
||||||
runner.run_all(true)
|
runner.run_all(true)
|
||||||
end, { desc = "run all cells of all languages", silent = true, buffer = true })
|
end, { desc = "run all cells of all languages", silent = true })
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,6 @@ in
|
||||||
python313Packages.pylatexenc
|
python313Packages.pylatexenc
|
||||||
quartoPkg
|
quartoPkg
|
||||||
zk
|
zk
|
||||||
marksman
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
nix = maybe "nix" (with pkgs; [
|
nix = maybe "nix" (with pkgs; [
|
||||||
|
|
@ -100,12 +99,13 @@ in
|
||||||
quartoPkg
|
quartoPkg
|
||||||
pkgs.air-formatter
|
pkgs.air-formatter
|
||||||
pkgs.yaml-language-server
|
pkgs.yaml-language-server
|
||||||
|
pkgs.rnvimserver
|
||||||
];
|
];
|
||||||
|
|
||||||
# cats without packages get empty lists
|
# cats without packages get empty lists
|
||||||
general = [ ];
|
general = [ ];
|
||||||
gitPlugins = [ ];
|
gitPlugins = [ ];
|
||||||
treesitterParsers = [ ];
|
treesitterParsers = [ pkgs.tree-sitter ];
|
||||||
utils = [ ];
|
utils = [ ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@
|
||||||
# Enable RC wrapping (allows neovim to find the config)
|
# Enable RC wrapping (allows neovim to find the config)
|
||||||
config.settings.wrapRc = lib.mkDefault true;
|
config.settings.wrapRc = lib.mkDefault true;
|
||||||
|
|
||||||
|
# Lua packages available to neovim (for :lua require())
|
||||||
|
config.settings.nvim_lua_env = lp:
|
||||||
|
lib.optionals (config.cats.general or false) [ lp.tiktoken_core ];
|
||||||
|
|
||||||
# Binary name for the wrapper
|
# Binary name for the wrapper
|
||||||
config.binName = lib.mkDefault "vv";
|
config.binName = lib.mkDefault "vv";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,10 @@
|
||||||
UV_PYTHON_DOWNLOADS = "never";
|
UV_PYTHON_DOWNLOADS = "never";
|
||||||
UV_PYTHON = pkgs.python.interpreter;
|
UV_PYTHON = pkgs.python.interpreter;
|
||||||
})
|
})
|
||||||
# R.nvim v1.x owns its cache and temporary directories and exports
|
(lib.mkIf (config.cats.r or false) {
|
||||||
# RNVIM_COMPLDIR/RNVIM_TMPDIR during setup. Do not inject literal `$PWD`
|
RNVIM_COMPLDIR = "$PWD/.r-compl";
|
||||||
# values into the wrapper environment.
|
TMPDIR = "$PWD/.r-tmp";
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
# Environment variables with defaults (can be overridden by user)
|
# Environment variables with defaults (can be overridden by user)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,16 @@ in
|
||||||
nvim-host.flags."--neovim-bin" = "${builtins.placeholder "out"}/bin/${config.binName}";
|
nvim-host.flags."--neovim-bin" = "${builtins.placeholder "out"}/bin/${config.binName}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
m = {
|
||||||
|
nvim-host.enable = false;
|
||||||
|
nvim-host.package = "${pkgs.uv}/bin/uv";
|
||||||
|
nvim-host.argv0 = "uv";
|
||||||
|
nvim-host.addFlag = [
|
||||||
|
"run"
|
||||||
|
"marimo"
|
||||||
|
"edit"
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
(lib.mkIf (config.cats.julia or false) {
|
(lib.mkIf (config.cats.julia or false) {
|
||||||
jl = {
|
jl = {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
lib,
|
lib,
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
|
||||||
config.specs.gitPlugins = lib.mkIf (config.cats.gitPlugins or false) {
|
config.specs.gitPlugins = lib.mkIf (config.cats.gitPlugins or false) {
|
||||||
data = [];
|
data = [];
|
||||||
};
|
};
|
||||||
|
|
@ -111,17 +110,13 @@
|
||||||
nvim-lspconfig
|
nvim-lspconfig
|
||||||
nvim-treesitter-context
|
nvim-treesitter-context
|
||||||
nvim-treesitter-textobjects
|
nvim-treesitter-textobjects
|
||||||
{
|
|
||||||
data = pkgs.vimPlugins.nvim-treesitter;
|
|
||||||
pname = "nvim-treesitter";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
data = pkgs.codecompanion-nvim.overrideAttrs (old: {
|
data = pkgs.codecompanion-nvim.overrideAttrs (old: {
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
});
|
});
|
||||||
pname = "codecompanion";
|
pname = "codecompanion";
|
||||||
}
|
}
|
||||||
] ++ builtins.attrValues pkgs.vimPlugins.nvim-treesitter.queries;
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
config.specs.treesitterParsers = lib.mkIf (config.cats.treesitterParsers or false) {
|
config.specs.treesitterParsers = lib.mkIf (config.cats.treesitterParsers or false) {
|
||||||
|
|
|
||||||
|
|
@ -128,20 +128,27 @@ local diagnostic_opts = {
|
||||||
-- Don't update diagnostics when typing
|
-- Don't update diagnostics when typing
|
||||||
update_in_insert = false,
|
update_in_insert = false,
|
||||||
}
|
}
|
||||||
later(function()
|
later(function() vim.diagnostic.config(diagnostic_opts) end)
|
||||||
vim.diagnostic.config(diagnostic_opts)
|
|
||||||
|
|
||||||
|
-- Custom autocommands ========================================================
|
||||||
|
local augroup = vim.api.nvim_create_augroup('CustomSettings', {})
|
||||||
|
|
||||||
-- Relax diagnostics for markdown (many false positives)
|
|
||||||
vim.api.nvim_create_autocmd('FileType', {
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
pattern = { 'markdown' },
|
pattern = { 'markdown' },
|
||||||
|
group = augroup,
|
||||||
callback = function()
|
callback = function()
|
||||||
vim.diagnostic.config({
|
vim.diagnostic.config({
|
||||||
signs = { severity = { min = 'WARN', max = 'ERROR' } },
|
signs = {
|
||||||
virtual_text = { severity = { min = 'HINT', max = 'ERROR' }, current_line = false },
|
severity = { min = 'WARN', max = 'ERROR' }
|
||||||
|
},
|
||||||
|
virtual_text = {
|
||||||
|
current_line = false,
|
||||||
|
severity = { min = 'HINT', max = 'ERROR' }
|
||||||
|
}
|
||||||
})
|
})
|
||||||
end,
|
end
|
||||||
})
|
})
|
||||||
end)
|
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("FileType", {
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
desc = "remove formatoptions",
|
desc = "remove formatoptions",
|
||||||
|
|
@ -150,6 +157,17 @@ vim.api.nvim_create_autocmd("FileType", {
|
||||||
vim.b.minitrailspace_disable = true -- Don't highlight trailing space by default
|
vim.b.minitrailspace_disable = true -- Don't highlight trailing space by default
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
group = augroup,
|
||||||
|
callback = function()
|
||||||
|
-- Don't auto-wrap comments and don't insert comment leader after hitting 'o'
|
||||||
|
-- If don't do this on `FileType`, this keeps reappearing due to being set in
|
||||||
|
-- filetype plugins.
|
||||||
|
vim.cmd('setlocal formatoptions-=r formatoptions-=o')
|
||||||
|
end,
|
||||||
|
desc = [[Ensure proper 'formatoptions']],
|
||||||
|
})
|
||||||
-- Neovide ==============================================
|
-- Neovide ==============================================
|
||||||
if vim.g.neovide then
|
if vim.g.neovide then
|
||||||
vim.g.neovide_cursor_vfx_mode = "pixiedust"
|
vim.g.neovide_cursor_vfx_mode = "pixiedust"
|
||||||
|
|
@ -158,7 +176,7 @@ if vim.g.neovide then
|
||||||
vim.g.neovide_cursor_short_animation_length = 0
|
vim.g.neovide_cursor_short_animation_length = 0
|
||||||
vim.g.neovide_font_hinting = 'none'
|
vim.g.neovide_font_hinting = 'none'
|
||||||
vim.g.neovide_font_edging = 'subpixelantialias'
|
vim.g.neovide_font_edging = 'subpixelantialias'
|
||||||
vim.o.guifont = 'JetBrainsMono Nerd Font:h14:#e-subpixelantialias:#h-none'
|
vim.o.guifont = 'JetBrainsMono Nerd Font,Symbols Nerd Font:h14:#e-subpixelantialias:#h-none'
|
||||||
vim.g.neovide_floating_corner_radius = 0.35
|
vim.g.neovide_floating_corner_radius = 0.35
|
||||||
vim.keymap.set("n", "<leader>nf", "<cmd>NeovideFullscreen<CR>", { desc = "Toggle Neovide Fullscreen" })
|
vim.keymap.set("n", "<leader>nf", "<cmd>NeovideFullscreen<CR>", { desc = "Toggle Neovide Fullscreen" })
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ end
|
||||||
|
|
||||||
Config.log = {}
|
Config.log = {}
|
||||||
Config.log_buf_id = Config.log_buf_id or nil
|
Config.log_buf_id = Config.log_buf_id or nil
|
||||||
Config.start_hrtime = Config.start_hrtime or vim.uv.hrtime()
|
Config.start_hrtime = Config.start_hrtime or vim.loop.hrtime()
|
||||||
|
|
||||||
Config.log_print = function()
|
Config.log_print = function()
|
||||||
if Config.log_buf_id == nil or not vim.api.nvim_buf_is_valid(Config.log_buf_id) then
|
if Config.log_buf_id == nil or not vim.api.nvim_buf_is_valid(Config.log_buf_id) then
|
||||||
|
|
@ -24,7 +24,7 @@ end
|
||||||
|
|
||||||
Config.log_clear = function()
|
Config.log_clear = function()
|
||||||
Config.log = {}
|
Config.log = {}
|
||||||
Config.start_hrtime = vim.uv.hrtime()
|
Config.start_hrtime = vim.loop.hrtime()
|
||||||
vim.cmd('echo "Cleared log"')
|
vim.cmd('echo "Cleared log"')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,28 +66,21 @@ nmap_leader('<Tab>', '<Cmd>bnext<CR>', 'Next buffer')
|
||||||
nmap_leader('<S-Tab>', '<Cmd>bprev<CR>', 'Prev buffer')
|
nmap_leader('<S-Tab>', '<Cmd>bprev<CR>', 'Prev buffer')
|
||||||
|
|
||||||
-- a is for 'AI'
|
-- a is for 'AI'
|
||||||
nmap_leader("aa", "<cmd>CodeCompanion /agent<CR>", "Agent chat (@{agent} tools)")
|
|
||||||
nmap_leader("ac", "<cmd>CodeCompanionChat Toggle<CR>", "Chat Toggle")
|
nmap_leader("ac", "<cmd>CodeCompanionChat Toggle<CR>", "Chat Toggle")
|
||||||
nmap_leader("aC", function()
|
-- nmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code")
|
||||||
local chat = require("codecompanion").last_chat()
|
-- nmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code")
|
||||||
if not chat then
|
|
||||||
return vim.notify("No CodeCompanion chat to compact", vim.log.levels.WARN)
|
|
||||||
end
|
|
||||||
require("codecompanion.interactions.chat.context_management.compaction").compact(chat, { min_token_savings = 0 })
|
|
||||||
end, "Compact chat")
|
|
||||||
nmap_leader("ag", "<cmd>CodeCompanion /commit<CR>", "Generate commit message")
|
nmap_leader("ag", "<cmd>CodeCompanion /commit<CR>", "Generate commit message")
|
||||||
nmap_leader("ai", "<cmd>CodeCompanionActions<CR>", "Chat Action")
|
nmap_leader("ai", "<cmd>CodeCompanionActions<CR>", "Chat Action")
|
||||||
nmap_leader("al", "<cmd>CodeCompanion /lsp<CR>", "Explain LSP Diagnostics")
|
nmap_leader("al", "<cmd>CodeCompanion /lsp<CR>", "Explain LSP Diagnostics")
|
||||||
nmap_leader("an", "<cmd>CodeCompanionChat Add<CR>", "Chat New")
|
nmap_leader("an", "<cmd>CodeCompanionChat Add<CR>", "Chat New")
|
||||||
nmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
|
nmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
|
||||||
nmap_leader("aw", "<cmd>CodeCompanion /tdd<CR>", "Workflow: plan, implement, test")
|
--nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer")
|
||||||
nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer")
|
nmap_leader("ax", "<cmd>CodeCompanion /fixer<CR>", "Code Fixer")
|
||||||
xmap_leader("aa", "<cmd>CodeCompanion /agent<CR>", "Agent on selection")
|
|
||||||
xmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code")
|
xmap_leader("ae", "<cmd>CodeCompanion /explain<CR>", "Explain Code")
|
||||||
xmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code")
|
xmap_leader("af", "<cmd>CodeCompanion /fix<CR>", "Fix Code")
|
||||||
xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Expert")
|
--xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Fixer")
|
||||||
|
xmap_leader("ap", "<cmd>CodeCompanion /expert<CR>", "Code Fixer")
|
||||||
xmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
|
xmap_leader("as", "<cmd>CodeCompanion /suggest<CR>", "Suggest Improvements")
|
||||||
nmap_leader("ak", "<cmd>CodeCompanionChat adapter=codex<CR>", "Chat with Codex")
|
|
||||||
|
|
||||||
-- b is for 'buffer'
|
-- b is for 'buffer'
|
||||||
nmap_leader('bb', '<Cmd>b#<CR>', 'Alternate')
|
nmap_leader('bb', '<Cmd>b#<CR>', 'Alternate')
|
||||||
|
|
@ -130,7 +123,7 @@ nmap_leader('fm', '<Cmd>Pick marks<CR>', 'Marks')
|
||||||
nmap_leader('fn', '<cmd>ZkNotes<CR>', "Notes")
|
nmap_leader('fn', '<cmd>ZkNotes<CR>', "Notes")
|
||||||
nmap_leader('fk', '<Cmd>Pick keymaps<CR>', 'Keymaps')
|
nmap_leader('fk', '<Cmd>Pick keymaps<CR>', 'Keymaps')
|
||||||
nmap_leader('fR', '<Cmd>Pick resume<CR>', 'Resume')
|
nmap_leader('fR', '<Cmd>Pick resume<CR>', 'Resume')
|
||||||
nmap_leader('fp', '<Cmd>Pick files<CR>', 'Files')
|
nmap_leader('fp', '<Cmd>Pick projects<CR>', 'Projects')
|
||||||
nmap_leader('fq', '<Cmd>Pick list scope="quickfix"<CR>', 'Quickfix')
|
nmap_leader('fq', '<Cmd>Pick list scope="quickfix"<CR>', 'Quickfix')
|
||||||
nmap_leader('fr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
|
nmap_leader('fr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
|
||||||
nmap_leader('flr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
|
nmap_leader('flr', '<Cmd>Pick lsp scope="references"<CR>', 'References (LSP)')
|
||||||
|
|
@ -171,7 +164,7 @@ vim.keymap.set({ 'n' }, 'grk', '<Cmd>lua vim.lsp.buf.hover()<CR>', { desc = 'Doc
|
||||||
vim.keymap.set({ 'n' }, 'gre', '<Cmd>lua vim.diagnostic.open_float()<CR>', { desc = 'Diagnostics' })
|
vim.keymap.set({ 'n' }, 'gre', '<Cmd>lua vim.diagnostic.open_float()<CR>', { desc = 'Diagnostics' })
|
||||||
|
|
||||||
nmap_lsp("K", '<Cmd>lua vim.lsp.buf.hover()<CR>', "Documentation")
|
nmap_lsp("K", '<Cmd>lua vim.lsp.buf.hover()<CR>', "Documentation")
|
||||||
local formatting_cmd = '<Cmd>lua require("conform").format({ lsp_format = "fallback" })<CR>'
|
local formatting_cmd = '<Cmd>lua require("conform").format({ lsp_fallback = true })<CR>'
|
||||||
nmap_leader('la', '<Cmd>lua vim.lsp.buf.code_action()<CR>', 'Actions')
|
nmap_leader('la', '<Cmd>lua vim.lsp.buf.code_action()<CR>', 'Actions')
|
||||||
nmap_leader('le', '<Cmd>lua vim.diagnostic.open_float()<CR>', 'Diagnostics popup')
|
nmap_leader('le', '<Cmd>lua vim.diagnostic.open_float()<CR>', 'Diagnostics popup')
|
||||||
nmap_leader('lf', formatting_cmd, 'Format')
|
nmap_leader('lf', formatting_cmd, 'Format')
|
||||||
|
|
@ -196,9 +189,11 @@ nmap_leader('Lx', '<Cmd>lua Config.execute_lua_line()<CR>', 'Execute `lua` line'
|
||||||
|
|
||||||
-- o is for 'other'
|
-- o is for 'other'
|
||||||
local trailspace_toggle_command = '<Cmd>lua vim.b.minitrailspace_disable = not vim.b.minitrailspace_disable<CR>'
|
local trailspace_toggle_command = '<Cmd>lua vim.b.minitrailspace_disable = not vim.b.minitrailspace_disable<CR>'
|
||||||
|
nmap_leader('od', '<Cmd>Neogen<CR>', 'Document')
|
||||||
nmap_leader('oh', '<Cmd>normal gxiagxila<CR>', 'Move arg left')
|
nmap_leader('oh', '<Cmd>normal gxiagxila<CR>', 'Move arg left')
|
||||||
nmap_leader('ol', '<Cmd>normal gxiagxina<CR>', 'Move arg right')
|
nmap_leader('ol', '<Cmd>normal gxiagxina<CR>', 'Move arg right')
|
||||||
nmap_leader('or', '<Cmd>lua MiniMisc.resize_window()<CR>', 'Resize to default width')
|
nmap_leader('or', '<Cmd>lua MiniMisc.resize_window()<CR>', 'Resize to default width')
|
||||||
|
nmap_leader('oS', '<Cmd>lua Config.insert_section()<CR>', 'Section insert')
|
||||||
nmap_leader('ot', '<Cmd>lua MiniTrailspace.trim()<CR>', 'Trim trailspace')
|
nmap_leader('ot', '<Cmd>lua MiniTrailspace.trim()<CR>', 'Trim trailspace')
|
||||||
nmap_leader('oT', trailspace_toggle_command, 'Trailspace hl toggle')
|
nmap_leader('oT', trailspace_toggle_command, 'Trailspace hl toggle')
|
||||||
nmap_leader('oz', '<Cmd>lua MiniMisc.zoom()<CR>', 'Zoom toggle')
|
nmap_leader('oz', '<Cmd>lua MiniMisc.zoom()<CR>', 'Zoom toggle')
|
||||||
|
|
|
||||||
|
|
@ -208,37 +208,112 @@ now_if_args(function()
|
||||||
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
|
on_attach = nil, -- (fun(buf: integer): boolean) return false to disable attaching
|
||||||
}
|
}
|
||||||
|
|
||||||
local ts_filetypes = {
|
|
||||||
"c", "cpp", "lua", "nix", "python", "r", "markdown", "query",
|
local ok_configs, configs = pcall(require, "nvim-treesitter.configs")
|
||||||
"vim", "vimdoc", "yaml", "json", "toml", "rust", "go",
|
|
||||||
"javascript", "typescript", "tsx", "html", "css", "sql",
|
if ok_configs and configs.setup then
|
||||||
"julia", "rnoweb", "latex", "gitcommit", "gitignore",
|
local opts = {
|
||||||
"git_config", "git_rebase", "diff", "dockerfile",
|
highlight = { enable = true },
|
||||||
"make", "xml", "zig", "regex", "csv", "bash",
|
indent = { enable = false },
|
||||||
"markdown_inline", "quarto", "rmd", "codecompanion",
|
textobjects = {
|
||||||
|
move = {
|
||||||
|
enable = true,
|
||||||
|
set_jumps = true,
|
||||||
|
goto_next_start = {
|
||||||
|
["]a"] = "@parameter.inner", -- fixed typo
|
||||||
|
["]f"] = "@function.outer",
|
||||||
|
["]o"] = "@loop.*",
|
||||||
|
["]s"] = { query = "@local.scope", desc = "Next scope" },
|
||||||
|
["]z"] = { query = "@fold", desc = "Next fold" },
|
||||||
|
},
|
||||||
|
goto_next_end = {
|
||||||
|
["]M"] = "@function.outer",
|
||||||
|
["]["] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_previous_start = {
|
||||||
|
["[a"] = "@parameter.inner",
|
||||||
|
["[f"] = "@function.outer",
|
||||||
|
["[o"] = "@loop.*",
|
||||||
|
["[s"] = { query = "@local.scope", query_group = "locals", desc = "Prev. scope" },
|
||||||
|
["[z"] = { query = "@fold", query_group = "folds", desc = "Prev. fold" },
|
||||||
|
},
|
||||||
|
goto_previous_end = {
|
||||||
|
["[M"] = "@function.outer",
|
||||||
|
["[]"] = "@class.outer",
|
||||||
|
},
|
||||||
|
goto_next = {
|
||||||
|
["]e"] = "@conditional.outer",
|
||||||
|
},
|
||||||
|
goto_previous = {
|
||||||
|
["[e"] = "@conditional.outer",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
swap = {
|
||||||
|
enable = true,
|
||||||
|
swap_next = {
|
||||||
|
["<leader>x"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
swap_previous = {
|
||||||
|
["<leader>X"] = "@parameter.inner",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lsp_interop = {
|
||||||
|
enable = true,
|
||||||
|
border = "none",
|
||||||
|
floating_preview_opts = {},
|
||||||
|
peek_definition_code = {
|
||||||
|
["<leader>lm"] = "@function.outer",
|
||||||
|
["<leader>lM"] = "@class.outer",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
local function start_treesitter(buf, filetype)
|
|
||||||
local lang = vim.treesitter.language.get_lang(filetype) or filetype
|
|
||||||
if #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0 then
|
-- Manual parser check for non-Nix users
|
||||||
return
|
if not Config.isNixCats then
|
||||||
|
local installed_check = function(lang)
|
||||||
|
return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0
|
||||||
end
|
end
|
||||||
vim.treesitter.start(buf, lang)
|
local to_install = vim.tbl_filter(installed_check, opts.ensure_installed)
|
||||||
vim.bo[buf].indentexpr = "v:lua.require('nvim-treesitter').indentexpr()"
|
if #to_install > 0 then
|
||||||
|
require("nvim-treesitter").install(to_install)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- Environment-specific Overrides
|
||||||
|
if not Config.isNixCats then
|
||||||
|
opts.auto_install = true
|
||||||
|
opts.ensure_installed = Config.treesitter_helpers.default_parsers
|
||||||
|
else
|
||||||
|
opts.auto_install = false
|
||||||
|
-- Nix handles installation, so ensure_installed is skipped/empty
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
configs.setup(opts)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("FileType", {
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
pattern = ts_filetypes,
|
pattern = "*",
|
||||||
callback = function(ev)
|
callback = function(args)
|
||||||
start_treesitter(ev.buf, vim.bo[ev.buf].filetype)
|
-- Use explicit buffer + filetype to avoid any ambiguity
|
||||||
|
local ok = pcall(vim.treesitter.start, args.buf, args.match)
|
||||||
|
vim.bo.syntax = 'on'
|
||||||
|
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
||||||
|
vim.wo[0][0].foldexpr = 'v:lua.vim.treesitter.foldexpr()'
|
||||||
|
vim.wo[0][0].foldmethod = 'expr'
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- FileType may have fired before this deferred setup ran.
|
-- Textobjects: require plugin and bail out quietly if missing
|
||||||
if vim.bo.filetype ~= "" then
|
local ok_nto, nto = pcall(require, "nvim-treesitter-textobjects")
|
||||||
start_treesitter(0, vim.bo.filetype)
|
if not ok_nto then
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
require("nvim-treesitter-textobjects").setup({
|
vim.g.no_plugin_maps = true
|
||||||
|
nto.setup({
|
||||||
move = {
|
move = {
|
||||||
set_jumps = true,
|
set_jumps = true,
|
||||||
},
|
},
|
||||||
|
|
@ -247,36 +322,70 @@ now_if_args(function()
|
||||||
local move = require("nvim-treesitter-textobjects.move")
|
local move = require("nvim-treesitter-textobjects.move")
|
||||||
local swap = require("nvim-treesitter-textobjects.swap")
|
local swap = require("nvim-treesitter-textobjects.swap")
|
||||||
|
|
||||||
vim.keymap.set("n", "]a", function() move.goto_next_start("@parameter.inner", "textobjects") end, { desc = "Next parameter" })
|
-- Map motion function names to actual functions
|
||||||
vim.keymap.set("n", "[a", function() move.goto_previous_start("@parameter.inner", "textobjects") end, { desc = "Prev parameter" })
|
local move_fns = {
|
||||||
vim.keymap.set("n", "]f", function() move.goto_next_start("@function.outer", "textobjects") end, { desc = "Next function" })
|
goto_next_start = move.goto_next_start,
|
||||||
vim.keymap.set("n", "[f", function() move.goto_previous_start("@function.outer", "textobjects") end, { desc = "Prev function" })
|
goto_next_end = move.goto_next_end,
|
||||||
vim.keymap.set("n", "]o", function() move.goto_next_start("@loop.*", "textobjects") end, { desc = "Next loop" })
|
goto_previous_start = move.goto_previous_start,
|
||||||
vim.keymap.set("n", "[o", function() move.goto_previous_start("@loop.*", "textobjects") end, { desc = "Prev loop" })
|
goto_previous_end = move.goto_previous_end,
|
||||||
vim.keymap.set("n", "]s", function() move.goto_next_start("@local.scope", "textobjects") end, { desc = "Next scope" })
|
goto_next = move.goto_next,
|
||||||
vim.keymap.set("n", "[s", function() move.goto_previous_start("@local.scope", "locals") end, { desc = "Prev scope" })
|
goto_previous = move.goto_previous,
|
||||||
vim.keymap.set("n", "]z", function() move.goto_next_start("@fold", "folds") end, { desc = "Next fold" })
|
}
|
||||||
vim.keymap.set("n", "[z", function() move.goto_previous_start("@fold", "folds") end, { desc = "Prev fold" })
|
|
||||||
vim.keymap.set("n", "]M", function() move.goto_next_end("@function.outer", "textobjects") end, { desc = "Next function end" })
|
|
||||||
vim.keymap.set("n", "][", function() move.goto_next_end("@class.outer", "textobjects") end, { desc = "Next class end" })
|
|
||||||
vim.keymap.set("n", "[M", function() move.goto_previous_end("@function.outer", "textobjects") end, { desc = "Prev function end" })
|
|
||||||
vim.keymap.set("n", "[]", function() move.goto_previous_end("@class.outer", "textobjects") end, { desc = "Prev class end" })
|
|
||||||
vim.keymap.set("n", "]e", function() move.goto_next("@conditional.outer", "textobjects") end, { desc = "Next conditional" })
|
|
||||||
vim.keymap.set("n", "[e", function() move.goto_previous("@conditional.outer", "textobjects") end, { desc = "Prev conditional" })
|
|
||||||
|
|
||||||
vim.keymap.set("n", "<leader>x", function() swap.swap_next("@parameter.inner", "textobjects") end, { desc = "Swap parameter next" })
|
-- All motions defined in one place
|
||||||
vim.keymap.set("n", "<leader>X", function() swap.swap_previous("@parameter.inner", "textobjects") end, { desc = "Swap parameter prev" })
|
-- spec = { query_or_list, query_group, desc }
|
||||||
|
local move_maps = {
|
||||||
|
goto_next_start = {
|
||||||
|
["]a"] = { "@parameter.inner", "textobjects", "Next parameter" },
|
||||||
|
["]f"] = { "@function.outer", "textobjects", "Next function start" },
|
||||||
|
["]o"] = { { "@loop.inner", "@loop.outer" }, "textobjects", "Next loop" },
|
||||||
|
["]s"] = { "@local.scope", "locals", "Next scope" },
|
||||||
|
["]z"] = { "@fold", "folds", "Next fold" },
|
||||||
|
},
|
||||||
|
goto_next_end = {
|
||||||
|
["]M"] = { "@function.outer", "textobjects", "Next function end" },
|
||||||
|
["]["] = { "@class.outer", "textobjects", "Next class end" },
|
||||||
|
},
|
||||||
|
goto_previous_start = {
|
||||||
|
["[a"] = { "@parameter.inner", "textobjects", "Previous parameter" },
|
||||||
|
["[f"] = { "@function.outer", "textobjects", "Previous function start" },
|
||||||
|
["[o"] = { { "@loop.inner", "@loop.outer" }, "textobjects", "Previous loop" },
|
||||||
|
["[s"] = { "@local.scope", "locals", "Previous scope" },
|
||||||
|
["[z"] = { "@fold", "folds", "Previous fold" },
|
||||||
|
},
|
||||||
|
goto_previous_end = {
|
||||||
|
["[M"] = { "@function.outer", "textobjects", "Previous function end" },
|
||||||
|
["[]"] = { "@class.outer", "textobjects", "Previous class end" },
|
||||||
|
},
|
||||||
|
goto_next = {
|
||||||
|
["]e"] = { "@conditional.outer", "textobjects", "Next conditional" },
|
||||||
|
},
|
||||||
|
goto_previous = {
|
||||||
|
["[e"] = { "@conditional.outer", "textobjects", "Previous conditional" },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
if not Config.isNixCats then
|
-- Generate motion keymaps
|
||||||
local installed_check = function(lang)
|
for fn_name, maps in pairs(move_maps) do
|
||||||
return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".*", false) == 0
|
local fn = move_fns[fn_name]
|
||||||
end
|
if fn then
|
||||||
local default_parsers = Config.treesitter_helpers.default_parsers
|
for lhs, spec in pairs(maps) do
|
||||||
local to_install = vim.tbl_filter(installed_check, default_parsers)
|
local query_or_list, group, desc = spec[1], spec[2], spec[3]
|
||||||
if #to_install > 0 then
|
vim.keymap.set({ "n", "x", "o" }, lhs, function()
|
||||||
require("nvim-treesitter").install(to_install)
|
fn(query_or_list, group)
|
||||||
|
end, { desc = desc })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Swap keymaps (unchanged, but minimal)
|
||||||
|
vim.keymap.set("n", "<leader>x", function()
|
||||||
|
swap.swap_next("@parameter.inner")
|
||||||
|
end, { desc = "Swap with next parameter" })
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<leader>X", function()
|
||||||
|
swap.swap_previous("@parameter.inner")
|
||||||
|
end, { desc = "Swap with previous parameter" })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- zk
|
-- zk
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,18 @@ local add = Config.add
|
||||||
local nix = require('config.nix')
|
local nix = require('config.nix')
|
||||||
|
|
||||||
if not Config.isNixCats then
|
if not Config.isNixCats then
|
||||||
local add = MiniDeps.add
|
local m_add = MiniDeps.add
|
||||||
|
|
||||||
now(function()
|
now(function()
|
||||||
add({ source = "R-nvim/R.nvim" })
|
m_add({ source = "R-nvim/R.nvim" })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
now_if_args(function()
|
now_if_args(function()
|
||||||
add({ source = "jmbuhr/otter.nvim" })
|
m_add({ source = "jmbuhr/otter.nvim" })
|
||||||
end)
|
end)
|
||||||
|
|
||||||
later(function()
|
later(function()
|
||||||
add({ source = "jpalardy/vim-slime" })
|
m_add({ source = "jpalardy/vim-slime" })
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -44,6 +44,12 @@ end)
|
||||||
-- r
|
-- r
|
||||||
now(function()
|
now(function()
|
||||||
if nix.get_cat("r", false) then
|
if nix.get_cat("r", false) then
|
||||||
|
local cwd = vim.fn.getcwd(-1)
|
||||||
|
vim.env.RNVIM_COMPLDIR = cwd .. "/.r-compl"
|
||||||
|
vim.env.R_LIBS_USER = (vim.env.R_LIBS_USER or ""):gsub("%$PWD", cwd)
|
||||||
|
vim.env.TMPDIR = cwd .. "/.r-tmp"
|
||||||
|
vim.fn.mkdir(vim.env.RNVIM_COMPLDIR, "p")
|
||||||
|
vim.fn.mkdir(vim.env.TMPDIR, "p")
|
||||||
vim.g.rout_follow_colorscheme = true
|
vim.g.rout_follow_colorscheme = true
|
||||||
require("r").setup({
|
require("r").setup({
|
||||||
-- Create a table with the options to be passed to setup()
|
-- Create a table with the options to be passed to setup()
|
||||||
|
|
@ -56,20 +62,6 @@ now(function()
|
||||||
rconsole_height = 20,
|
rconsole_height = 20,
|
||||||
nvimpager = "split_h",
|
nvimpager = "split_h",
|
||||||
pdfviewer = "",
|
pdfviewer = "",
|
||||||
-- Use R.nvim's built-in rnvimserver-backed language server. Do not
|
|
||||||
-- configure the external R languageserver through plugin/25_lsp.lua.
|
|
||||||
r_ls = {
|
|
||||||
completion = true,
|
|
||||||
hover = true,
|
|
||||||
signature = true,
|
|
||||||
definition = true,
|
|
||||||
references = true,
|
|
||||||
implementation = true,
|
|
||||||
document_symbol = true,
|
|
||||||
workspace_symbol = true,
|
|
||||||
document_highlight = true,
|
|
||||||
rename = true,
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
@ -77,6 +69,8 @@ end)
|
||||||
|
|
||||||
-- Quarto
|
-- Quarto
|
||||||
now(function()
|
now(function()
|
||||||
|
vim.treesitter.language.register("markdown", { "quarto", "rmd" })
|
||||||
|
|
||||||
if nix.get_cat({ "r", "markdown" }, false) then
|
if nix.get_cat({ "r", "markdown" }, false) then
|
||||||
vim.api.nvim_create_autocmd("FileType", {
|
vim.api.nvim_create_autocmd("FileType", {
|
||||||
pattern = { "quarto" },
|
pattern = { "quarto" },
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@ local later = MiniDeps.later
|
||||||
local nix = require('config.nix')
|
local nix = require('config.nix')
|
||||||
|
|
||||||
if not Config.isNixCats then
|
if not Config.isNixCats then
|
||||||
local add = MiniDeps.add
|
local m_add = MiniDeps.add
|
||||||
later(function()
|
later(function()
|
||||||
add({ source = "Bilal2453/luvit-meta" })
|
m_add({ source = "Bilal2453/luvit-meta" })
|
||||||
add({ source = "folke/lazydev.nvim" })
|
m_add({ source = "folke/lazydev.nvim" })
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@ local later = MiniDeps.later
|
||||||
local add = Config.add
|
local add = Config.add
|
||||||
|
|
||||||
if not Config.isNixCats then
|
if not Config.isNixCats then
|
||||||
local add = MiniDeps.add
|
local m_add = MiniDeps.add
|
||||||
|
|
||||||
later(function()
|
later(function()
|
||||||
add("stevearc/conform.nvim")
|
m_add("stevearc/conform.nvim")
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -23,6 +23,20 @@ later(function()
|
||||||
rmd = { "injected" },
|
rmd = { "injected" },
|
||||||
quarto = { "injected" },
|
quarto = { "injected" },
|
||||||
},
|
},
|
||||||
|
|
||||||
|
default_format_opts = {
|
||||||
|
lsp_format = "fallback",
|
||||||
|
},
|
||||||
|
|
||||||
|
formatters = {
|
||||||
|
my_styler = {
|
||||||
|
command = "R",
|
||||||
|
-- A list of strings, or a function that returns a list of strings
|
||||||
|
-- Return a single string instead of a list to run the command in a shell
|
||||||
|
args = { "-s", "-e", "styler::style_file(commandArgs(TRUE)[1])", "--args", "$FILENAME" },
|
||||||
|
stdin = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ local now = MiniDeps.now
|
||||||
local now_if_args = Config.now_if_args
|
local now_if_args = Config.now_if_args
|
||||||
|
|
||||||
-- Constants
|
-- Constants
|
||||||
local BLINK_VERSION = "v1.10.2"
|
local BLINK_VERSION = "v1.4.1"
|
||||||
|
|
||||||
-- Plugin sources configuration
|
-- Plugin sources configuration
|
||||||
local PLUGIN_SOURCES = {
|
local PLUGIN_SOURCES = {
|
||||||
|
|
@ -26,16 +26,26 @@ local PLUGIN_ADDS = {
|
||||||
-- Helper functions
|
-- Helper functions
|
||||||
local function create_system_prompt(role_description)
|
local function create_system_prompt(role_description)
|
||||||
return function(context)
|
return function(context)
|
||||||
local lang = context.filetype or "programmer"
|
return "I want you to act as a senior " .. context.filetype .. " developer. " .. role_description
|
||||||
return "I want you to act as a senior " .. lang .. " developer. " .. role_description
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_code_block(context)
|
local function get_code_block(context)
|
||||||
local text = require("codecompanion.helpers.code").get_code(context.start_line, context.end_line)
|
local text = require("codecompanion.helpers.actions").get_code(context.start_line, context.end_line)
|
||||||
return "```" .. context.filetype .. "\n" .. text .. "\n```"
|
return "```" .. context.filetype .. "\n" .. text .. "\n```"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function create_common_opts(mapping, short_name)
|
||||||
|
return {
|
||||||
|
mapping = mapping,
|
||||||
|
modes = { "v" },
|
||||||
|
short_name = short_name,
|
||||||
|
auto_submit = true,
|
||||||
|
stop_context_insertion = true,
|
||||||
|
user_prompt = true,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
local function get_mini_icons_highlight(ctx)
|
local function get_mini_icons_highlight(ctx)
|
||||||
local _, hl, _ = require("mini.icons").get("lsp", ctx.kind)
|
local _, hl, _ = require("mini.icons").get("lsp", ctx.kind)
|
||||||
return hl
|
return hl
|
||||||
|
|
@ -47,7 +57,7 @@ local function get_blink_fuzzy_setting()
|
||||||
}
|
}
|
||||||
|
|
||||||
if not Config.isNixCats then
|
if not Config.isNixCats then
|
||||||
setting.prebuilt_binaries = { force_version = BLINK_VERSION }
|
setting.prebuilt_binary = { force_version = BLINK_VERSION }
|
||||||
end
|
end
|
||||||
|
|
||||||
return setting
|
return setting
|
||||||
|
|
@ -55,10 +65,10 @@ end
|
||||||
|
|
||||||
-- Plugin loading
|
-- Plugin loading
|
||||||
if not Config.isNixCats then
|
if not Config.isNixCats then
|
||||||
local add = MiniDeps.add
|
local m_add = MiniDeps.add
|
||||||
|
|
||||||
now_if_args(function()
|
now_if_args(function()
|
||||||
add({
|
m_add({
|
||||||
source = "saghen/blink.cmp",
|
source = "saghen/blink.cmp",
|
||||||
depends = { "rafamadriz/friendly-snippets" },
|
depends = { "rafamadriz/friendly-snippets" },
|
||||||
checkout = BLINK_VERSION,
|
checkout = BLINK_VERSION,
|
||||||
|
|
@ -67,64 +77,29 @@ if not Config.isNixCats then
|
||||||
|
|
||||||
later(function()
|
later(function()
|
||||||
for _, source in ipairs(PLUGIN_SOURCES) do
|
for _, source in ipairs(PLUGIN_SOURCES) do
|
||||||
add({ source = source })
|
m_add({ source = source })
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_codecompanion_config()
|
local function get_codecompanion_config()
|
||||||
return {
|
return {
|
||||||
adapters = {
|
|
||||||
acp = {
|
|
||||||
-- Codex = heavy agent lane (ChatGPT Edu login via `codex login`; ~/.codex/auth.json).
|
|
||||||
-- Requires `codex-acp` on PATH (~/.nix-profile/bin). ACP-only slash commands in the
|
|
||||||
-- chat buffer: /resume (restore a past session, fresh chat only), /mode (switch agent
|
|
||||||
-- mode), /command, /acp_session_options (e.g. model per session); `\` triggers ACP
|
|
||||||
-- command completion (1-5s delay after chat open).
|
|
||||||
codex = function()
|
|
||||||
return require("codecompanion.adapters").extend("codex", {
|
|
||||||
defaults = {
|
|
||||||
auth_method = "chatgpt",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
interactions = {
|
interactions = {
|
||||||
chat = {
|
chat = {
|
||||||
adapter = {
|
adapter = {
|
||||||
name = "copilot",
|
name = "copilot",
|
||||||
model = "claude-sonnet-5",
|
model = "gemini-3.1-pro-preview",
|
||||||
},
|
|
||||||
slash_commands = {
|
|
||||||
["share"] = {
|
|
||||||
opts = {
|
|
||||||
token = os.getenv("GITHUB_GIST_TOKEN"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
opts = {
|
opts = {
|
||||||
completion_provider = "blink",
|
completion_provider = "blink",
|
||||||
context_management = {
|
|
||||||
editing = {
|
|
||||||
trigger = 0.65,
|
|
||||||
keep_cycles = 3,
|
|
||||||
exclude_tools = { "memory" },
|
|
||||||
},
|
|
||||||
compaction = {
|
|
||||||
trigger = 0.85,
|
|
||||||
min_token_savings = 10000,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
inline = {
|
inline = {
|
||||||
adapter = {
|
adapter = {
|
||||||
name = "copilot",
|
name = "copilot",
|
||||||
model = "gpt-5-mini",
|
model = "gemini-3.1-pro-preview",
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
|
||||||
shared = {
|
|
||||||
keymaps = {
|
keymaps = {
|
||||||
accept_change = {
|
accept_change = {
|
||||||
modes = { n = "ga" },
|
modes = { n = "ga" },
|
||||||
|
|
@ -137,24 +112,6 @@ local function get_codecompanion_config()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
background = {
|
|
||||||
adapter = {
|
|
||||||
name = "copilot",
|
|
||||||
model = "gpt-5-mini",
|
|
||||||
},
|
|
||||||
chat = {
|
|
||||||
callbacks = {
|
|
||||||
["on_ready"] = {
|
|
||||||
actions = { "interactions.background.builtin.chat_make_title" },
|
|
||||||
enabled = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
opts = {
|
|
||||||
enabled = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
display = {
|
display = {
|
||||||
chat = {
|
chat = {
|
||||||
show_settings = false,
|
show_settings = false,
|
||||||
|
|
@ -164,38 +121,12 @@ local function get_codecompanion_config()
|
||||||
height = 0.33,
|
height = 0.33,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
diff = {
|
|
||||||
enabled = true,
|
|
||||||
threshold_for_chat = 6,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
rules = {
|
|
||||||
default = {
|
|
||||||
description = "Collection of common files for all projects",
|
|
||||||
files = {
|
|
||||||
".clinerules",
|
|
||||||
".cursorrules",
|
|
||||||
".rules",
|
|
||||||
".github/copilot-instructions.md",
|
|
||||||
"AGENT.md",
|
|
||||||
"AGENTS.md",
|
|
||||||
{ path = "CLAUDE.md", parser = "claude" },
|
|
||||||
{ path = "CLAUDE.local.md", parser = "claude" },
|
|
||||||
{ path = "~/.claude/CLAUDE.md", parser = "claude" },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
opts = {
|
|
||||||
chat = {
|
|
||||||
autoload = "default",
|
|
||||||
enabled = true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
prompt_library = {
|
prompt_library = {
|
||||||
["expert"] = {
|
["expert"] = {
|
||||||
interaction = "chat",
|
interaction = "chat",
|
||||||
description = "Get expert advice from an LLM",
|
description = "Get expert advice from an LLM",
|
||||||
opts = { alias = "expert" },
|
--opts = create_common_opts("<localleader>ae", "expert"),
|
||||||
prompts = {
|
prompts = {
|
||||||
{
|
{
|
||||||
role = "system",
|
role = "system",
|
||||||
|
|
@ -215,7 +146,7 @@ local function get_codecompanion_config()
|
||||||
["fixer"] = {
|
["fixer"] = {
|
||||||
interaction = "chat",
|
interaction = "chat",
|
||||||
description = "Fix code errors with expert guidance",
|
description = "Fix code errors with expert guidance",
|
||||||
opts = { alias = "fixer" },
|
--opts = create_common_opts("<localleader>af", "afixer"),
|
||||||
prompts = {
|
prompts = {
|
||||||
{
|
{
|
||||||
role = "system",
|
role = "system",
|
||||||
|
|
@ -235,7 +166,7 @@ local function get_codecompanion_config()
|
||||||
["suggest"] = {
|
["suggest"] = {
|
||||||
interaction = "chat",
|
interaction = "chat",
|
||||||
description = "Suggest improvements to the buffer",
|
description = "Suggest improvements to the buffer",
|
||||||
opts = { alias = "suggest" },
|
--opts = create_common_opts("<localleader>as", "suggest"),
|
||||||
prompts = {
|
prompts = {
|
||||||
{
|
{
|
||||||
role = "system",
|
role = "system",
|
||||||
|
|
@ -257,53 +188,7 @@ local function get_codecompanion_config()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
["agent"] = {
|
}
|
||||||
interaction = "chat",
|
|
||||||
description = "Agentic coding with the @{agent} tool group (read/edit/grep/run)",
|
|
||||||
opts = { alias = "agent" },
|
|
||||||
prompts = {
|
|
||||||
{
|
|
||||||
role = "user",
|
|
||||||
content = function(context)
|
|
||||||
return "@{agent} Work on the following code:\n\n" .. get_code_block(context) .. "\n\n"
|
|
||||||
end,
|
|
||||||
opts = { contains_code = true },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
["tdd"] = {
|
|
||||||
interaction = "chat",
|
|
||||||
description = "Workflow: plan the buffer change, implement it, run the tests",
|
|
||||||
opts = { alias = "tdd", is_workflow = true },
|
|
||||||
prompts = {
|
|
||||||
{
|
|
||||||
{
|
|
||||||
role = "user",
|
|
||||||
content = function(context)
|
|
||||||
return "Let's work test-driven. First, study #buffer and the relevant parts of the codebase, then propose a concise implementation plan (no code yet).\n\nThe code under discussion:\n\n"
|
|
||||||
.. get_code_block(context)
|
|
||||||
.. "\n\nThe task: "
|
|
||||||
end,
|
|
||||||
opts = { contains_code = true },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{
|
|
||||||
role = "user",
|
|
||||||
content = "Implement the plan now, writing or updating tests alongside the code. @{agent}",
|
|
||||||
opts = { auto_submit = true },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{
|
|
||||||
role = "user",
|
|
||||||
content = "Run the project's test suite with @{run_command} and fix any failures until it passes.",
|
|
||||||
opts = { auto_submit = true },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -359,13 +244,6 @@ later(function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
-- CodeCompanion habit notes (chat buffer unless stated):
|
|
||||||
-- /compact compact history, keep summary /fork fork the conversation
|
|
||||||
-- /symbols insert symbols for a file /share export chat to a GitHub gist
|
|
||||||
-- gm toggle "btw" ephemeral message gty YOLO: approve all tool calls
|
|
||||||
-- gba/gbd buffer sync add/drop gd debug window (adapter/tools info)
|
|
||||||
-- Codex (ACP) lane: /resume (fresh chat only), /mode, /command, /acp_session_options,
|
|
||||||
-- `\` ACP command completion. Prompt library: /expert /fixer /suggest /agent /tdd (workflow).
|
|
||||||
later(function()
|
later(function()
|
||||||
add("codecompanion.nvim")
|
add("codecompanion.nvim")
|
||||||
|
|
||||||
|
|
@ -438,10 +316,7 @@ now_if_args(function()
|
||||||
},
|
},
|
||||||
snippets = { preset = "mini_snippets" },
|
snippets = { preset = "mini_snippets" },
|
||||||
sources = {
|
sources = {
|
||||||
per_filetype = {
|
default = { "references", "lsp", "path", "snippets", "buffer", "omni", "copilot", "codecompanion" },
|
||||||
codecompanion = { "codecompanion" },
|
|
||||||
},
|
|
||||||
default = { "references", "lsp", "path", "snippets", "buffer", "omni", "copilot" },
|
|
||||||
providers = {
|
providers = {
|
||||||
path = {
|
path = {
|
||||||
score_offset = 50,
|
score_offset = 50,
|
||||||
|
|
@ -460,6 +335,10 @@ now_if_args(function()
|
||||||
score_offset = 10,
|
score_offset = 10,
|
||||||
opts = { cmp_name = "cmdline" }
|
opts = { cmp_name = "cmdline" }
|
||||||
},
|
},
|
||||||
|
cmp_r = {
|
||||||
|
name = "cmp_r",
|
||||||
|
module = "blink.compat.source",
|
||||||
|
},
|
||||||
copilot = {
|
copilot = {
|
||||||
name = "copilot",
|
name = "copilot",
|
||||||
module = "blink-copilot",
|
module = "blink-copilot",
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,24 @@ if not Config.isNixCats then
|
||||||
end
|
end
|
||||||
|
|
||||||
now_if_args(function()
|
now_if_args(function()
|
||||||
-- R.nvim owns the R `r_ls` client and starts its bundled rnvimserver from
|
|
||||||
-- its own plugin directory. Keep R out of this generic server registry.
|
|
||||||
local servers = {
|
local servers = {
|
||||||
|
clangd = {},
|
||||||
basedpyright = {},
|
basedpyright = {},
|
||||||
ruff = {},
|
ruff = {},
|
||||||
marksman = {
|
marksman = {
|
||||||
filetypes = { "markdown", "markdown_inline", "codecompanion" },
|
filetypes = { "markdown", "markdown_inline", "codecompanion" },
|
||||||
},
|
},
|
||||||
|
r_ls = {
|
||||||
|
filetypes = { 'r', 'rmd', 'rmarkdown' },
|
||||||
|
settings = {
|
||||||
|
['r_ls'] = {
|
||||||
|
lsp = {
|
||||||
|
rich_documentation = true,
|
||||||
|
enable = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
julials = {
|
julials = {
|
||||||
settings = {
|
settings = {
|
||||||
julia = {
|
julia = {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue