Editora 0.22.0 docs. You are reading an archived version, kept so links from that release keep working. Read the 0.23.0 docs →

Running & debugging

Running files

You can run compact Java files, Python scripts and shell scripts with language services disabled. A green ▶ appears in the gutter of a runnable file:

  • a Java compact source file (JEP 512, a .java with a top-level void main) or an extensionless Java file with a java --source 25+ shebang,
  • a Python script (the ▶ sits on the if __name__ == "__main__" guard), or
  • a shell script: .sh, .bash, .zsh, .ksh and the other shell types, or a file whose shebang names a shell (see Shell scripts). Startup files that a shell reads rather than runs, such as .bashrc, .profile, .zshrc, .bash_logout, .xinitrc and .envrc, get no ▶.

Click the ▶, use the right-click Run File, or bind file.run (C-c r). Output streams to the Run tool window (M-9), which accepts stdin so console-style programs work. Double-click a stack-trace line to jump to the file and line: Java, Python and Node frames, and shell errors such as deploy.sh: line 12: ….

The console reads the terminal codes programs print: colours are drawn in the theme’s colours, a carriage return (\r) rewrites the current line so a progress bar stays on one line, and clear empties the console. Other cursor codes are dropped. Stop ends the program and everything it started, and the console then says Stopped. End Input in the console’s header, or Ctrl+D in the empty input field, closes the program’s input, so a loop that reads lines until the end of input can finish (Run: End Program Input, run.endInput).

While a program runs, a small spinner turns beside the Run window’s status, from the launch (including a configuration’s before-launch command) until the program exits, is stopped, or fails to start, so a script that prints little does not look stalled. The Run button on the tool-window stripe badges the same spinner on its icon, which shows a run is alive with the Run window closed or another window open in its place.

A clicked Java frame in the Run, Test or Build console is resolved by the language server, so a frame inside a dependency or the JDK opens its source instead of reporting “not found”. Frames in your own code open as usual, and filename matching handles anything the server can’t place, plus every non-Java trace.

