Skip to content

Commit

Permalink
Send window/workDoneProgress/create requests
Browse files Browse the repository at this point in the history
Fixes #34.
  • Loading branch information
valentjn committed Dec 22, 2020
1 parent f90a065 commit 1aa349f
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 212 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
import org.checkerframework.checker.initialization.qual.NotOnlyInitialized;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.CodeActionOptions;
import org.eclipse.lsp4j.ExecuteCommandOptions;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.WindowClientCapabilities;
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
Expand All @@ -42,6 +44,7 @@ public class LtexLanguageServer implements LanguageServer, LanguageClientAware {
private CodeActionGenerator codeActionGenerator;
private @NotOnlyInitialized LtexTextDocumentService ltexTextDocumentService;
private @NotOnlyInitialized LtexWorkspaceService ltexWorkspaceService;
private boolean clientSupportsWorkDoneProgress;
private boolean clientSupportsWorkspaceSpecificConfiguration;
private Instant startupInstant;

Expand All @@ -55,6 +58,7 @@ public LtexLanguageServer() {
this.codeActionGenerator = new CodeActionGenerator(this.settingsManager);
this.ltexTextDocumentService = new LtexTextDocumentService(this);
this.ltexWorkspaceService = new LtexWorkspaceService(this);
this.clientSupportsWorkDoneProgress = false;
this.clientSupportsWorkspaceSpecificConfiguration = false;
this.startupInstant = Instant.now();
}
Expand All @@ -67,20 +71,23 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
Tools.logger.info(Tools.i18n("initializingLtexLs",
((ltexLsVersion != null) ? ltexLsVersion : "null")));

ServerCapabilities capabilities = new ServerCapabilities();
capabilities.setTextDocumentSync(TextDocumentSyncKind.Full);
capabilities.setCodeActionProvider(new CodeActionOptions(CodeActionGenerator.getCodeActions()));
@Nullable ClientCapabilities clientCapabilities = params.getCapabilities();

List<String> commandNames = new ArrayList<>();
commandNames.addAll(LtexWorkspaceService.getCommandNames());
capabilities.setExecuteCommandProvider(new ExecuteCommandOptions(commandNames));
if (clientCapabilities != null) {
@Nullable WindowClientCapabilities windowClientCapabilities = clientCapabilities.getWindow();

if ((windowClientCapabilities != null) && (windowClientCapabilities.getWorkDoneProgress())) {
this.clientSupportsWorkDoneProgress = true;
}
}

// Until it is specified in the LSP that the locale is automatically sent with
// the initialization request, we have to do that manually.
// See https://github.com/microsoft/language-server-protocol/issues/754.
Tools.logger.warning("clientSupportsWorkDoneProgress = " + this.clientSupportsWorkDoneProgress);
@Nullable JsonObject initializationOptions = (JsonObject)params.getInitializationOptions();

if (initializationOptions != null) {
// Until it is specified in the LSP that the locale is automatically sent with
// the initialization request, we have to do that manually.
// See https://github.com/microsoft/language-server-protocol/issues/754.
if (initializationOptions.has("locale")) {
String localeLanguage = initializationOptions.get("locale").getAsString();
Locale locale = Locale.forLanguageTag(localeLanguage);
Expand All @@ -98,7 +105,16 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
}
}

return CompletableFuture.completedFuture(new InitializeResult(capabilities));
ServerCapabilities serverCapabilities = new ServerCapabilities();
serverCapabilities.setTextDocumentSync(TextDocumentSyncKind.Full);
serverCapabilities.setCodeActionProvider(
new CodeActionOptions(CodeActionGenerator.getCodeActions()));

List<String> commandNames = new ArrayList<>();
commandNames.addAll(LtexWorkspaceService.getCommandNames());
serverCapabilities.setExecuteCommandProvider(new ExecuteCommandOptions(commandNames));

return CompletableFuture.completedFuture(new InitializeResult(serverCapabilities));
}

@Override
Expand Down Expand Up @@ -175,6 +191,10 @@ public LtexTextDocumentService getLtexTextDocumentService() {
return this.ltexTextDocumentService;
}

public boolean isClientSupportingWorkDoneProgress() {
return this.clientSupportsWorkDoneProgress;
}

public boolean isClientSupportingWorkspaceSpecificConfiguration() {
return this.clientSupportsWorkspaceSpecificConfiguration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
import org.eclipse.lsp4j.TextDocumentItem;
import org.eclipse.lsp4j.WorkDoneProgressBegin;
import org.eclipse.lsp4j.WorkDoneProgressCreateParams;
import org.eclipse.lsp4j.WorkDoneProgressEnd;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.eclipse.xtext.xbase.lib.Pair;
Expand Down Expand Up @@ -405,51 +406,82 @@ public CompletableFuture<Pair<List<LanguageToolRuleMatch>, List<AnnotatedTextFra
}

String uri = getUri();

WorkDoneProgressBegin workDoneProgressBegin = new WorkDoneProgressBegin();
workDoneProgressBegin.setTitle(Tools.i18n("checkingUri", uri));
workDoneProgressBegin.setCancellable(false);

Either<String, Number> progressToken =
this.progressTokenGenerator.generate(uri, "checkDocument");

