120 lines
4.7 KiB
C#
120 lines
4.7 KiB
C#
using Godot;
|
|
using Microsoft.CodeAnalysis.Completion;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
using SharpIDE.Godot.Features.Problems;
|
|
|
|
namespace SharpIDE.Godot.Features.CodeEditor;
|
|
|
|
public partial class SharpIdeCodeEdit
|
|
{
|
|
private bool CompletionsPopupTryConsumeGuiInput(InputEvent @event)
|
|
{
|
|
var isCodeCompletionPopupOpen = _codeCompletionOptions.Length is not 0;
|
|
if (isCodeCompletionPopupOpen is false)
|
|
{
|
|
if (@event.IsActionPressed(InputStringNames.CodeEditorRequestCompletions))
|
|
{
|
|
completionTrigger = new CompletionTrigger(CompletionTriggerKind.InvokeAndCommitIfUnique);
|
|
CustomCodeCompletionRequested.InvokeParallelFireAndForget(completionTrigger!.Value, Text, GetCaretPosition());
|
|
return true;
|
|
}
|
|
}
|
|
if (isCodeCompletionPopupOpen)
|
|
{
|
|
if (@event is InputEventMouseButton { Pressed: true, ButtonIndex: MouseButton.Left or MouseButton.Right } mouseEvent)
|
|
{
|
|
var codeCompletionIndex = GetCompletionOptionAtPoint((Vector2I)mouseEvent.Position);
|
|
if (codeCompletionIndex is null)
|
|
{
|
|
// if the index is null, it means we clicked outside the completion popup, so close it
|
|
ResetCompletionPopupState();
|
|
return false;
|
|
}
|
|
|
|
// If no item is currently centered
|
|
if (_codeCompletionForceItemCenter is -1)
|
|
{
|
|
// center the current central item, as an anchor, before we update the selection
|
|
_codeCompletionForceItemCenter = _codeCompletionCurrentSelected;
|
|
}
|
|
|
|
_codeCompletionCurrentSelected = codeCompletionIndex.Value;
|
|
if (mouseEvent is { DoubleClick: true })
|
|
{
|
|
ApplySelectedCodeCompletion();
|
|
return true;
|
|
}
|
|
|
|
GD.Print($"Code completion option clicked: {codeCompletionIndex.Value}");
|
|
QueueRedraw();
|
|
return true;
|
|
}
|
|
|
|
if (@event is InputEventMouseButton { Pressed: true, ButtonIndex: MouseButton.WheelDown or MouseButton.WheelUp } scrollEvent)
|
|
{
|
|
if (_codeCompletionRect.HasPoint((Vector2I)scrollEvent.Position))
|
|
{
|
|
int scrollAmount = scrollEvent.ButtonIndex is MouseButton.WheelDown ? 1 : -1;
|
|
_codeCompletionCurrentSelected = Mathf.Clamp(
|
|
_codeCompletionCurrentSelected + scrollAmount,
|
|
0,
|
|
_codeCompletionOptions.Length - 1
|
|
);
|
|
_codeCompletionForceItemCenter = -1;
|
|
QueueRedraw();
|
|
return true;
|
|
}
|
|
}
|
|
else if (@event.IsActionPressed(InputStringNames.Backspace))
|
|
{
|
|
pendingCompletionFilterReason = CompletionFilterReason.Deletion;
|
|
return false;
|
|
}
|
|
|
|
if (@event is InputEventKey { Pressed: true, Keycode: Key.Up or Key.Down } inputEventKey)
|
|
{
|
|
var delta = inputEventKey.Keycode is Key.Up ? -1 : 1;
|
|
_codeCompletionCurrentSelected = Mathf.Clamp(
|
|
_codeCompletionCurrentSelected + delta,
|
|
0,
|
|
_codeCompletionOptions.Length - 1
|
|
);
|
|
_codeCompletionForceItemCenter = -1;
|
|
QueueRedraw();
|
|
return true;
|
|
}
|
|
|
|
if (@event is InputEventKey { Pressed: true, Keycode: Key.Escape })
|
|
{
|
|
ResetCompletionPopupState();
|
|
QueueRedraw();
|
|
return true;
|
|
}
|
|
|
|
if (@event is InputEventKey { Pressed: true, Keycode: Key.Enter or Key.Tab })
|
|
{
|
|
ApplySelectedCodeCompletion();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (@event is InputEventKey { Pressed: true, Unicode: not 0 } keyEvent)
|
|
{
|
|
|
|
var unicodeString = char.ConvertFromUtf32((int)keyEvent.Unicode);
|
|
if (isCodeCompletionPopupOpen && keyEvent.Unicode >= 32)
|
|
{
|
|
pendingCompletionFilterReason = CompletionFilterReason.Insertion;
|
|
return false; // Let the text update happen
|
|
}
|
|
|
|
if (isCodeCompletionPopupOpen is false && _codeCompletionTriggers.Contains(unicodeString, StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
_pendingCompletionTrigger = CompletionTrigger.CreateInsertionTrigger(unicodeString[0]);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
} |