Jump to content

Nvim: Difference between revisions

From Archive
Expanded with Claude Code workflow documentation
Expanded with hot reload details, diffview, mini.diff, statusline indicators
Line 16: Line 16:
</pre>
</pre>


'''Why not Cursor?'''
''Why not Cursor?''
* Nvim muscle memory preserved
* Nvim muscle memory preserved
* Complete control over AI integration points
* Complete control over AI integration
* No vendor lock-in
* No vendor lock-in
* tmux + ssh workflow stays intact
* tmux + ssh workflow stays intact
* Works on remote servers (VPS) seamlessly
* Works on remote servers seamlessly
* OSC52 clipboard works over SSH


== Core Stack ==
== Hot Reload System ==
''The killer feature.'' When Claude Code edits files, nvim reloads them automatically.
 
''Files:''
* <code>lua/custom/directory-watcher.lua</code> - Native fs_event monitoring
* <code>lua/custom/hotreload.lua</code> - Smart buffer reload logic
* <code>lua/custom/git-diff-hotreload.lua</code> - Diffview auto-refresh
 
''How it works:''
# Claude Code edits a file in right pane
# Directory watcher detects change (200ms debounce)
# Nvim reloads visible buffers (only if unmodified)
# Statusline shows green ⟳ for 5 seconds
# Notification: "📝 File reloaded (Claude Code edit)"


=== Base ===
''Safety:''
* '''LazyVim''' - Sane defaults, most disabled
* Never reloads modified buffers (won't lose unsaved work)
* '''oil.nvim''' - Filesystem as a buffer (<code>-</code> to toggle)
* Skips special buffers (neo-tree, diffview, terminals)
* '''telescope''' - Fuzzy finding everything
* Ignores .git/, node_modules/, swap files
* '''diffview''' - Git diff visualization


=== AI Integration ===
''Triggers:''
* '''copilot.lua''' - Ghost text (not popup completions)
* FocusGained, TermLeave (switching from Claude Code pane)
* '''Claude Code''' - CLI for big refactors (separate terminal)
* BufEnter, WinEnter (switching windows)
* CursorHold (idle cursor)
* Filesystem changes in project directory


== Inline AI (Ghost Text) ==
== Diffview Integration ==
''File: <code>~/.config/nvim/lua/plugins/copilot-inline.lua</code>''
Review all robot changes with one keystroke.


Ghost text suggestions that feel natural:
''File:'' <code>lua/plugins/claude-code-workflow.lua</code>


{| class="wikitable"
{| class="wikitable"
Line 44: Line 59:
! Key !! Action
! Key !! Action
|-
|-
| <code>Tab</code> || Accept full suggestion
| <code><leader>gd</code> || Open diffview (review all changes)
|-
|-
| <code>]s</code> / <code>[s</code> || Cycle through suggestions
| <code><leader>gh</code> || File history
|-
|-
| <code>C-Right</code> || Accept one word
| <code><leader>gc</code> || Close diffview
|-
|-
| <code>C-l</code> || Accept one line
| <code>]c</code> / <code>[c</code> || Jump between changes
|-
|-
| <code>C-]</code> || Dismiss
| <code>Tab</code> || Cycle through files
|}
|}


'''Why inline > popup:''' No fighting with LSP completions. Ghost text for AI, completion menu for LSP.
''Auto-refresh:'' When Claude Code commits, diffview refreshes automatically via git-diff-hotreload watching <code>.git/</code> directory.


== Hot Reload System ==
== Inline Git Diff ==
''Files: <code>directory-watcher.lua</code>, <code>hotreload.lua</code>''
''Plugin:'' mini.diff - shows deleted lines inline
 
{| class="wikitable"
|-
! Key !! Action
|-
| <code>gh</code> || Apply hunk
|-
| <code>gH</code> || Reset hunk
|-
| <code>[h</code> / <code>]h</code> || Navigate hunks
|-
| <code><leader>go</code> || Toggle diff overlay
|}
 
Uses <code></code> signs for additions/changes, clean minimal look.


When Claude Code edits files:
== Inline AI (Ghost Text) ==
# Filesystem watcher detects change
''File:'' <code>lua/plugins/copilot-inline.lua</code>
# Nvim auto-reloads visible buffers (only if unmodified)
# Statusline shows green ⟳ for 5 seconds
# Never loses unsaved work


== Diffview Integration ==
Ghost text suggestions, not popup completions:
''File: <code>git-diff-hotreload.lua</code>''


{| class="wikitable"
{| class="wikitable"
Line 73: Line 99:
! Key !! Action
! Key !! Action
|-
|-
| <code><leader>gd</code> || Open diffview (review changes)
| <code>Tab</code> || Accept full suggestion
|-
| <code>]s</code> / <code>[s</code> || Cycle through suggestions
|-
|-
| <code>]c</code> / <code>[c</code> || Jump between changes
| <code>C-Right</code> || Accept one word
|-
|-
| <code>Tab</code> || Cycle through files
| <code>C-l</code> || Accept one line
|-
|-
| <code><leader>gc</code> || Close diffview
| <code>C-]</code> || Dismiss
|}
|}
''Why inline > popup:'' Ghost text for AI, completion menu for LSP. No fighting between them.
== LSP & Formatting ==
''conform.nvim'' handles formatting with Prettier (respects project .prettierrc)
''Statusline shows active LSPs:''
* Vue, TypeScript, ESLint, Python, Rust, Lua icons
* Copilot filtered from display (but still active)
''Diagnostics:'' Error/warning/hint counts in statusline (E/W/H format)


== Yank With Context ==
== Yank With Context ==
Line 88: Line 127:
* <code><leader>ya</code> → Yank with absolute path
* <code><leader>ya</code> → Yank with absolute path


Output: <code>src/components/Button.tsx:15-23</code> + code block
''Output format:''
<pre>
src/components/Button.tsx:15-23
```tsx
import { useState } from 'react'
// selected code here
```
</pre>
 
Claude Code sees exact file + line numbers = perfect context.


== Statusline Indicators ==
== Statusline Indicators ==
* '''Red ●''' - Unsaved changes
''File:'' <code>lua/plugins/minimal-statusline.lua</code>
* '''Green ⟳''' - Just reloaded by Claude Code (5 sec flash)
 
* '''Gray "AI"''' - Copilot attached
{| class="wikitable"
* '''Blue Δ''' - Diffview open
|-
! Symbol !! Color !! Meaning
|-
| <code>●</code> || Red || Unsaved changes
|-
| <code>⟳</code> || Green || Just reloaded by Claude Code (5 sec)
|-
| <code>AI</code> || Gray || Copilot attached
|-
| <code>Δ</code> || Blue || Diffview open
|}
 
Also shows: file path (last 2 dirs + filename), line count, diagnostics, LSP icons.


== CLI Aliases ==
== CLI Aliases ==
Line 102: Line 162:
vs    # Fuzzy find files with bat preview
vs    # Fuzzy find files with bat preview
vg    # Grep contents, fuzzy find, open file
vg    # Grep contents, fuzzy find, open file
o    # Obsidian vault fuzzy finder
o    # Obsidian vault fuzzy finder (sorted by recency)
r    # Recent files across ALL ~/code projects
r    # Recent files across ALL ~/code projects
tip  # Random tip from ~/tips.txt
</pre>
</pre>


== Visual Plugins ==
== Plugin Stack ==
* '''ayu''' - Dark theme that doesn't burn retinas
''Core:''
* '''twilight''' - Dims inactive code
* LazyVim (base, most defaults disabled)
* '''zen-mode''' - Full screen focus
* oil.nvim (filesystem as buffer)
* telescope (fuzzy finding)
* diffview + mini.diff (git visualization)
* harpoon (quick file switching)
 
''AI:''
* copilot.lua (ghost text)
* Claude Code CLI (separate terminal)
 
''Visual:''
* ayu theme (dark, easy on eyes)
* twilight (dims inactive code)
* zen-mode (distraction-free)
 
''Workflow:''
* vim-tmux-navigator (seamless pane switching)
* surround, hardtime, vimbegood
 
== The Magic Moment ==
Robot edits 5 files → nvim shows green ⟳ → all files refresh → <code><leader>gd</code> → review everything in diffview → back to coding.
 
No manual steps. Just flow.


== See Also ==
== See Also ==
Line 115: Line 197:
* [[CLI]]
* [[CLI]]
* [[VPS]]
* [[VPS]]
* [[SSH]]


[[Category:Technical]]
[[Category:Technical]]

Revision as of 04:57, 15 January 2026

Neovim

LazyVim + Claude Code workflow for non-Cursor open source coding

nvim dotfiles

Philosophy

Code manually in nvim (left pane) with subtle AI assistance, while Claude Code handles big refactors in a separate tmux pane (right). Robot edits files → nvim auto-reloads → review changes instantly.

┌─────────────────┬─────────────────┐
│ nvim (manual)   │ Claude Code     │
│ - Ghost text AI │ - Big refactors │
│ - Hot reload    │ - File edits    │
│ - Diffview      │ - Commits       │
└─────────────────┴─────────────────┘

