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
32 changes: 23 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,15 @@ jobs:
key: ${{ runner.os }}-release-target-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-release-target-

- name: Build release binary
run: cargo build --release
- name: Build release binaries
run: |
cargo build --release --bin vimcode
cargo build --release --bin vcd --no-default-features

- name: Strip binary
run: strip target/release/vimcode
- name: Strip binaries
run: |
strip target/release/vimcode
strip target/release/vcd

# ── .deb package ──────────────────────────────────────────────────────────
- name: Install cargo-deb
Expand All @@ -70,11 +74,13 @@ jobs:
echo "DEB_PATH=$DEB" >> $GITHUB_ENV
echo "DEB_NAME=$(basename $DEB)" >> $GITHUB_ENV

# ── Rename raw binary ─────────────────────────────────────────────────────
- name: Prepare raw binary artifact
# ── Rename raw binaries ────────────────────────────────────────────────────
- name: Prepare raw binary artifacts
run: |
cp target/release/vimcode vimcode-linux-x86_64
cp target/release/vcd vcd-linux-x86_64
echo "BIN_NAME=vimcode-linux-x86_64" >> $GITHUB_ENV
echo "TUI_BIN_NAME=vcd-linux-x86_64" >> $GITHUB_ENV

# ── Publish to GitHub Releases ────────────────────────────────────────────
- name: Publish GitHub Release
Expand All @@ -91,7 +97,7 @@ jobs:
sudo apt -f install # installs any missing GTK4 runtime libraries
```

**Option B β€” raw binary**
**Option B β€” raw binary (GUI)**
```
# First install runtime dependencies:
sudo apt install libgtk-4-1 libglib2.0-0 libpango-1.0-0 libcairo2
Expand All @@ -100,18 +106,26 @@ jobs:
./vimcode-linux-x86_64
```

**Option C β€” Flatpak** (see attached `vimcode.flatpak` asset)
**Option C β€” TUI-only binary (no GTK required)**
```
chmod +x vcd-linux-x86_64
./vcd-linux-x86_64
```
No GTK4 or other GUI libraries needed β€” works on headless servers.

**Option D β€” Flatpak** (see attached `vimcode.flatpak` asset)
```
flatpak install vimcode.flatpak
flatpak run io.github.jdonaghy.VimCode
```

> Requires GTK 4.10+. Ubuntu 22.04 ships GTK 4.6 which is too old; Ubuntu 24.04+ recommended.
> GUI binary requires GTK 4.10+. Ubuntu 22.04 ships GTK 4.6 which is too old; Ubuntu 24.04+ recommended.
prerelease: false
make_latest: true
files: |
${{ env.DEB_PATH }}
${{ env.BIN_NAME }}
${{ env.TUI_BIN_NAME }}

flatpak:
name: Build Flatpak bundle
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 14 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "vimcode"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
description = "Vim-like code editor with GTK4 and tree-sitter"
license = "MIT"
Expand All @@ -26,11 +26,20 @@ path = "src/lib.rs"
[[bin]]
name = "vimcode"
path = "src/main.rs"
required-features = ["gui"]

[[bin]]
name = "vcd"
path = "src/tui_bin.rs"

[features]
default = ["gui"]
gui = ["gtk4", "relm4", "pangocairo", "gio"]

[dependencies]
gtk4 = { version = "0.7", features = ["v4_10"] }
relm4 = "0.7"
pangocairo = "0.18"
gtk4 = { version = "0.7", features = ["v4_10"], optional = true }
relm4 = { version = "0.7", optional = true }
pangocairo = { version = "0.18", optional = true }
ropey = "1.6.1"
tree-sitter = "0.20"
tree-sitter-rust = "0.20"
Expand All @@ -52,7 +61,7 @@ tree-sitter-toml = "0.20"
# TODO: tree-sitter-kotlin (no 0.20.x release on crates.io)
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
gio = "0.17"
gio = { version = "0.17", optional = true }
ratatui = "0.27"
ignore = "0.4"
regex = "1"
Expand Down
16 changes: 14 additions & 2 deletions PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
---

## Recently Completed
- **Session 155**: Core Commentary Feature β€” unified comment toggling into `src/core/comment.rs` (46+ language table, two-pass algorithm, override chain), `:Comment`/`:Commentary` commands, `vimcode.set_comment_style()` plugin API, Ctrl+/ fix for GTK+TUI, VSCode Ctrl+Q/F10, 19+31 tests
- **Session 154**: Keymaps editor in settings panel β€” `BufferEditor` setting type, scratch buffer with validation, `:Keymaps` command, GTK button + TUI display, 11 tests
- **Session 153**: Richer Lua Plugin API + VimCode Commentary + User Keymaps β€” Extended plugin API (cursor write, settings access, state queries, buffer insert/delete, register write, 7 new autocmd events, `set_mode()` refactor, visual/command keymap fallbacks); VimCode Commentary bundled extension (gcc/gc/`:Commentary`, 40+ language comment strings, undo support); plugin `set_lines` undo fix; user-configurable keymaps in settings.json (`"mode keys :command"` format, multi-key sequences, override built-in keys, `{count}` substitution); 22 + 17 + 13 = 52 new tests (2801 total)
- **Session 152**: Visual paste β€” `p`/`P` in visual mode replaces selection with register content; `"x` register selection in visual mode; `Ctrl+Shift+V` clipboard paste in Normal/Visual (TUI+GTK); TUI tab bar fix (breadcrumbs y-offset); multi-group `Ctrl-W h/l` navigates between groups before overflowing to sidebar; pre-existing test fix (`swap_scan_stale`); 8 tests
- **Session 151**: Tab drag-to-split β€” VSCode-style drag tab to edge for new split, drag to center to move between groups, drag within tab bar to reorder; `DropZone`/`TabDragState` core types, 7 engine methods, GTK overlay rendering; tab bar draw order fix (windows before tab bars, dividers before tab bars); new `vim-code.svg` gradient logo, removed old icon files; 15 tests
- **Session 150**: Tab switcher polish β€” Alt+t binding (TUI+GTK), modifier-release auto-confirm (GTK polling + TUI timeout), sans-serif UI font for tabs/popup, tab click fix (breadcrumbs y-offset, Pango-measured hit zones, deferred tree highlight)
- **Session 149**: Ctrl+Tab MRU tab switcher (VSCode-style popup, forward/backward cycling, Enter confirms, Escape cancels) + `autohide_panels` TUI setting (auto-hide sidebar/activity bar, Ctrl-W h reveals)
- **Session 148**: Netrw in-buffer file browser β€” `:Explore`/`:Sexplore`/`:Vexplore` (and `:Ex`/`:Sex`/`:Vex` aliases), Enter opens files/dirs, `-` navigates to parent, header shows current dir, respects `show_hidden_files`, 16 tests
- **Session 147**: TUI interactive settings panel β€” replaced read-only list with full interactive form (filterable categories, bool toggles, enum cycling, inline string/int editing, Ctrl+V paste, DynamicEnum for colorscheme with custom themes), 10 tests
- **Session 146**: Breadcrumbs bar β€” file path + tree-sitter symbol hierarchy below tab bar, 10-language scope walking, `breadcrumbs` setting, per-group bars, GTK+TUI rendering, 14 tests
- **Session 145**: VSCode theme loader (drop `.json` in `~/.config/vimcode/themes/`, `:colorscheme name`), TUI crash fix (`byte_to_char_idx` multi-byte UTF-8 panic), swap recovery R/D/A fix for TUI, sidebar keyboard nav (`Ctrl-W h/l` toolbar↔sidebar↔editor), editor click clears sidebar focus, 4 theme tests
- **Session 143**: Bug fixes β€” `:q` dirty guard allows close when buffer visible in another split, `autoread` setting + file auto-reload detection (2s poll in GTK+TUI), `:new`/`:split` respect `splitbelow`/`splitright`, `:e!` reload from disk, 9 integration tests
- **Session 142**: Vim compat batch 3 β€” 15 new commands (94% β†’ 97%), g?{motion} ROT13, CTRL-@, CTRL-V {char}, CTRL-O auto-return, !{motion}{filter}, CTRL-W H/J/K/L/T/x, visual block I/A, o_v/o_V force motion, 29 integration tests
- **Session 141**: Vim compat batch 2 β€” 27 new commands (85% β†’ 94%), gq/gw format operators, ga/g8/go/gm/gM/gI/gx/g'/g`/g&, CTRL-^, CTRL-L, N%, zs/ze, CTRL-W p/t/b/f/d, insert CTRL-A/CTRL-G u/j/k, visual gq/g CTRL-A/g CTRL-X, :make, :b {name}, 38 integration tests
Expand Down Expand Up @@ -37,7 +48,7 @@
- [x] **`:norm`** β€” execute normal command on a range of lines
- [x] **Fuzzy finder / Telescope-style** β€” Ctrl-P opens centered file-picker modal with subsequence scoring (session 53)
- [x] **Multiple cursors** β€” `Alt-D` (configurable) adds cursor at next match of word under cursor; all cursors receive identical keystrokes; Escape collapses to one
- [x] **Themes / plugin system** β€” named color themes selectable via `:colorscheme`; 4 built-in themes: onedark (default), gruvbox-dark, tokyo-night, solarized-dark (session 116)
- [x] **Themes / plugin system** β€” named color themes selectable via `:colorscheme`; 4 built-in themes + VSCode `.json` theme import from `~/.config/vimcode/themes/` (sessions 116, 145)
- [x] **LSP semantic tokens** β€” `textDocument/semanticTokens/full` overlay on tree-sitter; 8 semantic theme colors; binary-search span overlay; legend caching (sessions 131–132)

