Skip to content

Completion using arbitrary langauge servers in Java text blocks#1536

Draft
danthe1st wants to merge 1 commit into
eclipse-lsp4e:mainfrom
danthe1st:java-text-block-completion
Draft

Completion using arbitrary langauge servers in Java text blocks#1536
danthe1st wants to merge 1 commit into
eclipse-lsp4e:mainfrom
danthe1st:java-text-block-completion

Conversation

@danthe1st
Copy link
Copy Markdown
Contributor

@danthe1st danthe1st commented May 16, 2026

I think it would be nice if we could use language servers from inside Java text blocks.

To demonstrate it, I implemented a prototype that can provide completions in the following way:

  • If completions are requested in a Java text block, it gets the logical contents of a text block.
  • It finds the position in the logical text block where the completion should be inserted
  • The language servers are asked for completion using the logical contents and insertion position
  • Completion proposals are created for both the normal LSP proposals and the text block-based proposals
  • If the new completions are executed, it performs the changes on the original source code.

With the HTML language server from WildWebDeveloper, this looks like this:

image
Screencast_20260516_151757.webm

When I say logical content, I mean the parsed String that Java will know about (which I can get from JDT) which is also shown when hovering over it:
image

Specifically, I have the following questions:

  • Would there be interest in such a feature (I could imagine that being especially useful in conjunction with an SQL langauge server)?
  • I created a TextBlockSourceContentMapper for converting positions within the Java code to positions within the logical text block content. Does anyone a better approach (e.g. getting it from JDT in some way) to this?
  • What should be used to determine what language is used in a text block? Currently, I'm thinking of the following ways:
    • Variable/parameter names (e.g. if the String is directly assigned to a variable/used as a parameter named html, it may want to treat it like an .html file)
    • Annotations like @Language("sql") or @Sql that are somehow associated with the string (e.g. by annotating parameters or variables)
    • IntelliJ seems to do something similar
    • If we do this, we might want to add some GUI/preference screen where users can specify the annotation they want to use
    • Similarly, plugins (especially the one providing the LSP) might want to set this as well
  • If the String is passed to certain "known" method (e.g. Connection#prepareStatement), the language server could be inferred.
    • It might make sense to configure that via preferences and allow the plugin providing the LSP to set this as well.
  • When whatever Oracle/OpenJDK might create as a successor to String Templates, that could have something useful for indicating that

Limitations

This requires the org.eclipse.lsp4e.resourceFallback.enabled preference being set to true (at least for now).

Note that this is everything but complete. I am creating a draft pull request to have a prototype as a base for discussions. For example, I hardcoded it using html for now.

private ICompletionProposal[] asJavaProposals(CompletableFuture<ICompletionProposal[]> future, ContentAssistInvocationContext context)
throws InterruptedException, ExecutionException, TimeoutException {
private ICompletionProposal[] asJavaProposals(CompletableFuture<ICompletionProposal[]> future,
ContentAssistInvocationContext context) throws InterruptedException, ExecutionException, TimeoutException {
@martinlippert
Copy link
Copy Markdown
Contributor

I think this would indeed be a very nice feature to have. How to do identify the type of language in the text block? The code creates a doc with .html, which probably causes the HTML language serve to jump in. How do you plan to do that when you can't hard-code the type of language?

@FlorianKroiss
Copy link
Copy Markdown
Contributor

I think this would be a nice addition.

Regarding content recognition:
IntelliJ also recognizes special comments, i.e.

// language=HTML
String html = "<body><h1>hi</h1></body>";

@danthe1st
Copy link
Copy Markdown
Contributor Author

How to do identify the type of language in the text block?

That is one of the main unanswered questions that I mentioned in the PR and that I'd like to get feedback on. I guess that it would be inferred from the source code in some way and ideally, that could be configured by both users (via a preference screen) and plugins which may have more information on that (e.g. plugins may know methods that expect Strings corresponding to the language server they are providing).

@danthe1st
Copy link
Copy Markdown
Contributor Author

IntelliJ also recognizes special comments

I guess it might be useful to define a (configurable) regex for comments right before text blocks containing one group for the language?

@martinlippert
Copy link
Copy Markdown
Contributor

martinlippert commented May 16, 2026

I don't really have a perfect solution in mind, but I usually don't like those approaches very much that require the developers to add things to the source code just to make the tooling happy (or working).

@danthe1st
Copy link
Copy Markdown
Contributor Author

danthe1st commented May 16, 2026

I don't really have a perfect solution in mind, but I usually don't like those approaches very much that require the developers to add things to the source code just to make the tooling happy (or working).

I think we can still provide default values (i.e. have a configuration that's somewhat compatible with IntelliJ's approach) where applicable.

@martinlippert
Copy link
Copy Markdown
Contributor

I don't really have a perfect solution in mind, but I usually don't like those approaches very much that require the developers to add things to the source code just to make the tooling happy (or working).

I think we can still provide default values (i.e. have a configuration that's somewhat compatible with IntelliJ's approach) where applicable.

What exactly do you have in mind here? Not sure I understand the "provide default values". Can you elaborate on that?

@danthe1st
Copy link
Copy Markdown
Contributor Author

danthe1st commented May 19, 2026

What exactly do you have in mind here? Not sure I understand the "provide default values". Can you elaborate on that?

My idea is maybe something like the following:

  • By default, a comment with the content matching language=([\w]+) means that a String right after is treated as a file with that extension
    • If someone wants to, they could change that regex?
  • If a text block is assigned to a variable with a known name (e.g. html, sql or similar), that language server is used
    • I am not sure about making this dependent on variable names
  • A plugin providing a language server could somehow provide a list of method (parameter)s that are known to correspond to that language server
    • Users add more method (parameter)s to that list via a preference screen
  • The preferences could also contain a list of annotations used for identifying a language (such as @Sql or @Language) in case a user wants to add some

I guess it might make sense to start with the first one or two and others can be added later if someone is interested/has a good idea on how to do that.

@martinlippert
Copy link
Copy Markdown
Contributor

It would be useful to extract the exact strategy that identifies the language into a distinct component and open that up for extensions. The use case that I have in mind here is:

In the Spring Tools, we know precisely for example when a SQL statement is used in a @Query annotation. We can even identify the exact dialect (SQL, HQL, JPQL, etc.). So for this case, it would be nice if the Spring Tools extension could contribute something as an extension that basically delivers the information about "this string literal or text block is SQL" to the LSP4E mechanism. In that case, the user does not need to add extra language ID to the source code.

My guess is that other tools would also be able to identify those languages, since they are usually not totally random and can be inferred from the wider context. In our case it is the Spring Data specific @Query annotation (among those embedded languages that we identify).

@danthe1st danthe1st force-pushed the java-text-block-completion branch from 233aca5 to a584177 Compare May 20, 2026 16:28
@danthe1st
Copy link
Copy Markdown
Contributor Author

danthe1st commented May 20, 2026

I updated the PR with some code that uses // language=... comments for now but I don't have a concrete plan on how to allow other plugins to do this.

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.

4 participants