DocumentationEditors and debugging
Guides
Editors and debugging
cstudy stays the judge, and your editor stays yours: editors run cstudy commands, and debuggers attach to the runner that cstudy test --debug starts.
On this page
Any editor
cstudy does not need a particular editor. cstudy start opens the stub and the statement with $VISUAL or $EDITOR, and each language is an ordinary project, so a language server finds it with no extra setup when you open the workspace root:
- Python: the project in
python/, with its virtual environment inpython/.venv. - TypeScript:
typescript/, with its owntsconfig.json. - Java and Kotlin: the Gradle project in
jvm/. - Go:
go.workat the root lets gopls find the module ingo/. - Rust:
cstudy startlists each problem inrust/Cargo.tomlso rust-analyzer checks it.
A terminal editor such as Neovim works the same way: keep cstudy test --watch running in a split, and it reruns on every save.
Project files for VS Code and IntelliJ IDEA
cstudy init writes project files for both editors, so every cstudy action is ready to run. Each action exists in two forms: current file runs on the solution in the editor (cstudy test <file>), and active attempt runs on your active attempt (cstudy test).
| Action | Command |
|---|---|
| Test, perf, typecheck, bench, hint | cstudy test, test --perf, test --typecheck (TypeScript), bench, hint |
| Done | done --rating=ok|easy|hard or --gave-up |
| Submit, status | Project problems: submit, status |
| Solution, show, start | Current file only: solution, show, start --no-open |
| Workspace | next, stats, doctor |
| Debug | test --debug, with a debugger attached to the runner |
The files are yours to edit. cstudy ide brings them up to date after an upgrade: it rewrites only the files still as it wrote them, warns about the ones you changed, and never touches files it did not write, such as a run configuration of your own. cstudy ide --force overwrites your changes too; cstudy ide vscode or idea limits it to one editor.
$ cstudy ide
ide vscode, idea · 1 updated · 1 kept
warning kept .vscode/tasks.json: edited, or not written by cstudy (cstudy ide --force overwrites it)VS Code
- Run: Tasks: Run Task, then a
cstudy …task.doneasks for the rating. - Debug Python, TypeScript, Java, Go or Rust: set a breakpoint, open the solution, and start Debug current file (Python) (or TypeScript, Java, Go, Rust) from Run and Debug. Its task starts
cstudy test --debug, and the debugger attaches once cstudy prints that it is waiting. - Set up for you: the interpreter in
python/.venv, TypeScript fromtypescript/node_modules, the Gradle import ofjvm/, Go tools withGOTOOLCHAIN=local,rust/Cargo.tomlfor rust-analyzer, and recommended extensions: Python, Debugpy, Java, Gradle, Go, rust-analyzer and CodeLLDB.
Kotlin
Kotlin runs and tests in VS Code but cannot be debugged there, because the Java debugger does not bind Kotlin breakpoints. Debug Kotlin in IntelliJ IDEA.
Run cstudy doctor --fix before opening the workspace, so python/.venv exists. The Java extension needs a JDK 21, through JAVA_HOME or its own setting.
IntelliJ IDEA
- Run: pick a configuration in the folders
cstudy: current file,cstudy: active attempt,cstudy: workspaceandcstudy: debug. Current-file configurations go through a small launcher in.cs/runtime/ide/, because IntelliJ’s shell configurations cannot pass the open file. - Debug Java or Kotlin: set a breakpoint, then Debug (not Run) Debug current file (Java, Kotlin). It starts Debug JVM (listen) on port 5005 and
cstudy test --debug --debug-connect, whose JVM connects to it. The listener restarts itself, so you can leave it running. - Set up for you: the project JDK named
21and the Gradle projectjvm/. - Go and Rust run from the same configurations, with the Go or Rust plugin. Python and TypeScript run too, but debugging them is not set up: debug those in VS Code.
Once, by hand: accept IntelliJ’s prompt to set up the missing SDK 21 (or add one in Project Structure > SDKs), and click Load Gradle Project when it offers to.
Debugging with --debug
cstudy test --debug runs the normal judged run with the runner waiting for a debugger. Breakpoints in your file stop the real runner, and the verdict comes when the run ends. Your IDE configurations do this for you; from a terminal, start the run and attach any client of the language’s debug agent.
| Language | Agent | Default port | Needs |
|---|---|---|---|
| Python | debugpy | 5678 | debugpy in python/.venv; cstudy doctor --fix installs it |
| TypeScript | Node inspector | 9229 | Node 24 |
| Java, Kotlin | JDWP | 5005 | JDK 21; --debug-connect connects to a listening IDE instead |
| Go | Delve, headless | 2345 | go install github.com/go-delve/delve/cmd/[email protected] |
| Rust | debugserver (macOS) or lldb-server (Linux) | 12345 | Xcode Command Line Tools on macOS; CodeLLDB in VS Code |
Once the agent listens, cstudy prints one line to standard error. IDE tasks wait for it, and so can your own scripts:
cstudy: waiting for debugger on 127.0.0.1:5678 (python)
cstudy: waiting for debugger on 127.0.0.1:9229 (typescript)
cstudy: waiting for debugger on 127.0.0.1:5005 (java)
cstudy: waiting for debugger on 127.0.0.1:2345 (go)
cstudy: waiting for debugger on 127.0.0.1:12345 (rust)
cstudy: connecting to debugger at 127.0.0.1:5005 (kotlin)What changes in a debug run
- No time limits and no hang guard, since pauses at breakpoints would count. The report has no durations.
- A concurrent problem runs its ordinary cases only; stress runs are skipped while debugging.
- The run is not recorded and opens no level. A pass ends with
all passed (debug run: not recorded; cstudy test records the run). --watch,--perf,--json,--stress,--seedand--time-limitcannot be combined with it.--debug-port Npicks another port.- On a project problem,
--debugstops in the project’s code and its tests. Go debugs one package’s tests; Rust runs each test as its own process, so a debug run runs one test: the first that--caseselects, or the first of the suite.
Written for cstudy 0.8.0. The specs in the cstudy repository are the source of truth for every detail.