[0.11.0] - 2026-08-11
Added
-
New Maven Project. Editora could only ever open an existing folder as a project. There is now an IDEA-style wizard: pick an archetype, fill in the coordinates, and the generated project is registered and opened in its own window. Reachable from the File menu, the Project tree’s New ▸ submenu, and the palette as Maven: New Project….
- Archetypes come from a curated list that ships with Editora, with Load full catalog… to pull Maven Central’s if you need something else. Where both list the same archetype the curated pin wins, since the published catalog is often years behind.
- The package name is derived the way IntelliJ does it (
my-app→my_app,2048→_2048,new→new_), so a project name that isn’t a legal Java identifier still produces one. - Generation shells out to
mvn archetype:generaterather than writing a pom by hand, so the feature needs Maven on your PATH — which is checked before the wizard opens, not after five fields have been typed. - The new project arrives ready to run: a run configuration is seeded for its main class, with
mvn -q compileas its before-launch step, and that class is opened so Run works on the first press.
-
Git: Initialize Repository… — you could clone a repository but not start one, so a folder opened as a project had to be taken to a terminal for
git init. The command prompts for a folder (defaulting to the project root), runsgit init, and brings the Git UI up the usual way: status bar, Commit window, gutter change bars. Creating a repository inside an existing one is refused, naming the enclosing root, since it’s nearly always a mistake and awkward to undo. -
Copy the Markdown preview as rich text. Copying from the preview now puts an HTML flavour on the clipboard beside the plain text, so one Copy pastes formatted into Word, Teams, Outlook or Gmail while a plain-text target still gets the markup-stripped version. Both go on together and the receiving app picks, so there’s nothing to configure. Equations paste as images; headings, bold, lists, tables and links survive even in an app that throws the styling away.
-
Each tool window remembers its own size. Sizes were three numbers — one per side — shared by every window docked there, so sizing the Project tree and then opening the Structure outline left both at whatever the last one had been dragged to. On a first open, a panel whose content is already showing a horizontal scrollbar is widened to fit, up to 45% of the split.
-
Create a file of any supported type from the Project tree. Right-clicking a folder now opens a single New ▸ submenu: a generic
File…andFolder…, Text and Markdown, then one submenu per family — Java (Class, Interface, Record, Enum, Annotation,package-info.java), Web, Scripts, Languages, Data & Config, Docs & Diagrams, Build & Ops — about fifty types in all, each carrying the icon the file will show in the tree. You are asked for a name, prefilled with a sensible one, and the file opens with the caret already in the body rather than at the end.- A new Java file gets its package declaration from where it is created: “New ▸ Class” in
src/main/java/demowritespackage demo;. A qualified name (text.Slug) creates the sub-package folder and extends the package to match, andpackage-info/module-infoare accepted despite not being identifiers. - The typed name always wins over the type’s extension —
notes.jsonunder Text File gives you JSON, notnotes.json.txt, and a dotfile stays a dotfile. A name that tries to climb out of the folder (../x) creates nothing at all, and an existing file is never overwritten. - Also on the command palette as File: New File of Type… (and in the File menu), creating in the active file’s folder.
- The existing New Folder…, New From Template… and New Maven Project… items moved inside that same New ▸ submenu, shortened to Folder… / From Template… / Maven Project….
- A new Java file gets its package declaration from where it is created: “New ▸ Class” in
-
Filter and keyboard-navigate the Commit window. It now opens with a filter box focused, like Bookmarks and Personal Notes: type to narrow the changed files, Down or Enter to step into and open one. Typing a group’s name (
untracked) lists that whole group. Inside the tree,C-n/C-pmove andC-f/C-bexpand or collapse a group — chords the panel used to swallow, since it takes its own keys. Filtering is only a view: hiding a staged file behind a filter does not disable Commit, and staging still acts on the files you selected, not on everything that matches. -
C-n/C-pnow move the results from the filter box in every filterable tool window — Project, Structure, Bookmarks, Personal Notes, the Commit window and the build task trees — so narrowing and then picking never needs a hand off the keyboard. Previously only the GitHub window’s list did this. -
Stage or unstage several files at once. The Commit window’s file list is now multi-select: extend the selection with Shift+Up/Down from the keyboard or Shift/Ctrl-click with the mouse, then right-click and Stage, Unstage or Discard the whole run in one go. A mixed selection offers both Stage and Unstage, each acting only on the files it applies to, and Discard confirms once for the lot. Also on the palette as Git: Stage Selected Files and Git: Unstage Selected Files, and the menu key opens the same menu for the focused row, so the flow never needs the mouse. Each action is one
gitinvocation for the whole selection, so one refresh — not one per file. -
Filter and keyboard-navigate the build tool windows. The Maven, Gradle, npm, Cargo and Go task trees now open with a filter box focused, the way Bookmarks and Personal Notes do: type to narrow the goals, scripts or targets, Down or Enter to step into and run the result. Matching a section title (
lifecycle) keeps that whole section. Inside the tree,C-n/C-pmove andC-f/C-bexpand or collapse a section — chords the panel used to swallow, since it takes its own keys. -
The breadcrumb no longer opens a menu taller than your screen — clicking a folder with hundreds of entries used to produce a flat list you could only inch through with tiny scroll arrows. Past thirty entries it now splits into ranges (
android … cargo), each opening a submenu. -
Filter the message log — the session’s status messages fill up fast, and finding the one you want meant scrolling. The popup now opens with a filter field focused; type to narrow, Down or Enter to step into the results. It is also 40% wider and 20% taller.
-
Copy details from About — the About panel was rebuilt as a native-style panel (icon, version, links, and a monospace block listing Java, JavaFX, your OS and your config path) with a button that copies that block for a bug report.
-
The gutter ▶ uses your run configuration inside a Maven or Gradle project. It used to launch an ad-hoc “run this main class” with no before-launch build, no program or VM arguments, no working directory and no environment — which in a build-tool project is the wrong launch, and in a freshly generated one simply failed, because nothing had compiled yet. The configuration naming the clicked class wins, otherwise the one selected in the toolbar. Outside a build tool the old behaviour is unchanged.
-
Opening a project no longer leaves Run complaining about a missing file. A saved Java configuration resolves its classpath through an open Java file, so a session that had only
pom.xmlopen reported “open a Java file from the project” with the configuration sitting right there in the toolbar. The class that will run is now opened when the project restores — in the background, so it never steals the tab you left on.
Changed
-
A run configuration no longer picks run or debug for you. Each entry carried a “Kind” of run or debug that decided only what the Run button did with it — so a debug-kind entry turned Run into a second Debug button and left no way to plain-run it at all. The field is gone: one configuration, two buttons. Existing entries keep working; a saved kind is ignored. In exchange every configuration now gets a Debug: <name> command alongside its Run: <name> one, so a keybinding can reach either verb — which is the one thing Kind was genuinely good for. There is also a new Debug: Run Configuration… picker beside the existing Run one.
-
Inlay hints now appear where they belong. They used to be parked at the end of the line, so a call with several arguments produced a trailing run of grey text whose only clue to which hint went with which argument was left-to-right order. Each hint now renders inline at the position it describes, gently pushing the code after it aside, the way IntelliJ and VS Code do it. They remain annotations, not text: selecting or copying a line still gives you exactly what is in the file.
-
Inlay hints no longer label every argument of every call.
System.out.println("Hello")used to earn a greyx:, because the JDK declaresprintln(String x)— a hint that tells you nothing, and the common case rather than an edge one. Names that explain nothing (x,arg0) and names that merely repeat their argument (foo(name: name)) are now always hidden, and a picker in Settings → Code Completion chooses whether the rest appear on literal arguments only (the new default, matching VS Code) or on all of them. Type hints are never filtered. -
Git, GitHub and Web are no longer marked Beta.
-
The Output console appears when you are in a Git repository. Git and GitHub write every command they run into a transcript there, and in a repository with no build file its stripe button never appeared — so those transcripts had no way in.
-
Chrome sizing and alignment throughout. The status bar reads 20% larger and the toolbar’s labels 30%. The tool stripe’s icons line up with the first line of code rather than with the tab strip above it, and Quit sits directly above them. Every toolbar control — the project and run-configuration pickers included — is now the same height as the icons beside it, with their own text at a size that fits. Tabs are square, and the hairlines stacked between the toolbar, tab strip, diff viewer and View-Mode banner are gone.
-
The Settings window opens larger (clamped to your screen) so the template, snippet, external-tool and toolbar lists show their contents without scrolling, and each page now opens at its top instead of wherever the previous page was scrolled to.
-
Project, Bookmarks, Structure, Personal Notes and Commit share one font size — the five list tool windows disagreed, so a glance from one to the next changed size. A tool window’s title also matches the stripe button that opens it, icon included.
-
Toolbar regrouped. Undo/Redo is its own group rather than sharing one with the clipboard; Close no longer sits beside Save, where a mis-click discarded the tab instead of saving it; Clear Recent moved inside the Recent dropdown, where it can’t be hit by accident; Recent sits with the project controls and Settings beside About. New File and the page glyph were drawn taller than every other icon and now match. The command palette’s lightning bolt became a
>_prompt, Simple mode’s empty square became a window frame, and Settings’ sun became a cog. -
A side tool window’s header now starts level with the stripe button that opened it. The stripes were inset to line their first glyph up with the first line of code, but the panels beside them were not, so a panel’s header sat a tab strip’s height above its own button. The band across the top of the window is continuous now too — the panel’s top inset was painting white into an otherwise unbroken strip.
-
The overlay popups use the interface font throughout. The command palette’s chord chip, Find in Files’ line numbers and the message log’s timestamps were each the one monospace element in an otherwise Inter card, so they read as a different kind of text rather than part of the same surface. The trade is that timestamps and line numbers no longer sit in a perfectly aligned column, which JavaFX can’t give us without tabular figures.
-
Git status letters (M/A/D/R/U) are bold in the Project tree and the Commit window.
-
Go to Line opens where every other popup does — it was the one overlay centred in the middle of the window.
-
The Maven icon is legible at icon size. It was the official Apache Maven mark, a two-feather illustration whose hairline quills collapsed into a smudge at 19px; it is now a single bold feather.
Performance
-
Typing no longer gets slower the longer you leave Editora open. Every keystroke permanently leaked two JavaFX animation timers through the 80-column ruler, which measured the caret with a zero-width query — and that form makes the editor allocate a throwaway caret whose blink timer nothing ever stops. The timers accumulated as pulse receivers and were never released, so the cost grew with the session and did not recover:
keystrokes pulse receivers median keystroke 0 7 — 500 1,019 6.4 ms 1,000 2,019 11.8 ms 2,000 4,019 28.4 ms Measuring an actual character instead leaves the count flat and the keystroke at about 2 ms however long you type. A benchmark now counts pulse receivers per keystroke so this can’t come back.
-
The packaged app uses a third less memory, with far shorter GC pauses. It shipped with the serial collector, chosen on the reasoning that a mostly-idle editor would get sub-millisecond pauses and a smaller footprint from it. Measured on a real session, none of that held — it sized a ~548 MB young generation it never handed back, against a live set of about 72 MB, and had that much to copy on every collection. Switching to G1 with periodic uncommit: RSS 1130 → 738 MB, longest GC pause 138 → 34 ms (median 91 → 8 ms), startup unchanged. A 138 ms stop-the-world is eight dropped frames on the typing path.
Fixed
-
Sliding along the menu bar switches menus again. On Linux, moving the mouse from one menu to the next often did nothing. A menu popup is a real window, and JavaFX sizes that window to include the drop shadow — so the wide shadow the interface pass gave menus left 26px of invisible but mouse-catching window above every open menu, covering the bar and its neighbours’ titles. The menu’s shadow now falls entirely below it, and the popup starts exactly at the bar’s bottom edge.
-
Running a Java project works from a cold start. Generating a project and pressing Run walked into a chain of separate failures, each of which blamed something that was working correctly:
- “Could not resolve the classpath — make sure the Java project has finished importing”, on projects that
had imported perfectly. Editora never told jdtls which JDKs were installed, so a project asking for a
Java 17 execution environment on a machine with 21 and 25 got an empty classpath and no error. The
installed JDKs are now declared when the server starts, read from each one’s
releasefile rather than by running it. - The same message on a saved configuration, because it hand-built the request from the configuration’s own (usually blank) project name instead of asking jdtls to identify the class, the way Debug and the gutter marker already did.
- “No main class was found in this project” when debugging a saved configuration — jdtls answered correctly and the reply was discarded. Any absolute path in it broke the parse, so this failed on essentially every real project. Classpaths containing a space, comma or bracket were being silently mangled by the same bug.
- “Could not find or load main class” once the classpath did resolve:
archetype:generatewrites sources only and Editora runs jdtls without autobuild, so nothing had been compiled. - “No language server for file”: a background Java file’s server start is deferred until its tab is shown, so the file the launch routed through had never been opened on jdtls even though its tab was.
- “Could not resolve the classpath — make sure the Java project has finished importing”, on projects that
had imported perfectly. Editora never told jdtls which JDKs were installed, so a project asking for a
Java 17 execution environment on a machine with 21 and 25 got an empty classpath and no error. The
installed JDKs are now declared when the server starts, read from each one’s
-
The toolbar’s Stop button is enabled while a program is running. Nothing refreshed it when a run started or finished, so it stayed disabled — and greyed out — no matter what was running.
-
A run configuration added on the Settings page shows up in the toolbar. It was written to disk and then never appeared in the selector, or as a palette command, until the next launch, with nothing logged.
-
Tab on an already-indented line now moves the caret to where you type. Pressing Enter inside a block leaves the new line already carrying its indent, so Tab has no indentation left to add — and it did nothing at all. Going back to the start of that line (
C-a, Home, a click) and pressing Tab left the caret sitting at column 0, which reads as Tab being broken. It now puts the caret at the end of the indent, the way Emacs’ own TAB does. Repeated Tab still refuses to pile on more indentation, and an over-indented line is left alone rather than “corrected”. The same applies with a language server handling the re-indent; on-type formatting is untouched, since that fires while you are typing. -
Java completion no longer leaves placeholder text in your file. A language server can send a completion as a snippet — text with placeholders — and Editora was flattening every one of them into literal characters. jdtls does this everywhere, so:
- Typing
import java.utiand acceptingjava.utilproducedimport java.util.*;with the caret past the semicolon: an on-demand import nobody asked for, and no way to carry on toArrayList. The server had actually sentjava.util.${0:*};— the*is a placeholder meant to be selected. It now is, so typingArrayListreplaces it and you getimport java.util.ArrayList;. - Accepting a method left its arguments as text to delete:
list.addinsertedlist.add(e)with a literale. Now the argument is selected and Tab steps through the rest, soaddAll(int index, Collection c)fills in like any snippet. - The same applies to every other server that sends snippet completions.
- A server that marks an item as a snippet but sends an unescaped literal
$(phpactor’s$user, shell variables) is still inserted verbatim — only a real placeholder starts a snippet. - Bundled snippets ending in
${0:something}also select that text now, instead of leaving the caret in front of it. - No more doubled semicolon. Completing an import a second time —
import java.ut|;, caret before a semicolon that is already there — producedimport java.util.*;;. The server’s replacement range covers that semicolon (which is why its insert ends with one), and Editora was replacing only up to the caret. It now honours the end of the range the server sends, so the old semicolon is replaced rather than kept. The end only ever extends past the caret and never beyond the current line: anything you typed while the popup was open is still absorbed, and a stale range can’t eat the lines below.
- Typing
-
Accepting a completion that adds an import no longer moves your cursor. Typing
List<Itemand hitting Tab insertedimport demo.Inventory.Item;correctly, but then left the cursor at the end of that new import line — so the next thing you typed went into the import statement. The cursor now stays on the identifier you were typing, following its own text down as the import is added above it. -
A long status-bar message no longer squashes the segments beside it. The echo line and the state segments share one row, and when they did not all fit every one of them was shrunk — so a wordy message reduced
LSP: jdtls,Editable, the caret position and the rest to bare ellipses. The message now truncates on its own and the segments keep their full width; the full text is still one click away in the message log. -
Debugging now runs a configuration’s before-launch step. Only the Run path did. A configuration whose before-launch was
mvn -q compiletherefore compiled when you pressed Run and silently debugged the previous class files when you pressed Debug — every breakpoint landing on a stale line number, in the one mode where that is hardest to spot. A failing step now aborts the debug launch, exactly as it aborts a run.