GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Add a scijava-code-lsp ScriptDialect by gselzer · Pull Request #1 · scijava/scripting-appose-python

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 Appose Python script to plain python code. There's likely a lot of cleanup to be done here - claude had a big hand in making this code and may have touched some unnecessary files.

See scijava/scijava#294 for discussion

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
gselzer and others added 30 commits October 6, 2026 10:49
@gselzer @claude
Provide code completion
a308f24
Complete code in appose-python scripts in two layers:

* tree-sitter, in process: names in scope, script parameters, task,
  builtins and keywords, instantly and without any Python.
* Jedi, in a small tooling environment of its own (built in the
  background on first use), analyzing scripts against their own
  environment's interpreter: members, module contents, signatures and
  documentation. Answers come without blocking typing, as updates;
  documentation is fetched on demand.

Completion never builds a script's environment or disturbs its worker:
environments built earlier (in any session) are found read-only.
Dependencies a script declares but its environment lacks are installed
for completion only, into a separate overlay directory, once they stop
changing. Signature help comes from Jedi.

Also extract the engine's environment resolution into ScriptEnvironment,
shared with completion, and add ResidentWorkerService#find, a lookup
that never replaces a running worker.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Build Jedi's source from a ScriptDocument
526729e
The parameter preamble becomes ApposePythonDialect, and where the script runs (its environment's Python, its overlay) an EnvironmentContext. The preamble now lists imports first and task last.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Complete via jedi-language-server
e2b486c
The Jedi tasks (JediClient, jedi_complete.py) give way to jedi-language-server, run from the tooling environment via code-lsp's LspClient; PythonLspClient reads its Python signatures. Tree-sitter's completions, dependency overlays and script environments stay as they were: the overlay and the environment's Python become the server's extra path and environment.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Offer hover and diagnostics from jedi-language-server
3ef818c
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Offer jedi-language-server as the Python language server
5fd45f7
ApposePythonLspServerPlugin offers it via code-lsp's LspService, for this completer and others (e.g. Jython's); PythonLspClient moved to code-lsp.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Fix image parameters, and orphaned servers
1d07b04
The tooling environment gets NumPy: script parameters typed as NumPy arrays (e.g. images) were unknown to the server until the script's own environment was built, so 'image.' offered nothing from it.

jedi-language-server is started via a launcher that exits once this JVM is gone: the server does not notice by itself, and on Windows then loops, failing to write to the closed pipe, flooding its log (which now starts anew beyond 5 MB).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Serve appose-python as language servers
d43e685
Completion now comes from two lsp4j language servers, which code-lsp's
LanguageServerService merges: PythonSyntaxServerPlugin (tree-sitter:
instant names, parameters, builtins and keywords) and JediServerPlugin
(jedi-language-server, against the script's environment plus overlays,
seeing the script as plain Python). ApposePythonEnvironments holds what
the completer knew about environments; ApposePythonCodeCompleter, and
its merge and time budget, are gone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Move off scijava-code-api, now removed
5ecc6a0
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 <[email protected]>
@gselzer @claude
Tell language servers when script environments change
a6fa199
A script's environment can become available without the script
changing: when a script run builds it, or when packages it declares are
installed for completion. ResidentWorkerService now notifies listeners
of finished builds, and DependencyOverlays of ready overlays; the jedi
plugin passes both on to LanguageServerService.environmentsChanged(), so
open scripts move to the servers of where they run now. Tests ask
through script sessions.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Take over the Python completion front from code-lsp
4142f8f
PythonCompletionServer (with DelegatingLanguageServer) completes Java
members on objects jedi cannot see into. It is specific to Python, so
it lives here now, with the one plugin using it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Follow code-lsp's packages by purpose
4b4e8bc
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Set script files as suppliers in tests
42c0286
ScriptSession.setFile(File) is gone from code-lsp.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Take completions as one answer in tests
c1be7b6
code-lsp's merged completions now come once all servers have answered.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Combine jedi and the syntax-only server in one server
0fc15fc
code-lsp no longer merges several plugins' servers, nor moves scripts
between them. ApposePythonServerPlugin now offers one server,
ApposePythonLanguageServer: jedi's completions first, then the syntax
server's for other names; jedi's signatures, hover and problems, else
the syntax server's. It moves each script to a jedi of where it runs as
that changes (as its metadata is edited, or its environment is built).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Unify Environment's search paths and classpath
dabdd81
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 <[email protected]>
@gselzer @claude
Serve plain Python: sessions declare the parameters
105b768
Jedi and the syntax-only server now read the text the session makes in
ApposePythonDialect. The syntax server no longer reads #@ lines: it
finds the parameters and task among the names declared, with the
types they are annotated with.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Name what the declarations import, so it is not completed
d752803
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 <[email protected]>
@gselzer @claude
Follow ScriptDialect and ScriptDocument into code-lsp's core package
35543a2
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Offer jedi-language-server as a ServerProcessPlugin
54899bc
code-lsp now runs server processes from ServerProcessPlugins, replacing
its launch package. JediLanguageServerSpec becomes
JediServerProcessPlugin, a plugin that starts jedi-language-server in
the tooling environment; ApposePythonLspServerPlugin, which offered the
spec, is gone, and ApposePythonEnvironments gives just the tooling
Python.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Gather the completion code into the completion package
2b09eb2
The language server plugin, its server, the environments it analyzes
scripts against, jedi-language-server's plugin and the syntax-only
server join the rest of the completion code (and their tests, the
rest of its tests). The python package keeps what runs scripts.

