Skip to content

v0.3.0

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 05 Aug 11:22
· 57 commits to main since this release

The third beta. The headline is the editor: JSON, YAML and XML are now worked on by structure rather than by line number β€” an outline, one-keystroke navigation, folding, a path you can paste into jq, and a validator that puts the cursor on the problem. Plus uploading into FTP/SFTP panels with resume, panels that notice changes another program makes, and ZIP64 archives.

The editor understands JSON, YAML and XML

The symbol sidebar was empty for exactly the three formats an administrator edits most: JSON's tree-sitter grammar has no "definitions", and YAML and XML had no grammar at all. It now lists the keys of a JSON or YAML document and the elements of an XML one, nested as the document is, with elements named by their id, name or key attribute so twenty <server> entries are told apart. This covers the XML-based formats too β€” .plist, .svg, .csproj, .storyboard.

A file that does not parse still gets an outline down to the point where it breaks, which is when you most want one.

Navigation and selection

  • Ctrl+Cmd+Up / Down β€” out to the enclosing block, in to the first child.
  • Ctrl+Cmd+Left / Right β€” the previous or next entry at the same level, stepping over the whole block in between: from one server to the next without scrolling past forty lines of settings.
  • Ctrl+Cmd+A β€” select the enclosing block. Press it again and the selection grows outwards, so you can select exactly one service without dragging.

The path, in the notation your tools take

Ctrl+Cmd+C copies the cursor's position as .services.web.ports[0] for JSON and YAML β€” what jq and yq expect β€” or //server[@id='web-1']/port as an XPath. Keys that are not plain words are quoted for you: ."content-type", not .content-type, which in jq means something else entirely.

Validation that says where

Ctrl+Cmd+V checks the file and puts the cursor on the problem, with the reason in the window title. JSON and XML go through a real parser. YAML has none on this system, so the check covers what can be decided without one β€” a tab used to indent, indentation that lines up with nothing, a duplicate key, an unterminated quote β€” and says so instead of claiming the file is valid.

It also reports two things nothing else in the toolchain will:

  • a duplicate key, which every JSON parser accepts silently while discarding one of the two values;
  • a trailing comma, which Apple's own parser accepts and Python, Go and jq refuse.

The YAML check was measured against Ruby's Psych over 400 real YAML files (0 false alarms) and, in the other direction, over 294 deliberately broken ones. JSON agrees with Python's json module on 300 of 300 files; XML agrees with xmllint on 236 of 236.

Transformations

Minify to one line, sort keys recursively, escape or unescape as a JSON string, and JSON β†’ YAML β€” each one undoable in a single step, on the selection or the whole document. Minifying keeps the key order and the exact spelling of every number, because 1.0 and 1 are not the same version. There is deliberately no YAML β†’ JSON: it needs a YAML parser this system does not have, and a wrong guess about an anchor turns a config file into a different config file.

Folding

Option+Cmd with the arrows collapses the block at the cursor, the whole top level, or restores everything. Nothing is removed from the document β€” the text is only not drawn, so saving, undo and Find are unaffected, and Find still finds text inside a collapsed block. The header line stays visible and is marked, the line numbers skip what is hidden, and putting the cursor inside a fold opens it.

Elsewhere

  • F5 into an FTP or SFTP panel uploads, and resumes a partial remote file. Previously the remote path was handed to the local copy engine, which either failed or wrote to a same-named local path and reported success.
  • Panels notice changes another program makes, through FSEvents instead of polling.
  • ZIP64 archives can be read β€” entries and archives above 4 GB, and more than 65 535 entries.
  • The window's appearance is applied before the first frame, so a dark window no longer starts light and corrects itself.
  • Keyboard operation was broken in every window built in code and is now a gate: eight windows are checked for a closed Tab loop with nothing unreachable and nothing unlabelled.

Installing

This build is unsigned and un-notarized, like every build so far β€” the project has no Apple Developer ID. Gatekeeper blocks the first launch, and how you allow it depends on your macOS version:

  • macOS 15 Sequoia and later β€” double-click once, dismiss the warning, then go to System Settings β–Έ Privacy & Security and click Open Anyway. Apple removed the Control-click shortcut for unsigned software in macOS 15, so right-clicking does not help here.
  • macOS 13–14 β€” right-click the app β–Έ Open, then confirm.

Requires macOS 13 or later; the disk image is universal (Apple silicon and Intel).

Full notes: CHANGELOG.md