diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cb528a3a..98bd22ae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/Cargo.lock b/Cargo.lock index e2f565f7..31c67b31 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2138,7 +2138,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vimcode" -version = "0.2.0" +version = "0.3.0" dependencies = [ "copypasta-ext", "gio 0.17.10", diff --git a/Cargo.toml b/Cargo.toml index 04aa703a..f269364b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" @@ -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" @@ -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" diff --git a/PLAN.md b/PLAN.md index 2998762a..ee0d0082 100644 --- a/PLAN.md +++ b/PLAN.md @@ -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 @@ -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 @@ -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 ` and `:AiClear` commands (session 118) diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index b3bfb1a1..d02576c6 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -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**. --- @@ -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**. diff --git a/README.md b/README.md index 9908af0a..31722071 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ There's a touch of irony here - using a cli tool to write the editor that I've w - **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, 2621+ tests, zero async runtime dependency +- **Clean architecture** — platform-agnostic core, 2908+ 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* @@ -157,7 +157,8 @@ cargo fmt **Visual mode** - `v` — character selection; `V` — line selection; `Ctrl-V` — block selection -- All operators work on selection: `d`, `c`, `y`, `u`, `U`, `~` +- All operators work on selection: `d`, `c`, `y`, `u`, `U`, `~`, `p`/`P` (paste replaces selection) +- `"{reg}p` — paste from named register over selection (deleted text goes to unnamed register) - Block mode: rectangular selections, change/delete/yank uniform columns - `I` (block) — insert text at left edge of block (applied to all lines on Escape) - `A` (block) — append text after right edge of block (applied to all lines on Escape) @@ -198,7 +199,7 @@ cargo fmt - `".` — last inserted text (read-only) - `"_` — black hole register (discard without affecting other registers) - Registers preserve linewise/characterwise type -- `Ctrl-Shift-V` — paste clipboard in Command/Search/Insert mode (GTK); bracketed paste in TUI +- `Ctrl-Shift-V` — paste system clipboard in Normal/Visual/Insert/Command/Search mode (GTK + TUI with keyboard enhancement) **Find/Replace** - `:s/pattern/replacement/[flags]` — substitute on current line @@ -245,6 +246,8 @@ cargo fmt **Tabs** - `:tabnew` — new tab; `:tabclose` — close tab - `gt` / `gT` or `g` + `t` / `T` — next/previous tab +- `Ctrl+Tab` / `Ctrl+Shift+Tab` — MRU tab switcher popup (cycles most-recently-used tabs; Enter confirms, Escape cancels); release modifier to auto-confirm (GTK) +- `Alt+t` — MRU tab switcher (works in both TUI and GTK; hold Alt and press `t` to cycle; release Alt or wait 500ms to confirm in TUI) **Editor Groups (VSCode-style split panes, recursive)** - `Ctrl+\` — split editor right (any group can be split again for nested layouts) @@ -299,7 +302,7 @@ cargo fmt ### Live Grep -- `Ctrl-G` (Normal mode) — open the Telescope-style live grep modal +- `Ctrl-G` (Normal mode) — show file info (Vim compat); live grep is available via `:grep` or configurable panel key `` - 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 @@ -545,14 +548,22 @@ VimCode embeds Lua 5.4 (via `mlua`, fully vendored — no system Lua required). ```lua -- Event hooks -vimcode.on("save", function(path) end) -- fired after :w +vimcode.on("save", function(path) end) -- fired after :w (also "BufWrite") vimcode.on("open", function(path) end) -- fired on file open vimcode.on("cursor_move", function(line_col) end) -- fired when cursor moves (arg: "line,col") +vimcode.on("BufEnter", function() end) -- fired when switching to a buffer +vimcode.on("BufNew", function() end) -- fired when a new buffer is created +vimcode.on("InsertEnter", function() end) -- fired on entering insert mode +vimcode.on("InsertLeave", function() end) -- fired on leaving insert mode +vimcode.on("ModeChanged", function(change) end) -- arg: "Old:New" (e.g. "Normal:Insert") +vimcode.on("VimEnter", function() end) -- fired once after startup -- Custom commands / key mappings vimcode.command("MyCmd", function(args) end) vimcode.keymap("n", "x", function() end) -- normal mode vimcode.keymap("i", "", function() end) -- insert mode +vimcode.keymap("v", "X", function() end) -- visual mode +vimcode.keymap("c", "Y", function() end) -- command mode -- Editor API vimcode.message(text) -- show in status bar @@ -565,13 +576,27 @@ vimcode.async_shell(cmd, event [, opts]) -- run shell command in background thr -- Buffer API (current active buffer) vimcode.buf.lines() -- all lines as table vimcode.buf.line(n) -- line n (1-indexed) or nil -vimcode.buf.set_line(n, text) -- replace line n +vimcode.buf.set_line(n, text) -- replace line n (undoable) +vimcode.buf.insert_line(n, text) -- insert text before line n +vimcode.buf.delete_line(n) -- delete line n +vimcode.buf.set_cursor(line,col) -- move cursor (1-indexed, clamped) vimcode.buf.path() -- file path string or nil vimcode.buf.line_count() -- integer vimcode.buf.cursor() -- {line, col} (1-indexed) vimcode.buf.annotate_line(n, s) -- show virtual text after line n vimcode.buf.clear_annotations() -- remove all virtual text +-- Settings API +vimcode.opt.get(key) -- get setting value as string +vimcode.opt.set(key, value) -- set setting (applied after callback) + +-- State API (read-only queries) +vimcode.state.mode() -- "Normal", "Insert", "Visual", etc. +vimcode.state.filetype() -- language ID string (e.g. "rust") +vimcode.state.register(char) -- {content, linewise} or nil +vimcode.state.set_register(char, content, linewise) -- write register +vimcode.state.mark(char) -- {line, col} (1-indexed) or nil + -- Git API (synchronous subprocess calls) vimcode.git.blame_line(n) -- {hash,author,date,relative_date,message} or nil vimcode.git.log_file(limit) -- [{hash,message}, ...] for current file @@ -597,6 +622,10 @@ Then `:Hello world` shows "Hello from Lua! world" in the status bar. | `:Plugin reload` | Reload all plugins from disk | | `:Plugin enable ` | Enable a previously disabled plugin | | `:Plugin disable ` | Disable a plugin (persisted in settings) | +| `:Comment [N]` | Toggle comment on N lines from cursor (core feature, 46+ languages; `:Commentary` alias) | +| `:map` | List all user-defined key mappings | +| `:map n :Comment` | Add a key mapping (persisted to settings.json) | +| `:unmap n ` | Remove a key mapping | Plugins are loaded in alphabetical order on startup. Security: plugins have unrestricted file and process access (same trust model as Neovim). @@ -629,6 +658,7 @@ No C# Language Support extension — :ExtInstall csharp (N to dismiss) | `yaml` | YAML | yaml-language-server | — | | `markdown` | Markdown | marksman | — | | `git-insights` | (all files) | — | — | +| `commentary` | (all files, dormant — core handles comment toggling) | — | — | **Extensions sidebar panel** — click the extensions icon (󱧅) in the activity bar to open a VSCode-style panel with two sections: - **INSTALLED** — extensions currently installed; press `Enter` to view info, `d` to remove @@ -798,14 +828,16 @@ Additional options (set directly in `settings.json`): | `show_hidden_files` | `false` | Show dotfiles in file explorer (`:set showhiddenfiles` / `:set shf`) | | `swap_file` | `true` | Write swap files for crash recovery (`:set swapfile` / `:set noswapfile`) | | `updatetime` | `4000` | Milliseconds between swap file writes for dirty buffers (`:set updatetime=N`) | +| `breadcrumbs` | `true` | Show file path + symbol hierarchy bar below the tab bar (`:set breadcrumbs` / `:set nobreadcrumbs`) | +| `autohide_panels` | `false` | TUI only: hide sidebar + activity bar at startup; `Ctrl-W h` reveals them, focus returns to editor auto-hides (`:set autohidepanels` / `:set noautohidepanels`) | - `:set option?` — query current value (e.g. `:set ts?` → `tabstop=4`) - `:set option!` — toggle a boolean option (e.g. `:set wrap!`); `no