ScriptEnvironment, which both resolve scripts' environments with, is
public now; so is what completion uses of it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Fold PythonSyntax into PythonSyntaxLanguageServer
342671d
The syntax-only server was its analysis's only user, so the two are
one class now: the analysis (analyze, Context, Kind) is package-private,
for the tests. The dialect is the plugin's, so ApposePythonServerPlugin
keeps it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Fold DelegatingLanguageServer into PythonCompletionServer
fa75940
PythonCompletionServer was the only server built on it, so it passes
on what it does not change itself.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Complete Appose Python with jedi alone
9552b91
The syntax-only server (tree-sitter) answered only when jedi had failed,
or with names jedi had not completed: completions waited for jedi
anyway. Gone with it are the merging of the two servers' answers, the
fallbacks from jedi to it, and the tree-sitter dependencies.

Without jedi, the plugin no longer serves Appose Python at all.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Choose each script's environment as it is analyzed
4cbc7e3
ApposePythonEnvironments now gives the environment of each script as
code-lsp asks, before each request, so the script moves to another
jedi process once its environment is built or its overlay is ready.
This replaces the router that relocated scripts between servers, and
the listeners that told it to; PythonCompletionServer becomes
ApposePythonLanguageServer in its place.

Empty answers are no longer reused, as Jedi may know more once asked
again (e.g. after a new dependency's overlay is ready). Everything but
the two plugins is now package-private.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Get jedi from code-lsp-jedi; route scripts between its servers
cd8b723
jedi-language-server is now offered by scijava-code-lsp-jedi (a runtime
dependency), so JediServerProcessPlugin goes; the tooling environment
here only installs dependency overlays.

code-lsp's servers now analyze scripts in one environment each. Since a
script's environment is in its text, and changes as it is edited, the
new RoutingLanguageServer keeps a Python server per environment and
moves each script to the one where it runs now, as asked before each
request (and closes servers left without scripts).

Also follow code-lsp's API: plugins say which LSP language they serve
(appose-python), and ask whether python is served rather than catching
its absence.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Serve the script language by its name, as code-lsp now asks
3a784e5
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 <[email protected]>
@gselzer @claude
Offer only an Appose-Python dialect: completion moves to code-lsp-jedi
856b76f
ApposePythonDialect is now a ScriptDialect plugin: it shows scripts as
plain Python and says which built Appose environment each runs in.
The tuned server, the overlays and the routing moved to code-lsp-jedi
and code-lsp.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Test only Appose specifics: plain Python's tests move to code-lsp-jedi
27e57f7
The completion integration test keeps script environments, image
parameters and problems after #@ lines.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Follow scijava-code-lsp's rename of runtimeType to parameterType
e631dcf
Parameter types are never null, so stop checking for null.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Follow scijava-code-lsp's ScriptDialect.header
048fae7
The dialect writes its imports, its parameters' declarations and the
task's in one header line, and names what it imports only for them, to
hide from completion. Its tests now test each of its methods.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
gselzer and others added 5 commits October 16, 2026 17:29
@gselzer @claude
Need scijava-code-lsp-jedi only to test
9664a7c
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 <[email protected]>
@gselzer @claude
Follow scijava-code-lsp: an Optional file, and a non-null live state
f47ea10
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Analyze scripts with the packages they declare, as the dialect says
b9d633e
The overlays of packages a script declares, but its environment lacks,
move here from scijava-code-lsp-jedi, whose servers now analyze scripts
in exactly the environment they are given: ApposePythonDialect includes
them in the environment it reports. They are installed with Appose's uv.
Also follows scijava-code-lsp: sessions are made with the service.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Prebuild script environments for completion, not overlays
cd073e6
Completion now builds the environment a script declares, in the
background, once its configuration has stayed the same for a while
(ApposePythonEnvironments): waiting for a script running in it first,
and replacing its worker, as the script's next run would. Completion
then analyzes the script there, conda packages and environment files
included; and the next run need not build it. So the dependency overlays
are gone.

Also, an environment is no longer rebuilt in place while a worker of its
earlier configuration may still be running: ResidentWorker.release()
says when its process has ended, which LazyEnvironment waits for; and
files of an environment being built are not used. Workers are made in
one place (ScriptEnvironment.worker).

FIXME: unsaved scripts are named differently by completion and by runs
from the script editor, so a run builds another environment.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Follow scijava-code-lsp's sessions and environments
5cd99d0
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer gselzer changed the title Lsp completion Add a scijava-code-lsp ScriptDialect Oct 21, 2026
gselzer and others added 5 commits October 23, 2026 12:48
@gselzer @claude
Follow scijava-code-lsp's ScriptDialect.header Variables
3d971b4
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
POM: say when scijava-common 2.101.0 needn't be pinned
7723894
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Test completion with ty, rather than jedi-language-server
e50a0ac
scijava-code-lsp-jedi is gone; scijava-code-lsp-ty serves Python now.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
Assign the parameters the completion header declares
d25fb2b
The header declared each parameter by annotation only, e.g.
"image: numpy.ndarray". Some servers (e.g. ty) take a name that is only
annotated to be unbound, and complete none of its members; so each is
now also assigned, e.g. "image: numpy.ndarray = ...".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@gselzer @claude
README: describe environments prebuilt for completion
53f8185
Completion no longer installs a script's missing dependencies into an
overlay (since cd073e6): it builds the script's environment in the
background, once its declaration has settled.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@gselzer
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.