Headline Features
- Git history is a filesystem — the Git menu's Browse a revision mounts the repository's past into a panel. Every commit is a directory;
F3,F5, Compare files and Find file all work inside one. - Git time machine — press
tin a 3D panel and the landscape scrubs through the repository's history, directories swelling and whole subtrees growing out of their parent at the commit that created them. - Git blame in the viewer —
bshows who last changed each line, shaded by age;Enteropens the tree as it was at that line's commit. - Git activity calendar — the Details view shows a year of commits to the file or directory under the cursor as a GitHub-style grid.
- Thumbnail grid — a new view format shows a directory as pictures: images as thumbnails, STL/OBJ models rendered in 3D, loaded in the background.
- Activity log — a new panel format lists, live, what is created, written, removed and renamed anywhere under the other panel's directory.
- Receive over LAN — scan a QR code with a phone, pick files, and they land in the active panel's directory. The counterpart to Send over LAN.
- Follow mode —
fin the viewer tails a growing file liketail -f, and keeps up through truncation and log rotation. - Screensaver — optional and Norton Commander style: a starfield, matrix rain, a bouncing clock or growing pipes, in plain text.
- 3D model files support —
F3on an.stlor.objand the mesh is there, shaded and orbitable, drawn by the same software rasterizer the 3D panel uses. No converter, no external viewer, no new dependency. - Executable file viewer — View libraries, functions and strings of any executable file.
- Entropy file viewer — a third viewer mode maps a file by entropy, so compressed regions glow and padding goes flat, and the seams between a container's parts show as visible bands.
Enteropens the hex view at the byte under the cursor. - Directories in a 3D panel light up as things are written into them.
- Disc images, SQLite databases and JSON/TOML documents open like directories, natively — no
extfsscript, noisoinfo. - 3D scene is now stable — the tree is laid out in a world of its own and the camera flies to where you navigate, instead of the whole structure re-forming around you.
- File panels stays responsive with the 3D view up: input is batched per frame and scene rebuilds are rationed against the frame clock.
- Typing over a pre-filled dialog field replaces it instead of appending to it.
- A
*in an F6 target stands for the file's own name, so*.bakrenames a whole selection. - Settings is now a tabbed dialog
Added
Browsing git history
Git menu (Alt-G) → Browse a revision…, or the command palette
- The mount's root is the commit list, newest first, each commit a directory named
2026-09-11_15-42-47_a9ef3a7_Made-3d-topography-more-static. The timestamp leads, so the panel's ordinary sort by name is sort by time. Entersteps into a commit's tree;..goes back to the commit list, and..again leaves history for the working tree you started in. The panel's border names the revision you are in, in place of the branch it shows for a working directory.- Because history is just another filesystem to
rc, everything else keeps working:F3views a file as it was,F5copies it back out into the present, Compare files diffs it against your working copy, and Find file searches it. Sizes, the executable bit and symlinks are all as they were recorded. - No checkout, no stash, no second clone.
- Read-only. Copying, moving, renaming or deleting into a revision is refused before a transfer starts, rather than failing part-way through. Submodules show as empty directories, since their contents live in a repository of their own.
- The commit list is capped at the most recent 500, so opening history on a kernel-sized repository is instant rather than a five-second pause.
Git time machine
In a 3D-view panel: t
The 3D view already draws a directory tree as a landscape. The time machine drags that landscape through the repository's history: scrub back and the shape re-forms as you go — directories swelling as they fill up, whole branches growing out of their parent the moment they were first committed, and fading away again as you scrub back past their creation.
Put a panel into 3D view (Alt-T) with the other panel on a git work tree, then press t.
| Key | |
|---|---|
t
| Turn the time machine on or off |
[ / ]
| One commit older / newer |
{ / }
| Ten commits |
Shift-Home / Shift-End
| The first / last commit |
| Click the track | Seek to that point; the ◀/▶ ends step one commit
|
- A track under the scene shows where you are (
209/259); the panel's title names the commit. - Sizes come from git, which is why turning it on usually makes everything smaller: a work tree's
target/ornode_modules/was never committed, so it is not there. - Scrubbing is cheap. A commit's tree never changes, so one already visited is redrawn from memory; holding a step key down coalesces into a single read once the movement settles, and the next commit is fetched while you look at the one you are on. Dragging across two hundred commits costs a handful of reads, not one apiece.
Git blame in the viewer
In the viewer (F3): b
b on a file inside a git work tree adds a column beside the text showing which commit last changed each line.
| Key | |
|---|---|
b
| Show / hide the blame column |
↑ ↓, PgUp / PgDn, Home / End, or a click
| Move the line cursor |
Enter
| Open the tree at the cursor line's commit |
git blameruns in the background; the header reads[Blame…]until it is done. Like the other Git features, it needs thegitcommand.- Author and date are written once per run of lines from the same commit, and on the cursor line. Every line gets a bar shaded by its commit's age, newest brightest. The shades step through the file's commits in order rather than by date, so each commit stays distinguishable. Lines not yet committed are labelled
uncommitted. - The header shows the cursor line's commit: short id, author, date and subject.
Entercloses the viewer and mounts that revision in the active panel (see Browsing git history), in the directory that held the file at that commit, with the file under the cursor. A file renamed since is found under its old path.- Shown with raw text only; hex, the byte map and rendered Markdown hide it. On a narrow screen the column shows only the date.
Git activity calendar
Details view, for an item inside a git work tree
- Between the metadata and the preview, a grid of the last 53 weeks: a column per week with the current week on the right, and a row per weekday from Monday. Each day is shaded by how many commits touched the item, relative to its busiest day. The rule above it shows the year's total.
- Covers the file or directory under the other panel's cursor, or up to 100 tagged items together.
- Counted with
git login the background after the cursor has rested on an item for 250 ms, so moving down a listing starts nothing. The last 64 results are kept and shown immediately when revisited; Git menu actions and panel reloads clear them. - Days are UTC, like every other time the program shows.
- A narrow panel shows the most recent weeks that fit, a wide one gives each week two columns, and a panel too short for it leaves it out.
- Turn it off with Details view: git activity in the command palette.
The landscape reacts to the filesystem
In a 3D-view panel; on by default
While a 3D panel is up, a directory something writes into glows warm and fades back over about a second, so a burst of filesystem activity is visible as it happens. Point one panel at a build output directory, put the other in 3D, and you can watch a compile fill it in.
- Activity anywhere below a box surfaces on that box: the glow climbs to the nearest directory the scene actually draws, so work several levels down is not silently lost for happening out of sight.
- Like the cursor highlight, the glow is painted into the box's colour rather than drawn as an outline — the half-block and ASCII fallbacks reduce the scene to brightness alone, where a rim one pixel wide survives neither the downsample nor the ramp.
- It costs nothing when nothing is happening: the glow is what keeps the view asking for frames, and once the last one fades the scene goes back to idle.
- This needs a recursive watch on the tree being shown, which takes one watch descriptor per directory. On a very large or network-mounted tree that is worth avoiding, so it can be switched off with 3D view: show filesystem activity (
Ctrl-P, or Settings). If the system refuses the recursive watch — the per-user inotify limit is the usual reason — the view quietly does without the glow and the panel keeps its ordinary auto-refresh. - A box lights up; it does not grow. Sizes still come from the background crawler, which deliberately never re-walks a subtree it has already finished, so the landscape's shape is the shape it had when it was last crawled.
The Activity log
Left / Right menu → Activity log, or the command palette
A panel view format that lists what changes anywhere under the other panel's directory, newest at the top. Built on the same recursive watch as the 3D view's glow.
| Mark | Meaning |
|---|---|
+
| Created |
~
| Modified |
✓
| Written: a file opened for writing was closed |
-
| Removed |
→
| Renamed |
↑ / ↓
| Moved out of / into the watched tree |
| Key | |
|---|---|
↑ ↓, PgUp / PgDn, Home / End, or the mouse
| Move through the rows |
Enter / double-click
| Show the file in the other panel and switch to that panel |
Insert
| Pause / resume; events arriving while paused are held and counted |
Delete
| Clear the log |
Alt-Shift-I
| Filter by path (a glob, or plain text) |
- Bursts fold into one row with a count (
×400), and the separate halves of a rename are merged into oneold → newrow. - Each row shows how long ago it happened. Long paths keep the file name and shorten the directories from the left.
- The status line shows events per second and a sparkline of the last minute.
- The log follows the other panel: pointing that panel elsewhere starts it again there. It works whether Auto-refresh panels is on or not.
- Local directories only. If the system refuses the recursive watch, the log says so and falls back to the directory itself.
- Not part of the
Alt-Tcycle.
More things browsed like directories
Press Enter on one and .. at the top steps back out to the file, exactly as it does for an archive. All three are read-only, and say so before any bytes move.
- Disc images (
.iso,.img,.udf) — ISO 9660 read natively, including Joliet (long, mixed-case names as they were written, notLONGNAME.TXT;1) and Rock Ridge (real POSIX names, the executable bit, symlinks). This replaces mc'siso9660extfs script and theisoinfoit needs; therc.extrule stays for the rare image the built-in reader declines — a UDF-only one, say. - SQLite databases (
.db,.sqlite,.sqlite3,.db3) — tables and views as directories, rows as files showingcolumn = value, plus a_schema.sqlholding the statements that would rebuild it. Rows are named byrowid, by the primary key for aWITHOUT ROWIDtable, or by position for a view. Tables over a thousand rows are paged into directories rather than listed whole, and a blob is described (<blob, 200 bytes> a3f1…) instead of dumped into a text view. Opened read-only and immutable, so browsing a database another program is writing neither blocks it nor changes it. - JSON and TOML documents — objects and tables as directories, arrays as zero-padded numbered entries (so sorting by name sorts by index), each scalar a file holding its bare value. A setting six levels down is something you
cdto andF3, and Find file searches it like any other tree.
Each confirms what a file really is before claiming it — by header magic, or by parsing it — so a .db that is not a database, or a .json that does not parse, opens the way it always did instead of half-listing. Enter now resolves in this order: a real directory, then a built-in archive, then one of these native providers, then an rc.ext rule, and finally the image flasher, the default application, or simply running the file.
The thumbnail grid
Alt-T after the 3D view, or Left / Right menu → Thumbnails view
A view format showing the panel's own directory as a grid, each cell a picture over the file's name.
- Images (
.png,.jpg,.jpeg,.gif,.bmp,.webp) are decoded to thumbnails, using a photo's embedded EXIF thumbnail when it has one. STL and OBJ models are rendered by the model viewer's rasterizer and cropped to the model. Everything else shows its type: a Nerd Font icon when those are on, otherwiseDIRor the file extension. - True pixels on Kitty / Sixel / iTerm2, half-block cell art on a truecolor terminal, and an ASCII ramp otherwise.
- Pictures load in the background, four at a time, for the visible page and the one after it; a picture still loading shows
…. Each panel keeps up to 64 MB of thumbnails and releases them when it leaves the format. ↑ ↓move a row,← →one cell. Marking,Enter,F3, copy and move, and the mouse work as in the other formats.- Cell size: Options → Settings… → Thumbnail size (Small, Medium or Large).
- Limits: images up to 30 MB on local disk and 8 MB on remote or archive panels; models only from local disk, up to 16 MB and 150,000 triangles.
- The
Alt-Tcycle is now Full → Brief → Details → Tree → 3D → Thumbnails.
The 3D model viewer
F3 on a model file
Press F3 on an .stl or .obj and the mesh opens fullscreen as a shaded solid you can turn. Binary and ASCII STL and Wavefront OBJ are read natively — no converter, no external viewer, and no new dependency: the parsers are a few hundred lines of pure Rust, so the ARM cross-builds are unaffected.
| Key | |
|---|---|
← → ↑ ↓
| Orbit the camera |
+ / -
| Zoom in / out |
Home
| Re-frame the model |
| Drag / wheel | Orbit / zoom |
F8
| Switch between the model and the raw bytes |
F3 / Esc / F10 / q
| Close |
- It is drawn by the same software rasterizer the 3D panel uses — z-buffered, flat-shaded, no GPU and no 3D crate — so it lands on the same three tiers as everything else: true pixels on a Kitty / Sixel / iTerm2 terminal, half-block cell art on a truecolor one, and an ASCII luminance ramp otherwise. The header names the format and the triangle count.
- The facet normals stored in the file are ignored, in favour of ones computed from each triangle's winding. Exporters write them zeroed, unnormalised and outright inverted often enough that trusting them leaves a model with randomly unlit faces.
- Nothing is back-face culled, and the light is two-sided. Culling is only sound when a mesh's winding is consistent, and real STL and OBJ files routinely are not — an exporter that inverted a few facets would otherwise punch holes straight through the solid. The depth buffer gives the correct picture either way.
- The key light is fixed to the camera, so there is no angle you can orbit to that leaves the model in the dark.
- A file that does not parse — or one past the size cap — simply opens as raw text/hex, exactly as an image that cannot be decoded does. A
.stlthat is not really one behaves the way it always did. - Model files also take their own colour in the panel listings and their own solid — a cut gem — in the 3D landscape.
.ply,.3mf,.gltf,.stepand the rest are coloured as models too, though the viewer cannot open them yet.
Binary Entropy Map
*In the viewer: F4 until the desired mode is active
A third viewer mode beside Text and Hex, drawing the whole file as one picture. Each cell is a span of the file, coloured either by density — its Shannon entropy — or, with F8, by byte class: mostly-zero padding, printable ASCII, high bytes, or mixed. Compressed and encrypted regions come out bright and flat, padding and sparse holes come out dark, and the boundaries between a container's parts appear as visible bands. On a disc image or a firmware blob that is a structural overview no hex dump gives you.
| Key | |
|---|---|
← → ↑ ↓, PgUp / PgDn, Home / End
| Move the cursor |
Enter
| Open the hex view at that byte offset |
F8
| Colour by density / by byte class |
F4
| On round to Text |
- The header reports the byte offset and entropy under the cursor, and
Entercarries that offset into the hex view — which is what makes this a way of finding something rather than only a picture of it. See a suspicious seam, pressEnter, land on the bytes. - Density is entropy as a fraction of the most a sample that size could score, not the raw figure. A sample of n bytes cannot exceed
log2(n)bits however random it is, so on a small file — where a cell spans only a few bytes — raw entropy tops out well below 8 and a wholly incompressible file would be painted merely lukewarm. Dividing by the achievable maximum makes the picture mean the same thing at every file size. - The file is sampled, not read whole: 4096 cells, each reading at most 4 KiB from the start of its span. Building the map therefore costs the same bounded work on a 4 MB file as on a 40 GB disc image. The trade is that something small hiding in the middle of a large span will not register.
Executable viewer
*In the viewer: F4 until the desired mode is active
This mode opens by default when viewing executable files, and shows general information about the executable, as well as it's libraries, importsand exports, functions, and a browseable list of strings.
Follow mode in the viewer
In the viewer (F3): f
fjumps to the end of a local file and keeps the view there as lines are appended; the header reads[Follow].fagain stops following.- Scrolling up pauses it, and the header counts the lines that arrive meanwhile (
[Paused +12]). Scrolling back to the last page, orEnd, resumes. - A truncated file (
> app.log, logrotate'scopytruncate) is read again from the start. On Unix, a rotated log — renamed, with a new file created in its place — is followed to the new file. - The file is checked for growth every 100 ms; a large append is indexed at most 4 MB per check, so it never stalls the screen.
- Remote and archived files are viewed from a temporary copy, which never grows, so they cannot be followed.
- Log levels: in a file with no syntax highlighting that is named
*.log(or*.log.1and so on) or is being followed, a line is coloured by the first level word in its first 64 characters. Errors (ERROR,FATAL,err, …) take the theme's error colour, warnings its accent colour, and debug and trace output is dimmed.
Receive over LAN
File menu → Receive over LAN…, or the command palette
The counterpart to Send over LAN: files come from a phone or laptop on the same network into the directory the active panel shows.
- The dialog shows a QR code for an upload page. The page has a single Choose files button and uploads the chosen files one at a time, each with its own progress bar.
- The dialog shows the URL, the target directory, the file in progress with its percentage and speed, and a running count of files received.
- The URL carries a random 128-bit token; any request without it gets a 404 before its body is read.
- An upload is written to a hidden
.rc-upload-….partfile and renamed into place once complete. An existing file is never overwritten: a secondphoto.jpgis saved asphoto (1).jpg. An upload that is cut off, stalls for 30 seconds, or is cancelled leaves nothing behind. - Names are reduced to a plain file name, so nothing can be written outside the directory. On Unix, an upload larger than the free disk space is refused before it starts.
- Closing the dialog stops the server and aborts any upload still running.
- Plain HTTP on the local network, like Send over LAN. Local directories only.
Screensaver
Options → Settings… → Screensaver, or Start screensaver in the command palette
- After 1 to 30 minutes without a key press or mouse movement, the screen is replaced by an animation: Starfield, Matrix, Clock (local time in large digits, drifting and changing colour at each bounce), Pipes, or Random.
- Off by default.
- Any key or mouse movement brings the screen back, and that key does nothing else: an
Escpressed to wake the screen cannot abort a copy running behind a progress dialog. - A dialog that appears while it runs, such as an overwrite question from a background copy, ends the screensaver.
- Time spent in the subshell, a command's output or an external editor does not count as idle.
- Text only, advanced on the existing 100 ms tick; no pixel graphics.
A * in an F6 target
- A
*in the rename/move target stands for the file's own name, so*.bakrenamesnotes.txttonotes.txt.bak— and renames a whole marked set the same way, each file through its own name. - It is decided as a mask without asking the filesystem, so what a wildcard means cannot depend on whether a directory literally named
*happens to exist. - For anything more involved than a suffix, the multi-rename tool (
Shift-F6) and its[N]/[E]placeholders are still the right tool.
Settings dialog is now tabbed
- Tabs allow for more settings in the dialog.
- Each option shows descriptive text to make things intuitive for new users.
Changed
The viewer's F4 now cycles several more modes
F4 steps Text → Hex → Map → Text rather than toggling the first two, and the F-key bar names the mode it will move to. F8 keeps its meaning of "the other rendering of this same file": raw/render for Markdown, image/raw for a picture, model/raw for a mesh, and density/bytes for the map. Executables also have a "Binary" mode available, see above.
The 3D scene holds still while you move through it
- The tree is now laid out in a world of its own, anchored a couple of levels above the current directory and shrinking by a fixed factor per level, so every directory has a fixed place in a self-similar structure. Walking into a subdirectory no longer re-forms the geometry — it flies the camera to that subdirectory's own place and closes in, which is why the zoom tightens the deeper you go.
- When the anchor eventually has to move (or a long descent would run the scene into the floating-point floor), the frame is re-based by the similarity transform between the old layout and the new one, camera and animating boxes carried through it — so the re-anchor is invisible: the pixels after are the pixels before.
- A box's size is mapped against its siblings rather than the whole scene, so a box never changes size because something elsewhere in the tree came into view.
- Camera-distance limits are now multiples of the current level's scale rather than absolute world units, so the same numbers mean the same thing at every depth.
The other panel stays responsive with the 3D view up
- Input is batched into one frame. Auto-repeat and the wheel deliver events far faster than a frame can be drawn, and a burst of them is a burst of cursor moves — only where it ends up has to be painted. Answering each with its own frame let the terminal's input queue outrun the render loop, so a panel kept scrolling after the key was released. With the 3D view open, where a frame costs the terminal a whole re-transmitted image, that showed up as "scrolling the other panel is sluggish".
- A pointer event mid-batch forces a redraw before the hit test, so a click after something has moved the world still lands on the right file.
- The 3D view's scene-image rebuilds are rationed off the frame clock and a frame count rather than wall-clock time, so the repaint budget cannot race a slow build.
Filesystem watching
- Events are collected on the watcher's own thread and handed to the UI in batches, one wake-up per batch, instead of one redraw per event. A build writing thousands of files no longer means thousands of redraws.
- A recursive watch the system refuses is no longer retried on every frame, which re-walked the whole tree each time. It now falls back to the directory itself, once.
- A recursive watch that failed part-way no longer leaves behind the subdirectory watches it had already added.
- When both panels show the same directory, one panel moving away no longer removes the other panel's watch.
- The 3D view's activity glow now also works with Auto-refresh panels turned off.
Dialogs replace a pre-filled value when you type over it
A field that opens pre-filled and focused now opens fully marked, so the first keystroke replaces it rather than appending to it. The mark is dropped by any focus move or click, so tabbing through a form of existing settings can never wipe one. Applies to Find file, Select/Unselect by mask, Multi-rename, Save as, and the shared form fields.
Viewer highlight rows
A tinted line — a Find all hit, or the blame cursor — is now highlighted across the whole row, not only behind its text.
F-key bar layout
- The bar is laid out by display width rather than character count, so wide (CJK) labels keep to their share of the row. Counting characters made a segment up to twice as wide as its share, which shoved the later keys rightwards until F10 fell off the end of the bar.
- Zero-width combining marks (Devanagari vowel signs, for instance) ride along in the cell of the character they modify rather than each claiming a column, which otherwise left the bar short of the right edge and dropped the marks at render time.
- The bar now paints every column up to the right edge; a label clipped mid-glyph used to leave a notch of bare screen in the last column.
Translations
All new interface strings are translated into the 18 built-in languages.
Building
The bundled SQLite is a new C dependency:
Requires a recent stable Rust toolchain (edition 2024, Rust ≥ 1.85), plus a C/C++ compiler for the bundled
unrarand SQLite libraries — add--no-default-featuresto build without RAR and SQLite-browsing support if you'd rather not have one.
The tree is also rustfmt-clean now: rustfmt.toml sets use_small_heuristics = "Max" so the compact style the source is written in survives, and cargo fmt is the easiest way to match it. CI still does not gate on it.
getrandom (for the Receive over LAN token) and, on Windows, windows-sys (for the screensaver clock's local time) are now direct dependencies. Both were already in the dependency tree, so no new crates are built.
New config.toml keys; an older config without them gets the defaults:
| Key | Default | |
|---|---|---|
space3d_activity
| true
| The 3D view's filesystem-activity glow, and the recursive watch it needs |
details_activity
| true
| The git activity calendar in the Details view |
screensaver_minutes
| 0 (off)
| Idle minutes before the screensaver starts |
screensaver
| "random"
| random, starfield, matrix, clock or pipes
|
thumb_size
| "medium"
| small, medium or large thumbnail grid cells
|
themes.toml gains one colour, model_fg, for 3D model files in the panel listings; a theme file written before this release still loads and picks up the default.
Full Changelog: v1.8.1...v1.9.0