docs/features/session-persistence.md
Warning: This feature is experimental. The API and behavior may change.
Palette:
Detach. CLI:fresh -a,fresh --cmd session list|new|kill,fresh --restore,fresh --no-restore. Config:hot_exit,editor.restore_previous_session.
Detach from Fresh and reattach later, similar to tmux. Your editor state persists even after closing the terminal.
See also: Remote Editing (SSH) for pairing session persistence with remote hosts, and Devcontainers for routing through a container.
All buffers — including unnamed scratch buffers — persist across sessions automatically. When you quit Fresh, unsaved changes are preserved and restored on next startup. Configurable via the hot_exit setting (default: on).
Session state (open files, split layout, plugin state) is restored on startup by default. Control this with:
editor.restore_previous_session (config, default true) — when set to false, Fresh skips restoring tabs and splits but still brings back unsaved "hot-exit" content (dirty files and unnamed buffers).--no-restore (CLI) — one-shot skip equivalent to the config flag being off.--restore (CLI) — force a full workspace restore even when the config flag is off. Mutually exclusive with --no-restore.# Start or attach to a session for the current directory
fresh -a
# Detach: press Ctrl+Shift+D (or use Command Palette > "Detach")
# Terminal closes, but Fresh keeps running in the background
# Reattach later from the same directory
fresh -a
# List all running sessions
fresh --cmd session list
| Command | Mode | Description |
|---|---|---|
fresh myfile.txt | Direct | No server. Closing quits everything. |
fresh -a | Session | Background server. Supports detach/reattach. |
Use session mode for long-running tasks or SSH sessions where connection may drop.
With -a, Fresh starts a background server. The terminal is a lightweight client relaying input/output.
Terminal (Client) ←→ Unix Socket ←→ Fresh Server (Background)
↓ ↓
Your keyboard Editor state
Your screen Open files
Running terminals
Detaching exits only the client; the server keeps running.
| Command | Description |
|---|---|
fresh -a | Attach to session for current directory (starts server if needed) |
fresh -a <name> | Attach to named session |
fresh --cmd session list | List running sessions |
fresh --cmd session new <name> | Start a new named session |
fresh --cmd session open-file <name> <files> [--wait] | Open files in a session (starts and attaches if needed) |
fresh --cmd session kill | Kill session for current directory |
fresh --cmd session kill <name> | Kill named session |
fresh --cmd session kill --all | Kill all sessions |
For multiple sessions in the same directory:
fresh --cmd session new feature-work
fresh --cmd session list
fresh -a feature-work
Open files in an existing session without attaching to it. If no session is running, one is started and the client attaches interactively:
# Open file in current directory session (use "." for session name)
fresh --cmd session open-file . src/main.rs
# Open file at specific line and column
fresh --cmd session open-file myproject src/lib.rs:42:10
# Open multiple files
fresh --cmd session open-file . file1.rs file2.rs
This is useful for integrating Fresh with file managers or other tools—files open in the existing editor without starting a new terminal session.
--wait)The --wait flag keeps the CLI process alive until the user is done with the file. The process exits when:
@"message"# Open a file and block until the user closes the buffer
fresh --cmd session open-file . src/main.rs --wait
# Open at a line with a popup message — blocks until popup is dismissed
fresh --cmd session open-file . 'src/main.rs:42@"Review this function"' --wait
If no session is running, one is started automatically and the client attaches interactively (--wait is ignored in this case — quit or detach normally).
Set Fresh as git's editor so git commit, git rebase -i, etc. open in your running session and block until you close the buffer:
git config --global core.editor 'fresh --cmd session open-file . --wait'
Git appends the filename, so the final command becomes e.g. fresh --cmd session open-file . --wait .git/COMMIT_EDITMSG. The --wait flag can appear anywhere after the session name — files after it are collected normally.
Combine --wait with range selection and popup messages to walk a user through code one location at a time. Each command blocks until the user presses Escape, then the next location opens:
fresh --cmd session open-file . 'src/parse.rs:10-25@"Step 1: The parser entry point"' --wait
fresh --cmd session open-file . 'src/eval.rs:80-95@"Step 2: Expression evaluation"' --wait
fresh --cmd session open-file . 'src/emit.rs:5@"Step 3: Code generation starts here"' --wait
Popup messages support markdown. Use $'...' quoting for multi-line messages:
fresh --cmd session open-file . \
$'src/main.rs:1-15@"**Overview**\n\nThis is the entry point.\nNote the error handling on line 12."' --wait
The --wait blocking behavior makes session open-file composable with any tool that needs to present files to a user and wait for acknowledgement:
# Code review script
for file in $(git diff --name-only HEAD~1); do
fresh --cmd session open-file . "$file@\"Review this file\"" --wait
done
# Step through grep matches
grep -rn "TODO" src/ | while IFS=: read -r file line _; do
fresh --cmd session open-file . "$file:$line@\"TODO found here\"" --wait
done
Ctrl+Shift+D or Command Palette → "Detach" or File → Detach SessionCtrl+Q): Both client and server exitEach session consumes memory for open files, terminal scrollback, and LSP servers. Use fresh --cmd session list periodically to check for forgotten sessions.
When reattaching, terminal size may differ and some applications may not render correctly after resize. Scrollback is preserved but limited by buffer size.
| Platform | IPC Mechanism |
|---|---|
| Linux/macOS | Unix domain sockets |
| Windows | Named pipes |
Server may have crashed. Run fresh --cmd session kill to clean up, then fresh -a again.
Sessions are keyed by working directory. ~/project and /home/user/project create different sessions—use consistent paths.
Check for forgotten sessions with fresh --cmd session list.
| Platform | Location |
|---|---|
| Linux | $XDG_RUNTIME_DIR/fresh/ or /tmp/fresh-$UID/ |
| macOS | /tmp/fresh-$UID/ |
| Windows | %LOCALAPPDATA%\fresh\sockets\ |