Why not Cursor?

  • Nvim muscle memory preserved
  • Complete control over AI integration
  • No vendor lock-in
  • tmux + ssh workflow stays intact
  • Works on remote servers seamlessly
  • OSC52 clipboard works over SSH

Hot Reload System

The killer feature. When Claude Code edits files, nvim reloads them automatically.

Files:

  • lua/custom/directory-watcher.lua - Native fs_event monitoring
  • lua/custom/hotreload.lua - Smart buffer reload logic
  • lua/custom/git-diff-hotreload.lua - Diffview auto-refresh

How it works:

  1. Claude Code edits a file in right pane
  2. Directory watcher detects change (200ms debounce)
  3. Nvim reloads visible buffers (only if unmodified)
  4. Statusline shows green ⟳ for 5 seconds
  5. Notification: "📝 File reloaded (Claude Code edit)"

Safety:

  • Never reloads modified buffers (won't lose unsaved work)
  • Skips special buffers (neo-tree, diffview, terminals)
  • Ignores .git/, node_modules/, swap files

Triggers:

  • FocusGained, TermLeave (switching from Claude Code pane)
  • BufEnter, WinEnter (switching windows)
  • CursorHold (idle cursor)
  • Filesystem changes in project directory

Diffview Integration

Review all robot changes with one keystroke.

File: lua/plugins/claude-code-workflow.lua

Key Action
<leader>gd Open diffview (review all changes)
<leader>gh File history
<leader>gc Close diffview
]c / [c Jump between changes
Tab Cycle through files

Auto-refresh: When Claude Code commits, diffview refreshes automatically via git-diff-hotreload watching .git/ directory.

Inline Git Diff

Plugin: mini.diff - shows deleted lines inline

Key Action
gh Apply hunk
gH Reset hunk
[h / ]h Navigate hunks
<leader>go Toggle diff overlay

Uses signs for additions/changes, clean minimal look.

Inline AI (Ghost Text)

File: lua/plugins/copilot-inline.lua

Ghost text suggestions, not popup completions:

Key Action
Tab Accept full suggestion
]s / [s Cycle through suggestions
C-Right Accept one word
C-l Accept one line
C-] Dismiss

Why inline > popup: Ghost text for AI, completion menu for LSP. No fighting between them.

LSP & Formatting

conform.nvim handles formatting with Prettier (respects project .prettierrc)

Statusline shows active LSPs:

  • Vue, TypeScript, ESLint, Python, Rust, Lua icons
  • Copilot filtered from display (but still active)

Diagnostics: Error/warning/hint counts in statusline (E/W/H format)

Yank With Context

Share code with Claude Code including file path:

  • <leader>yr → Yank with relative path
  • <leader>ya → Yank with absolute path

Output format:

src/components/Button.tsx:15-23
```tsx
import { useState } from 'react'
// selected code here
```

Claude Code sees exact file + line numbers = perfect context.

Statusline Indicators

File: lua/plugins/minimal-statusline.lua

Symbol Color Meaning
Red Unsaved changes
Green Just reloaded by Claude Code (5 sec)
AI Gray Copilot attached
Δ Blue Diffview open

Also shows: file path (last 2 dirs + filename), line count, diagnostics, LSP icons.

CLI Aliases

v     # Just nvim
n     # nvim . (open with oil.nvim)
vs    # Fuzzy find files with bat preview
vg    # Grep contents, fuzzy find, open file
o     # Obsidian vault fuzzy finder (sorted by recency)
r     # Recent files across ALL ~/code projects
tip   # Random tip from ~/tips.txt

Plugin Stack

Core:

  • LazyVim (base, most defaults disabled)
  • oil.nvim (filesystem as buffer)
  • telescope (fuzzy finding)
  • diffview + mini.diff (git visualization)
  • harpoon (quick file switching)

AI:

  • copilot.lua (ghost text)
  • Claude Code CLI (separate terminal)

Visual:

  • ayu theme (dark, easy on eyes)
  • twilight (dims inactive code)
  • zen-mode (distraction-free)

Workflow:

  • vim-tmux-navigator (seamless pane switching)
  • surround, hardtime, vimbegood

The Magic Moment

Robot edits 5 files → nvim shows green ⟳ → all files refresh → <leader>gd → review everything in diffview → back to coding.

No manual steps. Just flow.

See Also


Technical
Core Technical · CLI · Dotfiles · Nvim · SSH · VPS
Tools Sketchybar · ArchiveBox · ThinkPad Linux
Systems Automation · Personal APIs · Quantified Self
Reference Runbooks · New Computer Runbook · Syntax guide