### Enhanced Editor
Expand All @@ -58,10 +69,11 @@
- [x] **VSCode-style menus** β€” application menu bar (File / Edit / View / Go / Run / Terminal / Help) in GTK; command palette (`Ctrl-Shift-P`) lists all commands + key bindings; fuzzy-searchable; both GTK native menus and TUI pop-up menu overlay (sessions 81–82, 100–101)
- [x] **Command palette** β€” `Ctrl-Shift-P` floating modal; lists named commands with descriptions and current keybindings; typing filters; Enter executes; shared GTK + TUI (session 101)
- [x] **Settings editor** β€” `:Settings` opens `settings.json` in an editor tab; Settings sidebar panel shows live values; auto-reload on save in both backends (session 117)
- [x] **Settings sidebar (GTK)** β€” native GTK form with 30 settings in 7 categories, search, Adwaita dark theme (session 117b/117c)
- [x] **Settings sidebar (GTK + TUI)** β€” interactive form with 32 settings in 8 categories, search, live controls; GTK native widgets (session 117b/117c), TUI interactive form with keyboard nav + inline editing (session 147)

### Extension System
- [x] **Extension mechanism** β€” Lua 5.4 plugin sandbox; plugins register commands/keymaps/hooks, read/write buffer text, show messages; `~/.config/vimcode/plugins/` auto-loaded; bundled language-pack extensions + GitHub registry; `:ExtInstall/:ExtList/:ExtEnable/:ExtDisable/:ExtRemove` (sessions 98, 113–114)
- [x] **Keymap editor in settings panel** β€” "User Keymaps" row in the Settings sidebar opens a scratch buffer (one keymap per line, format `mode keys :command`). `:w` validates, updates `settings.keymaps`, calls `rebuild_user_keymaps()`. Also accessible via `:Keymaps` command. Tab shows `[Keymaps]`. GTK button + TUI "N defined β–Έ". 11 tests. (session 154)