languageClient.notifyProgress(new ProgressParams(progressToken, workDoneProgressBegin));
final CompletableFuture<@Nullable Either<String, Number>> workDoneProgressCreateFuture =
((this.languageServer.isClientSupportingWorkDoneProgress())
? languageClient.createProgress(new WorkDoneProgressCreateParams(progressToken)).handle(
(Void voidObject, @Nullable Throwable e) -> {
if (e == null) {
WorkDoneProgressBegin workDoneProgressBegin = new WorkDoneProgressBegin();
workDoneProgressBegin.setTitle(Tools.i18n("checkingUri", uri));
workDoneProgressBegin.setCancellable(false);
languageClient.notifyProgress(new ProgressParams(
progressToken, workDoneProgressBegin));
return progressToken;
} else {
return null;
}
})
: CompletableFuture.completedFuture(null));

ConfigurationItem configurationItem = new ConfigurationItem();
configurationItem.setScopeUri(uri);
configurationItem.setSection("ltex");
ConfigurationParams configurationParams = new ConfigurationParams(
Collections.singletonList(configurationItem));

CompletableFuture<List<Object>> configurationFuture =
languageClient.configuration(configurationParams);
CompletableFuture<List<@Nullable Object>> workspaceSpecificConfigurationFuture =
(this.languageServer.isClientSupportingWorkspaceSpecificConfiguration()
? languageClient.ltexWorkspaceSpecificConfiguration(configurationParams)
: CompletableFuture.completedFuture(Collections.singletonList(null)));

return configurationFuture.thenCombine(workspaceSpecificConfigurationFuture,
(List<Object> configuration, List<@Nullable Object> workspaceSpecificConfiguration) -> {
JsonElement jsonConfiguration = (JsonElement)configuration.get(0);
@Nullable Object workspaceSpecificConfigurationElement =
workspaceSpecificConfiguration.get(0);
@Nullable JsonElement jsonWorkspaceSpecificConfiguration =
((workspaceSpecificConfigurationElement != null)
? (JsonElement)workspaceSpecificConfigurationElement : null);

this.languageServer.getSettingsManager().setSettings(
jsonConfiguration, jsonWorkspaceSpecificConfiguration);

this.checkingResult = this.languageServer.getDocumentChecker().check(this);

return this.checkingResult;
}).whenComplete((
Pair<List<LanguageToolRuleMatch>, List<AnnotatedTextFragment>> checkingResult,
Throwable e) -> {
if (languageClient != null) {
languageClient.notifyProgress(new ProgressParams(
progressToken, new WorkDoneProgressEnd()));
}
});
CompletableFuture<List<Object>> intermediateResult1 = workDoneProgressCreateFuture.thenCompose(
(@Nullable Either<String, Number> curProgressToken) -> {
return languageClient.configuration(configurationParams);
});

@SuppressWarnings({"assignment.type.incompatible", "return.type.incompatible"})
CompletableFuture<Pair<List<Object>, List<@Nullable Object>>> intermediateResult2 =
intermediateResult1.thenCompose(
(List<Object> configurationResult) -> {
return (this.languageServer.isClientSupportingWorkspaceSpecificConfiguration()
? languageClient.ltexWorkspaceSpecificConfiguration(configurationParams)
: CompletableFuture.completedFuture(Collections.singletonList(null))).thenApply(
(List<@Nullable Object> workspaceSpecificConfigurationResult) -> {
return Pair.of(configurationResult, workspaceSpecificConfigurationResult);
});
});

CompletableFuture<Pair<List<LanguageToolRuleMatch>, List<AnnotatedTextFragment>>>
intermediateResult3 = intermediateResult2.thenApply(
(Pair<List<Object>, List<@Nullable Object>> futureArgument) -> {
List<Object> configurationResult = futureArgument.getKey();
List<@Nullable Object> workspaceSpecificConfigurationResult = futureArgument.getValue();

try {
JsonElement jsonConfiguration = (JsonElement)configurationResult.get(0);
@Nullable Object workspaceSpecificConfiguration =
workspaceSpecificConfigurationResult.get(0);
@Nullable JsonElement jsonWorkspaceSpecificConfiguration =
((workspaceSpecificConfiguration != null)
? (JsonElement)workspaceSpecificConfiguration : null);

this.languageServer.getSettingsManager().setSettings(
jsonConfiguration, jsonWorkspaceSpecificConfiguration);

Pair<List<LanguageToolRuleMatch>, List<AnnotatedTextFragment>> checkingResult =
this.languageServer.getDocumentChecker().check(this);
this.checkingResult = checkingResult;

return checkingResult;
} finally {
@Nullable Either<String, Number> curProgressToken =
workDoneProgressCreateFuture.join();

if ((languageClient != null) && (curProgressToken != null)) {
languageClient.notifyProgress(new ProgressParams(
curProgressToken, new WorkDoneProgressEnd()));
}
}
});

return intermediateResult3;
}
}
2 changes: 1 addition & 1 deletion ltexls-core/src/test/java/LspMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public enum Type {
private JsonObject body;

private static final Pattern logPattern = Pattern.compile(
"\\[[^\\]]+\\] (\\S+) (\\S+) '([^' ]+)(?: - \\(([^\\)]+)\\))?'.*\\R(?:Params|Result): ");
"\\[[^\\]]+\\] (\\S+) (\\S+) '([^' ]+)(?: - \\(([^\\)]+)\\))?'.*\\R(?:Params|Result):");
private static final Pattern headerPattern = Pattern.compile("(\\S+): (.*)\r\n");

/**
Expand Down
Loading

0 comments on commit 1aa349f

Please sign in to comment.