Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/commands/plan-next.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Read CLAUDE.md, PROJECT_STATE.md, and PLAN.md only.
Read CLAUDE.md, PROJECT_STATE.md, PLAN.md, and BUGS.md only.
Do not scan or explore the src/ directory yet.
Summarize the next incomplete task from PLAN.md.
Summarize the next incomplete task from PLAN.md and bugs from BUGS.md.
List what files you expect to touch and why.
Then wait for my confirmation before doing anything.
12 changes: 10 additions & 2 deletions BUGS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# Known Bugs

No known bugs.
- **(Low) GTK Explorer: Enter requires two presses after arrow-key navigation** — After using arrow keys to navigate to a folder in the GTK TreeView, the first Enter press doesn't expand/collapse; the second does. Likely a GTK4 TreeView cursor/selection sync issue or interaction between GTK's built-in key bindings and the `row_activated` signal. Works correctly after the first activation. TUI explorer is unaffected.

## Resolved

All bugs below were fixed in Session 220 or earlier. See SESSION_HISTORY.md for details.
All bugs below were fixed in Session 225 or earlier. See SESSION_HISTORY.md for details.

- **Search `n` doesn't scroll far enough — match off-screen** — Both TUI and GTK approximate `viewport_lines` missed the tab bar row entirely (GTK) or didn't account for breadcrumbs/hide_single_tab (TUI). The approximate value was set every loop iteration, overwriting the accurate per-window value from the renderer. Fixed by computing correct chrome row count (status + cmd + tab bar + breadcrumbs, minus hidden tab bar) in both backends.
- **Explorer tree doesn't reveal active buffer on folder open** — TUI sidebar had no `reveal_path()` call at startup or after `open_folder()`. Added initial reveal before the event loop and after folder picker confirmation.
- **Visual yank doesn't move cursor to selection start** — `yank_visual_selection()` left cursor at end of selection. Vim moves cursor to start (line-wise: col 0; char-wise: start col). Fixed in `visual.rs` + updated integration test.
- **YAML syntax breaks after editing** — tree-sitter-yaml has an external scanner (like Markdown) that corrupts state during incremental reparsing without `InputEdit`. Fixed by skipping old-tree reuse for YAML in `syntax.rs::reparse()`, same as Markdown.
- **Crash in `completion_prefix_at_cursor` (index out of bounds)** — cursor col could exceed `chars.len()` after edits; clamped col to valid range in `motions.rs`.
- **Swap files don't preserve most recent edits on crash** — swap files were only written every 4 seconds (updatetime); edits in the last 0-4s were lost on panic. Added `emergency_swap_flush()` that writes all dirty buffers immediately, invoked from panic hooks (both GTK and TUI) and from the TUI `catch_unwind` error handler. Global engine pointer registered at startup via `swap::register_emergency_engine()`.
- **Crash in `active_window_mut` (stale WindowId after tab/group close)** — `active_tab().active_window` could point to a `WindowId` no longer in `self.windows` after certain tab/group close sequences. Added `repair_active_window()` self-healing method that finds a valid window from the current tab's layout or creates a scratch window as last resort. Called from `active_window_mut()` and after all close operations (`close_tab`, `close_editor_group`, `close_window`, `close_other_tabs`, `close_tabs_to_right/left`, `close_saved_tabs`).

- **`cargo run -- file.rs` restores entire previous session** — Skip `restore_session_files()` when CLI file/directory argument is provided. Use `open_file_with_mode(Permanent)` to load the file into the initial scratch window's tab (no leftover "[No Name]" tab).
- **TUI: cannot drag tab to create new editor group when only one group exists** — `compute_tui_tab_drop_zone()` single-group branch only handled tab bar reorder. Added content area edge zone detection using terminal size, and visual feedback rendering in `render_tab_drag_overlay()` for `Center`/`Split` zones.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "vimcode"
version = "0.5.1"
version = "0.6.0"
edition = "2021"
description = "Vim-like code editor with GTK4 and tree-sitter"
license = "MIT"
Expand Down
55 changes: 52 additions & 3 deletions PLAN.md

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions PROJECT_STATE.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# VimCode Project State

**Last updated:** Mar 26, 2026 (Session 224Release prep v0.5.1) | **Tests:** 4769
**Last updated:** Mar 29, 2026 (Session 233Explorer focus UX + GTK fixes) | **Tests:** 4986

