0.3.0
This version brings major features and many quality-of-life improvements and bug fixes:
- A cool dashboard plugin
- Devcontainer support
- init.ts
And more (see below). A large version is more likely to contain regression bugs, so please bear with me if you encounter problems, and open github issues without hesitation.
Features
-
Dashboard plugin: Built-in TUI dashboard that replaces the usual "[No Name]" with useful at-a-glance info.
- Default widgets: git status + repo URL, a "vs master" row (commits ahead/behind), and disk usage for common mounts.
- Opt-in widgets: weather, and open GitHub PRs for the current repo.
- Auto-open (on startup / last-buffer-close) is configurable — e.g.
editor.getPluginApi("dashboard")?.setAutoOpen(false)ininit.ts. When off, use the "Show Dashboard" command in the palette. - Third-party plugins and
init.tscan contribute their own rows via theregisterSection()API. Theinit.tsstarter template includes ready-to-paste snippets for enabling the opt-in widgets, toggling auto-open, and registering custom sections (see below).
-
Devcontainer support (thanks @masak1yu!): Fresh integrates with the devcontainer CLI (install it yourself).
- Detects
.devcontainer/devcontainer.jsonand offers Attach / Rebuild / Detach. - Embedded terminal, filesystem, and LSP servers all run inside the devcontainer.
Dev Container: Create Configscaffolds a config for projects that don't have one.Dev Container: Show Portsmerges configuredforwardPortswith livedocker portoutput.Dev Container: Show Logscaptures the container's recent stdout/stderr.- Build log streams into a workspace split; failed attaches offer Retry / Show Logs / Detach via a recovery popup.
initializeCommandruns on attach.
- Detects
-
init.ts: Fresh now auto-loads~/.config/fresh/init.ts! Allows you to run plugin code on startup, which complements the purely declarative config system with imperative, environment-aware logic. Use command paletteinit: Editto generate a template with some examples. Useinit: Reloadto run it after editing. Use--no-init/--safeto skip loading.- Tip: Enable LSP when editing
init.tsto get help and completions. - Example (for the Dashboard plugin):
// in your init.ts file: const dash = editor.getPluginApi("dashboard"); if (dash) { dash.registerSection("env", async (ctx) => { ctx.kv("USER", editor.getEnv("USER") || "?"); }); }
Will add a line like this to your dashboard:
│ ▎ ENV │ │ USER someone │ - Tip: Enable LSP when editing
-
{remote}status-bar indicator: Clickable status-bar element that lights up when you're attached to an SSH remote or devcontainer, with a context-aware menu (detach, show logs, retry attach, …). SurfacesConnecting/Connected/FailedAttachstates. Fresh's config v1→v2 migration injects{remote}into customizedstatus_bar.left. -
Hot-exit restore split from session restore:
editor.restore_previous_sessionconfig and the--no-restore/--restoreCLI flags now control workspace/tab restoration separately from hot-exit content — unsaved scratch buffers come back even when you opt out of full session restore (#1404). -
File explorer — cut/copy/paste + multi-selection + right-click context menu (thanks @theogravity!):
Ctrl+C/Ctrl+X/Ctrl+Vwith same-dir auto-rename and per-file conflict prompt on cross-dir paste.Shift+Up/Downfor multi-select.- Right-click context menu (#1684) with the usual file operations, honoring the active multi-selection.
- Cut-pending items are dimmed until pasted; cancel a pending cut with Escape or by pasting back into the same directory.
- Renaming a file or directory relocates any open buffers inside it; deleting a file closes its buffer.
-
File explorer — keyboard preview: Moving the cursor with Up/Down in the explorer previews the highlighted file in a preview tab (#1570), so you can scan files without leaving the keyboard.
-
Quick Open / Go-to Line live preview: Typing
:<N>in the file finder (or in the standalone:mode) scrolls the cursor to the target line live as you type; Enter commits, Escape reverts, mouse movement or clicks also commit. -
Terminal shell override (#1637): New
terminal.shellconfig option lets you pick a different shell for the integrated terminal without reassigning$SHELL(which affectsformat_on_saveand other features). -
Suspend process (Unix): New
Suspend Processaction sends Fresh to the background like Ctrl+Z in a shell. Routed through the client in session mode so the server stays up. -
Current-column highlight: New
highlight_current_column/Toggle Current Column Highlight— highlights the cursor's column for alignment work. -
Post-EOF shading (#779): Rows past end-of-file render with a distinct background so the boundary is obvious; works alongside
show_tilde. -
Regex replacement escapes:
\n,\t,\r, and\\in the replacement string are now interpreted when regex mode is on.
Improvements
-
SSH URLs on the CLI:
fresh ssh://user@host:port/pathlaunches a session whose filesystem and process authority point at the remote host. -
Redraw Screen command (#1070): Added a
redraw_screenaction and palette entry that clears the terminal and fully repaints the UI, useful when an external program scribbles over the TUI. -
Terminal window title (#1618): Fresh sets the terminal window title from the active buffer's filename, matching other editors.
-
LSP status popup upgrades: LSP popup now shows better options for enabling/disabling the nudge.
-
Find Next centers vertically (#1251): When the next match is off-screen, scroll it to roughly the middle of the viewport so you keep context above and below it. Matches that are already visible are not re-scrolled.
-
Adaptive line-number gutter (#1204): The gutter now grows with the buffer's line count rather than reserving 4 digits by default — a small file reclaims 2–3 columns of editor width.
-
File explorer width in percent or columns (#1118, #1212, #1213):
file_explorer.widthnow accepts"30%"(percent of terminal width) or"24"(absolute columns). Dragging the divider preserves whichever form you configured. Legacy integer/fraction values keep working. -
Relative paths to theme files (#1621): User themes in
config.jsoncan be spelled out as relative to your themes directory:- "dark" or "builtin://dark" — any built-in by name
- "my-theme.json" or "subdir/dark.json" — nested relative path in your user themes dir - useful for sharing Fresh config.json in a dotfiles repo
- "file://${HOME}/themes/x.json" — absolute path; ${HOME}, ${XDG_CONFIG_HOME} are expanded
- "https://github.com/foo/themes#dark" — URL-packaged theme
-
Plugin API additions:
-
editor.overrideThemeColors(...)for in-memory theme mutation. -
editor.parseJsonc(...)for host-side JSONC parsing. - Plugin-created terminals now have an ephemeral lifetime — they close cleanly when the action that spawned them finishes.
- Plugin authors can augment
FreshPluginRegistryto makeeditor.getPluginApi("name")return a typed interface (noas-cast needed). Augmentations are emitted to~/.config/fresh/types/plugins.d.tsat load time. -
spawnHostProcessnow returns a handle withkill()(and a matchingKillHostProcesscommand). -
BufferInfo.splitssurfaces which splits display a buffer, for "focus-if-visible" dedupe. -
editor.setRemoteIndicatorState(...)/clearRemoteIndicatorState()let remote plugins drive the status-bar{remote}element. - Dashboard gains
dash.registerSection()(with a returned remover) anddash.clearAllSections()for plugin extension.
-
-
JSONC language:
.jsoncfiles and well-known JSONC-with-.json-suffix files (devcontainer.json,tsconfig.json,.eslintrc.json,.babelrc, VS Code settings files) now get a dedicatedjsonclanguage with comment-tolerant highlighting and LSP routing throughvscode-json-language-serverwith the correctlanguageId. -
macOS Alt+Right / Option+Right stops at word end (#1288): Selection no longer extends past trailing whitespace, matching TextEdit / VS Code on Mac.
Bug Fixes
-
File Explorer
.gitignoreimprovements (#1388): Files are now visible only if they aren't hidden by ANY of the filters (hidden files,.gitignorefiles). Also, File Explorer will do a better job of auto-reloading when.gitignorechanges. -
Scrollbar theme colours (#1554): The scrollbar now honours
theme.scrollbar_track_fg/scrollbar_thumb_fg. A few themes were updated to define this missing value. -
Fixed panic when clicking split + terminal (#1620).
-
Fixed LSP server crash loop (#1612): When LSP fails on startup, restart bypassed the normal restart count limiter, now fixed.
-
Fixed Markdown preview/compose wrapping when File Explorer is open: When compose width was set (e.g. 80), opening the File Explorer sidebar pushed tables off the right edge. Separator rows no longer overflow when table cells are truncated.
-
More settings propagate live: File-explorer width and flag changes made in the Settings UI apply immediately on save, without a restart.
-
Devcontainer: no re-prompt after restart: Fresh no longer shows the "Attach?" prompt again after the post-attach self-restart.
-
Dashboard polish: Doesn't steal focus from a CLI-supplied file, underline only on clickable spans (not trailing padding), clicks dispatch only from underlined column ranges, immediate repaint on split resize.
-
Quieter LSP: Suppress
MethodNotFounderrors from LSP servers (#1649) — servers that don't implement an optional method no longer spam the log. -
Plugin action popups survive buffer switches: Popups stay visible when the active buffer changes, and concurrent popups queue LIFO so the newest shows first.
-
Encoding detection on CJK files (#1635): Files whose only non-ASCII bytes sat past the 8 KB sample window were mis-detected; the sample boundary is now treated as truncation so the full file is considered before the encoding is guessed.
-
Review diff — no fold jitter: Toggling a fold no longer re-centers the viewport.
-
LSP — cleaner disables: No spurious warning when opening a file for a language whose LSP is explicitly disabled in config. The indicator shows buffer-skip state (e.g. file too large) instead of a generic warning.
-
Windows — preserve UNC paths:
pathJoinplugin API now preserves\\?\UNC prefixes on Windows. -
Hardware cursor no longer bleeds through popups: The terminal hardware cursor is hidden when an overlay popup covers it.
-
Focus — tab clicks reset explorer context (#1540): Clicking a tab or buffer no longer leaves the FileExplorer key context active.
-
File explorer poll fixes: Background refresh no longer collapses folders you've expanded, and resets the cursor to the root only when the selected path is genuinely gone.
-
Review PR Branch — default-branch detection: The prompt now pre-fills the repo's actual default branch (via
origin/HEAD) instead of hard-codingmain. -
Review: PageUp/PageDown: Paging in review-branch mode now scrolls the commit list instead of moving the cursor by one row.
Under the Hood
- Authority abstraction: Filesystem, process-spawning, and LSP routing are now consolidated behind a single
Authorityslot, with plugin ops (editor.setAuthority/clearAuthority/spawnHostProcess) for plugins that want to target the host even while attached elsewhere. This is what makes the devcontainer andssh://flows work uniformly.