Preferences
Press ⌘, for the in-app Preferences window. Everything also lives in a small JSON file under ~/Library/Application Support/com.mpjhorner.IdeUltra/. Edit either; both round-trip through the same data model.
settings.json
User-tunable preferences. Survives across sessions, never touched during normal editing.
{
"theme": "Dark",
"zoom": 1.0,
"sidebar_width": 260.0,
"sidebar_visible": true,
"markdown_preview": true,
"autosave_on_focus_loss": true,
"keymap_preset": "Default",
"keymap_chosen": true,
"trim_trailing_whitespace_on_save": true,
"ensure_final_newline_on_save": true,
"indent_style": { "Spaces": 4 },
"soft_wrap": false
}
| Key | Type | Notes |
|---|---|---|
theme | "Dark" or "Light" | Use View → Theme in the app. |
zoom | float, 0.5–3.0 | Use ⌘= / ⌘- / ⌘0. |
sidebar_width | float, ≥220 | Drag the splitter between sidebar and editor. |
sidebar_visible | bool | ⌘B toggles. |
markdown_preview | bool | ⌥⌘M toggles when the active tab is a .md file. |
autosave_on_focus_loss | bool | Save every dirty buffer when the window loses focus. |
keymap_preset | "Default", "VsCode", "PhpStorm" | Welcome modal asks; Edit → Keymap switches. |
keymap_chosen | bool | If false, the welcome modal shows on next launch. |
trim_trailing_whitespace_on_save | bool | Strips spaces/tabs/CR at end of each line before write. |
ensure_final_newline_on_save | bool | Appends a final \n if the buffer doesn't end with one. |
indent_style | "Tab" or { "Spaces": n } | Multi-line Tab/Shift+Tab uses this unit. |
soft_wrap | bool | Wrap long lines in the editor. |
session.json
What you had open when you last quit. Restored on relaunch.
{
"window": { "size": [1400, 900], "pos": [200, 100] },
"last_folder": "/Users/you/work/myproject",
"open_tabs": [
"/Users/you/work/myproject/src/main.rs",
"/Users/you/work/myproject/Cargo.toml"
],
"active_tab": 1,
"recent_files": { "entries": [] },
"pane2_active": null,
"focused_right": false
}
Hand-edit either file (close IdeUltra first) and the next launch picks up the change. Both files are written atomically (.tmp + rename), so an interrupted save can't corrupt them.
Recovery
Every dirty buffer is snapshotted to ~/Library/Application Support/com.mpjhorner.IdeUltra/recovery/ on a one-second debounce. Each snapshot is a pair: <hash>.json with metadata + <hash>.txt with the contents.
On normal save the snapshot is dropped. On startup, any recoveries whose original file is older than the snapshot are surfaced in a modal. Recoveries whose original has been saved through some other route are silently cleaned up.
Logs
log.ndjson in the same directory. One JSON object per line. Tail it for live diagnostics:
tail -f ~/Library/Application\ Support/com.mpjhorner.IdeUltra/log.ndjson
The log includes cold-start timing, every workspace open, every file open and save, git refreshes, recovery scans, fuzzy-find query telemetry, and any warnings (failed reload, save errors, missing tabs on restore).