Godot WIP
This commit is contained in:
@@ -121,7 +121,8 @@ public static class RoslynAnalysis
|
|||||||
Guard.Against.Null(compilation, nameof(compilation));
|
Guard.Against.Null(compilation, nameof(compilation));
|
||||||
|
|
||||||
var diagnostics = compilation.GetDiagnostics(cancellationToken);
|
var diagnostics = compilation.GetDiagnostics(cancellationToken);
|
||||||
return diagnostics.Where(d => d.Severity is not DiagnosticSeverity.Hidden).ToImmutableArray();
|
diagnostics = diagnostics.Where(d => d.Severity is not DiagnosticSeverity.Hidden).ToImmutableArray();
|
||||||
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<ImmutableArray<CodeAction>> GetCodeFixesAsync(Diagnostic diagnostic)
|
public static async Task<ImmutableArray<CodeAction>> GetCodeFixesAsync(Diagnostic diagnostic)
|
||||||
|
|||||||
BIN
src/SharpIDE.Godot/CascadiaCode.ttf
Normal file
BIN
src/SharpIDE.Godot/CascadiaCode.ttf
Normal file
Binary file not shown.
35
src/SharpIDE.Godot/CascadiaCode.ttf.import
Normal file
35
src/SharpIDE.Godot/CascadiaCode.ttf.import
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="font_data_dynamic"
|
||||||
|
type="FontFile"
|
||||||
|
uid="uid://7jc0nj310cu6"
|
||||||
|
path="res://.godot/imported/CascadiaCode.ttf-a3719bc78bb5325e1cfcc893e4ab58da.fontdata"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://CascadiaCode.ttf"
|
||||||
|
dest_files=["res://.godot/imported/CascadiaCode.ttf-a3719bc78bb5325e1cfcc893e4ab58da.fontdata"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
Rendering=null
|
||||||
|
antialiasing=1
|
||||||
|
generate_mipmaps=false
|
||||||
|
disable_embedded_bitmaps=true
|
||||||
|
multichannel_signed_distance_field=false
|
||||||
|
msdf_pixel_range=8
|
||||||
|
msdf_size=48
|
||||||
|
allow_system_fallback=true
|
||||||
|
force_autohinter=false
|
||||||
|
hinting=1
|
||||||
|
subpixel_positioning=4
|
||||||
|
keep_rounding_remainders=true
|
||||||
|
oversampling=0.0
|
||||||
|
Fallbacks=null
|
||||||
|
fallbacks=[]
|
||||||
|
Compress=null
|
||||||
|
compress=true
|
||||||
|
preload=[]
|
||||||
|
language_support={}
|
||||||
|
script_support={}
|
||||||
|
opentype_features={}
|
||||||
30
src/SharpIDE.Godot/CustomSyntaxHighlighter.cs
Normal file
30
src/SharpIDE.Godot/CustomSyntaxHighlighter.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Godot;
|
||||||
|
using Godot.Collections;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace SharpIDE.Godot;
|
||||||
|
|
||||||
|
public partial class CustomHighlighter : SyntaxHighlighter
|
||||||
|
{
|
||||||
|
public override Dictionary _GetLineSyntaxHighlighting(int line)
|
||||||
|
{
|
||||||
|
var highlights = new Dictionary();
|
||||||
|
var text = GetTextEdit().GetLine(line);
|
||||||
|
|
||||||
|
var regex = new Regex(@"\bTODO\b");
|
||||||
|
var matches = regex.Matches(text);
|
||||||
|
|
||||||
|
foreach (Match match in matches)
|
||||||
|
{
|
||||||
|
highlights[match.Index] = new Dictionary
|
||||||
|
{
|
||||||
|
{ "color", new Color(1, 0, 0) }, // red
|
||||||
|
{ "underline", true }, // not implemented
|
||||||
|
{ "length", match.Length } // not implemented
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return highlights;
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/SharpIDE.Godot/CustomSyntaxHighlighter.cs.uid
Normal file
1
src/SharpIDE.Godot/CustomSyntaxHighlighter.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://b6wpiabl7sutg
|
||||||
@@ -1,6 +1,51 @@
|
|||||||
extends Node
|
extends Node2D
|
||||||
|
|
||||||
|
# Declare an empty dictionary object
|
||||||
|
var game = {}
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
# Initialize a player dictionary
|
||||||
# asdfasdfasdfadsf asdf asdfa sdfadf
|
var player = {
|
||||||
|
"name": "Thor",
|
||||||
|
"inventory": ["sword", "shield", "map"],
|
||||||
|
"location": "Castellion",
|
||||||
|
"energy": 67
|
||||||
|
}
|
||||||
|
|
||||||
|
if game.empty():
|
||||||
|
# Add data to the game dictionary
|
||||||
|
game["player"] = player
|
||||||
|
game["score"] = 0
|
||||||
|
game["dummy"] = null
|
||||||
|
|
||||||
|
if game.has("dummy"):
|
||||||
|
game.erase("dummy")
|
||||||
|
|
||||||
|
print(game.get("dummy", "Key not found!"))
|
||||||
|
|
||||||
|
if game.has_all(["player", "score"]):
|
||||||
|
print(game["player"]["name"])
|
||||||
|
|
||||||
|
player["energy"] += 1
|
||||||
|
|
||||||
|
print(game.keys().size())
|
||||||
|
print(game.size())
|
||||||
|
print(player.values()[0])
|
||||||
|
|
||||||
|
# Alternative way to initialize a dictionary
|
||||||
|
var d = {
|
||||||
|
a = {
|
||||||
|
a1 = {
|
||||||
|
a11 = 1, a12 = 2
|
||||||
|
},
|
||||||
|
a2 = 3
|
||||||
|
},
|
||||||
|
b = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Make copies of the dictionary
|
||||||
|
var deep_copy = d.duplicate(true)
|
||||||
|
var shallow_copy = d.duplicate()
|
||||||
|
print(deep_copy)
|
||||||
|
# I expected the shallow copy to be truncated
|
||||||
|
print(shallow_copy)
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.Loader;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Microsoft.Build.Locator;
|
||||||
|
using Microsoft.CodeAnalysis.CodeFixes;
|
||||||
|
using Microsoft.CodeAnalysis.Host.Mef;
|
||||||
|
using SharpIDE.Application.Features.Analysis;
|
||||||
|
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||||
|
|
||||||
namespace SharpIDE.Godot;
|
namespace SharpIDE.Godot;
|
||||||
|
|
||||||
@@ -8,13 +18,26 @@ public partial class IdeRoot : Control
|
|||||||
private FileDialog _fileDialog = null!;
|
private FileDialog _fileDialog = null!;
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
|
MSBuildLocator.RegisterDefaults();
|
||||||
|
|
||||||
_openSlnButton = GetNode<Button>("%OpenSlnButton");
|
_openSlnButton = GetNode<Button>("%OpenSlnButton");
|
||||||
_fileDialog = GetNode<FileDialog>("%OpenSolutionDialog");
|
_fileDialog = GetNode<FileDialog>("%OpenSolutionDialog");
|
||||||
_fileDialog.FileSelected += OnFileSelected;
|
_fileDialog.FileSelected += OnFileSelected;
|
||||||
|
//_fileDialog.Visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFileSelected(string path)
|
private async void OnFileSelected(string path)
|
||||||
{
|
{
|
||||||
GD.Print($"Selected: {path}");
|
try
|
||||||
|
{
|
||||||
|
GD.Print($"Selected: {path}");
|
||||||
|
var solutionModel = await VsPersistenceMapper.GetSolutionModel(path);
|
||||||
|
RoslynAnalysis.StartSolutionAnalysis(path);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
GD.PrintErr($"Error loading solution: {e.Message}");
|
||||||
|
GD.PrintErr(e.StackTrace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://b2oniigcp5ew5"]
|
[gd_scene load_steps=4 format=3 uid="uid://b2oniigcp5ew5"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bavypuy7b375x" path="res://IdeRoot.cs" id="1_whawi"]
|
[ext_resource type="Script" uid="uid://bavypuy7b375x" path="res://IdeRoot.cs" id="1_whawi"]
|
||||||
|
[ext_resource type="Script" uid="uid://du2lt7r1p1qfy" path="res://SharpIdeCodeEdit.cs" id="2_qjf5e"]
|
||||||
|
[ext_resource type="FontFile" uid="uid://7jc0nj310cu6" path="res://CascadiaCode.ttf" id="2_rk34b"]
|
||||||
|
|
||||||
[node name="IdeRoot" type="Control"]
|
[node name="IdeRoot" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
@@ -46,16 +48,20 @@ split_offset = 250
|
|||||||
[node name="SolutionExplorerPanel" type="Panel" parent="VBoxContainer/HBoxContainer/HSplitContainer"]
|
[node name="SolutionExplorerPanel" type="Panel" parent="VBoxContainer/HBoxContainer/HSplitContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="CodeEdit" type="CodeEdit" parent="VBoxContainer/HBoxContainer/HSplitContainer"]
|
[node name="SharpIdeCodeEdit" type="CodeEdit" parent="VBoxContainer/HBoxContainer/HSplitContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
theme_override_fonts/font = ExtResource("2_rk34b")
|
||||||
|
highlight_current_line = true
|
||||||
gutters_draw_line_numbers = true
|
gutters_draw_line_numbers = true
|
||||||
code_completion_enabled = true
|
code_completion_enabled = true
|
||||||
auto_brace_completion_enabled = true
|
auto_brace_completion_enabled = true
|
||||||
|
script = ExtResource("2_qjf5e")
|
||||||
|
HighlightStartOffset = 0
|
||||||
|
|
||||||
[node name="OpenSolutionDialog" type="FileDialog" parent="."]
|
[node name="OpenSolutionDialog" type="FileDialog" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
title = "Open a File"
|
title = "Open a File"
|
||||||
visible = true
|
position = Vector2i(0, 36)
|
||||||
ok_button_text = "Open"
|
ok_button_text = "Open"
|
||||||
dialog_hide_on_ok = true
|
dialog_hide_on_ok = true
|
||||||
file_mode = 0
|
file_mode = 0
|
||||||
|
|||||||
80
src/SharpIDE.Godot/SharpIdeCodeEdit.cs
Normal file
80
src/SharpIDE.Godot/SharpIdeCodeEdit.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace SharpIDE.Godot;
|
||||||
|
|
||||||
|
public partial class SharpIdeCodeEdit : CodeEdit
|
||||||
|
{
|
||||||
|
[Signal]
|
||||||
|
public delegate void CodeFixesRequestedEventHandler();
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public int HighlightStartOffset = 0;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
public int HighlightEndOffset = 0;
|
||||||
|
|
||||||
|
private int _currentLine;
|
||||||
|
private int _selectionStartCol;
|
||||||
|
private int _selectionEndCol;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
//AddThemeFontOverride("Cascadia Code", ResourceLoader.Load<Font>("res://CascadiaCode.ttf"));
|
||||||
|
this.CodeCompletionRequested += OnCodeCompletionRequested;
|
||||||
|
this.CodeFixesRequested += OnCodeFixesRequested;
|
||||||
|
this.CaretChanged += () =>
|
||||||
|
{
|
||||||
|
_selectionStartCol = GetSelectionFromColumn();
|
||||||
|
_selectionEndCol = GetSelectionToColumn();
|
||||||
|
_currentLine = GetCaretLine();
|
||||||
|
GD.Print($"Selection changed to line {_currentLine}, start {_selectionStartCol}, end {_selectionEndCol}");
|
||||||
|
};
|
||||||
|
this.SyntaxHighlighter = new CustomHighlighter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnderlineRange(int line, int caretStartCol, int caretEndCol, Color color, float thickness = 1.5f)
|
||||||
|
{
|
||||||
|
if (line < 0 || line >= GetLineCount())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (caretStartCol >= caretEndCol) // nothing to draw
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Clamp columns to line length
|
||||||
|
int lineLength = GetLine(line).Length;
|
||||||
|
caretStartCol = Mathf.Clamp(caretStartCol, 0, lineLength);
|
||||||
|
caretEndCol = Mathf.Clamp(caretEndCol, 0, lineLength);
|
||||||
|
|
||||||
|
var charRect = GetRectAtLineColumn(line, caretEndCol);
|
||||||
|
var charWidth = charRect.Size.X;
|
||||||
|
|
||||||
|
var startPos = GetPosAtLineColumn(line, caretStartCol);
|
||||||
|
if (caretStartCol is 0)
|
||||||
|
{
|
||||||
|
startPos.X -= 9; // Seems to be a bug or intended "feature" of GetPosAtLineColumn
|
||||||
|
}
|
||||||
|
var endPos = GetPosAtLineColumn(line, caretEndCol);
|
||||||
|
startPos.X += charWidth;
|
||||||
|
endPos.X += charWidth;
|
||||||
|
startPos.Y -= 1;
|
||||||
|
endPos.Y -= 1;
|
||||||
|
DrawLine(startPos, endPos, color, thickness);
|
||||||
|
}
|
||||||
|
public override void _Draw()
|
||||||
|
{
|
||||||
|
UnderlineRange(_currentLine, _selectionStartCol, _selectionEndCol, new Color(1, 0, 0));
|
||||||
|
//UnderlineRange(_currentLine, 0, 7, new Color(1, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCodeFixesRequested()
|
||||||
|
{
|
||||||
|
GD.Print("Code fixes requested");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCodeCompletionRequested()
|
||||||
|
{
|
||||||
|
var caretColumn = GetCaretColumn();
|
||||||
|
var caretLine = GetCaretLine();
|
||||||
|
GD.Print($"Code completion requested at line {caretLine}, column {caretColumn}");
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/SharpIDE.Godot/SharpIdeCodeEdit.cs.uid
Normal file
1
src/SharpIDE.Godot/SharpIdeCodeEdit.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://du2lt7r1p1qfy
|
||||||
Reference in New Issue
Block a user