Skip to content
This repository has been archived by the owner on Jul 10, 2024. It is now read-only.

Commit

Permalink
inlayhintgenerator with anchor and binarysearch
Browse files Browse the repository at this point in the history
  • Loading branch information
HendrikMennen committed Jul 3, 2024
1 parent 762d3b3 commit cf22a8d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 90 deletions.
6 changes: 3 additions & 3 deletions src/OneWare.Essentials/EditorExtensions/ExtendedTextEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ExtendedTextEditor : TextEditor
// private ElementGenerator ElementGenerator { get; }
public FoldingManager? FoldingManager { get; private set; }

public InlayHintRenderer InlayHintRenderer { get; }
public InlayHintGenerator InlayHintGenerator { get; }

public ExtendedTextEditor()
{
Expand All @@ -51,7 +51,7 @@ public ExtendedTextEditor()
WordRenderer = new WordHighlightRenderer(TextArea.TextView);
MarkerService = new TextMarkerService(Document);
ModificationService = new TextModificationService(TextArea.TextView);
InlayHintRenderer = new InlayHintRenderer(this);
InlayHintGenerator = new InlayHintGenerator(this);

TextArea.TextView.BackgroundRenderers.Add(BracketRenderer);
TextArea.TextView.BackgroundRenderers.Add(LineRenderer);
Expand All @@ -61,7 +61,7 @@ public ExtendedTextEditor()

TextArea.TextView.LineTransformers.Add(ModificationService);
//TextArea.TextView.ElementGenerators.Add(ElementGenerator);
TextArea.TextView.ElementGenerators.Add(InlayHintRenderer);
TextArea.TextView.ElementGenerators.Add(InlayHintGenerator);
}

protected override void OnDocumentChanged(DocumentChangedEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,52 +11,54 @@ namespace OneWare.Essentials.EditorExtensions;

public class InlayHint
{
public TextLocation Location { get; init; }

//Will be used internally
public int Offset { get; set; } = -1;

public string Text { get; init; } = string.Empty;
}

public class InlayHintRenderer : VisualLineElementGenerator
internal class InlayHintWithAnchor
{
public InlayHint Hint { get; init; }

Check warning on line 21 in src/OneWare.Essentials/EditorExtensions/InlayHintGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Hint' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 21 in src/OneWare.Essentials/EditorExtensions/InlayHintGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Hint' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public TextAnchor Anchor { get; set; }

Check warning on line 22 in src/OneWare.Essentials/EditorExtensions/InlayHintGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Anchor' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 22 in src/OneWare.Essentials/EditorExtensions/InlayHintGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Anchor' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
public Control Control { get; set; }

Check warning on line 23 in src/OneWare.Essentials/EditorExtensions/InlayHintGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Control' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 23 in src/OneWare.Essentials/EditorExtensions/InlayHintGenerator.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Control' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
}

public class InlayHintGenerator : VisualLineElementGenerator
{
private readonly TextEditor _editor;
private readonly List<InlayHint> _hints = [];
private readonly List<Control> _hintControls = [];
private readonly List<InlayHintWithAnchor> _hints = [];

public InlayHintRenderer(TextEditor editor)
public InlayHintGenerator(TextEditor editor)
{
_editor = editor;
}

public void SetInlineHints(IEnumerable<InlayHint> hints)
{
_hints.Clear();
_hintControls.Clear();

_hints.AddRange(hints);

var foreground = Application.Current!.FindResource(Application.Current!.RequestedThemeVariant, "ThemeForegroundLowBrush") as IBrush;
var background = Application.Current!.FindResource(Application.Current!.RequestedThemeVariant, "ThemeBackgroundBrush") as IBrush;

foreach (var hint in _hints)
_hints.AddRange(hints.Select(x => new InlayHintWithAnchor()
{
_hintControls.Add(new Border()
Hint = x,
Anchor = _editor.Document.CreateAnchor(x.Offset),
Control = new Border()
{
Margin = new Thickness(1, 0, 5, 0),
Background = background,
CornerRadius = new CornerRadius(3),
VerticalAlignment = VerticalAlignment.Center,
Child = new TextBlock()
{
Text = hint.Text,
Text = x.Text,
Foreground = foreground,
Margin = new Thickness(2,0),
VerticalAlignment = VerticalAlignment.Center
}
});
}
}
}));

_editor.TextArea.TextView.Redraw();
}
Expand All @@ -66,53 +68,25 @@ public void ClearInlineHints()
_hints.Clear();
_editor.TextArea.TextView.Redraw();
}

private static InlayHint? FindNextPosition(List<InlayHint> positions, TextLocation startPosition)
{
int left = 0;
int right = positions.Count - 1;

while (left <= right)
{
int mid = left + (right - left) / 2;
int comparison = positions[mid].Location.CompareTo(startPosition);

if (comparison >= 0)
{
if (mid == 0 || positions[mid - 1].Location.CompareTo(startPosition) < 0)
{
return positions[mid];
}
right = mid - 1;
}
else
{
left = mid + 1;
}
}

return null;
}

public override int GetFirstInterestedOffset(int startOffset)
{
var position = _editor.Document.GetLocation(startOffset);
var next = FindNextPosition(_hints, position);
var index = _hints.BinarySearch(startOffset, (a, b) => a.CompareTo(b.Anchor.Offset));;

if(next == null)
return -1;
if (index < 0)
index = ~index;
if (index < _hints.Count)
{
return _hints[index].Anchor.Offset;
}

next.Offset = _editor.Document.GetOffset(next.Location);
return next.Offset;
return -1;
}

public override VisualLineElement? ConstructElement(int offset)
{
var index = _hints.FindIndex(hint => hint.Offset == offset);
var index = _hints.BinarySearch(offset, (a, b) => a.CompareTo(b.Anchor.Offset));

if (index < 0) return null;

var control = _hintControls[index];
return new InlineObjectElement(0, control);
return index < 0 ? null : new InlineObjectElement(0, _hints[index].Control);
}
}
30 changes: 0 additions & 30 deletions src/OneWare.Essentials/EditorExtensions/InlayHintLineText.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ protected override void OnAssistanceDeactivated()
base.OnAssistanceDeactivated();
Editor.Editor.ModificationService.ClearModification("caretHighlight");
Editor.Editor.ModificationService.ClearModification("semanticTokens");
Editor.Editor.InlayHintRenderer.ClearInlineHints();
Editor.Editor.InlayHintGenerator.ClearInlineHints();
}

protected virtual void DocumentChanged(object? sender, DocumentChangeEventArgs e)
Expand Down Expand Up @@ -598,15 +598,15 @@ protected virtual async Task UpdateInlayHintsAsync()

if (inlayHintContainer is not null)
{
Editor.Editor.InlayHintRenderer.SetInlineHints(inlayHintContainer.Select(x => new InlayHint()
Editor.Editor.InlayHintGenerator.SetInlineHints(inlayHintContainer.Select(x => new InlayHint()
{
Location = new TextLocation(x.Position.Line + 1, x.Position.Character + 1),
Offset = Editor.CurrentDocument.GetOffset(x.Position.Line+1, x.Position.Character+1),
Text = x.Label.ToString()
}));
}
else
{
Editor.Editor.InlayHintRenderer.ClearInlineHints();
Editor.Editor.InlayHintGenerator.ClearInlineHints();
}
}

Expand Down

0 comments on commit cf22a8d

Please sign in to comment.