fresh-editor 0.4.0

A lightweight, fast terminal-based text editor with LSP support and TypeScript plugins
Documentation

███████╗██████╗ ███████╗███████╗██╗  ██╗
██╔════╝██╔══██╗██╔════╝██╔════╝██║  ██║
█████╗  ██████╔╝█████╗  ███████╗███████║
██╔══╝  ██╔══██╗██╔══╝  ╚════██║██╔══██║
██║     ██║  ██║███████╗███████║██║  ██║
╚═╝     ╚═╝  ╚═╝╚══════╝╚══════╝╚═╝  ╚═╝

The Terminal Text Editor

Easy To Use | TypeScript Extensible | Light And Fast | Huge File Support

Full documentation: https://getfresh.dev/docs

  Fresh is a terminal text editor with multi-cursor editing, macros,
  integrated terminal, LSP support (completion, diagnostics, rename,
  code actions), a TypeScript plugin system, session persistence,
  SSH remote editing, a package manager, themes, and i18n.

  Everything is discoverable from two places: the command palette
  (Ctrl+P / ^P) and the menu bar at the top of the screen.
  If you're not sure how to do something, start there. The
  Show Keybindings command lists every shortcut.

Privacy: Fresh checks for updates once daily, sending only the
  editor version and OS type — no personal data, file contents, or
  usage behavior. Disable with "check_for_updates": false in config
  or --no-upgrade-check on the CLI (also in Settings editor).

╔════════════════════════════════════════════════════════════╗
║                   COMMAND PALETTE                          ║
╚════════════════════════════════════════════════════════════╝

  Ctrl+P / ^P opens the command palette. It defaults to command
  mode (> prefix). Backspace to clear the prefix and switch modes:

  >            run commands (default)
  (no prefix)  fuzzy file search
  #            switch between open buffers
  :            go to line number

  Queries are split on spaces — each term must match independently,
  so "feat view" finds "features/groups/view.tsx". Tab accepts
  the top result.

╔════════════════════════════════════════════════════════════╗
║                        EDITING                             ║
╚════════════════════════════════════════════════════════════╝

Multiple Cursors & Block Selection
────────────────────────────────────────────────────────────
  "Add Cursor at Next Occurrence" adds a cursor at the next
  match of your selection (or selects the word under cursor
  first). You can also add cursors above/below. All editing operations — typing, delete,
  paste — apply to every cursor simultaneously.

  Block selection (rectangular) is also available. When you type or
  delete in a block selection, it converts to multiple cursors
  automatically.

Macros & Bookmarks
────────────────────────────────────────────────────────────
  Fresh has 10 macro recording slots and 10 bookmark slots. Record a
  macro, replay it, set bookmarks and jump to them — all via the
  command palette or their keybindings. Both are per-session.

Shell Piping
────────────────────────────────────────────────────────────
  The "Shell Command" action pipes the buffer (or selection) through
  a shell command and shows the output. A variant replaces the
  selection with the output. Useful for formatting, sorting, or
  transforming text with any unix tool.

╔════════════════════════════════════════════════════════════╗
║                 SEARCH & REPLACE                           ║
╚════════════════════════════════════════════════════════════╝

  Search and Replace are in the Edit menu and command palette.
  Supports regex. Interactive replace highlights each match and you
  press y (yes), n (skip), ! (replace all remaining), or q (quit).

  "Find Next Occurrence" / "Find Previous Occurrence" search
  for the word under cursor without opening a panel — useful
  for quick navigation through a symbol's usages.

  The Git Grep plugin provides project-wide search with live preview
  via the command palette.

╔════════════════════════════════════════════════════════════╗
║                  INTEGRATED TERMINAL                       ║
╚════════════════════════════════════════════════════════════╝

  Open a terminal from the command palette. The terminal has two
  modes (shown in the status bar): Terminal (keys go to shell) and
  Terminal (read only) (scrollback — you can scroll, search, and
  copy text). Toggle between them via the command palette or its
  keybinding.

  Most editor shortcuts still work in terminal mode. If a terminal
  app needs keys that the editor would intercept, toggle
  keyboard capture — the UI dims to indicate ALL keys (except
  the capture toggle itself) go to the terminal.

  You can open multiple terminals as tabs. Scrollback history is
  preserved across editor restarts. Mouse events are forwarded to
  terminal apps in alternate screen mode (vim, htop, etc.).

╔════════════════════════════════════════════════════════════╗
║                    LSP & CODE INTEL                        ║
╚════════════════════════════════════════════════════════════╝

  Fresh auto-detects installed language servers. Just install the
  server binary and it works — built-in configs exist for many
  languages (e.g. rust-analyzer, gopls, clangd, pylsp).
  Open the Settings editor to see the full list under LSP.

  Features: completion, go-to-definition, find references, hover,
  code actions, rename, inline diagnostics, semantic highlighting,
  and inlay hints.

  To add an LSP for a new language, use the Settings editor (command
  palette > "Open Settings", then search for "lsp") to add both a
  language and LSP entry with matching keys. You can also pass
  "initialization_options" and set "process_limits" to cap memory
  and CPU. LSP can be toggled per-buffer via the command palette.

╔════════════════════════════════════════════════════════════╗
║                     CONFIGURATION                          ║
╚════════════════════════════════════════════════════════════╝

Settings & Layers
────────────────────────────────────────────────────────────
  The Settings editor (Edit > Settings, or command palette) groups
  all options by category with search and inline descriptions. A
  layer selector chooses where changes are saved:

  • User      ~/.config/fresh/config.json  (personal defaults)
  • Project   .fresh/config.json           (shared via VCS)
  • Session   Temporary overrides, not persisted.

  Layers override bottom-up: Session > Project > User > Defaults.
  Nested objects (editor, lsp, languages) are deep-merged — a
  project config setting only "editor.tab_size" won't clobber your
  other user settings. Lists (keybindings, on_save) are replaced
  entirely by higher layers.

  For complex config (LSP init options, keybinding arrays), click
  Edit in the Settings footer to open the raw JSON. Only
  non-default values need to be present.

Keybindings
────────────────────────────────────────────────────────────
  Fresh has three base keymaps: default, emacs, and macos. Switch
  via View > Keybinding Style or the Settings editor. Custom
  bindings in the "keybindings" array take precedence over the keymap.

  The Keybinding Editor (Edit > Keybinding Editor) lets you browse
  all bindings in a searchable table. Press / to text-search, r to
  find a binding by pressing the actual key combo, c/s to
  filter by context or source. Add, edit, and delete visually.

  Bindings have a "when" context: global (always), normal (editor),
  prompt, popup, file_explorer, menu, terminal. The same key can
  do different things depending on focus.

Themes
────────────────────────────────────────────────────────────
  Select Theme from the command palette. To customize, use
  Edit Theme — a live visual editor where you tweak colors and
  see changes immediately. Built-in themes can't be modified
  directly but "Save As" forks them. Custom themes are JSON
  in ~/.config/fresh/themes/ using [R,G,B] arrays. Community
  themes are installable via the package manager.

