mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-04 00:56:31 +02:00
Add line formatting with auto indentation and fix syntax highlighting in editor
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user