Latency is the feature.
A native code editor built around the gap between a keystroke and a photon, and measured against it rather than described as fast.
Beta. Windows today, macOS and Linux to come.
1/// What a frame is allowed to cost. 2pub struct Budget { 3 pub frame: Duration, 4} 5 6impl Budget { 7 // 60 Hz, less the compositor’s slice. 8 pub fn interactive() -> Self { 9 Self { frame: Duration::from_micros(16_667) } 10 } 11 12 pub fn met_by(&self, measured: Duration) -> bool { 13 measured <= self.frame 14 } 15}Measured, not asserted
Every editor worth using is fast at the thing it was designed around and slow at
everything else. The only way that claim means anything is with a figure behind it, so ferrum-bench is a headless latency harness that reports p50 through p99.9,
gates against a baseline, and refuses to call a noisy run a result.
- Frame of a 100k line file
- 545µs
- A pane of a 4,800 row tree
- 171µs
- Languages highlighted
- 14
- Tests in the workspace
- 1022
In-process CPU work on one thread, p50, on a 2070 and an i7-8700K. Not end-to-end latency, and the tool that produces these says so on every run.
Search every file, and replace across them
ctrl-shift-f searches the project with the same case, whole-word and regex toggles as the find bar. alt-h folds out the replace box and ctrl-alt-Enter replaces every match. Files open with unsaved changes are left alone, and the summary says how many.
ctrl-shift-falt-hctrl-alt-Enter
7 results in 6 files
- ferrum-render/budget.rs:9 frame: Duration::from_micros(16_667),
- ferrum-render/atlas.rs:41 let waited: Duration = start.elapsed();
- ferrum-bench/report.rs:118 fn p99(samples: &[Duration]) -> Duration {
- ferrum-term/pty.rs:64 timeout: Duration::from_millis(8),
- ferrum-render/budget.rs:22 pub fn met_by(&self, m: Duration) -> bool {
- ferrum-text/shape.rs:77 let budget: Duration = self.frame / 4;
- ferrum-bench/run.rs:205 samples: Vec<Duration>,
See what changed, beside what was committed
Clicking a changed file in source control opens it next to the version in HEAD: committed on the left and read only, the working file on the right, changed lines banded on both. It finds the files you have been working on — it does not stage or commit.
HEAD read only
28fn present(&mut self) { 29 let t = Instant::now(); 30 31 self.draw(self.budget); 32 self.swap(); 33 34 let spent = t.elapsed(); 35 if spent.as_millis() > 33 { 36 self.missed += 1; 37 } 38}Working file
28fn present(&mut self) { 29 let t = Instant::now(); 30 31 self.draw(self.budget); 32 self.swap(); 33 34 let spent = t.elapsed(); 35 if !self.budget.met_by(spent) { 36 self.missed(spent); 37 } 38}A terminal underneath, not in another window
ctrl-backtick opens a shell in a panel and closes it from inside. It handles what a shell, a compiler and a test runner emit: colour, cursor movement, erasing, scroll regions and the alternate screen. The selection follows the text, not the screen.
ctrl-`ctrl-shift-eshift-PageUp
1/// What a frame is allowed to cost. 2pub struct Budget { 3 pub frame: Duration, 4} 5 6impl Budget {$ cargo test --workspace Compiling ferrum-render v0.1.0 Compiling ferrum-shell v0.1.0 Finished test profile in 4.31stest result: ok. 1022 passed; 0 failed$ ▊Bring the theme you already use
Two themes ship, built from one design in two appearances. Beyond those, Ferrum reads any theme installed in Visual Studio Code — a real translation, deriving what a theme leaves unset and compositing translucent colours onto the surface beneath them.
1/// What a frame is allowed to cost. 2pub struct Budget { 3 pub frame: Duration, 4 pub input: Duration, 5} 6 7impl Budget { 8 // 60 Hz, less the compositor’s slice. 9 pub fn interactive() -> Self {10 Self {11 frame: Duration::from_micros(16_667),12 input: Duration::from_millis(8),13 }14 }1516 pub fn met_by(&self, measured: Duration) -> bool {17 measured <= self.frame18 }19}Ferrum Light
ferrum-lightWarm near-neutrals over a white code canvas. The accent is the same hue at a lower lightness, because the dark theme’s orange manages only 3.12:1 on white.
Fourteen languages, coloured by a real parser
Tree-sitter grammars, resolved against the theme's role table rather than a list of colour names — so a keyword is a keyword in every theme, including the one you brought from Visual Studio Code. Markdown is the block grammar only: headings, fences and lists colour, emphasis inside a paragraph does not.
- Rust
- TypeScript
- JavaScript
- TSX
- Python
- Go
- C
- HTML
- CSS
- JSON
- TOML
- YAML
- Markdown
- Shell
The icons are the editor's own, from the Material Icon Theme it generates its file tree set from.
And the rest of it
Multiple carets
alt-click adds one, ctrl-alt-up and down add one above or below, and every edit applies at every caret. Escape collapses back to one.
Open by typing
ctrl-p opens a file by part of its path. ctrl-o and ctrl-shift-o open a file or a folder through the platform’s own dialog.
Split into columns
ctrl-backslash opens a column beside the current one. Each keeps its own tabs and its own scroll; alt-left and alt-right move between them.
A tree that watches
A file created by a build or a git checkout appears on its own. Icons come from the file type, and git status sits beside the name.
Rendered Markdown and HTML
The dropdown at the right of the path bar switches between source and rendered. There is no CSS and no script — it is a reader, not a browser.
Diagnostics from rust-analyzer
Rust only, and only when rust-analyzer is already on your PATH. Underlines hide while they are stale rather than drifting to the wrong place.
Your fonts
Any family installed on the machine, by name rather than by file — Consolas by default on Windows, because that is what most people arrive reading code in.
Settings that follow you
Sign the editor in from the Account menu and push or pull settings.toml between machines through your account here.
Try it
It opens a project, shows you the files with their icons and what git says about each, lets you edit them in tabs, searches all of them, and runs a shell underneath. The download page says what is not there yet.