> Feature documentation lives in **README.md**.
> Per-session implementation notes through Session 224 are in **SESSION_HISTORY.md**.
> Per-session implementation notes through Session 232 are in **SESSION_HISTORY.md**.

---

Expand All @@ -26,5 +26,4 @@ When implementing a new key/command, add tests covering:

## Recent Work

> All sessions through 224 archived in **SESSION_HISTORY.md**. No recent unarchived work.

> All sessions through 233 archived in **SESSION_HISTORY.md**.
31 changes: 28 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ For detailed how-to guides and configuration references, see the **[VimCode Wiki
- **First-class Vim mode** — deeply integrated, not a plugin
- **Cross-platform** — GTK4 desktop UI + full terminal (TUI) backend
- **CPU rendering** — Cairo/Pango (works in VMs, remote desktops, SSH)
- **Clean architecture** — platform-agnostic core, 4,769 tests, zero async runtime dependency
- **Clean architecture** — platform-agnostic core, 4,814 tests, zero async runtime dependency

> **Note:** VimCode does not implement VimScript. Extension and scripting is handled via
> the built-in Lua 5.4 plugin system. The goal is full Vim *keybinding* and *editing*
Expand Down Expand Up @@ -350,6 +350,22 @@ The tab context menu offers both: "Split Right/Down" creates a Vim window split

VimCode uses a unified picker system for file finding, live grep, and command palette. All pickers share the same UI and keybindings. Fuzzy match characters are highlighted in the results.

#### Command Center

Click the search box in the menu bar (or run `:CommandCenter`) to open the unified picker. Type a prefix to switch modes:

| Prefix | Mode |
|--------|------|
| _(none)_ | Fuzzy file search (same as `Ctrl-P`) |
| `>` | Command palette (same as `Ctrl-Shift-P`) |
| `@` | Go to symbol in current file (LSP `documentSymbol`) |
| `#` | Workspace symbol search (LSP `workspace/symbol`) |
| `:` | Go to line number |
| `%` | Search for text in project (live grep) |
| `debug` | Start debugging (show launch configurations) |
| `task` | Run a task (from tasks.json) |
| `?` | Show available prefix modes |

#### Fuzzy File Finder

- `Ctrl-P` or `<leader>sf` (Normal mode) — open the fuzzy file picker
Expand All @@ -361,6 +377,7 @@ VimCode uses a unified picker system for file finding, live grep, and command pa
#### Live Grep

- `Ctrl-Shift-F` or `<leader>sg` (Normal mode) — open the live grep picker
- `<leader>sw` — open live grep pre-filled with the word under the cursor
- A centered floating two-column modal appears over the editor
- Type to instantly search file *contents* across the entire project (live-as-you-type, query ≥ 2 chars)
- Left pane shows results in `filename.rs:N: snippet` format; right pane shows ±5 context lines around the match
Expand Down Expand Up @@ -483,6 +500,7 @@ For full details on adapters, launch.json, conditional breakpoints, and the debu
| `:Gblame` | `:Gb` | Open `git blame` in scroll-synced vertical split |
| `:Gswitch <branch>` | `:Gsw` | Switch to an existing branch |
| `:Gbranch <name>` | | Create a new branch and switch to it |
| `:Gbranches` | | Open branch picker (fuzzy-filter, click status bar branch) |
| `:Ghs` | `:Ghunk` | Stage hunk under cursor (in a `:Gdiff` buffer) |
| `:Gshow <hash>` | | Show commit in Git Log panel (navigates and expands) |

Expand Down Expand Up @@ -770,7 +788,7 @@ Full editor in the terminal via ratatui + crossterm — feature-parity with GTK.

- **Layout:** activity bar (3 cols) | sidebar | editor area; status line + command line full-width at bottom
- **Sidebar:** same file explorer as GTK with Nerd Font icons
- **Mouse support:** click-to-position, double-click word select, click-and-drag visual selection, window switching, scroll wheel (targets pane under cursor), scrollbar click-to-jump and drag; drag event coalescing for smooth scrollbar tracking; bracketed paste support
- **Mouse support:** click-to-position, double-click word select, click-and-drag visual selection, window switching, scroll wheel (targets pane under cursor), scrollbar click-to-jump and drag; drag event coalescing for smooth scrollbar tracking; bracketed paste support; click branch name in status bar to open branch picker
- **Sidebar resize:** drag separator column; `Alt+Left` / `Alt+Right` keyboard resize (min 15, max 60 cols)
- **Scrollbars:** `█` / `░` thumb/track in uniform grey; vsplit separator doubles as left-pane vertical scrollbar; horizontal scrollbar row when content wider than viewport; `┘` corner when both axes present
- **Scroll sync:** `:Gblame` pairs stay in sync across keyboard nav and mouse events
Expand Down Expand Up @@ -859,6 +877,7 @@ Full editor in the terminal via ratatui + crossterm — feature-parity with GTK.
| `gt` / `gT` | Next / previous tab |
| `Ctrl+Tab` / `Ctrl+Shift+Tab` | MRU tab switcher (forward / backward) |
| `Alt+t` | MRU tab switcher (TUI + GTK compatible) |
| `Ctrl+Alt+Left` / `Ctrl+Alt+Right` | Navigate back / forward through tab history |
| `gd` | Go to definition (LSP) |
| `gr` | Find references (LSP) — multiple results open quickfix |
| `gi` | Insert at last insert position |
Expand Down Expand Up @@ -888,6 +907,7 @@ Full editor in the terminal via ratatui + crossterm — feature-parity with GTK.
| `<leader>ca` | Show LSP code actions for current line |
| `<leader>sf` | Open fuzzy file finder (same as Ctrl-P) |
| `<leader>sg` | Open live grep picker (same as Ctrl-Shift-F) |
| `<leader>sw` | Grep word under cursor |
| `<leader>sp` | Open command palette (same as Ctrl-Shift-P) |
| `za` / `zo` / `zc` / `zR` | Fold toggle / open / close / open all |
| `zA` / `zO` / `zC` | Fold toggle / open / close recursively |
Expand Down Expand Up @@ -994,7 +1014,9 @@ All ex commands support Vim-style abbreviations (e.g., `:j` for `:join`, `:y` fo
| `:b {name}` | Switch to buffer matching partial file name |
| `:!{cmd}` | Execute shell command and show output |
| `:r {file}` | Read file contents into buffer after cursor line |
| `:tabmove [N]` | Move current tab to position N (0-based, default = end) |
| `:tabmove [N]` | Move current tab to position N (1-based, 0 = end) |
| `:navback` | Navigate to previous tab in history |
| `:navforward` | Navigate to next tab in history |
| `:Gdiff` / `:Gdiffsplit` | Git diff (unified / side-by-side) |
| `:Gstatus` | Git status |
| `:Gadd` / `:Gadd!` | Stage file / stage all |
Expand All @@ -1005,6 +1027,7 @@ All ex commands support Vim-style abbreviations (e.g., `:j` for `:join`, `:y` fo
| `:Gblame` | Blame (scroll-synced split) |
| `:Gswitch <branch>` / `:Gsw` | Switch to existing branch |
| `:Gbranch <name>` | Create new branch and switch to it |
| `:Gbranches` | Open branch picker (status bar click also works) |
| `:Ghs` / `:Ghunk` | Stage hunk under cursor |
| `:Gshow <hash>` | Show commit in Git Log panel (navigates and expands) |
| `:DiffPeek` | Open diff hunk peek popup at cursor (revert/stage) |
Expand All @@ -1022,6 +1045,7 @@ All ex commands support Vim-style abbreviations (e.g., `:j` for `:join`, `:y` fo
| `:DiffToggleContext` | Toggle hiding unchanged sections in diff view |
| `:diffoff` | Clear diff highlighting |
| `:grep <pat>` / `:vimgrep <pat>` | Search project, populate quickfix list |
| `:GrepWord` | Grep the word under cursor (same as `<leader>sw`) |
| `:copen` / `:ccl` | Open / close quickfix panel |
| `:cn` / `:cp` | Next / previous quickfix item |
| `:cc N` | Jump to Nth quickfix item (1-based) |
Expand All @@ -1040,6 +1064,7 @@ All ex commands support Vim-style abbreviations (e.g., `:j` for `:join`, `:y` fo
| `:nextdiag` / `:prevdiag` | Jump to next / previous LSP diagnostic |
| `:nexthunk` / `:prevhunk` | Jump to next / previous git hunk |
| `:fuzzy` | Open fuzzy file finder |
| `:CommandCenter` | Open Command Center (unified picker with prefix modes) |
| `:sidebar` | Toggle sidebar |
| `:palette` | Open command palette |
| `:Comment [N]` | Toggle comment on N lines (46+ languages; `:Commentary` alias) |
Expand Down
Loading
Loading