### AI Integration
- [x] **AI assistant panel** β€” sidebar chat panel; configurable provider (Anthropic Claude, OpenAI, Ollama local); `ai_provider`/`ai_api_key`/`ai_model`/`ai_base_url` in settings; activity bar chat icon opens panel; multi-turn conversation; `:AI <msg>` and `:AiClear` commands (session 118)
Expand Down
16 changes: 5 additions & 11 deletions PROJECT_STATE.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# VimCode Project State

**Last updated:** Mar 7, 2026 (Session 143 β€” 3 bug fixes + :e! reload) | **Tests:** 2621
**Last updated:** Mar 9, 2026 (Session 155 β€” Core Commentary Feature) | **Tests:** 2908

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

---

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

## Recent Work

**Session 143 β€” File management bug fixes (2621 tests):**
Fixed 3 bugs found during Neovim comparison + added `:e!`: (1) `:q` now allows closing a dirty buffer if it's visible in another window (was blocked unconditionally), (2) File auto-reload with `autoread` setting (default true) β€” `file_mtime` tracking on `BufferState`, `check_file_changes()` on Engine (called every 2s from both GTK and TUI backends), `reload_from_disk()` for clean buffers, W12 warning for dirty buffers, (3) `:new`/`:split`/`:vnew`/`:vsplit` now respect `splitbelow`/`splitright` settings (was hardcoded `new_first=false`), (4) `:e!` reload current file from disk (discard changes). 9 integration tests in `tests/vim_compat_batch3.rs`.
**Session 155 β€” Core Commentary Feature (2908 tests):**
Unified comment toggling from three separate implementations (Lua plugin, Rust `toggle_comment_range()`, Rust `vscode_toggle_line_comment()`) into a single core module `src/core/comment.rs`. New `CommentStyle`/`CommentStyleOwned` types, `comment_style_for_language()` table covering 46+ languages (including block comments for HTML/CSS/XML), two-pass `compute_toggle_edits()` algorithm, `resolve_comment_style()` override chain (plugin β†’ extension manifest β†’ built-in β†’ fallback `#`). Added `CommentConfig` to `ExtensionManifest` in `extensions.rs`. New `toggle_comment()` method on Engine replaces old `toggle_comment_range()` and `vscode_toggle_line_comment()`. Rewired `gcc`, visual `gc`, and VSCode `Ctrl+/` to use the new core. Added `:Comment` command (`:Commentary` kept as alias). Plugin API: `vimcode.set_comment_style(lang_id, {line, block_open, block_close})`. Fixed Ctrl+/ in GTK (key name `"slash"` not `"/"`) and TUI (crossterm byte 0x1F β†’ `Char('7')` mapping). VSCode mode: added Ctrl+Q quit, F10 menu toggle, menu visible by default. 19 unit tests in `comment.rs`, 31 integration tests in `tests/commentary.rs`.

