github sinelaw/fresh v0.3.0
fresh-editor 0.3.0

9 hours ago

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) in init.ts. When off, use the "Show Dashboard" command in the palette.
    • Third-party plugins and init.ts can contribute their own rows via the registerSection() API. The init.ts starter 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.json and offers Attach / Rebuild / Detach.
    • Embedded terminal, filesystem, and LSP servers all run inside the devcontainer.
    • Dev Container: Create Config scaffolds a config for projects that don't have one.
    • Dev Container: Show Ports merges configured forwardPorts with live docker port output.
    • Dev Container: Show Logs captures the container's recent stdout/stderr.
    • Build log streams into a workspace split; failed attaches offer Retry / Show Logs / Detach via a recovery popup.
    • initializeCommand runs on attach.
  • 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 palette init: Edit to generate a template with some examples. Use init: Reload to run it after editing. Use --no-init / --safe to skip loading.

    • Tip: Enable LSP when editing init.ts to 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                │
    
  • {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, …). Surfaces Connecting / Connected / FailedAttach states. Fresh's config v1→v2 migration injects {remote} into customized status_bar.left.

  • Hot-exit restore split from session restore: editor.restore_previous_session config and the --no-restore / --restore CLI 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+V with same-dir auto-rename and per-file conflict prompt on cross-dir paste.
    • Shift+Up/Down for 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.shell config option lets you pick a different shell for the integrated terminal without reassigning $SHELL (which affects format_on_save and other features).

  • Suspend process (Unix): New Suspend Process action 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/path launches a session whose filesystem and process authority point at the remote host.

  • Redraw Screen command (#1070): Added a redraw_screen action 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.width now 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.json can 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 FreshPluginRegistry to make editor.getPluginApi("name") return a typed interface (no as-cast needed). Augmentations are emitted to ~/.config/fresh/types/plugins.d.ts at load time.
    • spawnHostProcess now returns a handle with kill() (and a matching KillHostProcess command).
    • BufferInfo.splits surfaces 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) and dash.clearAllSections() for plugin extension.
  • JSONC language: .jsonc files and well-known JSONC-with-.json-suffix files (devcontainer.json, tsconfig.json, .eslintrc.json, .babelrc, VS Code settings files) now get a dedicated jsonc language with comment-tolerant highlighting and LSP routing through vscode-json-language-server with the correct languageId.

  • 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 .gitignore improvements (#1388): Files are now visible only if they aren't hidden by ANY of the filters (hidden files, .gitignore files). Also, File Explorer will do a better job of auto-reloading when .gitignore changes.

  • 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 MethodNotFound errors 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: pathJoin plugin 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-coding main.

  • 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 Authority slot, 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 and ssh:// flows work uniformly.

Don't miss a new fresh release

NewReleases is sending notifications on new releases.