Skip to content

Commit

Permalink
enhance documentcolor
Browse files Browse the repository at this point in the history
  • Loading branch information
CppCXY committed Jun 27, 2024
1 parent dbdbc7e commit a3f7230
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 56 deletions.
35 changes: 27 additions & 8 deletions EmmyLua.LanguageServer/CodeLens/CodeLensBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
using EmmyLua.CodeAnalysis.Compilation.Semantic;
using EmmyLua.CodeAnalysis.Compilation.Search;
using EmmyLua.CodeAnalysis.Compilation.Semantic;
using EmmyLua.CodeAnalysis.Syntax.Kind;
using EmmyLua.CodeAnalysis.Syntax.Node;
using EmmyLua.CodeAnalysis.Syntax.Node.SyntaxNodes;
using EmmyLua.LanguageServer.Server;
using EmmyLua.LanguageServer.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;

namespace EmmyLua.LanguageServer.CodeLens;

public class CodeLensBuilder
{
public static string VscodeCommandName = "emmy.showReferences";
private const string VscodeCommandName = "emmy.showReferences";
private const string OtherCommandName = "editor.action.showReferences";

private static readonly JsonSerializer Serializer = new JsonSerializer()
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};

public CodeLensContainer Build(SemanticModel semanticModel, ServerContext context)
{
Expand Down Expand Up @@ -56,10 +65,10 @@ public OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens Resolve(
var semanticModel = context.GetSemanticModel(documentId);
if (semanticModel is not null)
{
var references = semanticModel.FindReferences(element);
var references = semanticModel.FindReferences(element).ToList();
codeLens = codeLens with
{
Command = MakeCommand(references.Count() - 1, nameElement)
Command = MakeCommand(references, nameElement, context)
};
}
}
Expand All @@ -73,17 +82,27 @@ public OmniSharp.Extensions.LanguageServer.Protocol.Models.CodeLens Resolve(

return codeLens;
}



private static Command MakeCommand(int count, LuaSyntaxElement element)
private static Command MakeCommand(List<ReferenceResult> results, LuaSyntaxElement element,
ServerContext serverContext)
{
var range = element.Range;
var line = element.Tree.Document.GetLine(range.StartOffset);
var col = element.Tree.Document.GetCol(range.StartOffset);
var position = new Position(line, col);
var locations = results.Select(it => it.Location.ToLspLocation()).ToList();
return new Command
{
Title = $"{count} usage",
Name = VscodeCommandName,
Arguments = [element.Tree.Document.Uri, line, col]
Title = $"{results.Count - 1} usage",
Name = serverContext.IsVscode ? VscodeCommandName : OtherCommandName,
Arguments =
[
element.Tree.Document.Uri,
JToken.FromObject(position, Serializer),
JToken.FromObject(locations, Serializer)
]
};
}
}
121 changes: 77 additions & 44 deletions EmmyLua.LanguageServer/DocumentColor/DocumentColorBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using EmmyLua.CodeAnalysis.Document;
using EmmyLua.CodeAnalysis.Syntax.Kind;
using EmmyLua.CodeAnalysis.Syntax.Node;
using EmmyLua.CodeAnalysis.Syntax.Node.SyntaxNodes;
using EmmyLua.LanguageServer.Util;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;

Expand All @@ -15,83 +16,115 @@ public List<ColorInformation> Build(SemanticModel semanticModel)
var colors = new List<ColorInformation>();
var stringTokens = semanticModel
.Document.SyntaxTree.SyntaxRoot.DescendantsWithToken
.OfType<LuaSyntaxToken>();
.OfType<LuaStringToken>();

foreach (var token in stringTokens)
{
if (token is { Kind: LuaTokenKind.TkString or LuaTokenKind.TkDocDetail })
{
CheckColor(token, colors, semanticModel);
}
CheckColor(token, colors, semanticModel);
}

return colors;
}

