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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return Microsoft.CodeAnalysis.CSharp.SymbolDisplay.FormatLiteral(input, false);
|
||||
|
||||
@@ -47,6 +47,12 @@ internal class InputHandler(TextEditor textEditor)
|
||||
case ConsoleKey.E:
|
||||
textEditor.CursorPosition.X = textEditor.Lines.Count > textEditor.CursorPosition.Y ? textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length : 0;
|
||||
return true;
|
||||
|
||||
case ConsoleKey.F:
|
||||
textEditor.FormatLines();
|
||||
textEditor.Display(true);
|
||||
WriteStatus("Formatted!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (keyInfo.Key == ConsoleKey.DownArrow)
|
||||
@@ -274,6 +280,11 @@ internal class InputHandler(TextEditor textEditor)
|
||||
WriteStatus(string.Empty);
|
||||
break;
|
||||
|
||||
case "format":
|
||||
textEditor.FormatLines();
|
||||
WriteStatus("Formatted!");
|
||||
break;
|
||||
|
||||
case "exit":
|
||||
return false;
|
||||
|
||||
@@ -331,20 +342,28 @@ internal class InputHandler(TextEditor textEditor)
|
||||
|
||||
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.IsStepDebugMode = stepMode;
|
||||
Console.Clear();
|
||||
Console.CursorVisible = true;
|
||||
|
||||
if (debugMode)
|
||||
if (canRunUnsavedBuffer)
|
||||
{
|
||||
textEditor.YesNtInterpreter.Execute(textEditor.CurrentPath, true);
|
||||
textEditor.YesNtInterpreter.Execute([.. textEditor.Lines], debugMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
textEditor.YesNtInterpreter.Execute(textEditor.CurrentPath);
|
||||
textEditor.YesNtInterpreter.Execute(textEditor.CurrentPath, debugMode);
|
||||
}
|
||||
|
||||
while (Console.KeyAvailable)
|
||||
@@ -357,4 +376,3 @@ internal class InputHandler(TextEditor textEditor)
|
||||
textEditor.EditMode = Mode.Command;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
|
||||
{
|
||||
input = input.Replace("\0", string.Empty);
|
||||
|
||||
if (input.StartsWith('#'))
|
||||
if (input.TrimStart(' ').StartsWith('#'))
|
||||
{
|
||||
input = AddColorInformation(input, input, ConsoleColor.Gray, SearchMode.Exact);
|
||||
}
|
||||
@@ -68,7 +68,8 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
|
||||
_ => statement.Name.Trim()
|
||||
};
|
||||
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))
|
||||
{
|
||||
@@ -78,7 +79,7 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
|
||||
{
|
||||
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))
|
||||
{
|
||||
@@ -104,7 +105,7 @@ internal partial class SyntaxHighlighter(ReadOnlyCollection<StatementInformation
|
||||
}
|
||||
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))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user