是否可以在运行时将完成项添加到 Microsoft 语言服务器?
Is it possible to add completion items to a Microsoft Language Server in runtime?
我正在尝试开发一个 IntelliJ 插件,它在 ballerina 的 lsp4intellij 的帮助下提供语言服务器。
事情是,我有一个特殊条件:完成项列表应该在运行时是可编辑的。
但是我还没有找到任何方法将新的 completionItems 传送到 LanguageServer 进程 运行。
我目前的想法是向插件添加一个操作,该操作会构建一个新的 jar,然后使用 Java 编译器 API.
使用新的 jar 重新启动服务器
问题是,我需要从插件项目中获取源代码,包括可从 运行 插件访问的 gradle 依赖项...有什么想法吗?
如果您的要求是在 IntelliJ UI 中显示之前修改完成项(来自语言服务器),您可以通过实现 LSP4IntelliJ 的
LSPExtensionManager 在你的插件中。
目前,我们没有关于 LSP4IntelliJ 扩展点的适当文档,但您可以参考我们的 Ballerina IntelliJ 插件作为参考实现,它已经实现了 Ballerina LSP Extension manager to override/modify completion items at the client runtime in here。
对于那些可能偶然发现这一点的人 - 确实可以更改 LanguageServer 在运行时可以提供的 CompletionItems 的数量。
我简单地编辑了TextDocumentService.java(我使用的库是LSP4J)。
它是这样工作的:
LanguageServer 的主要功能需要使用一个附加参数启动,该参数是您定义 CompletionItems 的配置文件的路径。
从 LSP4IntelliJ 调用它看起来像这样:
String[] command = new String[]{"java", "-jar",
"path\to\LangServer.jar", "path\to\config.json"};
IntellijLanguageClient.addServerDefinition(new RawCommandServerDefinition("md,java", command));
然后,路径字符串将传递给 CustomTextDocumentServer.java 的构造函数,后者将在新的计时器线程中解析 config.json。
一个例子:
public class CustomTextDocumentService implements TextDocumentService {
private List<CompletionItem> providedItems;
private String pathToConfig;
public CustomTextDocumentService(String pathToConfig) {
this.pathToConfig = pathToConfig;
Timer timer = new Timer();
timer.schedule(new ReloadCompletionItemsTask(), 0, 10000);
loadCompletionItems();
}
@Override
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(CompletionParams completionParams) {
return CompletableFuture.supplyAsync(() -> {
List<CompletionItem> completionItems;
completionItems = this.providedItems;
// Return the list of completion items.
return Either.forLeft(completionItems);
});
}
@Override
public void didOpen(DidOpenTextDocumentParams didOpenTextDocumentParams) {
}
@Override
public void didChange(DidChangeTextDocumentParams didChangeTextDocumentParams) {
}
@Override
public void didClose(DidCloseTextDocumentParams didCloseTextDocumentParams) {
}
@Override
public void didSave(DidSaveTextDocumentParams didSaveTextDocumentParams) {
}
private void loadCompletionItems() {
providedItems = new ArrayList<>();
CustomParser = new CustomParser(pathToConfig);
ArrayList<String> variables = customParser.getTheParsedItems();
for(String variable : variables) {
String itemTxt = "$" + variable + "$";
CompletionItem completionItem = new CompletionItem();
completionItem.setInsertText(itemTxt);
completionItem.setLabel(itemTxt);
completionItem.setKind(CompletionItemKind.Snippet);
completionItem.setDetail("CompletionItem");
providedItems.add(completionItem);
}
}
class ReloadCompletionItemsTask extends TimerTask {
@Override
public void run() {
loadCompletionItems();
}
}
}
我正在尝试开发一个 IntelliJ 插件,它在 ballerina 的 lsp4intellij 的帮助下提供语言服务器。
事情是,我有一个特殊条件:完成项列表应该在运行时是可编辑的。
但是我还没有找到任何方法将新的 completionItems 传送到 LanguageServer 进程 运行。
我目前的想法是向插件添加一个操作,该操作会构建一个新的 jar,然后使用 Java 编译器 API.
使用新的 jar 重新启动服务器问题是,我需要从插件项目中获取源代码,包括可从 运行 插件访问的 gradle 依赖项...有什么想法吗?
如果您的要求是在 IntelliJ UI 中显示之前修改完成项(来自语言服务器),您可以通过实现 LSP4IntelliJ 的 LSPExtensionManager 在你的插件中。
目前,我们没有关于 LSP4IntelliJ 扩展点的适当文档,但您可以参考我们的 Ballerina IntelliJ 插件作为参考实现,它已经实现了 Ballerina LSP Extension manager to override/modify completion items at the client runtime in here。
对于那些可能偶然发现这一点的人 - 确实可以更改 LanguageServer 在运行时可以提供的 CompletionItems 的数量。
我简单地编辑了TextDocumentService.java(我使用的库是LSP4J)。
它是这样工作的:
LanguageServer 的主要功能需要使用一个附加参数启动,该参数是您定义 CompletionItems 的配置文件的路径。 从 LSP4IntelliJ 调用它看起来像这样:
String[] command = new String[]{"java", "-jar",
"path\to\LangServer.jar", "path\to\config.json"};
IntellijLanguageClient.addServerDefinition(new RawCommandServerDefinition("md,java", command));
然后,路径字符串将传递给 CustomTextDocumentServer.java 的构造函数,后者将在新的计时器线程中解析 config.json。
一个例子:
public class CustomTextDocumentService implements TextDocumentService {
private List<CompletionItem> providedItems;
private String pathToConfig;
public CustomTextDocumentService(String pathToConfig) {
this.pathToConfig = pathToConfig;
Timer timer = new Timer();
timer.schedule(new ReloadCompletionItemsTask(), 0, 10000);
loadCompletionItems();
}
@Override
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(CompletionParams completionParams) {
return CompletableFuture.supplyAsync(() -> {
List<CompletionItem> completionItems;
completionItems = this.providedItems;
// Return the list of completion items.
return Either.forLeft(completionItems);
});
}
@Override
public void didOpen(DidOpenTextDocumentParams didOpenTextDocumentParams) {
}
@Override
public void didChange(DidChangeTextDocumentParams didChangeTextDocumentParams) {
}
@Override
public void didClose(DidCloseTextDocumentParams didCloseTextDocumentParams) {
}
@Override
public void didSave(DidSaveTextDocumentParams didSaveTextDocumentParams) {
}
private void loadCompletionItems() {
providedItems = new ArrayList<>();
CustomParser = new CustomParser(pathToConfig);
ArrayList<String> variables = customParser.getTheParsedItems();
for(String variable : variables) {
String itemTxt = "$" + variable + "$";
CompletionItem completionItem = new CompletionItem();
completionItem.setInsertText(itemTxt);
completionItem.setLabel(itemTxt);
completionItem.setKind(CompletionItemKind.Snippet);
completionItem.setDetail("CompletionItem");
providedItems.add(completionItem);
}
}
class ReloadCompletionItemsTask extends TimerTask {
@Override
public void run() {
loadCompletionItems();
}
}
}