Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 70 additions & 67 deletions CodeiumVS/CodeLensConnection/CodeLensConnectionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,94 +5,97 @@

namespace CodeiumVS
{
using System;
using System.Diagnostics;
using System.IO.Pipes;
using System.Linq;
using System.Threading.Tasks;
using System;
using System.Diagnostics;
using System.IO.Pipes;
using System.Linq;
using System.Threading.Tasks;

using StreamJsonRpc;
using StreamJsonRpc;

using CodeLensConnections = System.Collections.Concurrent.ConcurrentDictionary<System.Guid, CodeLensConnectionHandler>;
using CodeLensDetails = System.Collections.Concurrent.ConcurrentDictionary<System.Guid, FunctionInfo>;
using CodeLensConnections =
System.Collections.Concurrent.ConcurrentDictionary<System.Guid, CodeLensConnectionHandler>;
using CodeLensDetails =
System.Collections.Concurrent.ConcurrentDictionary<System.Guid, FunctionInfo>;

public class CodeLensConnectionHandler : IRemoteVisualStudio, IDisposable
{
private static readonly CodeLensConnections connections = new CodeLensConnections();
private static readonly CodeLensDetails detailsData = new CodeLensDetails();
public class CodeLensConnectionHandler : IRemoteVisualStudio, IDisposable
{
private static readonly CodeLensConnections connections = new CodeLensConnections();
private static readonly CodeLensDetails detailsData = new CodeLensDetails();

private JsonRpc? rpc;
private Guid? dataPointId;
private JsonRpc? rpc;
private Guid? dataPointId;

public static async Task AcceptCodeLensConnections()
public static async Task AcceptCodeLensConnections()
{
try
{
try
{
while (true)
{
var stream = new NamedPipeServerStream(
PipeName.Get(Process.GetCurrentProcess().Id),
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
await stream.WaitForConnectionAsync().Caf();
_ = HandleConnection(stream);
}
}
catch (Exception ex)
while (true)
{
throw;
}

static async Task HandleConnection(NamedPipeServerStream stream)
{
try
{
var handler = new CodeLensConnectionHandler();
var rpc = JsonRpc.Attach(stream, handler);
handler.rpc = rpc;
await rpc.Completion;
handler.Dispose();
stream.Dispose();
}
catch (Exception ex)
{
CodeiumVSPackage.Instance.LogAsync("Handle Connection Error");
}
var stream =
new NamedPipeServerStream(PipeName.Get(Process.GetCurrentProcess().Id),
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous);
await stream.WaitForConnectionAsync().Caf();
_ = HandleConnection(stream);
}
}
catch (Exception ex)
{
throw;
}

public void Dispose()
static async Task HandleConnection(NamedPipeServerStream stream)
{
if (dataPointId.HasValue)
try
{
_ = connections.TryRemove(dataPointId.Value, out var _);
_ = detailsData.TryRemove(dataPointId.Value, out var _);
var handler = new CodeLensConnectionHandler();
var rpc = JsonRpc.Attach(stream, handler);
handler.rpc = rpc;
await rpc.Completion;
handler.Dispose();
stream.Dispose();
}
catch (Exception ex)
{
CodeiumVSPackage.Instance.LogAsync("Handle Connection Error");
}
}
}

// Called from each CodeLensDataPoint via JSON RPC.
public void RegisterCodeLensDataPoint(Guid id)
public void Dispose()
{
if (dataPointId.HasValue)
{
dataPointId = id;
connections[id] = this;
_ = connections.TryRemove(dataPointId.Value, out var _);
_ = detailsData.TryRemove(dataPointId.Value, out var _);
}
}

public static void StoreDetailsData(Guid id, FunctionInfo closestFunction) => detailsData[id] = closestFunction;
// Called from each CodeLensDataPoint via JSON RPC.
public void RegisterCodeLensDataPoint(Guid id)
{
dataPointId = id;
connections[id] = this;
}

public static FunctionInfo GetDetailsData(Guid id) => detailsData[id];
public static void
StoreDetailsData(Guid id, FunctionInfo closestFunction) => detailsData[id] = closestFunction;

public static async Task RefreshCodeLensDataPoint(Guid id)
{
if (!connections.TryGetValue(id, out var conn))
throw new InvalidOperationException($"CodeLens data point {id} was not registered.");
public static FunctionInfo GetDetailsData(Guid id) => detailsData[id];

Debug.Assert(conn.rpc != null);
await conn.rpc!.InvokeAsync(nameof(IRemoteCodeLens.Refresh)).Caf();
}
public static async Task RefreshCodeLensDataPoint(Guid id)
{
if (!connections.TryGetValue(id, out var conn))
throw new InvalidOperationException($"CodeLens data point {id} was not registered.");

public static async Task RefreshAllCodeLensDataPoints()
=> await Task.WhenAll(connections.Keys.Select(RefreshCodeLensDataPoint)).Caf();
Debug.Assert(conn.rpc != null);
await conn.rpc!.InvokeAsync(nameof(IRemoteCodeLens.Refresh)).Caf();
}

public static async Task RefreshAllCodeLensDataPoints() =>
await Task.WhenAll(connections.Keys.Select(RefreshCodeLensDataPoint)).Caf();
}
}
136 changes: 67 additions & 69 deletions CodeiumVS/CodeLensConnection/CodeLensListener.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,89 +17,87 @@
namespace CodeiumVS
{

[Export(typeof(ICodeLensCallbackListener))]
[ContentType("C/C++")]
[ContentType("CSharp")]
[ContentType("Basic")]
[ContentType("vbscript")]
[ContentType("TypeScript")]
[ContentType("JavaScript")]
[ContentType("html")]
[ContentType("HTMLX")]
[ContentType("Razor")]
public class CodeLensListener : ICodeLensCallbackListener, ICodeLensListener
{
[Export(typeof(ICodeLensCallbackListener))]
[ContentType("C/C++")]
[ContentType("CSharp")]
[ContentType("Basic")]
[ContentType("vbscript")]
[ContentType("TypeScript")]
[ContentType("JavaScript")]
[ContentType("html")]
[ContentType("HTMLX")]
[ContentType("Razor")]
public class CodeLensListener : ICodeLensCallbackListener, ICodeLensListener
{

public int GetVisualStudioPid() => Process.GetCurrentProcess().Id;
public int GetVisualStudioPid() => Process.GetCurrentProcess().Id;

public bool IsCodeiumCodeLensActive() => CodeiumVSPackage.Instance != null && CodeiumVSPackage.Instance.SettingsPage.EnableCodeLens;
FunctionInfo GetClosestFunction(IList<Packets.FunctionInfo>? functions, int line)
public bool
IsCodeiumCodeLensActive() => CodeiumVSPackage.Instance != null
&& CodeiumVSPackage.Instance.SettingsPage.EnableCodeLens;
FunctionInfo GetClosestFunction(IList<Packets.FunctionInfo>? functions, int line)
{

FunctionInfo minFunction = null;
int minDistance = int.MaxValue;
foreach (var f in functions)
{

FunctionInfo minFunction = null;
int minDistance = int.MaxValue;
foreach (var f in functions)
var distance = Math.Abs(f.DefinitionLine - line);
if (distance < minDistance)
{
var distance = Math.Abs(f.DefinitionLine - line);
if (distance < minDistance)
{
minDistance = distance;
minFunction = f;
}
minDistance = distance;
minFunction = f;
}

return minFunction;
}

public async Task<FunctionInfo> LoadInstructions(
Guid dataPointId,
Guid projGuid,
string filePath,
int textStart,
int textLen,
CancellationToken ct)
{
try
{

ITextDocument _document;
TextViewListener.Instance.documentDictionary.TryGetValue(filePath.ToLower(), out _document);
var key = typeof(CodeiumCompletionHandler);
var props = _document.TextBuffer.Properties;
CodeiumCompletionHandler handler;
if (props.ContainsProperty(key))
{
handler = props.GetProperty<CodeiumCompletionHandler>(key);
}
else
{
handler = null;
return null;
}

IList<FunctionInfo>? functions =
await CodeiumVSPackage.Instance.LanguageServer.GetFunctionsAsync(
_document.FilePath,
_document.TextBuffer.CurrentSnapshot.GetText(),
handler.GetLanguage(),
0,
ct);
return minFunction;
}

var line = new Span(textStart, textLen);
var snapshotLine = _document.TextBuffer.CurrentSnapshot.GetLineFromPosition(line.Start);
var lineN = snapshotLine.LineNumber;
FunctionInfo closestFunction = GetClosestFunction(functions, lineN);
CodeLensConnectionHandler.StoreDetailsData(dataPointId, closestFunction);
public async Task<FunctionInfo> LoadInstructions(Guid dataPointId, Guid projGuid,
string filePath, int textStart, int textLen,
CancellationToken ct)
{
try
{

return closestFunction;
ITextDocument _document;
TextViewListener.Instance.documentDictionary.TryGetValue(filePath.ToLower(),
out _document);
var key = typeof(CodeiumCompletionHandler);
var props = _document.TextBuffer.Properties;
CodeiumCompletionHandler handler;
if (props.ContainsProperty(key))
{
handler = props.GetProperty<CodeiumCompletionHandler>(key);
}
catch (Exception ex)
else
{
CodeiumVSPackage.Instance.LogAsync(ex.ToString());

handler = null;
return null;
}

IList<FunctionInfo>? functions =
await CodeiumVSPackage.Instance.LanguageServer.GetFunctionsAsync(
_document.FilePath,
_document.TextBuffer.CurrentSnapshot.GetText(),
handler.GetLanguage(),
0,
ct);

var line = new Span(textStart, textLen);
var snapshotLine = _document.TextBuffer.CurrentSnapshot.GetLineFromPosition(line.Start);
var lineN = snapshotLine.LineNumber;
FunctionInfo closestFunction = GetClosestFunction(functions, lineN);
CodeLensConnectionHandler.StoreDetailsData(dataPointId, closestFunction);

return closestFunction;
}
catch (Exception ex)
{
CodeiumVSPackage.Instance.LogAsync(ex.ToString());

return null;
}
}
}
}
2 changes: 1 addition & 1 deletion CodeiumVS/CodeiumVS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
10 changes: 4 additions & 6 deletions CodeiumVS/CodeiumVSPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ await LogAsync(
{
await LogAsync(
$"CodeiumVSPackage.InitializeAsync: Failed to register commands; Exception {ex}");
await VS.MessageBox.ShowErrorAsync(
"Windsurf: Failed to register commands.",
"Windsurf might not work correctly. Please check the output window for more details.");
await VS.MessageBox.ShowErrorAsync("Windsurf: Failed to register commands.",
"Windsurf might not work correctly. Please check " +
"the output window for more details.");
}

try
Expand Down Expand Up @@ -226,9 +226,7 @@ public static void OpenInBrowser(string url)
{
Action<string>[] methods = [
(_url) =>
{
Process.Start(new ProcessStartInfo { FileName = _url, UseShellExecute = true });
},
{ Process.Start(new ProcessStartInfo { FileName = _url, UseShellExecute = true }); },
(_url) =>
{ Process.Start("explorer.exe", _url); },
(_url) =>
Expand Down
Loading