Add line formatting with auto indentation and fix syntax highlighting in editor

This commit is contained in:
Stone_Red
2026-03-04 23:02:40 +01:00
parent a2f621d3f4
commit 163bf677ae
3 changed files with 158 additions and 27 deletions
+112
View File
@@ -203,6 +203,118 @@ internal class TextEditor
return padding; return padding;
} }
public void FormatLines()
{
const int indentationSize = 4;
List<string> blockStack = [];
for (int i = 0; i < Lines.Count; i++)
{
string trimmed = Lines[i].Trim(' ');
if (string.IsNullOrWhiteSpace(trimmed))
{
Lines[i] = string.Empty;
continue;
}
if (trimmed.StartsWith('#'))
{
Lines[i] = trimmed;
continue;
}
if (trimmed == "else:")
{
for (int j = blockStack.Count - 1; j >= 0; j--)
{
if (blockStack[j] is "if" or "else")
{
blockStack.RemoveAt(j);
break;
}
}
}
bool isTerminatingStatement = trimmed == "exit"
|| trimmed.StartsWith("throw ", StringComparison.Ordinal)
|| trimmed.StartsWith("error ", StringComparison.Ordinal);
bool closesFunctionBlock = isTerminatingStatement && blockStack.Count > 0 && blockStack[^1] == "func";
if (trimmed == "end_if")
{
for (int j = blockStack.Count - 1; j >= 0; j--)
{
if (blockStack[j] is "if" or "else")
{
blockStack.RemoveAt(j);
break;
}
}
}
else if (trimmed == "end_while")
{
for (int j = blockStack.Count - 1; j >= 0; j--)
{
if (blockStack[j] == "while")
{
blockStack.RemoveAt(j);
break;
}
}
}
else if (trimmed == "return")
{
for (int j = blockStack.Count - 1; j >= 0; j--)
{
if (blockStack[j] == "func")
{
blockStack.RemoveAt(j);
break;
}
}
}
int lineIndentation = closesFunctionBlock ? Math.Max(0, blockStack.Count - 1) : blockStack.Count;
Lines[i] = new string(' ', lineIndentation * indentationSize) + trimmed;
if (!isTerminatingStatement && (
(trimmed.StartsWith("if ", StringComparison.Ordinal) && trimmed.EndsWith(':'))
|| (trimmed.StartsWith("while ", StringComparison.Ordinal) && trimmed.EndsWith(':'))
|| (trimmed.StartsWith("func ", StringComparison.Ordinal) && trimmed.EndsWith(':'))
|| trimmed == "else:"))
{
if (trimmed.StartsWith("if ", StringComparison.Ordinal))
{
blockStack.Add("if");
}
else if (trimmed.StartsWith("while ", StringComparison.Ordinal))
{
blockStack.Add("while");
}
else if (trimmed.StartsWith("func ", StringComparison.Ordinal))
{
blockStack.Add("func");
}
else
{
blockStack.Add("else");
}
}
if (isTerminatingStatement)
{
while (blockStack.Count > 0 && blockStack[^1] != "func")
{
blockStack.RemoveAt(blockStack.Count - 1);
}
if (closesFunctionBlock && blockStack.Count > 0 && blockStack[^1] == "func")
{
blockStack.RemoveAt(blockStack.Count - 1);
}
}
}
}
private static string ToLiteral(string input) private static string ToLiteral(string input)
{ {
return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(input, false); return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(input, false);
+23 -5
View File
@@ -47,6 +47,12 @@ internal class InputHandler(TextEditor textEditor)
case ConsoleKey.E: case ConsoleKey.E:
textEditor.CursorPosition.X = textEditor.Lines.Count > textEditor.CursorPosition.Y ? textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length : 0; textEditor.CursorPosition.X = textEditor.Lines.Count > textEditor.CursorPosition.Y ? textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length : 0;
return true; return true;
case ConsoleKey.F:
textEditor.FormatLines();
textEditor.Display(true);
WriteStatus("Formatted!");
return true;
} }
} }
if (keyInfo.Key == ConsoleKey.DownArrow) if (keyInfo.Key == ConsoleKey.DownArrow)
@@ -274,6 +280,11 @@ internal class InputHandler(TextEditor textEditor)
WriteStatus(string.Empty); WriteStatus(string.Empty);
break; break;
case "format":
textEditor.FormatLines();
WriteStatus("Formatted!");
break;
case "exit": case "exit":
return false; return false;
@@ -331,20 +342,28 @@ internal class InputHandler(TextEditor textEditor)
private void ExecuteWithDebugScreen(string saveInput, bool debugMode, bool stepMode) private void ExecuteWithDebugScreen(string saveInput, bool debugMode, bool stepMode)
{ {
if (textEditor.Save(saveInput, true)) string[] parts = saveInput.Split(' ', StringSplitOptions.RemoveEmptyEntries);
bool hasPathArgument = parts.Length > 1;
bool canRunUnsavedBuffer = !hasPathArgument && string.IsNullOrWhiteSpace(textEditor.CurrentPath);
bool canExecute = canRunUnsavedBuffer || textEditor.Save(saveInput, true);
if (!canExecute)
{ {
return;
}
textEditor.EditMode = Mode.Debug; textEditor.EditMode = Mode.Debug;
textEditor.IsStepDebugMode = stepMode; textEditor.IsStepDebugMode = stepMode;
Console.Clear(); Console.Clear();
Console.CursorVisible = true; Console.CursorVisible = true;
if (debugMode) if (canRunUnsavedBuffer)
{ {
textEditor.YesNtInterpreter.Execute(textEditor.CurrentPath, true); textEditor.YesNtInterpreter.Execute([.. textEditor.Lines], debugMode);
} }
else else
{ {
textEditor.YesNtInterpreter.Execute(textEditor.CurrentPath); textEditor.YesNtInterpreter.Execute(textEditor.CurrentPath, debugMode);
} }
while (Console.KeyAvailable) while (Console.KeyAvailable)
@@ -356,5 +375,4 @@ internal class InputHandler(TextEditor textEditor)
textEditor.IsStepDebugMode = false; textEditor.IsStepDebugMode = false;
textEditor.EditMode = Mode.Command; textEditor.EditMode = Mode.Command;
} }
}
} }
+5 -4
View File
@@ -30,7 +30,7 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
{ {
input = input.Replace("\0", string.Empty); input = input.Replace("\0", string.Empty);
if (input.StartsWith('#')) if (input.TrimStart(' ').StartsWith('#'))
{ {
input = AddColorInformation(input, input, ConsoleColor.Gray, SearchMode.Exact); input = AddColorInformation(input, input, ConsoleColor.Gray, SearchMode.Exact);
} }
@@ -68,7 +68,8 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
_ => statement.Name.Trim() _ => statement.Name.Trim()
}; };
input = input.TrimEnd(' '); input = input.TrimEnd(' ');
if (statement.SearchMode == SearchMode.StartOfLine && input.StartsWith(name)) string inputTrim = input.Trim(' ');
if (statement.SearchMode == SearchMode.StartOfLine && inputTrim.StartsWith(name))
{ {
if (statement.Separator is not null && input.Contains(statement.Separator)) if (statement.Separator is not null && input.Contains(statement.Separator))
{ {
@@ -78,7 +79,7 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
{ {
continue; continue;
} }
input = AddColorInformation(input, input[..name.Length], statement.Color, statement.SearchMode); input = AddColorInformation(input, name, statement.Color, statement.SearchMode);
} }
else if (statement.SearchMode == SearchMode.Contains && input.Contains(name)) else if (statement.SearchMode == SearchMode.Contains && input.Contains(name))
{ {
@@ -104,7 +105,7 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
} }
input = AddColorInformation(input, input[^name.Length..], statement.Color, statement.SearchMode); input = AddColorInformation(input, input[^name.Length..], statement.Color, statement.SearchMode);
} }
else if (statement.SearchMode == SearchMode.Exact && input.Equals(name)) else if (statement.SearchMode == SearchMode.Exact && inputTrim.Equals(name))
{ {
if (statement.Separator is not null && input.Contains(statement.Separator)) if (statement.Separator is not null && input.Contains(statement.Separator))
{ {