Pass per-file program arguments with file.runWithArgs (remembered across runs and reused by the debugger), and repeat the last run with run.rerun. Rerun first saves the file it runs, even when another tab is in front. Arguments are split the way a shell splits them: quote an argument that contains spaces ("two words" or 'two words'), and put a backslash before a space, quote or backslash to keep it (O\'Brien). Inside double quotes, \" and \\ are escapes; a backslash before any other character stays, so a Windows path such as C:\tools\x.exe is kept as typed. An unclosed quote stops the run with a message instead of joining the rest of the line into one argument. $NAME in an argument is passed as written. Running a Java file needs JDK 25 or newer. Editora uses the selected Default JDK when one is configured, or java on your PATH, and checks that exact launcher before running. An extensionless shebang can request a newer source release.

For Maven projects, Settings → Languages & Tools → Build Tools → Default JDK selects the toolchain used by Run, Debug, Maven classpath resolution, Maven tasks, and before-launch steps. Installed JDKs are discovered from the usual platform locations and common version managers. A run configuration’s JDK field can inherit that choice or override it for one configuration. The Default JDK also applies to standalone Java Run and Debug.

Shell scripts

A shell script runs under the interpreter its shebang names, as ./script would in a terminal, with the shebang’s options:

First lineRuns
#!/bin/bash -eu/bin/bash -eu script
#!/usr/bin/env -S bash -ebash -e script
#!/bin/sh/bin/sh script
#!/usr/bin/env zshzsh script
#!/usr/bin/env python3python3 script
nonebash script, or zsh for a .zsh file

The env forms are read as env reads them: env -u NAME runs the script without NAME set, and env -C DIR runs it in that folder (Run reports a folder that does not exist). #!/bin/busybox sh runs busybox’s shell. When an interpreter path in the shebang does not exist on this machine, Run uses the command of that name on your PATH instead. A run configuration can set its own interpreter.

A shell run gets TERM=xterm-256color, so scripts that ask tput for colours get them. When a bash script asks a question with read -p "Name: ", the prompt shows in the console, although bash prints such prompts only to a terminal; type the answer in the input field.

If the script has Windows (CRLF) line endings or starts with a byte-order mark, Run warns first, because bash then fails with errors that never mention the cause. Convert and Run saves the file with LF line endings (and UTF-8 without a byte-order mark) and runs it; Run Anyway runs it as it is. When .editorconfig requires CRLF for the file, only Run Anyway is offered.

On Windows, bash and sh come from Git Bash: the one beside the git.exe on your PATH, then a standard Git for Windows install, then any other bash on your PATH (MSYS2, Cygwin). The WSL launcher in System32 is never used, because it cannot open a Windows path. Lines typed into the console reach the script with Unix line endings.

Shell scripts can’t be debugged; use Run with Trace to see each line as it runs.

Run with Trace

Run: Run with Trace (run.trace, also in the Run menu and the editor’s right-click menu on a shell script) runs the active shell script with -x, keeping the shebang’s interpreter. Under bash, each command is printed before it runs with its file and line:

+/home/me/deploy.sh:12: tar czf site.tgz public

Double-click a trace line to open that line. Trace lines are drawn muted, not as errors. A script run by sh or dash is traced too, but its trace lines carry no file and line, because those shells can’t print them. zsh scripts and scripts in other languages can’t be traced.

To trace a run configuration, put -x in its Interpreter options; the trace lines link to their source the same way.

Running on a remote host

A file in a remote folder runs on its host, when that host may run commands; otherwise Run says so when you launch it. That covers Run on a file, a Java project’s main class (the gutter ▶, Run Main Class, or a saved configuration, with the class path the host’s jdtls or Maven gives), and script, make and npm configurations of a remote project. A shell script runs under the interpreter its shebang names, found on the host, and Run with Trace works there too; the read -p prompts described above show only for a local run. Output, input and Stop work as for a local run, over the same SSH connection, and a makefile at a remote project’s root shows the run-configuration toolbar as it does locally. A configuration’s working directory is a folder on the host.

The host’s own java is used, or the JDK home set for that host in Settings → Remote. Your local Default JDK and a configuration’s JDK override are paths on this machine, so they are not sent to the host.

Running in a container or WSL

A project whose tools run in a container or, on Windows, in a WSL distribution runs its programs there: Run on a file, a main class, and every kind of run configuration, with the java, interpreters and environment the container or distribution has. Output, input and Stop work as for a local run, and Stop ends what the program started inside. The files are handed over by the names they have inside, and a configuration’s absolute working directory is read as a folder there.

Running a project’s main class

Beyond single files, Run: Run Main Class… (run.mainClass) and Debug: Debug Main Class… (debug.mainClass) pick any main class in the active file’s Maven or Gradle project and run it in the Run console or debug it with breakpoints. A green ▶ also appears in the gutter next to every public static void main, and the editor right-click menu offers Run ‘….main()’ and Debug ‘….main()’.

There are two paths under that, picked automatically:

  • With the Java language server set up, Editora asks it for the project’s main classes and resolved classpath. This is the fast, project-wide path, and it is the only one that can debug.
  • Without it, plain Run falls back to the build tool: Maven resolves the classpath (mvn compile dependency:build-classpath) and runs the file’s main, and Gradle delegates to its run task, or bootRun in a Spring Boot project. In a multi-module Maven build the fallback runs from the reactor root with -pl <module> -am, so a submodule that depends on an uninstalled sibling still runs.

Run configurations

A run configuration saves how something is launched: a name, what to launch, program arguments, VM arguments, environment variables, an optional JDK override, and a working directory.

Run configurations belong to a project: each project window keeps its own list. The No Project window has none; there, a script or a compact Java file runs from its gutter ▶ or File: Run (file.run), as described in Running files.

Environment takes KEY=value pairs, quoted and escaped like program arguments. $NAME and ${NAME} in a value expand to that variable: one set earlier in the same field, or else the environment the program would get anyway, so PATH=/opt/tools/bin:$PATH adds a folder to the real PATH. Single quotes keep $ as it is. In a remote project, a variable that is not set earlier in the field is passed to the host as written.

A relative Working directory is relative to the project root. Run names a working directory or script that does not exist, and opens the configuration at the field to fix.

What a configuration can launch

Pick a Type in the project’s Run Configurations window:

TypeLaunches
Java main classa main in the project, via the language server or the build tool
Python scripta .py file with your python3
Shell scripta script with the interpreter its shebang names (or bash), unless Interpreter is set
Make targeta target in a makefile
NPM scripta named package.json script via npm run

The form shows only the fields the selected type uses. A Java main class has no Script / target field; a Python, shell, Make or NPM configuration has no Main class, Module, VM arguments or JDK. A hidden field keeps its value, so switching the type and back loses nothing. A Python or shell script can be picked with Browse… beside Script / target; a script inside the project is saved relative to the project root.

A shell configuration also has Interpreter and Interpreter options. Left blank, the script’s shebang decides (see Shell scripts); set, they replace it, for example /opt/homebrew/bin/bash with -eu. Options alone keep the shebang’s interpreter and replace its options.

Script and make configurations need no language server. Only Java configurations can be debugged; Debug on any other type says so, and for a shell configuration it points to Run with Trace.

The toolbar selector

The toolbar carries a configuration dropdown with Run, Debug and Stop beside it; your choice is remembered across restarts. The dropdown ends with Edit Configurations…, which opens the separate Run Configurations window with the configuration you had selected already picked out. The same window is available as Run: Edit Run Configurations… (run.editConfigs).

Starting a file or configuration always opens and focuses the Run tool window. If that process is already active, Run brings its existing console back instead of hiding the useful output behind a busy message.

The group only appears in a project window where you could launch something: a Maven, Gradle, npm, Cargo or Go build file inside the project, or a makefile at its root. Anything you have already saved keeps the group visible regardless, because a configuration only needs a main method and a plain Java folder can hold one. The palette commands work in any project either way. The No Project window never shows the group, and its run configuration commands say to open a project.

Each configuration also becomes a real command, so it appears in the palette by name and can be given its own keyboard shortcut in Settings → Keymaps, the same way saved macros and external tools work.

A step before the launch

A configuration can name a command to run first, such as a build or a codegen step. A non-zero exit aborts the launch, so a stale binary is never run by accident.

Sharing them with your team

ActionCommand
Write them into the projectrun.exportConfigs
Merge the project’s back inrun.importConfigs

Export Configurations to Project writes them to .editora/run-configurations.json inside the project, where they can be committed alongside the project’s committed settings. Import merges them back by name, so importing twice doesn’t duplicate and a colleague’s edit updates a configuration rather than doubling it.

Creating and editing them

The Run Configurations window (run.editConfigs, or Edit Configurations… in the toolbar dropdown) is a master-detail editor for the list, and Run: Save Run Configuration… creates one from the palette; Run: Run Configuration… runs one and Run: Delete Run Configuration… removes one.

Add starts from the file you are looking at rather than a blank entry. For an active Python or shell script it adds a configuration of that type for the script, named after the file. For a Java file it prefills the main class from the active Java file (or the one your Gradle build declares as mainClass, mainClass.set(…), or the legacy mainClassName), names the configuration after that class, and puts the cursor in whichever field still needs you. Adding twice from the same file gets you “App” and “App (2)” rather than two entries sharing a name.

Run: Save Run Configuration… saves the active Java file’s main class, or the active Python or shell script, with the file’s program arguments.

Running an incomplete configuration opens its form at the field you need to fill in, rather than naming the problem and leaving you to find it. VM arguments and environment variables apply to both Run and Debug. Before a script configuration runs, Editora saves that script if it has unsaved edits in any tab.

A saved configuration does not depend on which tab is in front: any open Java file in the project serves, and it reports an error only when there isn’t one.

Debugging

Beta

Editora debugs Java, Python, and JavaScript (Node) through the Debug Adapter Protocol, with an IntelliJ-style Debug tool window (M-g d). Debugging is off by default; enable it in Settings → Debugging. Shell scripts can’t be debugged; Run with Trace shows each line of a script as it runs.

ActionCommandDefault key
Start / continuedebug.startC-c C-d d
Continuedebug.continueC-c C-d c
Pausedebug.pauseC-c C-d p
Stopdebug.stopC-c C-d k
Restartdebug.restart(palette)
Step overdebug.stepOverC-c C-d n
Step intodebug.stepIntoC-c C-d i
Step outdebug.stepOutC-c C-d o
Run to cursordebug.runToCursorC-c C-d u
Jump to linedebug.jumpToLineC-c C-d j
Toggle breakpointdebug.toggleBreakpointC-c C-b
Edit breakpointdebug.editBreakpointC-c C-d e
Break on exceptionsdebug.toggleExceptionBreakpoints(palette)
Debug a project main classdebug.mainClass(palette)
Debug a saved run configurationdebug.config(palette)
Debug via build tooldebug.viaBuild(palette)
Attach to a running JVMdebug.attachC-c C-d a
Turn the Python or JavaScript adapter on or offdebug.toggleAdapter(palette)
Set an adapter’s pathdebug.setAdapterPath(palette)

The keys are the Emacs keymap’s; the step commands are also buttons in the Debug window.

The Debug window has a threads and call-stack view, a lazy variables tree with set-value, watches, and an evaluate console. While suspended, inline values appear after each line and hovering a variable shows its value. Breakpoints live in a leftmost gutter strip and are saved per project. Edit Breakpoint is a form for all three: a condition, a log message (which turns it into a logpoint that logs and never suspends), and an enabled toggle. Breakpoints in closed files are honored too.

While a session runs, a breakpoint the debugger has not verified (its code is not loaded yet, or the line has no code) is drawn as a hollow ring, with the debugger’s explanation on hover. Every breakpoint is hollow from the start of the session until the debugger answers, and the markers return to normal when the session ends.

When the panel is wide enough, the call stack, variables, and console sit side by side; they stack when it is narrow. The call stack lists the innermost 1,000 frames when the adapter supports partial stacks. The console is cleared at each launch and kept after the session ends, and its right-click menu has Clear Console. Restart is disabled for a debugger attached to a test or build run (its tooltip says why); a session started with Debug → Attach can still be restarted.

A spinner beside the Debug window’s status turns while the before-launch build, the session start, or the program is running, and stops while the program is paused (at a breakpoint, a step, or Pause).

Program input in the Debug console

A debugged Java program can read its standard input from the Debug console. The field does one of two things, and its prompt says which:

  • While the program runs, Enter sends the line to the program (an empty line counts).
  • While it is paused, Enter evaluates an expression.

End the input with Ctrl+D in the field, the console’s right-click menu, or Debug: End Program Input (EOF) (debug.endProgramInput).

In this mode Editora starts the Java program itself rather than leaving it to the debugger, and stops it on Stop, Restart, a new launch, a failed launch, or closing the window. The session ends when the program exits, after its last output, and the console reports the exit code. Lines written to stdout and stderr at almost the same moment can appear in either order.

It is on by default. The switch is under Settings → Debugging → Java (or Debug: Toggle Program Input in the Debug Console, debug.toggleProgramConsole) and takes effect at the next launch. Attached sessions, Python, and JavaScript are unaffected. It has not yet been confirmed on Windows.

Compact .java sources and extensionless Java --source 25+ shebang files can be debugged with breakpoints, stepping, and local variables. Editora maps breakpoints and stack frames to the original file and removes its temporary compiled files after the session. Java debugging needs the Java language server and debug adapter described below.

JUnit tests are debugged from their gutter icon or with Debug Test at Caret, including tests inside @Nested classes; see the test runner.

When the Debug panel has the keyboard (it shows an active-focus highlight), gdb-style single keys drive the session: n to step over, s to step into, f to finish (step out), and so on. Stepping keeps focus in the panel, so you can step repeatedly without your key presses landing in the editor. A fresh breakpoint hit while you’re editing still takes you to the code.

Debug via the build tool

Some applications are meant to be started by the build tool rather than by a bare java command. Debug: Debug via Build Tool (debug.viaBuild) launches the app under a suspended JVM through Gradle (run or bootRun with --debug-jvm) or, for a Spring Boot Maven project, spring-boot:run with a JDWP agent. Editora watches the build output for the JDWP banner and attaches the debugger when the app is listening. It complements Debug Main Class, which uses the language server; a plain Maven main has no uniform build-tool debug mechanism, so use Debug Main Class there.

Debugging on a remote host

A file in a remote folder is debugged on its host, when that host may run commands, with breakpoints, stepping, variables and the call stack as for a local file. Breakpoints of a remote file are kept across reconnects.

  • Python runs debugpy on the host, which needs its own (pip install debugpy).
  • JavaScript runs vscode-js-debug and node on the host.
  • Java in a Maven or Gradle project goes through the host’s jdtls: Debug, Debug Main Class, Attach (where localhost is the host), Debug Test, and a saved configuration. Editora copies its java-debug plugin to ~/.cache/editora on the host. A Java file outside a project is compiled on the host for the debugger.

The adapters’ locations can be set per host in Settings → Remote (Python for debugging, js-debug server, Node.js, java-debug plugin jar). Other languages cannot be debugged on a host yet.

Debugging in a container or WSL

A project whose tools run in a container or in a WSL distribution is debugged there, as on a remote host: Python with the debugpy installed there, JavaScript with vscode-js-debug and node there, and Java through the jdtls running there, with Editora’s java-debug plugin copied into ~/.cache/editora. A Java file outside a project is compiled there for the debugger. The debugger’s port inside is reached from here whatever the container’s network, through a relay that needs nc, bash or python3 inside (see Ports and debuggers).

Installing adapters

Adapters are not bundled. Three palette commands download each language’s adapter, together with its language server, into your config folder:

CommandInstallsNeeds
Install: Java Language Support (install.javaSupport)jdtls and the Microsoft java-debug plugintar, and a JDK to run jdtls
Install: Python Language Support (install.pythonSupport)Pyright and debugpyNode.js with npm, and Python with pip
Install: JavaScript / Node Language Support (install.jsSupport)typescript-language-server and vscode-js-debugNode.js with npm, and tar

Editora does not install those runtimes for you. A downloaded server or adapter is unpacked beside the installed version and replaces it only once it is complete, so a failed install leaves the working one in place.

To install an adapter by hand instead, the Editora repository has a helper script for each:

  • Java: the Microsoft java-debug plugin (layered onto jdtls), scripts/install-java-debug.sh. If your jdtls distribution already bundles and loads java-debug itself (Homebrew’s does), Editora detects that and needs no second copy.
  • Python: debugpy, scripts/install-debugpy.sh.
  • JavaScript: vscode-js-debug, scripts/install-js-debug.sh.

The Settings → Debugging page shows a live found/not-found status for each.

For sending HTTP requests from .http files, see the HTTP client. For Maven, npm, Cargo, Go, and Gradle tasks, see Build tools. A build task that would run a project’s own ./mvnw or ./gradlew asks you to trust the folder first.