**Session 142 β€” Vim compatibility batch 3: 15 new commands (2612 tests):**
Implemented 15 more missing Vim commands, raising VIM_COMPATIBILITY.md from 380/403 (94%) to 400/414 (97%). `g?{motion}` ROT13 encode (with text objects), `CTRL-@` insert previous text + exit, `CTRL-V {char}` insert literal character, `CTRL-O` auto-return to Insert after one Normal command, `!{motion}{filter}` filter through external command, `CTRL-W H/J/K/L` move window to far edge, `CTRL-W T` move window to new group, `CTRL-W x` exchange windows, visual block `I`/`A` (insert/append applied to all block lines on Escape), `o_v`/`o_V` force charwise/linewise motion mode. Added `insert_ctrl_o_active`, `insert_ctrl_v_pending`, `visual_block_insert_info`, `force_motion_mode` fields. Enhanced `apply_operator_text_object()` with case/ROT13/indent/filter support. 29 integration tests in `tests/vim_compat_batch3.rs`. Sections now at 100%: Window commands (31/31), Visual mode (26/26), Editing (51/51).

**Session 141 β€” Vim compatibility batch 2: 27 new commands (2583 tests):**
Implemented 27 more missing Vim commands, raising VIM_COMPATIBILITY.md from 348/403 (85%) to 380/403 (94%). **Tier 1 (quick wins):** `ga` ASCII value, `g8` UTF-8 bytes, `go` byte offset, `gm`/`gM` middle of screen/text, `gI` insert at column 1, `gx` open URL, `g'`/`` g` `` mark without jumplist, `g&` repeat `:s` globally, `CTRL-^` alternate buffer, `CTRL-L` redraw, `N%` go to N% of file, `zs`/`ze` scroll cursor to left/right edge, `:b {name}` buffer by name, `:make`. **Tier 2 (medium effort):** `gq{motion}`/`gw{motion}` format operators (with text object support), `CTRL-W p`/`t`/`b` window navigation, `CTRL-W f`/`d` split+open/definition, insert `CTRL-A` repeat last insertion, insert `CTRL-G u`/`j`/`k` break undo/move, visual `gq`/`g CTRL-A`/`g CTRL-X`. Added `prev_active_group`/`insert_ctrl_g_pending` fields, `format_lines()` method, 38 integration tests in `tests/vim_compat_batch2.rs`. Sections now at 100%: Movement (48/48), Editing (50/50), z-commands (23/23).

> Sessions 140 and earlier archived in **SESSION_HISTORY.md**.
> Sessions 154 and earlier archived in **SESSION_HISTORY.md**.
Loading