-
Notifications
You must be signed in to change notification settings - Fork 105
/
Copy pathLanguageClientWorkspaceFoldersManager.cs
101 lines (83 loc) · 4.12 KB
/
LanguageClientWorkspaceFoldersManager.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using OmniSharp.Extensions.LanguageServer.Protocol;
using OmniSharp.Extensions.LanguageServer.Protocol.Client;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Workspace;
namespace OmniSharp.Extensions.LanguageServer.Client
{
internal class LanguageClientWorkspaceFoldersManager : ILanguageClientWorkspaceFoldersManager, IDisposable
{
private readonly IWorkspaceLanguageClient _client;
private readonly ConcurrentDictionary<DocumentUri, WorkspaceFolder> _workspaceFolders;
private readonly ReplaySubject<IEnumerable<WorkspaceFolder>> _workspaceFoldersSubject;
public LanguageClientWorkspaceFoldersManager(IWorkspaceLanguageClient client, IEnumerable<WorkspaceFolder> workspaceFolders)
{
_client = client;
_workspaceFolders = new ConcurrentDictionary<DocumentUri, WorkspaceFolder>(DocumentUri.Comparer);
_workspaceFoldersSubject = new ReplaySubject<IEnumerable<WorkspaceFolder>>(1);
foreach (var folder in workspaceFolders)
{
_workspaceFolders.TryAdd(folder.Uri, folder);
}
}
Task<Container<WorkspaceFolder>> IRequestHandler<WorkspaceFolderParams, Container<WorkspaceFolder>>.
Handle(WorkspaceFolderParams request, CancellationToken cancellationToken) =>
Task.FromResult(new Container<WorkspaceFolder>(_workspaceFolders.Values));
public void Add(DocumentUri uri, string name) => Add(new WorkspaceFolder { Name = name, Uri = uri });
public void Add(WorkspaceFolder folder, params WorkspaceFolder[] workspaceFolders) => Add(new[] { folder }.Concat(workspaceFolders));
public void Add(IEnumerable<WorkspaceFolder> workspaceFolders)
{
var additions = new HashSet<WorkspaceFolder>();
foreach (var item in workspaceFolders.Except(_workspaceFolders.Values).ToArray())
{
if (_workspaceFolders.TryAdd(item.Uri, item))
{
additions.Add(item);
}
}
if (additions.Count == 0) return;
_client.DidChangeWorkspaceFolders(
new DidChangeWorkspaceFoldersParams {
Event = new WorkspaceFoldersChangeEvent {
Added = new Container<WorkspaceFolder>(additions)
}
}
);
_workspaceFoldersSubject.OnNext(_workspaceFolders.Values);
}
public void Remove(DocumentUri name) => Remove(_workspaceFolders.Values.Where(z => z.Uri == name));
public void Remove(string name) => Remove(_workspaceFolders.Values.Where(z => z.Name == name));
public void Remove(WorkspaceFolder folder, params WorkspaceFolder[] workspaceFolders) => Remove(new[] { folder }.Concat(workspaceFolders));
public void Remove(IEnumerable<WorkspaceFolder> items)
{
var removals = new HashSet<WorkspaceFolder>();
foreach (var item in items.ToArray())
{
if (_workspaceFolders.TryRemove(item.Uri, out _))
{
removals.Add(item);
}
}
if (removals.Count == 0) return;
_client.DidChangeWorkspaceFolders(
new DidChangeWorkspaceFoldersParams {
Event = new WorkspaceFoldersChangeEvent {
Removed = new Container<WorkspaceFolder>(removals)
}
}
);
_workspaceFoldersSubject.OnNext(_workspaceFolders.Values);
}
public IObservable<IEnumerable<WorkspaceFolder>> WorkspaceFolders => _workspaceFoldersSubject.AsObservable();
public IEnumerable<WorkspaceFolder> CurrentWorkspaceFolders => _workspaceFolders.Values;
public void Dispose() => _workspaceFoldersSubject?.Dispose();
}
}