OmniSharp / OmniSharp/csharp-language-server-protocol
TextDocumentSyncHandler doesn't seem to take into consideration its TextDocumentSyncRegistrationOptions
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 638
- Forks
- 109
- Avg merge
- 1m
- Merged PRs (30d)
- 2
Description
Hello,
I ask for your help again.
In our extension we want to manage the updates of two type of files.
To do so we created two different SyncHandlers, each of which inherits from TextDocumentSyncHandlerBase.
Each handler implement its own DocumentSelector, with the appropriate pattern and language for the kind of file it needs to manage. The DocumentSelector is then passed to the TextDocumentSyncRegistrationOptions created in CreateRegistrationOptions.
But when our server receives a request managed by the TextDocumentSyncHandler (for example a DidOpenTextDocumentParams request) it systematically calls both Handlers, as if it didn't do any checking with the TextDocumentSyncRegistrationOptions of any of the handlers.
Is it possible to configure the handlers as I intend to do (each one managing a specific extension) or are the requests automatically linked to every handlers of the server ?
Here is the code for our handlers.
When I do a modification in "test.amlg" the Handle functions in both Handlers are called.
internal class AmlgDocumentSyncHandler : TextDocumentSyncHandlerBase
{
private readonly Workspace workspace;
private readonly DocumentSelector documentSelector = new DocumentSelector(
new DocumentFilter
{
Pattern = "**/*.amlg",
Language = "amlg",
Scheme = "file"
}
);
public AmlgDocumentSyncHandler(Workspace workspace, ILogger logger) : base()
{
Log = logger.ForContext<AmlgDocumentSyncHandler>();
this.workspace = workspace;
}
private ILogger Log { get; }
public override TextDocumentAttributes GetTextDocumentAttributes(DocumentUri uri) => new TextDocumentAttributes(uri, "amlg");
public override Task<Unit> Handle(DidOpenTextDocumentParams request, CancellationToken cancellationToken)
{
Log.Information("Document Opened");
workspace.Open(request.TextDocument.Uri, request.TextDocument.Version ?? 0, request.TextDocument.Text);
return Unit.Task;
}
public override Task<Unit> Handle(DidChangeTextDocumentParams request, CancellationToken cancellationToken)
{
Log.Information("Document Changed");
workspace.Change(request.TextDocument.Uri, request.TextDocument.Version ?? 0, request.ContentChanges.Last().Text);
return Unit.Task;
}
public override Task<Unit> Handle(DidCloseTextDocumentParams request, CancellationToken cancellationToken)
{
Log.Information("Document Closed");
workspace.Close(request.TextDocument.Uri);
return Unit.Task;
}
public override Task<Unit> Handle(DidSaveTextDocumentParams request, CancellationToken cancellationToken)
{
return Unit.Task;
}
protected override TextDocumentSyncRegistrationOptions CreateRegistrationOptions(SynchronizationCapability capability, ClientCapabilities clientCapabilities)
{
return new TextDocumentSyncRegistrationOptions()
{
Save = true,
Change = TextDocumentSyncKind.Full,
DocumentSelector = documentSelector
};
}
}
internal class JsonDocumentSyncHandler : TextDocumentSyncHandlerBase
{
private readonly Workspace workspace;
private readonly DocumentSelector documentSelector = new DocumentSelector(
new DocumentFilter
{
Pattern = "**/model.json",
Language = "json",
Scheme = "file"
}
);
public JsonDocumentSyncHandler(Workspace workspace, ILogger logger) : base()
{
Log = logger.ForContext<JsonDocumentSyncHandler>();
this.workspace = workspace;
}
private ILogger Log { get; }
public override TextDocumentAttributes GetTextDocumentAttributes(DocumentUri uri) => new TextDocumentAttributes(uri, "json");
public override Task<Unit> Handle(DidOpenTextDocumentParams request, CancellationToken cancellationToken)
{
Log.Information("Project Opened");
workspace.OpenProject(request.TextDocument.Uri, request.TextDocument.Text);
return Unit.Task;
}
public override Task<Unit> Handle(DidChangeTextDocumentParams request, CancellationToken cancellationToken)
{
Log.Information("Project Changed");
workspace.ChangeProject(request.TextDocument.Uri, request.ContentChanges.Last().Text);
return Unit.Task;
}
public override Task<Unit> Handle(DidCloseTextDocumentParams request, CancellationToken cancellationToken)
{
Log.Information("Project Closed");
workspace.CloseProject(request.TextDocument.Uri);
return Unit.Task;
}
public override Task<Unit> Handle(DidSaveTextDocumentParams request, CancellationToken cancellationToken)
{
return Unit.Task;
}
protected override TextDocumentSyncRegistrationOptions CreateRegistrationOptions(SynchronizationCapability capability, ClientCapabilities clientCapabilities)
{
return new TextDocumentSyncRegistrationOptions()
{
Save = true,
Change = TextDocumentSyncKind.Full,
DocumentSelector = documentSelector
};
}
}
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing TextDocumentSyncHandlerBase dispatch for DidOpenTextDocumentParams, DidChangeTextDocumentParams, and related requests, then compare it with the DocumentSelector returned by each handler's CreateRegistrationOptions. Reproduce the case with the AmlgDocumentSyncHandler and JsonDocumentSyncHandler examples; done means only the handler whose selector matches the document receives the request.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100