Improved flow
This commit is contained in:
285
docs/guides/ai-assistant.md
Normal file
285
docs/guides/ai-assistant.md
Normal file
@@ -0,0 +1,285 @@
|
||||
# AI Assistant Guide (opencode.nvim)
|
||||
|
||||
This guide covers using opencode.nvim for AI-assisted coding in Neovim.
|
||||
|
||||
## Overview
|
||||
|
||||
opencode.nvim provides AI assistance directly in Neovim:
|
||||
- Ask questions about code
|
||||
- Get explanations
|
||||
- Generate code and tests
|
||||
- Refactor and optimize
|
||||
- Review changes
|
||||
- Document code
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Open AI Panel
|
||||
|
||||
```
|
||||
<leader>kk Toggle opencode panel
|
||||
```
|
||||
|
||||
The panel opens on the right side (40% width).
|
||||
|
||||
### Ask a Question
|
||||
|
||||
```
|
||||
<leader>ka Ask opencode (prompts for input)
|
||||
```
|
||||
|
||||
Or with file context:
|
||||
```
|
||||
<leader>kA Ask about current file
|
||||
```
|
||||
|
||||
## Key Bindings
|
||||
|
||||
### General
|
||||
|
||||
| Key | Mode | Action |
|
||||
|-----|------|--------|
|
||||
| `<leader>kk` | n | Toggle opencode panel |
|
||||
| `<leader>ka` | n, v | Ask opencode |
|
||||
| `<leader>kA` | n, v | Ask about current file |
|
||||
| `<leader>kn` | n | New session |
|
||||
|
||||
### Code Understanding
|
||||
|
||||
| Key | Mode | Action |
|
||||
|-----|------|--------|
|
||||
| `<leader>ke` | n | Explain code near cursor |
|
||||
| `<leader>kE` | v | Explain selection |
|
||||
|
||||
### Code Review
|
||||
|
||||
| Key | Mode | Action |
|
||||
|-----|------|--------|
|
||||
| `<leader>kr` | n | Review current file |
|
||||
| `<leader>kg` | n | Review git diff |
|
||||
| `<leader>kf` | n | Fix diagnostics/errors |
|
||||
| `<leader>kq` | n | Fix quickfix items |
|
||||
|
||||
### Code Generation
|
||||
|
||||
| Key | Mode | Action |
|
||||
|-----|------|--------|
|
||||
| `<leader>ko` | v | Optimize selection |
|
||||
| `<leader>kR` | v | Refactor selection |
|
||||
| `<leader>kd` | v | Document selection |
|
||||
| `<leader>kt` | v | Generate tests for selection |
|
||||
|
||||
### Harpoon Integration
|
||||
|
||||
| Key | Mode | Action |
|
||||
|-----|------|--------|
|
||||
| `<leader>kh` | n | Ask about harpooned files |
|
||||
| `<leader>kH` | n | Analyze harpooned files |
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Understanding Code
|
||||
|
||||
1. Place cursor on complex code
|
||||
2. `<leader>ke` - Explain code near cursor
|
||||
|
||||
Or for larger sections:
|
||||
1. Select code in visual mode (`V`)
|
||||
2. `<leader>kE` - Explain selection
|
||||
|
||||
### Fixing Bugs
|
||||
|
||||
1. See error in diagnostics
|
||||
2. `<leader>kf` - Ask AI to fix
|
||||
3. Review suggested fix
|
||||
4. Apply or modify as needed
|
||||
|
||||
### Generating Tests
|
||||
|
||||
1. Select function to test (`V` for lines)
|
||||
2. `<leader>kt` - Generate tests
|
||||
3. Review generated tests
|
||||
4. Adjust assertions as needed
|
||||
|
||||
### Refactoring
|
||||
|
||||
1. Select code to refactor (`V`)
|
||||
2. `<leader>kR` - Request refactoring
|
||||
3. Describe what you want (or let AI decide)
|
||||
4. Review and apply
|
||||
|
||||
### Code Review
|
||||
|
||||
Before committing:
|
||||
```
|
||||
<leader>kg Review git diff
|
||||
```
|
||||
|
||||
AI will analyze your changes and suggest improvements.
|
||||
|
||||
### Documenting Code
|
||||
|
||||
1. Select function/class (`V`)
|
||||
2. `<leader>kd` - Generate documentation
|
||||
3. Review generated docs
|
||||
4. Integrate into code
|
||||
|
||||
## Working with Multiple Files
|
||||
|
||||
### Harpoon Context
|
||||
|
||||
Mark related files with harpoon, then ask about them together:
|
||||
|
||||
1. Mark files: `<leader>H` on each file
|
||||
2. `<leader>kh` - Ask about all harpooned files
|
||||
3. AI has context of all marked files
|
||||
|
||||
Example question:
|
||||
> "How does the user service interact with the database layer?"
|
||||
|
||||
### Analyze Architecture
|
||||
|
||||
```
|
||||
<leader>kH Analyze harpooned files
|
||||
```
|
||||
|
||||
Good for understanding relationships between files.
|
||||
|
||||
## Effective Prompting
|
||||
|
||||
### Be Specific
|
||||
|
||||
Bad: "Fix this code"
|
||||
Good: "This function throws an error when the array is empty. Add a guard clause."
|
||||
|
||||
### Provide Context
|
||||
|
||||
Bad: "Add error handling"
|
||||
Good: "Add try-catch with proper error logging following our project's error handling pattern"
|
||||
|
||||
### Ask for Explanations
|
||||
|
||||
- "Explain why this regex works"
|
||||
- "What are the edge cases here?"
|
||||
- "Why might this be slow?"
|
||||
|
||||
### Request Alternatives
|
||||
|
||||
- "Show me 3 ways to implement this"
|
||||
- "What's a more functional approach?"
|
||||
- "How would you do this idiomatically in Go?"
|
||||
|
||||
## Session Management
|
||||
|
||||
### New Session
|
||||
|
||||
```
|
||||
<leader>kn Start fresh session
|
||||
```
|
||||
|
||||
Clears context for a new topic.
|
||||
|
||||
### Continuing Conversations
|
||||
|
||||
The panel maintains conversation history. Follow up naturally:
|
||||
1. Ask initial question
|
||||
2. "Can you also handle the null case?"
|
||||
3. "Now add tests for this"
|
||||
|
||||
## Integration with Workflow
|
||||
|
||||
### During Development
|
||||
|
||||
1. Write initial implementation
|
||||
2. `<leader>ke` - Understand any complex parts
|
||||
3. `<leader>kt` - Generate tests
|
||||
4. `<leader>ko` - Optimize if needed
|
||||
|
||||
### During Code Review
|
||||
|
||||
1. `<leader>gd` - Open diffview
|
||||
2. `<leader>kg` - AI review of changes
|
||||
3. Address suggestions
|
||||
4. Create PR
|
||||
|
||||
### While Debugging
|
||||
|
||||
1. Hit an error
|
||||
2. `<leader>kf` - Ask AI to fix
|
||||
3. Or `<leader>ke` - Understand the error first
|
||||
4. Apply fix
|
||||
|
||||
## Tips
|
||||
|
||||
### Quick Explanations
|
||||
|
||||
`K` (hover) shows LSP docs, but for deeper understanding:
|
||||
```
|
||||
<leader>ke AI explanation with context
|
||||
```
|
||||
|
||||
### Iterative Refinement
|
||||
|
||||
1. Get initial suggestion
|
||||
2. "Make it more concise"
|
||||
3. "Add error handling"
|
||||
4. "Use async/await instead"
|
||||
|
||||
### Learning Patterns
|
||||
|
||||
Ask AI to explain patterns:
|
||||
- "Explain the repository pattern used here"
|
||||
- "What design pattern would improve this?"
|
||||
- "Show me the idiomatic way in this language"
|
||||
|
||||
### Code Generation Templates
|
||||
|
||||
For repetitive tasks:
|
||||
1. `<leader>ka`
|
||||
2. "Generate a CRUD API endpoint for User model following the pattern in user.controller.ts"
|
||||
|
||||
## Customization
|
||||
|
||||
### Panel Position
|
||||
|
||||
Configured in `lua/plugins/opencode.lua`:
|
||||
```lua
|
||||
opts = {
|
||||
window = {
|
||||
position = "right", -- or "left", "top", "bottom"
|
||||
width = 0.4, -- 40% of screen
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Auto-reload
|
||||
|
||||
When AI edits files, they auto-reload:
|
||||
```lua
|
||||
auto_reload_buffers_on_edit = true,
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Panel Not Opening
|
||||
|
||||
1. Check opencode is installed: `:Lazy`
|
||||
2. Verify configuration in `lua/plugins/opencode.lua`
|
||||
|
||||
### Slow Responses
|
||||
|
||||
- Large files take longer
|
||||
- Consider selecting specific sections instead of whole files
|
||||
|
||||
### Context Issues
|
||||
|
||||
If AI seems confused:
|
||||
1. `<leader>kn` - New session
|
||||
2. Provide clearer context
|
||||
3. Select specific code rather than asking about whole file
|
||||
|
||||
### Not Understanding Codebase
|
||||
|
||||
Use harpoon to provide multi-file context:
|
||||
1. Mark relevant files
|
||||
2. `<leader>kh` - Include them in question
|
||||
413
docs/guides/debugging.md
Normal file
413
docs/guides/debugging.md
Normal file
@@ -0,0 +1,413 @@
|
||||
# Debugging Guide
|
||||
|
||||
This guide covers debugging with DAP (Debug Adapter Protocol) for TypeScript, Python, and Go.
|
||||
|
||||
## Overview
|
||||
|
||||
DAP provides IDE-like debugging:
|
||||
- Breakpoints (line, conditional, logpoints)
|
||||
- Step through code (into, over, out)
|
||||
- Variable inspection
|
||||
- Call stack navigation
|
||||
- Expression evaluation
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Basic Debugging Flow
|
||||
|
||||
1. **Set breakpoint**: `<leader>db`
|
||||
2. **Start debugger**: `<leader>dc`
|
||||
3. **Step through**: `<leader>di` (into), `<leader>do` (over)
|
||||
4. **Inspect**: `<leader>du` (toggle UI)
|
||||
5. **Stop**: `<leader>dt`
|
||||
|
||||
## Key Bindings
|
||||
|
||||
### Breakpoints
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>db` | Toggle breakpoint |
|
||||
| `<leader>dB` | Conditional breakpoint |
|
||||
| `<leader>dl` | Log point (print without stopping) |
|
||||
|
||||
### Execution Control
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>dc` | Continue (or start) |
|
||||
| `<leader>di` | Step into |
|
||||
| `<leader>do` | Step over |
|
||||
| `<leader>dO` | Step out |
|
||||
| `<leader>dC` | Run to cursor |
|
||||
| `<leader>dp` | Pause |
|
||||
| `<leader>dt` | Terminate |
|
||||
| `<leader>dr` | Toggle REPL |
|
||||
|
||||
### UI & Inspection
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>du` | Toggle DAP UI |
|
||||
| `<leader>de` | Evaluate expression |
|
||||
| `<leader>dw` | Add to watch |
|
||||
| `<leader>ds` | View scopes |
|
||||
|
||||
## DAP UI Layout
|
||||
|
||||
When you press `<leader>du`, the UI shows:
|
||||
|
||||
```
|
||||
┌─────────────┬─────────────────────┐
|
||||
│ Scopes │ │
|
||||
│ (variables) │ Source Code │
|
||||
├─────────────┤ (your file) │
|
||||
│ Breakpoints │ │
|
||||
├─────────────┤ │
|
||||
│ Call Stack │ │
|
||||
├─────────────┼─────────────────────┤
|
||||
│ Watch │ Console/REPL │
|
||||
└─────────────┴─────────────────────┘
|
||||
```
|
||||
|
||||
### Scopes Panel
|
||||
|
||||
Shows variables in current scope:
|
||||
- Local variables
|
||||
- Function arguments
|
||||
- Global variables
|
||||
- Expand objects/arrays with `<cr>`
|
||||
|
||||
### Call Stack Panel
|
||||
|
||||
Shows function call hierarchy:
|
||||
- Current function at top
|
||||
- Click to jump to that frame
|
||||
- See where you came from
|
||||
|
||||
### Breakpoints Panel
|
||||
|
||||
Lists all breakpoints:
|
||||
- Toggle enable/disable
|
||||
- Delete breakpoints
|
||||
- See conditions
|
||||
|
||||
### Watch Panel
|
||||
|
||||
Add expressions to monitor:
|
||||
- `<leader>dw` to add
|
||||
- Updates as you step
|
||||
|
||||
## Debugging by Language
|
||||
|
||||
### TypeScript/JavaScript
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
```bash
|
||||
npm install -g @vscode/js-debug
|
||||
```
|
||||
|
||||
#### Debug Current File
|
||||
|
||||
1. Open your `.ts` or `.js` file
|
||||
2. `<leader>db` - Set breakpoint
|
||||
3. `<leader>dc` - Start debugging
|
||||
4. Select "Node.js: Launch" or similar
|
||||
|
||||
#### Debug Tests
|
||||
|
||||
```
|
||||
<leader>td Debug test at cursor
|
||||
```
|
||||
|
||||
This automatically sets up the test runner with debugging.
|
||||
|
||||
#### launch.json Example
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "pwa-node",
|
||||
"request": "launch",
|
||||
"name": "Debug Current File",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"sourceMaps": true
|
||||
},
|
||||
{
|
||||
"type": "pwa-node",
|
||||
"request": "launch",
|
||||
"name": "Debug Server",
|
||||
"program": "${workspaceFolder}/src/index.ts",
|
||||
"preLaunchTask": "tsc: build",
|
||||
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
```bash
|
||||
pip install debugpy
|
||||
```
|
||||
|
||||
#### Debug Current File
|
||||
|
||||
1. Open your `.py` file
|
||||
2. `<leader>db` - Set breakpoint
|
||||
3. `<leader>dc` - Start debugging
|
||||
4. Select "Python: Current File"
|
||||
|
||||
#### Debug Tests
|
||||
|
||||
```
|
||||
<leader>td Debug test at cursor
|
||||
```
|
||||
|
||||
#### launch.json Example
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: Current File",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Python: Flask",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "flask",
|
||||
"args": ["run", "--debug"],
|
||||
"env": {
|
||||
"FLASK_APP": "app.py"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python: Django",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/manage.py",
|
||||
"args": ["runserver", "--noreload"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
```bash
|
||||
go install github.com/go-delve/delve/cmd/dlv@latest
|
||||
```
|
||||
|
||||
#### Debug Current File
|
||||
|
||||
1. Open your `.go` file
|
||||
2. `<leader>db` - Set breakpoint
|
||||
3. `<leader>dc` - Start debugging
|
||||
4. Select "Go: Debug Package"
|
||||
|
||||
#### Debug Tests
|
||||
|
||||
```
|
||||
<leader>td Debug test at cursor
|
||||
```
|
||||
|
||||
Works with table-driven tests too!
|
||||
|
||||
#### launch.json Example
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug Package",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${fileDirname}"
|
||||
},
|
||||
{
|
||||
"name": "Debug Main",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}/cmd/server"
|
||||
},
|
||||
{
|
||||
"name": "Attach to Process",
|
||||
"type": "go",
|
||||
"request": "attach",
|
||||
"mode": "local",
|
||||
"processId": "${command:pickProcess}"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Breakpoint Types
|
||||
|
||||
### Line Breakpoint
|
||||
|
||||
Standard breakpoint - stops when line is reached:
|
||||
```
|
||||
<leader>db Toggle on current line
|
||||
```
|
||||
|
||||
### Conditional Breakpoint
|
||||
|
||||
Only stops when condition is true:
|
||||
```
|
||||
<leader>dB Prompts for condition
|
||||
```
|
||||
|
||||
Example conditions:
|
||||
- `x > 10`
|
||||
- `user.name == "test"`
|
||||
- `items.length > 0`
|
||||
|
||||
### Log Point
|
||||
|
||||
Prints message without stopping:
|
||||
```
|
||||
<leader>dl Prompts for log message
|
||||
```
|
||||
|
||||
Use `{}` for interpolation:
|
||||
- `Value of x: {x}`
|
||||
- `User: {user.name}`
|
||||
|
||||
### Hit Count Breakpoint
|
||||
|
||||
Stop after N hits (set via conditional):
|
||||
```
|
||||
<leader>dB Enter: hitCount > 5
|
||||
```
|
||||
|
||||
## Debugging Strategies
|
||||
|
||||
### Step Through Unknown Code
|
||||
|
||||
1. Set breakpoint at entry point
|
||||
2. `<leader>dc` - Start
|
||||
3. `<leader>di` - Step into functions to understand them
|
||||
4. `<leader>do` - Step over when you understand
|
||||
5. `<leader>dO` - Step out when done with function
|
||||
|
||||
### Find Where Value Changes
|
||||
|
||||
1. Set breakpoint where value is used
|
||||
2. `<leader>dw` - Add variable to watch
|
||||
3. Step through, watching for changes
|
||||
4. Or use conditional breakpoint: `x != expectedValue`
|
||||
|
||||
### Debug Loops
|
||||
|
||||
1. Set conditional breakpoint: `i == problematicIndex`
|
||||
2. Or use hit count: stop after N iterations
|
||||
3. Check variables at specific iteration
|
||||
|
||||
### Remote Debugging
|
||||
|
||||
For processes running elsewhere:
|
||||
|
||||
1. Start process with debug flag
|
||||
2. Use "attach" configuration
|
||||
3. Connect to debug port
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Finding a Bug
|
||||
|
||||
1. Reproduce the bug path
|
||||
2. Set breakpoint before bug occurs
|
||||
3. `<leader>dc` - Start debugging
|
||||
4. Step through, inspecting variables
|
||||
5. Find where actual != expected
|
||||
6. Fix and re-test
|
||||
|
||||
### Understanding New Code
|
||||
|
||||
1. Set breakpoint at function entry
|
||||
2. `<leader>dc` - Start with a test case
|
||||
3. `<leader>di` - Step into each function
|
||||
4. Use watch to track key variables
|
||||
5. Build mental model of flow
|
||||
|
||||
### Performance Investigation
|
||||
|
||||
Use log points to trace without stopping:
|
||||
1. `<leader>dl` at key points
|
||||
2. Log timing: `Start: {Date.now()}`
|
||||
3. Run normally
|
||||
4. Check console for timing
|
||||
|
||||
## Tips
|
||||
|
||||
### Quick Variable Inspection
|
||||
|
||||
Hover over variable with cursor - shows value in float.
|
||||
|
||||
### REPL Usage
|
||||
|
||||
`<leader>dr` opens REPL where you can:
|
||||
- Evaluate expressions
|
||||
- Call functions
|
||||
- Modify variables (sometimes)
|
||||
|
||||
### Restart Debugging
|
||||
|
||||
If you need to start over:
|
||||
```
|
||||
<leader>dt Terminate
|
||||
<leader>dc Start again
|
||||
```
|
||||
|
||||
### Breakpoint Persistence
|
||||
|
||||
Breakpoints are saved per session. They'll be there when you reopen the file.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Debugger Won't Start
|
||||
|
||||
1. Check adapter is installed
|
||||
2. `:DapShowLog` for errors
|
||||
3. Verify launch configuration
|
||||
|
||||
### Breakpoints Not Hit
|
||||
|
||||
1. Verify file paths match
|
||||
2. Check source maps (TypeScript)
|
||||
3. Ensure code is actually executed
|
||||
|
||||
### Variables Not Showing
|
||||
|
||||
1. Might be optimized out (Go)
|
||||
2. Check scope (local vs global)
|
||||
3. Try evaluating directly: `<leader>de`
|
||||
|
||||
### Source Maps Issues (TypeScript)
|
||||
|
||||
1. Ensure `sourceMaps: true` in launch.json
|
||||
2. Check tsconfig has `sourceMap: true`
|
||||
3. Verify outFiles pattern matches
|
||||
|
||||
### Slow Debugging
|
||||
|
||||
1. Reduce number of breakpoints
|
||||
2. Use conditional breakpoints
|
||||
3. Disable logging breakpoints when not needed
|
||||
509
docs/guides/git-workflow.md
Normal file
509
docs/guides/git-workflow.md
Normal file
@@ -0,0 +1,509 @@
|
||||
# Git Workflow Guide
|
||||
|
||||
This guide covers the complete git workflow in Neovim, from making changes to creating pull requests.
|
||||
|
||||
## Overview
|
||||
|
||||
Your config includes:
|
||||
|
||||
- **Diffview**: Side-by-side diffs, file history, merge resolution
|
||||
- **Git-blame**: Inline blame annotations
|
||||
- **Gitsigns**: Gutter signs, hunk staging
|
||||
- **Octo**: GitHub PRs and issues in Neovim
|
||||
- **Lazygit**: Full TUI git client (optional)
|
||||
|
||||
## Daily Git Workflow
|
||||
|
||||
### 1. Check Status
|
||||
|
||||
See what's changed:
|
||||
|
||||
```
|
||||
<leader>gd Open diffview (all changes)
|
||||
```
|
||||
|
||||
Or use gitsigns to see hunks in current file:
|
||||
|
||||
```
|
||||
]h Jump to next hunk
|
||||
[h Jump to previous hunk
|
||||
```
|
||||
|
||||
### 2. Stage Changes
|
||||
|
||||
#### Stage Hunks (Gitsigns)
|
||||
|
||||
Gitsigns provides inline staging in the current buffer:
|
||||
|
||||
```
|
||||
]h Jump to next hunk
|
||||
[h Jump to previous hunk
|
||||
<leader>ghs Stage hunk under cursor (in normal or visual mode)
|
||||
<leader>ghr Reset hunk (undo changes)
|
||||
<leader>ghS Stage entire buffer
|
||||
<leader>ghu Undo stage hunk
|
||||
<leader>ghp Preview hunk inline
|
||||
```
|
||||
|
||||
**Note**: The `<leader>ghs` command works in both normal and visual mode. In visual mode, it stages the selected lines.
|
||||
|
||||
#### Stage in Diffview
|
||||
|
||||
**Important**: To stage/unstage files in diffview, you need to open the main diffview (not file history):
|
||||
|
||||
1. Open diffview with `<leader>gd` (this shows the file panel on the left)
|
||||
2. Focus the file panel (press `<leader>e` if needed)
|
||||
3. Use these keys in the file panel:
|
||||
|
||||
```
|
||||
- Toggle stage/unstage file (under cursor)
|
||||
S Stage all files
|
||||
U Unstage all files
|
||||
X Revert file changes
|
||||
<cr> Open diff for selected file
|
||||
<tab> Toggle file panel
|
||||
```
|
||||
|
||||
**Note**: If you see a telescope-like picker, you're in file history mode. Use `<leader>gd` (without arguments) to open the main diffview with staging capabilities.
|
||||
|
||||
### 3. Review Before Commit
|
||||
|
||||
```
|
||||
<leader>gd Open diffview
|
||||
```
|
||||
|
||||
Navigate files in left panel, review diffs on right.
|
||||
|
||||
### 4. Commit
|
||||
|
||||
Close diffview first (`<leader>gD`), then:
|
||||
|
||||
```
|
||||
:Git commit Open commit message editor
|
||||
```
|
||||
|
||||
Or use terminal/lazygit:
|
||||
|
||||
```
|
||||
<leader>gg Open lazygit (if installed)
|
||||
```
|
||||
|
||||
## Viewing History
|
||||
|
||||
### File History
|
||||
|
||||
See all commits that changed current file:
|
||||
|
||||
```
|
||||
<leader>gf File history for current file
|
||||
```
|
||||
|
||||
In history view:
|
||||
|
||||
- `j/k` - Navigate commits
|
||||
- `<cr>` - View diff at that commit
|
||||
- `<tab>` - Toggle file panel
|
||||
|
||||
### Branch History
|
||||
|
||||
See all commits on current branch:
|
||||
|
||||
```
|
||||
<leader>gF Full branch history
|
||||
```
|
||||
|
||||
### Compare to Main
|
||||
|
||||
See what's different from main branch:
|
||||
|
||||
```
|
||||
<leader>gm Compare to origin/main
|
||||
<leader>gM Compare to origin/master
|
||||
```
|
||||
|
||||
## Git Blame
|
||||
|
||||
### Toggle Inline Blame
|
||||
|
||||
```
|
||||
<leader>gB Toggle blame annotations
|
||||
```
|
||||
|
||||
Shows author and commit info at end of each line.
|
||||
|
||||
### Investigate a Commit
|
||||
|
||||
When blame is on:
|
||||
|
||||
```
|
||||
<leader>go Open commit in browser (GitHub)
|
||||
<leader>gy Copy commit URL
|
||||
```
|
||||
|
||||
## Working with PRs (Octo)
|
||||
|
||||
### List PRs
|
||||
|
||||
```
|
||||
<leader>gpl List all PRs
|
||||
```
|
||||
|
||||
Navigate and press `<cr>` to open.
|
||||
|
||||
### Create PR
|
||||
|
||||
```
|
||||
<leader>gpc Create new PR
|
||||
```
|
||||
|
||||
This opens a buffer to write PR title and description.
|
||||
|
||||
### Checkout PR
|
||||
|
||||
```
|
||||
<leader>gpo Checkout a PR locally
|
||||
```
|
||||
|
||||
Select from list of PRs.
|
||||
|
||||
### Review PR
|
||||
|
||||
#### Start Review
|
||||
|
||||
```
|
||||
<leader>grs Start review
|
||||
```
|
||||
|
||||
#### Add Comments
|
||||
|
||||
In PR file:
|
||||
|
||||
```
|
||||
<leader>ca Add comment at cursor
|
||||
```
|
||||
|
||||
#### Submit Review
|
||||
|
||||
```
|
||||
<leader>grc Submit review
|
||||
```
|
||||
|
||||
Choose: Approve, Comment, or Request Changes.
|
||||
|
||||
#### Other Review Actions
|
||||
|
||||
```
|
||||
<leader>grr Resume review (if interrupted)
|
||||
<leader>grd Discard review
|
||||
```
|
||||
|
||||
### Merge PR
|
||||
|
||||
```
|
||||
<leader>gpm Merge PR
|
||||
```
|
||||
|
||||
### View in Browser
|
||||
|
||||
```
|
||||
<leader>gpb Open PR in browser
|
||||
```
|
||||
|
||||
## Working with Issues (Octo)
|
||||
|
||||
### List Issues
|
||||
|
||||
```
|
||||
<leader>gil List issues
|
||||
```
|
||||
|
||||
### Create Issue
|
||||
|
||||
```
|
||||
<leader>gic Create new issue
|
||||
```
|
||||
|
||||
### Open in Browser
|
||||
|
||||
```
|
||||
<leader>gib Open issue in browser
|
||||
```
|
||||
|
||||
## Merge Conflicts
|
||||
|
||||
### Open Merge Tool
|
||||
|
||||
When you have conflicts:
|
||||
|
||||
```
|
||||
:DiffviewOpen
|
||||
```
|
||||
|
||||
Diffview detects conflicts and shows 3-way merge view.
|
||||
|
||||
### Resolve Conflicts
|
||||
|
||||
In merge view:
|
||||
|
||||
- Left: Ours (current branch)
|
||||
- Center: Result (what you're building)
|
||||
- Right: Theirs (incoming changes)
|
||||
|
||||
Navigate conflicts:
|
||||
|
||||
```
|
||||
]x Next conflict
|
||||
[x Previous conflict
|
||||
```
|
||||
|
||||
Choose resolution:
|
||||
|
||||
```
|
||||
<leader>co Choose ours
|
||||
<leader>ct Choose theirs
|
||||
<leader>cb Choose both
|
||||
<leader>c0 Choose none
|
||||
```
|
||||
|
||||
### Complete Merge
|
||||
|
||||
After resolving all conflicts:
|
||||
|
||||
```
|
||||
:DiffviewClose
|
||||
:Git add .
|
||||
:Git commit
|
||||
```
|
||||
|
||||
## Advanced Diffview
|
||||
|
||||
### Custom Comparisons
|
||||
|
||||
Compare any refs:
|
||||
|
||||
```
|
||||
:DiffviewOpen origin/main...HEAD
|
||||
:DiffviewOpen HEAD~5
|
||||
:DiffviewOpen branch1..branch2
|
||||
```
|
||||
|
||||
### Diffview Panel Keys
|
||||
|
||||
**In the File Panel** (left side when open with `<leader>gd`):
|
||||
|
||||
```
|
||||
j/k Navigate files
|
||||
<cr> Open diff for selected file
|
||||
- Toggle stage/unstage file
|
||||
S Stage all files
|
||||
U Unstage all files
|
||||
X Revert file changes
|
||||
<tab> Toggle file panel visibility
|
||||
<leader>e Focus file panel
|
||||
<leader>b Toggle file panel
|
||||
R Refresh file list
|
||||
L Show commit log
|
||||
g? Show help
|
||||
```
|
||||
|
||||
**In the Diff View** (right side):
|
||||
|
||||
```
|
||||
<tab> Navigate to next file
|
||||
<leader>e Focus file panel
|
||||
<leader>b Toggle file panel
|
||||
g? Show help
|
||||
```
|
||||
|
||||
**Important**: The staging keys (`-`, `S`, `U`) only work in the **file panel**, not in the diff view itself. Make sure you're focused on the left panel (press `<leader>e` to focus it).
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Feature Development
|
||||
|
||||
1. Create branch (terminal):
|
||||
|
||||
```bash
|
||||
git checkout -b feature/my-feature
|
||||
```
|
||||
|
||||
2. Make changes, stage hunks:
|
||||
|
||||
```
|
||||
<leader>ghs Stage hunk
|
||||
```
|
||||
|
||||
3. Review all changes:
|
||||
|
||||
```
|
||||
<leader>gd Open diffview
|
||||
```
|
||||
|
||||
4. Commit (in terminal or lazygit)
|
||||
|
||||
5. Compare to main before PR:
|
||||
|
||||
```
|
||||
<leader>gm Compare to main
|
||||
```
|
||||
|
||||
6. Create PR:
|
||||
|
||||
```
|
||||
<leader>gpc Create PR
|
||||
```
|
||||
|
||||
### Code Review
|
||||
|
||||
1. List PRs:
|
||||
|
||||
```
|
||||
<leader>gpl
|
||||
```
|
||||
|
||||
2. Select and open PR
|
||||
|
||||
3. Start review:
|
||||
|
||||
```
|
||||
<leader>grs
|
||||
```
|
||||
|
||||
4. Navigate files, add comments
|
||||
|
||||
5. Submit:
|
||||
|
||||
```
|
||||
<leader>grc
|
||||
```
|
||||
|
||||
### Investigating a Bug
|
||||
|
||||
1. Find when bug was introduced:
|
||||
|
||||
```
|
||||
<leader>gf File history
|
||||
```
|
||||
|
||||
2. Navigate commits to find the change
|
||||
|
||||
3. Check blame for context:
|
||||
|
||||
```
|
||||
<leader>gB Toggle blame
|
||||
```
|
||||
|
||||
4. Open commit in browser:
|
||||
|
||||
```
|
||||
<leader>go
|
||||
```
|
||||
|
||||
### Resolving Merge Conflicts
|
||||
|
||||
1. After `git merge` with conflicts:
|
||||
|
||||
```
|
||||
:DiffviewOpen
|
||||
```
|
||||
|
||||
2. For each conflicting file:
|
||||
- Navigate to conflict
|
||||
- Choose resolution
|
||||
- Move to next
|
||||
|
||||
3. When done:
|
||||
|
||||
```
|
||||
:DiffviewClose
|
||||
git add . && git commit
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
### Quick Hunk Preview
|
||||
|
||||
Without opening diffview, you can preview hunks inline:
|
||||
|
||||
```
|
||||
<leader>ghp Preview hunk inline (shows diff in floating window)
|
||||
```
|
||||
|
||||
### Understanding Diffview Modes
|
||||
|
||||
Diffview has different modes:
|
||||
|
||||
1. **Main Diffview** (`<leader>gd`): Shows file panel + diff view. Use this for staging/unstaging files.
|
||||
2. **File History** (`<leader>gf`): Shows a picker to select commits. This is read-only.
|
||||
3. **Branch History** (`<leader>gF`): Shows all commits on current branch. This is read-only.
|
||||
|
||||
For staging/unstaging, always use `<leader>gd` (main diffview).
|
||||
|
||||
### Blame with Commit Message
|
||||
|
||||
The inline blame shows:
|
||||
|
||||
- Author
|
||||
- Relative time
|
||||
- Short commit message
|
||||
|
||||
### Stashing
|
||||
|
||||
Use terminal or lazygit:
|
||||
|
||||
```
|
||||
git stash
|
||||
git stash pop
|
||||
```
|
||||
|
||||
### Interactive Rebase
|
||||
|
||||
Use terminal (not supported in Neovim):
|
||||
|
||||
```bash
|
||||
git rebase -i HEAD~5
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Octo Not Working
|
||||
|
||||
1. Ensure `gh` CLI is installed
|
||||
2. Authenticate: `gh auth login`
|
||||
3. Check `:Octo` commands are available
|
||||
|
||||
### Diffview Slow
|
||||
|
||||
For large repos:
|
||||
|
||||
- Limit file count in view
|
||||
- Use specific file paths
|
||||
|
||||
### Gitsigns Not Showing
|
||||
|
||||
1. Verify file is in git repo
|
||||
2. `:Gitsigns debug_messages`
|
||||
3. Check file isn't ignored
|
||||
4. Ensure `lazyvim.plugins.extras.lang.git` is enabled in `lazyvim.json`
|
||||
|
||||
### Diffview Shows Telescope Picker Instead of File Panel
|
||||
|
||||
If `<leader>gd` shows a picker instead of the file panel:
|
||||
|
||||
1. Make sure you're using `<leader>gd` (not `<leader>gf` or `<leader>gF`)
|
||||
2. `<leader>gf` opens file history (picker mode) - this is read-only
|
||||
3. `<leader>gd` opens main diffview with file panel - use this for staging
|
||||
4. If file panel isn't visible, press `<tab>` or `<leader>b` to toggle it
|
||||
5. Press `<leader>e` to focus the file panel before using staging keys
|
||||
|
||||
### Staging Keys Don't Work in Diffview
|
||||
|
||||
The staging keys (`-`, `S`, `U`) are built into diffview.nvim and should work by default. If they don't:
|
||||
|
||||
1. Make sure you're in the **file panel** (left side), not the diff view (right side)
|
||||
2. Press `<leader>e` to focus the file panel first
|
||||
3. Make sure you opened diffview with `<leader>gd` (not file history)
|
||||
4. Check if there's a key conflict: run `:checkhealth diffview` or `:Telescope keymaps` and search for `-`
|
||||
5. If `-` is mapped elsewhere, it might conflict - diffview keymaps are buffer-local, so conflicts are rare
|
||||
|
||||
**Note**: Diffview's keymaps are set automatically when the file panel is active. If they're not working, there might be a plugin loading issue. Try restarting Neovim or running `:Lazy sync`.
|
||||
409
docs/guides/go-workflow.md
Normal file
409
docs/guides/go-workflow.md
Normal file
@@ -0,0 +1,409 @@
|
||||
# Go Development Workflow
|
||||
|
||||
This guide covers Go development in Neovim with gopls, testing, and debugging.
|
||||
|
||||
## Overview
|
||||
|
||||
Your config includes:
|
||||
- **LSP**: gopls (via LazyVim go extra)
|
||||
- **Linting**: golangci-lint
|
||||
- **Testing**: go test via neotest
|
||||
- **Debugging**: delve via DAP
|
||||
- **Formatting**: gofmt/goimports
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Project Setup
|
||||
|
||||
1. Ensure Go is installed and `GOPATH` is set
|
||||
2. Open your Go project:
|
||||
```bash
|
||||
nvim /path/to/project
|
||||
```
|
||||
|
||||
3. gopls will auto-start when you open a `.go` file
|
||||
|
||||
### Module Initialization
|
||||
|
||||
If starting fresh:
|
||||
```bash
|
||||
go mod init myproject
|
||||
```
|
||||
|
||||
## LSP Features
|
||||
|
||||
### Navigation
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `gd` | Go to definition |
|
||||
| `gr` | Go to references |
|
||||
| `gI` | Go to implementation |
|
||||
| `gy` | Go to type definition |
|
||||
| `K` | Hover documentation |
|
||||
|
||||
### Code Actions
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>ca` | Code actions |
|
||||
| `<leader>cr` | Rename symbol |
|
||||
| `<leader>cf` | Format (gofmt) |
|
||||
|
||||
### Go-Specific Actions
|
||||
|
||||
Press `<leader>ca` for:
|
||||
- Add import
|
||||
- Organize imports
|
||||
- Extract function
|
||||
- Extract variable
|
||||
- Generate interface stubs
|
||||
- Add struct tags
|
||||
- Fill struct
|
||||
|
||||
### Diagnostics
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>cd` | Line diagnostics |
|
||||
| `]d` / `[d` | Next/prev diagnostic |
|
||||
| `<leader>xx` | Toggle trouble |
|
||||
|
||||
## Testing
|
||||
|
||||
### Running Tests
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>tt` | Run test at cursor |
|
||||
| `<leader>tf` | Run file tests |
|
||||
| `<leader>ta` | Run all tests |
|
||||
| `<leader>tl` | Re-run last test |
|
||||
|
||||
### Test File Convention
|
||||
|
||||
Go tests live in `*_test.go` files:
|
||||
|
||||
```go
|
||||
// math_test.go
|
||||
package math
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
result := Add(2, 3)
|
||||
if result != 5 {
|
||||
t.Errorf("expected 5, got %d", result)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test Output
|
||||
|
||||
```
|
||||
<leader>ts Toggle test summary
|
||||
<leader>to Show test output
|
||||
<leader>tO Toggle output panel
|
||||
]t / [t Jump to failed tests
|
||||
```
|
||||
|
||||
### Table-Driven Tests
|
||||
|
||||
Common Go pattern - cursor on any test case runs it:
|
||||
|
||||
```go
|
||||
func TestAdd(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
a, b int
|
||||
expected int
|
||||
}{
|
||||
{"positive", 2, 3, 5},
|
||||
{"negative", -1, -1, -2},
|
||||
{"zero", 0, 0, 0},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// <leader>tt here runs this specific case
|
||||
if got := Add(tt.a, tt.b); got != tt.expected {
|
||||
t.Errorf("got %d, want %d", got, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Debugging Tests
|
||||
|
||||
```
|
||||
<leader>td Debug test at cursor
|
||||
```
|
||||
|
||||
## Debugging with Delve
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Install delve:
|
||||
```bash
|
||||
go install github.com/go-delve/delve/cmd/dlv@latest
|
||||
```
|
||||
|
||||
### Setting Breakpoints
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>db` | Toggle breakpoint |
|
||||
| `<leader>dB` | Conditional breakpoint |
|
||||
|
||||
### Running Debugger
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>dc` | Continue/Start |
|
||||
| `<leader>di` | Step into |
|
||||
| `<leader>do` | Step over |
|
||||
| `<leader>dO` | Step out |
|
||||
| `<leader>dt` | Terminate |
|
||||
|
||||
### DAP UI
|
||||
|
||||
```
|
||||
<leader>du Toggle DAP UI
|
||||
<leader>de Evaluate expression
|
||||
```
|
||||
|
||||
### launch.json
|
||||
|
||||
For custom debug configs, create `.vscode/launch.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug Package",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${fileDirname}"
|
||||
},
|
||||
{
|
||||
"name": "Debug Main",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceFolder}/cmd/myapp"
|
||||
},
|
||||
{
|
||||
"name": "Attach to Process",
|
||||
"type": "go",
|
||||
"request": "attach",
|
||||
"mode": "local",
|
||||
"processId": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Code Quality
|
||||
|
||||
### Formatting
|
||||
|
||||
Go code is auto-formatted on save. Manual format:
|
||||
```
|
||||
<leader>cf Format with gofmt
|
||||
```
|
||||
|
||||
### Imports
|
||||
|
||||
goimports manages imports automatically:
|
||||
- Adds missing imports on save
|
||||
- Removes unused imports
|
||||
- Sorts imports
|
||||
|
||||
### Linting
|
||||
|
||||
golangci-lint runs automatically. View issues:
|
||||
```
|
||||
<leader>xx Toggle trouble (all diagnostics)
|
||||
```
|
||||
|
||||
### Struct Tags
|
||||
|
||||
Generate/modify struct tags via code actions:
|
||||
|
||||
```go
|
||||
type User struct {
|
||||
Name string // <leader>ca → "Add json tag"
|
||||
Email string
|
||||
}
|
||||
```
|
||||
|
||||
Result:
|
||||
```go
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
```
|
||||
|
||||
## AI Assistance
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>ka` | Ask opencode |
|
||||
| `<leader>ke` | Explain code |
|
||||
| `<leader>kR` | Refactor selection |
|
||||
| `<leader>kt` | Generate tests |
|
||||
| `<leader>kd` | Generate comments |
|
||||
|
||||
### Generate Tests
|
||||
|
||||
1. Select function in visual mode
|
||||
2. `<leader>kt`
|
||||
3. Review generated table-driven tests
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Starting New Feature
|
||||
|
||||
1. Create/open `.go` file
|
||||
2. `<leader>H` - Mark with harpoon
|
||||
3. Write code, LSP handles imports
|
||||
4. `<leader>tt` - Test as you go
|
||||
|
||||
### Implementing Interface
|
||||
|
||||
1. Write struct
|
||||
2. `<leader>ca` → "Generate interface stubs"
|
||||
3. Select interface to implement
|
||||
4. Fill in method bodies
|
||||
|
||||
### Debugging
|
||||
|
||||
1. `<leader>db` - Set breakpoint
|
||||
2. `<leader>dc` - Start debugger
|
||||
3. Use step commands to navigate
|
||||
4. `<leader>de` - Evaluate expressions
|
||||
5. `<leader>dt` - Terminate when done
|
||||
|
||||
### Error Handling
|
||||
|
||||
Common Go pattern - AI can help:
|
||||
|
||||
1. Write function that returns error
|
||||
2. `<leader>ka` - "Add proper error handling"
|
||||
3. Or use snippet (if configured):
|
||||
```go
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Standard Layout
|
||||
|
||||
```
|
||||
myproject/
|
||||
├── cmd/
|
||||
│ └── myapp/
|
||||
│ └── main.go
|
||||
├── internal/
|
||||
│ └── pkg/
|
||||
├── pkg/
|
||||
│ └── public/
|
||||
├── go.mod
|
||||
└── go.sum
|
||||
```
|
||||
|
||||
### go.mod
|
||||
|
||||
```go
|
||||
module github.com/user/myproject
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/some/dependency v1.0.0
|
||||
)
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
### Quick Run
|
||||
|
||||
```
|
||||
:!go run . Run current package
|
||||
:!go run main.go Run specific file
|
||||
```
|
||||
|
||||
Or use executor:
|
||||
```
|
||||
<leader>Brs Set command: go run .
|
||||
<leader>Brr Run it
|
||||
```
|
||||
|
||||
### Build
|
||||
|
||||
```
|
||||
:!go build . Build current package
|
||||
```
|
||||
|
||||
### Generate
|
||||
|
||||
```
|
||||
:!go generate ./... Run go generate
|
||||
```
|
||||
|
||||
### Module Commands
|
||||
|
||||
```
|
||||
:!go mod tidy Clean up go.mod
|
||||
:!go mod download Download dependencies
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
- `K` on any symbol shows docs
|
||||
- Works with standard library
|
||||
- Shows function signatures
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### gopls Not Starting
|
||||
|
||||
1. `:LspInfo` - Check status
|
||||
2. Verify gopls is installed:
|
||||
```bash
|
||||
go install golang.org/x/tools/gopls@latest
|
||||
```
|
||||
3. Check `go.mod` exists in project root
|
||||
|
||||
### Imports Not Working
|
||||
|
||||
1. Check gopls is running: `:LspInfo`
|
||||
2. Verify `goimports` is installed:
|
||||
```bash
|
||||
go install golang.org/x/tools/cmd/goimports@latest
|
||||
```
|
||||
|
||||
### Debugger Issues
|
||||
|
||||
1. Verify delve is installed:
|
||||
```bash
|
||||
go install github.com/go-delve/delve/cmd/dlv@latest
|
||||
```
|
||||
2. Check `:DapShowLog` for errors
|
||||
3. Ensure code is compiled (not just source)
|
||||
|
||||
### Slow LSP
|
||||
|
||||
1. Check for large generated files
|
||||
2. Add to `.gopls.json`:
|
||||
```json
|
||||
{
|
||||
"build.directoryFilters": ["-vendor", "-node_modules"]
|
||||
}
|
||||
```
|
||||
363
docs/guides/python-workflow.md
Normal file
363
docs/guides/python-workflow.md
Normal file
@@ -0,0 +1,363 @@
|
||||
# Python Development Workflow
|
||||
|
||||
This guide covers Python development in Neovim with virtual environment support, testing, and debugging.
|
||||
|
||||
## Overview
|
||||
|
||||
Your config includes:
|
||||
- **LSP**: Pyright (via LazyVim python extra)
|
||||
- **Linting**: Ruff or pylint
|
||||
- **Testing**: pytest via neotest
|
||||
- **Debugging**: debugpy via DAP
|
||||
- **Virtual Environments**: venv-selector
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Project Setup
|
||||
|
||||
1. Open your Python project:
|
||||
```bash
|
||||
nvim /path/to/project
|
||||
```
|
||||
|
||||
2. Select virtual environment:
|
||||
```
|
||||
<leader>cv Open venv selector
|
||||
```
|
||||
|
||||
3. The LSP will restart with the selected venv.
|
||||
|
||||
## Virtual Environment Management
|
||||
|
||||
### Selecting a Virtual Environment
|
||||
|
||||
```
|
||||
<leader>cv Open venv selector
|
||||
```
|
||||
|
||||
This searches for:
|
||||
- `.venv/` in project
|
||||
- `venv/` in project
|
||||
- Poetry environments
|
||||
- Conda environments
|
||||
- pyenv environments
|
||||
|
||||
### Creating a Virtual Environment
|
||||
|
||||
If you don't have one:
|
||||
|
||||
```bash
|
||||
# In terminal or with <leader>ft (float term)
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Then `<leader>cv` to select it.
|
||||
|
||||
## LSP Features
|
||||
|
||||
### Navigation
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `gd` | Go to definition |
|
||||
| `gr` | Go to references |
|
||||
| `gI` | Go to implementation |
|
||||
| `K` | Hover documentation |
|
||||
|
||||
### Code Actions
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>ca` | Code actions |
|
||||
| `<leader>cr` | Rename symbol |
|
||||
| `<leader>cf` | Format document |
|
||||
|
||||
### Diagnostics
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>cd` | Line diagnostics |
|
||||
| `]d` / `[d` | Next/prev diagnostic |
|
||||
| `<leader>xx` | Toggle trouble |
|
||||
|
||||
## Testing with pytest
|
||||
|
||||
### Running Tests
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>tt` | Run test at cursor |
|
||||
| `<leader>tf` | Run file tests |
|
||||
| `<leader>ta` | Run all tests |
|
||||
| `<leader>tl` | Re-run last test |
|
||||
|
||||
### Test Discovery
|
||||
|
||||
pytest finds tests in:
|
||||
- `test_*.py` files
|
||||
- `*_test.py` files
|
||||
- Functions named `test_*`
|
||||
- Classes named `Test*`
|
||||
|
||||
### Test Output
|
||||
|
||||
```
|
||||
<leader>ts Toggle test summary
|
||||
<leader>to Show test output
|
||||
<leader>tO Toggle output panel
|
||||
]t / [t Jump to next/prev failed test
|
||||
```
|
||||
|
||||
### Debugging Tests
|
||||
|
||||
```
|
||||
<leader>td Debug test at cursor
|
||||
```
|
||||
|
||||
This starts debugpy and allows stepping through test code.
|
||||
|
||||
## Debugging
|
||||
|
||||
### Setup
|
||||
|
||||
debugpy should be installed in your virtual environment:
|
||||
```bash
|
||||
pip install debugpy
|
||||
```
|
||||
|
||||
### Setting Breakpoints
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>db` | Toggle breakpoint |
|
||||
| `<leader>dB` | Conditional breakpoint |
|
||||
|
||||
### Running Debugger
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>dc` | Continue/Start |
|
||||
| `<leader>di` | Step into |
|
||||
| `<leader>do` | Step over |
|
||||
| `<leader>dO` | Step out |
|
||||
| `<leader>dt` | Terminate |
|
||||
|
||||
### DAP UI
|
||||
|
||||
```
|
||||
<leader>du Toggle DAP UI
|
||||
<leader>de Evaluate expression
|
||||
```
|
||||
|
||||
### launch.json
|
||||
|
||||
For custom configurations, create `.vscode/launch.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: Current File",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Python: Flask",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "flask",
|
||||
"args": ["run", "--debug"],
|
||||
"env": {
|
||||
"FLASK_APP": "app.py"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Python: FastAPI",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "uvicorn",
|
||||
"args": ["main:app", "--reload"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Code Quality
|
||||
|
||||
### Formatting
|
||||
|
||||
```
|
||||
<leader>cf Format with black/ruff
|
||||
```
|
||||
|
||||
### Import Sorting
|
||||
|
||||
If using isort or ruff:
|
||||
```
|
||||
<leader>ca Code actions → Organize imports
|
||||
```
|
||||
|
||||
### Type Checking
|
||||
|
||||
Pyright provides type checking. For strict mode, add `pyrightconfig.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"typeCheckingMode": "strict"
|
||||
}
|
||||
```
|
||||
|
||||
Or in `pyproject.toml`:
|
||||
|
||||
```toml
|
||||
[tool.pyright]
|
||||
typeCheckingMode = "strict"
|
||||
```
|
||||
|
||||
## AI Assistance
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>ka` | Ask opencode |
|
||||
| `<leader>ke` | Explain code |
|
||||
| `<leader>kR` | Refactor selection |
|
||||
| `<leader>kt` | Generate tests |
|
||||
| `<leader>kd` | Generate docstrings |
|
||||
|
||||
### Generate Docstrings
|
||||
|
||||
1. Place cursor on function
|
||||
2. `<leader>kd` (or use neogen: `<leader>cn`)
|
||||
3. Review and adjust
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Starting New Feature
|
||||
|
||||
1. `<leader>cv` - Ensure correct venv
|
||||
2. Create/open file
|
||||
3. `<leader>H` - Mark with harpoon
|
||||
4. Write code with LSP assistance
|
||||
5. `<leader>tt` - Test as you go
|
||||
|
||||
### Debugging an Issue
|
||||
|
||||
1. `<leader>xx` - View all diagnostics
|
||||
2. Navigate to issue
|
||||
3. `<leader>db` - Set breakpoint
|
||||
4. `<leader>dc` - Start debugger
|
||||
5. Step through code
|
||||
|
||||
### Adding Tests
|
||||
|
||||
1. Create `test_*.py` file
|
||||
2. Write test function:
|
||||
```python
|
||||
def test_something():
|
||||
assert my_function() == expected
|
||||
```
|
||||
3. `<leader>tt` - Run test
|
||||
4. `<leader>to` - View output
|
||||
|
||||
## Project Configuration
|
||||
|
||||
### pyproject.toml
|
||||
|
||||
Modern Python projects use `pyproject.toml`:
|
||||
|
||||
```toml
|
||||
[project]
|
||||
name = "myproject"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.11"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
python_files = "test_*.py"
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 88
|
||||
select = ["E", "F", "I"]
|
||||
|
||||
[tool.pyright]
|
||||
venvPath = "."
|
||||
venv = ".venv"
|
||||
```
|
||||
|
||||
### pytest.ini
|
||||
|
||||
For pytest configuration:
|
||||
|
||||
```ini
|
||||
[pytest]
|
||||
testpaths = tests
|
||||
python_files = test_*.py
|
||||
addopts = -v --tb=short
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
### Quick REPL
|
||||
|
||||
```
|
||||
<leader>ft Open floating terminal
|
||||
python Start Python REPL
|
||||
```
|
||||
|
||||
### Run Current File
|
||||
|
||||
```
|
||||
:!python % Run current file
|
||||
```
|
||||
|
||||
Or use executor:
|
||||
```
|
||||
<leader>Brs Set command: python %
|
||||
<leader>Brr Run it
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
- `K` on any symbol shows docstring
|
||||
- Works with standard library and packages
|
||||
|
||||
### Find TODOs
|
||||
|
||||
```
|
||||
<leader>xt Show all TODO/FIXME comments
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### LSP Not Finding Imports
|
||||
|
||||
1. Check venv is selected: `<leader>cv`
|
||||
2. `:LspInfo` - Verify pyright is attached
|
||||
3. Check `pyrightconfig.json` or `pyproject.toml`
|
||||
|
||||
### Wrong Python Version
|
||||
|
||||
1. `<leader>cv` - Select correct venv
|
||||
2. Or set explicitly in `pyrightconfig.json`:
|
||||
```json
|
||||
{
|
||||
"pythonVersion": "3.11"
|
||||
}
|
||||
```
|
||||
|
||||
### Tests Not Found
|
||||
|
||||
1. Check file naming: `test_*.py`
|
||||
2. Check function naming: `test_*`
|
||||
3. Verify pytest is installed in venv
|
||||
|
||||
### Debugger Not Starting
|
||||
|
||||
1. Install debugpy: `pip install debugpy`
|
||||
2. Check `:DapShowLog` for errors
|
||||
3. Verify venv is active
|
||||
449
docs/guides/snippets.md
Normal file
449
docs/guides/snippets.md
Normal file
@@ -0,0 +1,449 @@
|
||||
# Custom Snippets Guide
|
||||
|
||||
This guide explains how to create and use custom code snippets with LuaSnip.
|
||||
|
||||
## Overview
|
||||
|
||||
Snippets are code templates that expand when you type a trigger and press `<Tab>`. Your config supports:
|
||||
|
||||
- **Lua snippets**: Full power of Lua for dynamic snippets
|
||||
- **VS Code snippets**: JSON format in `snippets/vscode/`
|
||||
|
||||
## Snippet Locations
|
||||
|
||||
```
|
||||
~/.config/nvim/snippets/
|
||||
├── all.lua # Global snippets (all filetypes)
|
||||
├── typescript.lua # TypeScript/JavaScript
|
||||
├── python.lua # Python
|
||||
├── go.lua # Go
|
||||
└── vscode/ # VS Code format snippets (optional)
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Open Snippet File
|
||||
|
||||
```lua
|
||||
-- For TypeScript snippets:
|
||||
nvim ~/.config/nvim/snippets/typescript.lua
|
||||
```
|
||||
|
||||
### 2. Add a Simple Snippet
|
||||
|
||||
```lua
|
||||
local ls = require("luasnip")
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
|
||||
return {
|
||||
s("cl", { t("console.log("), i(1), t(")") }),
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Reload Snippets
|
||||
|
||||
```
|
||||
<leader>cS Reload all snippets
|
||||
```
|
||||
|
||||
### 4. Use Snippet
|
||||
|
||||
Type `cl` and press `<Tab>` to expand.
|
||||
|
||||
## Snippet Anatomy
|
||||
|
||||
### Basic Structure
|
||||
|
||||
```lua
|
||||
s(trigger, nodes, opts)
|
||||
```
|
||||
|
||||
- **trigger**: What you type to activate
|
||||
- **nodes**: The content (text, placeholders, etc.)
|
||||
- **opts**: Optional settings
|
||||
|
||||
### Node Types
|
||||
|
||||
| Node | Function | Purpose |
|
||||
|------|----------|---------|
|
||||
| `t(text)` | Text node | Static text |
|
||||
| `i(index, default)` | Insert node | Tab stop/placeholder |
|
||||
| `c(index, choices)` | Choice node | Multiple options |
|
||||
| `f(func, args)` | Function node | Dynamic content |
|
||||
| `d(index, func, args)` | Dynamic node | Complex dynamic content |
|
||||
| `rep(index)` | Repeat node | Mirror another node |
|
||||
|
||||
## Examples by Complexity
|
||||
|
||||
### 1. Simple Text Replacement
|
||||
|
||||
```lua
|
||||
-- Expands "todo" to "// TODO: "
|
||||
s("todo", { t("// TODO: "), i(0) })
|
||||
```
|
||||
|
||||
### 2. Multiple Tab Stops
|
||||
|
||||
```lua
|
||||
-- Arrow function with parameters and body
|
||||
s("af", {
|
||||
t("const "),
|
||||
i(1, "name"),
|
||||
t(" = ("),
|
||||
i(2),
|
||||
t(") => {"),
|
||||
t({"", " "}),
|
||||
i(0),
|
||||
t({"", "}"}),
|
||||
})
|
||||
```
|
||||
|
||||
Tab order: name → parameters → body
|
||||
|
||||
### 3. Using fmt() for Cleaner Syntax
|
||||
|
||||
```lua
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
|
||||
s("fn", fmt([[
|
||||
function {}({}) {{
|
||||
{}
|
||||
}}
|
||||
]], { i(1, "name"), i(2), i(0) }))
|
||||
```
|
||||
|
||||
Note: `{{` and `}}` escape braces in fmt.
|
||||
|
||||
### 4. Choice Node
|
||||
|
||||
```lua
|
||||
-- Choose between const, let, var
|
||||
s("var", {
|
||||
c(1, {
|
||||
t("const"),
|
||||
t("let"),
|
||||
t("var"),
|
||||
}),
|
||||
t(" "),
|
||||
i(2, "name"),
|
||||
t(" = "),
|
||||
i(0),
|
||||
})
|
||||
```
|
||||
|
||||
Press `<C-n>` / `<C-p>` to cycle choices.
|
||||
|
||||
### 5. Function Node (Dynamic)
|
||||
|
||||
```lua
|
||||
-- Automatically generate return type
|
||||
s("fn", {
|
||||
t("function "),
|
||||
i(1, "name"),
|
||||
t("("),
|
||||
i(2),
|
||||
t("): "),
|
||||
f(function(args)
|
||||
-- Generate return type based on function name
|
||||
local name = args[1][1]
|
||||
if name:match("^is") then return "boolean" end
|
||||
if name:match("^get") then return "string" end
|
||||
return "void"
|
||||
end, {1}),
|
||||
t({" {", " "}),
|
||||
i(0),
|
||||
t({"", "}"}),
|
||||
})
|
||||
```
|
||||
|
||||
### 6. Repeat Node
|
||||
|
||||
```lua
|
||||
-- Class with constructor that uses the class name
|
||||
s("class", {
|
||||
t("class "),
|
||||
i(1, "Name"),
|
||||
t({" {", " constructor("}),
|
||||
i(2),
|
||||
t({") {", " "}),
|
||||
i(0),
|
||||
t({"", " }", "", "}", ""}),
|
||||
t("export default "),
|
||||
rep(1), -- Repeats the class name
|
||||
t(";"),
|
||||
})
|
||||
```
|
||||
|
||||
### 7. Dynamic Node
|
||||
|
||||
```lua
|
||||
-- Generate multiple parameters dynamically
|
||||
s("params", {
|
||||
t("function("),
|
||||
d(1, function()
|
||||
-- Could read from clipboard, analyze code, etc.
|
||||
return sn(nil, { i(1, "param1"), t(", "), i(2, "param2") })
|
||||
end),
|
||||
t(")"),
|
||||
})
|
||||
```
|
||||
|
||||
## Language-Specific Examples
|
||||
|
||||
### TypeScript
|
||||
|
||||
```lua
|
||||
-- snippets/typescript.lua
|
||||
local ls = require("luasnip")
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
local c = ls.choice_node
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
|
||||
return {
|
||||
-- Console log
|
||||
s("cl", { t("console.log("), i(1), t(")") }),
|
||||
|
||||
-- Console log with label
|
||||
s("cll", fmt('console.log("{}: ", {})', { i(1, "label"), rep(1) })),
|
||||
|
||||
-- Arrow function
|
||||
s("af", fmt("const {} = ({}) => {{\n {}\n}}", { i(1, "name"), i(2), i(0) })),
|
||||
|
||||
-- React functional component
|
||||
s("rfc", fmt([[
|
||||
export function {}({}: {}) {{
|
||||
return (
|
||||
<div>
|
||||
{}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
]], { i(1, "Component"), i(2, "props"), i(3, "Props"), i(0) })),
|
||||
|
||||
-- useState hook
|
||||
s("us", fmt("const [{}, set{}] = useState({})", {
|
||||
i(1, "state"),
|
||||
f(function(args)
|
||||
local name = args[1][1]
|
||||
return name:sub(1,1):upper() .. name:sub(2)
|
||||
end, {1}),
|
||||
i(2, "initialValue"),
|
||||
})),
|
||||
|
||||
-- useEffect hook
|
||||
s("ue", fmt([[
|
||||
useEffect(() => {{
|
||||
{}
|
||||
}}, [{}])
|
||||
]], { i(1), i(2) })),
|
||||
|
||||
-- Try-catch
|
||||
s("tc", fmt([[
|
||||
try {{
|
||||
{}
|
||||
}} catch (error) {{
|
||||
{}
|
||||
}}
|
||||
]], { i(1), i(2, "console.error(error)") })),
|
||||
}
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
```lua
|
||||
-- snippets/python.lua
|
||||
local ls = require("luasnip")
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
|
||||
return {
|
||||
-- Main block
|
||||
s("main", fmt([[
|
||||
if __name__ == "__main__":
|
||||
{}
|
||||
]], { i(0) })),
|
||||
|
||||
-- Function with docstring
|
||||
s("def", fmt([[
|
||||
def {}({}):
|
||||
"""{}"""
|
||||
{}
|
||||
]], { i(1, "name"), i(2), i(3, "Description"), i(0) })),
|
||||
|
||||
-- Class
|
||||
s("class", fmt([[
|
||||
class {}:
|
||||
"""{}"""
|
||||
|
||||
def __init__(self, {}):
|
||||
{}
|
||||
]], { i(1, "Name"), i(2, "Description"), i(3), i(0) })),
|
||||
|
||||
-- Async function
|
||||
s("adef", fmt([[
|
||||
async def {}({}):
|
||||
{}
|
||||
]], { i(1, "name"), i(2), i(0) })),
|
||||
|
||||
-- Try-except
|
||||
s("try", fmt([[
|
||||
try:
|
||||
{}
|
||||
except {} as e:
|
||||
{}
|
||||
]], { i(1), i(2, "Exception"), i(3, "raise") })),
|
||||
|
||||
-- Context manager
|
||||
s("with", fmt([[
|
||||
with {}({}) as {}:
|
||||
{}
|
||||
]], { i(1, "open"), i(2), i(3, "f"), i(0) })),
|
||||
}
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
```lua
|
||||
-- snippets/go.lua
|
||||
local ls = require("luasnip")
|
||||
local s = ls.snippet
|
||||
local t = ls.text_node
|
||||
local i = ls.insert_node
|
||||
local c = ls.choice_node
|
||||
local fmt = require("luasnip.extras.fmt").fmt
|
||||
|
||||
return {
|
||||
-- Error handling
|
||||
s("iferr", fmt([[
|
||||
if err != nil {{
|
||||
return {}
|
||||
}}
|
||||
]], { c(1, { t("err"), i(nil, "nil, err") }) })),
|
||||
|
||||
-- Function
|
||||
s("fn", fmt([[
|
||||
func {}({}) {} {{
|
||||
{}
|
||||
}}
|
||||
]], { i(1, "name"), i(2), i(3, "error"), i(0) })),
|
||||
|
||||
-- Method
|
||||
s("meth", fmt([[
|
||||
func ({} *{}) {}({}) {} {{
|
||||
{}
|
||||
}}
|
||||
]], { i(1, "r"), i(2, "Receiver"), i(3, "Method"), i(4), i(5, "error"), i(0) })),
|
||||
|
||||
-- Struct
|
||||
s("st", fmt([[
|
||||
type {} struct {{
|
||||
{}
|
||||
}}
|
||||
]], { i(1, "Name"), i(0) })),
|
||||
|
||||
-- Interface
|
||||
s("iface", fmt([[
|
||||
type {} interface {{
|
||||
{}
|
||||
}}
|
||||
]], { i(1, "Name"), i(0) })),
|
||||
|
||||
-- Test function
|
||||
s("test", fmt([[
|
||||
func Test{}(t *testing.T) {{
|
||||
{}
|
||||
}}
|
||||
]], { i(1, "Name"), i(0) })),
|
||||
|
||||
-- Table-driven test
|
||||
s("ttest", fmt([[
|
||||
func Test{}(t *testing.T) {{
|
||||
tests := []struct {{
|
||||
name string
|
||||
{}
|
||||
}}{{
|
||||
{{}},
|
||||
}}
|
||||
|
||||
for _, tt := range tests {{
|
||||
t.Run(tt.name, func(t *testing.T) {{
|
||||
{}
|
||||
}})
|
||||
}}
|
||||
}}
|
||||
]], { i(1, "Name"), i(2, "// fields"), i(0) })),
|
||||
}
|
||||
```
|
||||
|
||||
## VS Code Format Snippets
|
||||
|
||||
You can also use JSON snippets in `snippets/vscode/`:
|
||||
|
||||
```json
|
||||
// snippets/vscode/typescript.json
|
||||
{
|
||||
"Console Log": {
|
||||
"prefix": "cl",
|
||||
"body": ["console.log($1)"],
|
||||
"description": "Console log"
|
||||
},
|
||||
"Arrow Function": {
|
||||
"prefix": "af",
|
||||
"body": [
|
||||
"const ${1:name} = (${2:params}) => {",
|
||||
" $0",
|
||||
"}"
|
||||
],
|
||||
"description": "Arrow function"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
### Trigger Naming
|
||||
|
||||
Use short, memorable triggers:
|
||||
- `cl` → console.log
|
||||
- `fn` → function
|
||||
- `iferr` → if err != nil
|
||||
|
||||
### Tab Stop Order
|
||||
|
||||
- `i(1)` → First tab stop
|
||||
- `i(2)` → Second tab stop
|
||||
- `i(0)` → Final cursor position (always last)
|
||||
|
||||
### Default Values
|
||||
|
||||
```lua
|
||||
i(1, "default") -- Shows "default", selected for replacement
|
||||
```
|
||||
|
||||
### Testing Snippets
|
||||
|
||||
1. Edit snippet file
|
||||
2. `<leader>cS` - Reload
|
||||
3. Open file of that type
|
||||
4. Type trigger + `<Tab>`
|
||||
|
||||
### Debugging Snippets
|
||||
|
||||
If snippet doesn't work:
|
||||
1. Check Lua syntax (`:luafile %`)
|
||||
2. Verify filetype matches
|
||||
3. Check trigger isn't conflicting
|
||||
|
||||
## Reloading
|
||||
|
||||
```
|
||||
<leader>cS Reload all custom snippets
|
||||
```
|
||||
|
||||
Changes take effect immediately after reload.
|
||||
294
docs/guides/typescript-workflow.md
Normal file
294
docs/guides/typescript-workflow.md
Normal file
@@ -0,0 +1,294 @@
|
||||
# TypeScript Development Workflow
|
||||
|
||||
This guide covers the complete TypeScript/JavaScript development workflow in Neovim.
|
||||
|
||||
## Overview
|
||||
|
||||
Your config includes:
|
||||
- **LSP**: TypeScript language server (tsserver) via LazyVim extras
|
||||
- **Linting**: ESLint integration
|
||||
- **Testing**: Vitest via neotest
|
||||
- **Debugging**: DAP for Node.js
|
||||
- **Formatting**: Prettier (via conform.nvim)
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Project Setup
|
||||
|
||||
1. Open your TypeScript project:
|
||||
```bash
|
||||
nvim /path/to/project
|
||||
```
|
||||
|
||||
2. Session will auto-restore if you've worked on it before, or:
|
||||
```
|
||||
<leader>qs Restore session for this directory
|
||||
```
|
||||
|
||||
3. Mark important files with Harpoon:
|
||||
```
|
||||
<leader>H Add current file to harpoon
|
||||
<leader>1-9 Quick access to marked files
|
||||
```
|
||||
|
||||
## LSP Features
|
||||
|
||||
### Navigation
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `gd` | Go to definition |
|
||||
| `gr` | Go to references |
|
||||
| `gI` | Go to implementation |
|
||||
| `gy` | Go to type definition |
|
||||
| `K` | Hover documentation |
|
||||
|
||||
### Code Actions
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>ca` | Code actions (imports, fixes, refactors) |
|
||||
| `<leader>cr` | Rename symbol (project-wide) |
|
||||
| `<leader>cf` | Format document |
|
||||
|
||||
### Common Code Actions
|
||||
|
||||
When you press `<leader>ca`, you'll see options like:
|
||||
- Add missing imports
|
||||
- Remove unused imports
|
||||
- Organize imports
|
||||
- Convert to arrow function
|
||||
- Extract to function/variable
|
||||
- Move to new file
|
||||
|
||||
### Diagnostics
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>cd` | Show line diagnostics |
|
||||
| `]d` / `[d` | Next/prev diagnostic |
|
||||
| `]e` / `[e` | Next/prev error |
|
||||
| `<leader>xx` | Toggle trouble (diagnostics list) |
|
||||
|
||||
## Testing with Vitest
|
||||
|
||||
### Running Tests
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>tt` | Run test at cursor |
|
||||
| `<leader>tf` | Run all tests in file |
|
||||
| `<leader>ta` | Run all tests in project |
|
||||
| `<leader>tl` | Re-run last test |
|
||||
|
||||
### Test Output
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>ts` | Toggle test summary panel |
|
||||
| `<leader>to` | Show test output |
|
||||
| `<leader>tO` | Toggle output panel |
|
||||
|
||||
### Watch Mode
|
||||
|
||||
```
|
||||
<leader>tw Toggle watch mode for current file
|
||||
```
|
||||
|
||||
Tests will auto-run when file changes - great for TDD!
|
||||
|
||||
### Debugging Tests
|
||||
|
||||
```
|
||||
<leader>td Debug test at cursor (starts DAP)
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
### Setting Breakpoints
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>db` | Toggle breakpoint |
|
||||
| `<leader>dB` | Conditional breakpoint |
|
||||
| `<leader>dl` | Log point |
|
||||
|
||||
### Running Debugger
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>dc` | Continue/Start debugging |
|
||||
| `<leader>di` | Step into |
|
||||
| `<leader>do` | Step over |
|
||||
| `<leader>dO` | Step out |
|
||||
| `<leader>dt` | Terminate |
|
||||
|
||||
### DAP UI
|
||||
|
||||
```
|
||||
<leader>du Toggle DAP UI (shows variables, call stack, etc.)
|
||||
<leader>de Evaluate expression under cursor
|
||||
```
|
||||
|
||||
### launch.json
|
||||
|
||||
For custom debug configurations, create `.vscode/launch.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug Current File",
|
||||
"program": "${file}",
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Debug Tests",
|
||||
"program": "${workspaceFolder}/node_modules/vitest/vitest.mjs",
|
||||
"args": ["run", "${relativeFile}"],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Linting (ESLint)
|
||||
|
||||
ESLint runs automatically and shows diagnostics inline.
|
||||
|
||||
### Fix All
|
||||
|
||||
```
|
||||
<leader>ca Then select "Fix all ESLint problems"
|
||||
```
|
||||
|
||||
Or format the file which may also run ESLint fixes:
|
||||
```
|
||||
<leader>cf Format document
|
||||
```
|
||||
|
||||
## Code Generation with AI
|
||||
|
||||
Use opencode.nvim for AI-assisted coding:
|
||||
|
||||
| Key | Action |
|
||||
|-----|--------|
|
||||
| `<leader>ka` | Ask opencode (general) |
|
||||
| `<leader>ke` | Explain code at cursor |
|
||||
| `<leader>kR` | Refactor selection (visual) |
|
||||
| `<leader>kt` | Generate tests for selection |
|
||||
| `<leader>kd` | Document selection |
|
||||
|
||||
### Example: Generate Tests
|
||||
|
||||
1. Select a function in visual mode (`V` to select lines)
|
||||
2. `<leader>kt` - Generate tests
|
||||
3. Review and accept generated tests
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Starting a New Feature
|
||||
|
||||
1. `<leader>ff` - Find/create feature file
|
||||
2. `<leader>H` - Mark it with harpoon
|
||||
3. Write code with LSP assistance
|
||||
4. `<leader>ca` - Add imports as needed
|
||||
5. `<leader>tt` - Run tests as you go
|
||||
|
||||
### Fixing a Bug
|
||||
|
||||
1. `<leader>xx` - Open trouble to see all errors
|
||||
2. Navigate to error location
|
||||
3. `K` - Read documentation
|
||||
4. `gd` - Go to definition if needed
|
||||
5. `<leader>db` - Set breakpoint
|
||||
6. `<leader>td` - Debug the test
|
||||
|
||||
### Refactoring
|
||||
|
||||
1. `gr` - Find all references
|
||||
2. `<leader>cr` - Rename symbol
|
||||
3. `<leader>ca` - Apply refactoring code actions
|
||||
4. `<leader>kR` - Use AI for complex refactors
|
||||
|
||||
### Code Review Prep
|
||||
|
||||
1. `<leader>gm` - Compare to main branch
|
||||
2. Review your changes
|
||||
3. `<leader>kg` - AI review of git diff
|
||||
4. Fix any issues
|
||||
5. `<leader>gpc` - Create PR
|
||||
|
||||
## Project-Specific Settings
|
||||
|
||||
### TypeScript Config
|
||||
|
||||
Your `tsconfig.json` is respected by the LSP. Common settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ESLint Config
|
||||
|
||||
`.eslintrc.js` or `eslint.config.js` is auto-detected.
|
||||
|
||||
### Prettier Config
|
||||
|
||||
`.prettierrc` is respected by the formatter.
|
||||
|
||||
## Tips
|
||||
|
||||
### Import Organization
|
||||
|
||||
- `<leader>ca` → "Organize imports" - sorts and removes unused
|
||||
- Or configure to organize on save
|
||||
|
||||
### Quick Type Info
|
||||
|
||||
- `K` on any symbol shows type information
|
||||
- Works on function parameters, variables, etc.
|
||||
|
||||
### Find All TODO/FIXME
|
||||
|
||||
```
|
||||
<leader>xt Open todo list (via todo-comments)
|
||||
```
|
||||
|
||||
### Symbol Search
|
||||
|
||||
```
|
||||
<leader>ss Search symbols in file
|
||||
<leader>sS Search symbols in workspace
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### LSP Not Working
|
||||
|
||||
1. `:LspInfo` - Check LSP status
|
||||
2. `:Mason` - Verify typescript-language-server installed
|
||||
3. Check for `tsconfig.json` in project root
|
||||
|
||||
### ESLint Not Running
|
||||
|
||||
1. `:LspInfo` - Check if eslint is attached
|
||||
2. Verify `.eslintrc` exists
|
||||
3. Check `node_modules` for eslint
|
||||
|
||||
### Slow Performance
|
||||
|
||||
1. Check `tsconfig.json` includes/excludes
|
||||
2. Exclude `node_modules` from searches
|
||||
3. Use project-specific `tsconfig` for large monorepos
|
||||
Reference in New Issue
Block a user