private void CheckColor(LuaSyntaxToken token, List<ColorInformation> colors, SemanticModel semanticModel)
private void CheckColor(LuaStringToken token, List<ColorInformation> colors, SemanticModel semanticModel)
{
var text = token.RepresentText;
var pos = 0;
var text = token.Text;

while ((pos = text.IndexOf('#', pos)) != -1)
for (var i = 0; i < text.Length; i++)
{
var start = pos;
var end = pos + 7;
if (end > text.Length)
if (char.IsAsciiHexDigit(text[i]))
{
return;
}

var sourceRange = new SourceRange()
{
StartOffset = token.Range.StartOffset + start,
Length = 7
};

var color = text.Substring(start, 7);
var start = i;
var length = 1;
while (i + length < text.Length && char.IsAsciiHexDigit(text[i + length]))
{
length++;
}

try
{
colors.Add(new ColorInformation()
if (length is 6 or 8)
{
Range = sourceRange.ToLspRange(semanticModel.Document),
Color = new OmniSharp.Extensions.LanguageServer.Protocol.Models.DocumentColor()
var range = new SourceRange()
{
Red = int.Parse(color.Substring(1, 2), NumberStyles.HexNumber) / 255.0,
Green = int.Parse(color.Substring(3, 2), NumberStyles.HexNumber) / 255.0,
Blue = int.Parse(color.Substring(5, 2), NumberStyles.HexNumber) / 255.0,
Alpha = 1
}
});
StartOffset = token.Range.StartOffset + start,
Length = length
};
AddColorInformation(text[start..(start + length)], range, colors, semanticModel);
}

i += length;
}
catch (Exception)
}
}

void AddColorInformation(ReadOnlySpan<char> colorText, SourceRange range, List<ColorInformation> colors,
SemanticModel semanticModel)
{
if (colorText.Length == 6)
{
var red = int.Parse(colorText.Slice(0, 2), NumberStyles.HexNumber) / 255.0f;
var green = int.Parse(colorText.Slice(2, 2), NumberStyles.HexNumber) / 255.0f;
var blue = int.Parse(colorText.Slice(4, 2), NumberStyles.HexNumber) / 255.0f;

colors.Add(new ColorInformation()
{
// ignored
}
Range = range.ToLspRange(semanticModel.Document),
Color = new OmniSharp.Extensions.LanguageServer.Protocol.Models.DocumentColor()
{
Red = red,
Green = green,
Blue = blue,
Alpha = 1
}
});
}
else if (colorText.Length == 8)
{
var red = int.Parse(colorText.Slice(0, 2), NumberStyles.HexNumber) / 255.0f;
var green = int.Parse(colorText.Slice(2, 2), NumberStyles.HexNumber) / 255.0f;
var blue = int.Parse(colorText.Slice(4, 2), NumberStyles.HexNumber) / 255.0f;
var alpha = int.Parse(colorText.Slice(6, 2), NumberStyles.HexNumber) / 255.0f;

pos = end;
colors.Add(new ColorInformation()
{
Range = range.ToLspRange(semanticModel.Document),
Color = new OmniSharp.Extensions.LanguageServer.Protocol.Models.DocumentColor()
{
Red = red,
Green = green,
Blue = blue,
Alpha = alpha
}
});
}
}

public List<ColorPresentation> ModifyColor(ColorInformation info, SemanticModel semanticModel)
{
var range = info.Range;
var rangeLength = 0;
if (range is { Start: { } start, End: { } end })
{
rangeLength = end.Character - start.Character;
}

var color = info.Color;
var colorPresentations = new List<ColorPresentation>();
var r = (int) (color.Red * 255);
var g = (int) (color.Green * 255);
var b = (int) (color.Blue * 255);

var r = (int)(color.Red * 255);
var g = (int)(color.Green * 255);
var b = (int)(color.Blue * 255);
var a = (int)(color.Alpha * 255);

var newText = rangeLength == 6 ? $"{r:X2}{g:X2}{b:X2}" : $"{r:X2}{g:X2}{b:X2}{a:X2}";
var colorPresentation = new ColorPresentation()
{
Label = $"#{r:X2}{g:X2}{b:X2}",
Label = $"{r:X2}{g:X2}{b:X2}",
TextEdit = new TextEdit()
{
Range = info.Range,
NewText = $"#{r:X2}{g:X2}{b:X2}"
NewText = newText
}
};
colorPresentations.Add(colorPresentation);
return colorPresentations;
}
}
}
4 changes: 1 addition & 3 deletions EmmyLua.LanguageServer/DocumentColor/DocumentColorHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ public class DocumentColorHandler(ServerContext context) : DocumentColorHandlerB
protected override DocumentColorRegistrationOptions CreateRegistrationOptions(ColorProviderCapability capability,
ClientCapabilities clientCapabilities)
{
return new()
{
};
return new();
}

public override Task<Container<ColorInformation>?> Handle(DocumentColorParams request, CancellationToken cancellationToken)
Expand Down
2 changes: 1 addition & 1 deletion EmmyLua/CodeAnalysis/Common/ILocation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ public interface ILocation

public string UriLocation => $"{Document.Uri}#{StartLine}:{StartCol}-{EndLine}:{EndCol}";

public string LspLocation => $"{Document.Uri}#{StartLine + 1}:{StartCol}";
public string LspLocation => $"{Document.Uri}#L{StartLine + 1}:{StartCol}";
}

0 comments on commit a3f7230

Please sign in to comment.