Skip to content

Add a scijava-code-lsp ScriptDialect - #14

Draft
gselzer wants to merge 28 commits into
masterfrom
lsp-completion
Draft

gselzer wants to merge 28 commits into
masterfrom
lsp-completion

Conversation

@gselzer

@gselzer gselzer commented Oct 21, 2026

Copy link
Copy Markdown
Member

This PR adds a org.scijava.code.lsp.ScriptDialect that describes how to convert a SciJava Jython script to plain jython code.

See scijava/scijava#294 for discussion

ctrueden and others added 28 commits June 21, 2026 21:27
Port the Jython completion engine from the (now-retired) script-editor-jython
repo into this scripting plugin, so Jython provides both its ScriptLanguage and
its CodeCompleter while depending only on scijava-common + jython — no Swing or
RSyntaxTextArea.

- JythonCodeCompleter: a CodeCompleterPlugin that derives the line context from
  a CompletionRequest and returns neutral Completions + a ParameterChoices.
- JythonAutoCompletions: the analysis engine, emitting neutral
  org.scijava.script.complete.Completion (no RSTA), with auto-imports expressed
  as Completion.TextEdit and parameter assistance via ParameterChoices.
- JythonScriptParser/Scope/DotAutocompletions* and an internal CompletionText:
  unchanged AST logic, with class discovery/javadoc via scijava-common's
  ClassIndex.
- The legacy RSTA glue (LanguageSupportPlugin, AutocompletionProvider,
  AutoCompletion, FunctionCompletion) is dropped; syntax highlighting moves to
  script-editor. The hardcoded ImageJ ij.dir scan is replaced by locating the
  jython jar on the classpath.

Adds an antlr-runtime dependency (Jython AST) and a temporary scijava-common
version override until a release pins the new completion SPI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Still need a version newer than pom-scijava though
TODO: Need to understand
Find the call around the caret, take the callee's overloads from the
completion engine (methods before the "(", constructors after it), type
the arguments with the engine's own inference, and rate the overloads
with code-api's Signatures. This replaces the TypeResolver, which
code-api no longer has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
If a Python language server is offered (see code-lsp's LspService), its completions follow Jython's own: for Python modules, and for Java classes from Python stubs of the packages the script imports and its parameters' types (JavaStubs, written by reflection in the background, with the packages their signatures refer to). JythonDialect declares parameters as Python types for the server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JythonLanguageServer (JythonServerPlugin) replaces JythonCodeCompleter, with the same engine, now producing LSP completions (methods and constructors as snippets with typed label details). In a call's arguments, with nothing typed, the variables of the parameter's type come first. JythonPythonServerPlugin offers a Python language server (if one is, e.g. by scripting-appose-python) for Jython scripts, with the Java stubs as search path and without its problems; the language server service merges its completions after Jython's own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its remaining types (ScriptDocument, ScriptDialect, ClassIndex,
Signatures, Environment) come from scijava-code-lsp, and script
parameters from the LanguageServerService.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
code-lsp's signatures no longer carry their fit; the best fits still
come first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
code-lsp no longer merges several plugins' servers. JythonServerPlugin
now gives JythonLanguageServer a PythonCompanion (jedi, if offered):
Jython's completions first, then jedi's for other names; jedi's
signatures and hover where Jython has none; Jython's problems only.

Stubs are written as scripts open and change, rather than whenever
where they run was asked; and jedi's environment is the stubs alone, so
interpreters share the editor's jedi.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both are ordered places imports are resolved from; each server reads
them as its language does. Nothing read the classpath.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jython's analysis and the Python server beside it now read the same
text, which the session makes in JythonDialect: parameters are
declared as instances of their classes (e.g. img = net.imglib2.img.Img()),
which both understand. So the server no longer reads #@ lines, and
PythonCompanion no longer transforms scripts for jedi.

Jython's analysis now resolves classes by their full names, and the
stubs follow imports separated by semicolons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jython hands scripts Python values for strings, numbers and booleans
(e.g. a java.lang.String becomes a unicode, whose Java methods fail),
and array.array for arrays. Declaring them so, Jython's analysis no
longer offers Java members that fail at run time (e.g.
name.toUpperCase), and jedi sees the same types as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
E.g. a package imported only to declare a parameter's type is no
longer offered (see ScriptDialect#imported).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The completion classes move to the completion package, with their
tests.

The Python server beside Jython's analysis now comes from
scijava-code-lsp-jedi (a runtime dependency), rather than from
scripting-appose-python; tests run without it, so that they need not
build its environment.

Also follow code-lsp's API: the plugin serves the jython LSP language
(not python, which it builds on), and the companion asks whether python
is served rather than catching its absence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
code-lsp's sessions ask for the LSP language named as the script's
language, in lower case, so the plugin no longer declares the script
language it serves separately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JythonDialect is now a ScriptDialect plugin, showing Jython scripts to
scijava-code-lsp-jython's server as plain Jython. Jackson is pinned to
2.19.2, which code-lsp-jedi now brings in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JythonDialectTest keeps what needs SciJava scripts (#@ parameters).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dialect writes its imports and declarations in one header line, and
names the packages it imports only for them, to hide from completion.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The dialect names its server only by language id: applications choose
their servers, as scripting-groovy now has them do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
scijava-code-lsp-jython now analyzes Jython with jedi-language-server,
whose completions are labeled by name alone (e.g. "upper", not
"name.upper").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants