You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Explorer shows the folder as it was when you expanded it, not as it is now, and gives no sign that anything has changed.
The vision's user spends most of their day navigating codebases and reviewing PRs, and a lot happens to their files outside the editor:
git switch / git checkout to review a branch adds and removes files.
A build writes bin/, obj/ and generated sources, and a test run leaves snapshots.
An agent or a script in the terminal next door creates and deletes files.
Afterwards the tree still lists deleted files and leaves out new ones. Nothing marks it as stale, and you can't refresh it, so the workarounds are collapsing and re-expanding the folder or restarting TuiCode. The reviewer reported it on #270 (comment): "these files aren't added/removed from the Explorer automatically (and there's no way to manually refresh the Explorer)."
Evidence from the code (origin/mainf1ac508):
FileExplorerView reads a folder's children once, when it's expanded. After that it only refreshes them for its own actions (create, delete, move, paste, via RefreshKeepingExpansion).
Notice when open files change on disk #133 added DiskWatcher, which watches the files behind open tabs. It doesn't watch the tree, and ShowChangedOnDisk only recolours rows that already exist.
There's no refresh command. None of the ~70 commands re-reads the tree.
Most editors the user comes from refresh on their own. VS Code watches the workspace and also has a Refresh Explorer button for when watching fails. Watching has a known cost on Linux: VS Code documents the ENOSPC "unable to watch for file changes" failure on large trees. DiskWatcher's own notes flag the same limit (fs.inotify.max_user_instances, shared by the whole login session).
Options considered
A manual Refresh explorer command only. Cheap and dependable, and uses no watchers. But you have to suspect the tree is stale before you'd refresh it, and the whole problem is that you can't tell.
Re-read the expanded folders whenever the Explorer gets focus. No watchers, and a branch switch shows up the next time you look at the tree. But the tree stays wrong while it's visible and the editor has focus, which is how you usually see it.
Watch every expanded folder, one non-recursive watcher each, and refresh just that folder when it changes. Keep a manual refresh as the fallback.(Proposed.) Covers exactly what the reviewer asked for ("folders that are expanded in the tree"), and what's collapsed costs nothing. It uses the same debounced, degrade-on-failure pattern DiskWatcher already uses. The cost is one watcher per expanded folder, which is usually a handful and can be capped.
One recursive watcher on the workspace root (VS Code's approach). Hears everything with one instance. But on Linux, .NET adds an inotify watch for every directory underneath, including node_modules, bin and obj. That's the ENOSPC trap, and it would need an exclude list and settings. Over the top for a tree that only shows expanded folders anyway.
Poll expanded folders on a timer. Simple, and works on file systems where watchers don't, such as some network mounts. But it's either slow to notice or does a lot of needless reads.
Option 3 includes option 1 as its first slice, so there's a dependable way to refresh before the automatic one lands, and it's still there as a fallback whenever a watcher can't be set up.
Proposal
The Explorer keeps itself up to date, and you can refresh it yourself.
Refresh explorer: a new command in the palette (Ctrl+E), with mnemonic re. It re-reads every expanded folder.
Automatic: each expanded folder is watched. When files or folders appear, disappear or get renamed in it, that folder refreshes on its own, after the same short settling delay DiskWatcher uses so that a git switch becomes one refresh rather than hundreds. Collapsing a folder stops watching it.
The tree doesn't jump. Expanded folders stay expanded, and the selection stays on the same path. If the selected entry is gone, the selection moves to its neighbour, as it does after Delete. The scroll position only moves if it has to.
Failure is quiet and safe. A folder that can't be watched (out of inotify instances, no permission) is logged, and Refresh still works for it. Watchers are capped. Past the cap, the most recently expanded folders are watched and the rest rely on Refresh.
Mockup
Before: git switch pr-branch in another terminal adds Parser.cs and removes Legacy.cs.
Showing git status in the tree (modified, untracked badges). That's a separate opportunity.
Settings for watcher excludes or polling.
Showing a changed folder's contents while it's collapsed. Expanding it re-reads it anyway.
Rough breakdown
I can refresh the Explorer when it's out of date.Refresh explorer re-reads every expanded folder, keeping expansion and selection. Small, dependable, and useful straight away after a branch switch.
The Explorer notices new, removed and renamed files by itself. Watchers on expanded folders, a debounced per-folder refresh, a cap, and quiet degradation. Depends on 1 for the refresh it triggers.
Settled with the reviewer
Cap on watchers: 64 expanded folders, half of Linux's default 128 max_user_instances. Past that, folders rely on Refresh.
No default key for Refresh explorer. Mnemonic re and the palette.
Recorded from the reviewer's comment on #270 (#270 (comment)), as a follow-up under #133.
If I have a directory open in TuiCode and files are created or removed from that directory by an external process, these files aren't added/removed from the Explorer automatically (and there's no way to manually refresh the Explorer).
Ideally the Explorer would automatically detect changes to the presence of files in any folders that are expanded in the tree.
Opportunity
The Explorer shows the folder as it was when you expanded it, not as it is now, and gives no sign that anything has changed.
The vision's user spends most of their day navigating codebases and reviewing PRs, and a lot happens to their files outside the editor:
git switch/git checkoutto review a branch adds and removes files.bin/,obj/and generated sources, and a test run leaves snapshots.Afterwards the tree still lists deleted files and leaves out new ones. Nothing marks it as stale, and you can't refresh it, so the workarounds are collapsing and re-expanding the folder or restarting TuiCode. The reviewer reported it on #270 (comment): "these files aren't added/removed from the Explorer automatically (and there's no way to manually refresh the Explorer)."
Evidence from the code (
origin/mainf1ac508):FileExplorerViewreads a folder's children once, when it's expanded. After that it only refreshes them for its own actions (create, delete, move, paste, viaRefreshKeepingExpansion).DiskWatcher, which watches the files behind open tabs. It doesn't watch the tree, andShowChangedOnDiskonly recolours rows that already exist.Most editors the user comes from refresh on their own. VS Code watches the workspace and also has a Refresh Explorer button for when watching fails. Watching has a known cost on Linux: VS Code documents the ENOSPC "unable to watch for file changes" failure on large trees.
DiskWatcher's own notes flag the same limit (fs.inotify.max_user_instances, shared by the whole login session).Options considered
DiskWatcheralready uses. The cost is one watcher per expanded folder, which is usually a handful and can be capped.node_modules,binandobj. That's the ENOSPC trap, and it would need an exclude list and settings. Over the top for a tree that only shows expanded folders anyway.Option 3 includes option 1 as its first slice, so there's a dependable way to refresh before the automatic one lands, and it's still there as a fallback whenever a watcher can't be set up.
Proposal
The Explorer keeps itself up to date, and you can refresh it yourself.
Ctrl+E), with mnemonicre. It re-reads every expanded folder.DiskWatcheruses so that agit switchbecomes one refresh rather than hundreds. Collapsing a folder stops watching it.Mockup
Before:
git switch pr-branchin another terminal addsParser.csand removesLegacy.cs.About a quarter of a second later, with no keypress (
Legacy.cswas selected, so the selection moves to its neighbour):The manual route in the command palette:
No new controls, and no status bar message for automatic refreshes. They should just be right.
Scope
In
re, rebindable in Settings, no default key).Out
Rough breakdown
Settled with the reviewer
max_user_instances. Past that, folders rely on Refresh.reand the palette.Original idea
Recorded from the reviewer's comment on #270 (#270 (comment)), as a follow-up under #133.