╔════════════════════════════════════════════════════════════╗
║                       PLUGINS                              ║
╚════════════════════════════════════════════════════════════╝

  Plugins are TypeScript running in a QuickJS sandbox. Each plugin
  gets its own isolated context. Fresh ships with TODO Highlighter,
  Git Grep (project-wide search), and Git Find File.

  The package manager (command palette > "pkg:") installs plugins,
  themes, language packs, and bundles from a git registry. You can
  also install from any git URL, including monorepo subdirectories
  via URL fragment (https://github.com/user/repo#packages/foo).

  Scaffold new packages with
  fresh --init plugin|theme|language|bundle.
  Packages are stored under ~/.config/fresh/plugins/packages/,
  ~/.config/fresh/themes/packages/, and ~/.config/fresh/grammars/.

  Experimental plugins: Vi Mode (modal editing with operators,
  motions, text objects), Diagnostics Panel, Side-by-Side Diff.

╔════════════════════════════════════════════════════════════╗
║              SESSION PERSISTENCE  (Experimental)           ║
╚════════════════════════════════════════════════════════════╝

  fresh -a starts (or reattaches to) a background server for the
  current directory. The "Detach" command (File menu or command
  palette) disconnects the client while the editor keeps running
  with all state intact. fresh -a from the same directory
  reattaches. Quit exits both client and server.

  Named sessions (fresh -a myname) allow multiple sessions per
  directory. fresh --cmd session list/kill manages running
  sessions.
  You can open files in a running session without attaching:
  fresh --cmd session open-file . src/main.rs:42 — useful for
  integrating Fresh with file managers or other tools.

  Workspace state (open files, splits, cursor positions, undo
  history) is saved even in direct mode (without -a).
  Session mode additionally preserves running terminal processes.

╔════════════════════════════════════════════════════════════╗
║                REMOTE EDITING (SSH)  (Experimental)        ║
╚════════════════════════════════════════════════════════════╝

  fresh user@host:/path/to/file edits a remote file over SSH.
  fresh user@host:~ opens the remote home directory in the file
  explorer. Supports password and key auth, sudo save for protected
  files, and efficient patched saves (only changed bytes transfer).
  Requires Python 3 on the remote host. Status bar shows
  [SSH:user@host].

  Alternative: SSH into the machine and run fresh -a directly on
  the remote host for a persistent session that survives dropped
  connections.

╔════════════════════════════════════════════════════════════╗
║                     GOOD TO KNOW                           ║
╚════════════════════════════════════════════════════════════╝

File Handling
────────────────────────────────────────────────────────────
  Fresh auto-detects text encoding and converts to UTF-8 in memory.
  Many encodings are supported (UTF-16, GBK, Shift-JIS, Latin-1,
  etc.). The on-disk encoding and line ending format (LF/CRLF/CR)
  are shown in the status bar — click either to change.

  The CLI accepts file:line:col syntax, multiple files, and stdin
  piping (echo hello | fresh -). Binary files open read-only. If a
  save fails due to permissions, Fresh offers a sudo fallback.

  Unsaved changes are auto-recovered from
  ~/.local/share/fresh/recovery/ if the editor crashes.

Git Integration
────────────────────────────────────────────────────────────
  The gutter shows git diff indicators (green = added, yellow =
  modified, red = deleted). The file explorer shows per-file git
  status (M/A/U) with hover tooltips showing diff stats. Parent
  folders show a dot when they contain unsaved files.

Editor Features
────────────────────────────────────────────────────────────
  Bracket matching highlights pairs with rainbow colors by nesting
  depth. Pressing Enter between brackets expands them with correct
  indentation. Line wrap is available (command palette) — Up/Down
  and Home/End move by visual line when wrapping is enabled.

  The status bar language indicator is clickable to switch
  syntax.
  Relative line numbers and cursor style (block/bar/underline)
  are configurable via the Settings editor or command palette.

macOS
────────────────────────────────────────────────────────────
  Fresh auto-detects macOS and uses an appropriate keymap. Some key
  combinations require terminal-specific configuration,
  particularly in Terminal.app and iTerm2 (Option-as-Meta,
  Shift+Arrow mappings).
  Kitty and Ghostty work best out of the box. See the online docs
  for per-terminal setup instructions. If keys aren't working, use
  Help > Debug Keyboard Events or the "Calibrate Keyboard" command.

I18n
────────────────────────────────────────────────────────────
  UI language is auto-detected from your system locale. Change it
  via the command palette ("Select Locale"), View > Select Locale,
  or from the CLI with fresh --locale es.

Terminal Colors
────────────────────────────────────────────────────────────
  Fresh auto-detects truecolor/256/16 support. GNU Screen and tmux
  may interfere — override with FRESH_COLOR_MODE=256 fresh if
  colors look wrong.

────────────────────────────────────────────────────────────
Full documentation: https://getfresh.dev/docs
Report issues:      https://github.com/sinelaw/fresh/issues
────────────────────────────────────────────────────────────

Press q or Esc to close this page