mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-04 09:06:41 +02:00
- Add cls statement (clear screen)
- Improved code structure of the editor - Some bug fixes
This commit is contained in:
@@ -44,12 +44,12 @@ namespace YesNt.Interpreter
|
|||||||
|
|
||||||
private void ParentRuntimeInformation_OnExit(string exitMessage, bool stopChildTasks)
|
private void ParentRuntimeInformation_OnExit(string exitMessage, bool stopChildTasks)
|
||||||
{
|
{
|
||||||
Exit($"Parent task was terminated!", stopChildTasks);
|
Exit($"Terminated by parent task", stopChildTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteLine(string output)
|
public void WriteLine(string output, bool forceWrite = false)
|
||||||
{
|
{
|
||||||
if (Stop)
|
if (Stop && !forceWrite || parentRuntimeInformation?.StopAllTasks == true && !forceWrite)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ namespace YesNt.Interpreter
|
|||||||
{
|
{
|
||||||
if (IsTask)
|
if (IsTask)
|
||||||
{
|
{
|
||||||
parentRuntimeInformation.WriteLine(output.FromSaveString() + Environment.NewLine);
|
parentRuntimeInformation.WriteLine(output.FromSaveString(), forceWrite);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -71,9 +71,9 @@ namespace YesNt.Interpreter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(string output)
|
public void Write(string output, bool forceWrite = false)
|
||||||
{
|
{
|
||||||
if (Stop)
|
if (Stop && !forceWrite || parentRuntimeInformation?.StopAllTasks == true && !forceWrite)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ namespace YesNt.Interpreter
|
|||||||
{
|
{
|
||||||
if (IsTask)
|
if (IsTask)
|
||||||
{
|
{
|
||||||
parentRuntimeInformation.Write(output.FromSaveString());
|
parentRuntimeInformation.Write(output.FromSaveString(), forceWrite);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -99,7 +99,7 @@ namespace YesNt.Interpreter
|
|||||||
{
|
{
|
||||||
if (!Stop)
|
if (!Stop)
|
||||||
{
|
{
|
||||||
WriteLine($"{Environment.NewLine}[{(IsTask ? "A child task" : "The process")} was terminated at line {LineNumber + 1} with the message: {message}]");
|
WriteLine($"{Environment.NewLine}[{(IsTask ? "A child task" : "The process")} was terminated at line {LineNumber + 1} with the message: {message}]", true);
|
||||||
Stop = true;
|
Stop = true;
|
||||||
}
|
}
|
||||||
if (stopAllTasks == true && StopAllTasks == false)
|
if (stopAllTasks == true && StopAllTasks == false)
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ namespace YesNt.Interpreter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
runtimeInfo.Exit($"Label \"{runtimeInfo.SearchLabel}\" not found", false);
|
runtimeInfo.Exit($"Label \"{runtimeInfo.SearchLabel}\" not found", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,5 +48,11 @@ namespace YesNt.Interpreter.Statements
|
|||||||
}
|
}
|
||||||
RuntimeInfo.CurrentLine = args.TrimEnd();
|
RuntimeInfo.CurrentLine = args.TrimEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Statement("cls", SearchMode.Exact, SpaceAround.None)]
|
||||||
|
public void Clear(string args)
|
||||||
|
{
|
||||||
|
Console.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+96
-280
@@ -8,15 +8,17 @@ namespace YesNt.CodeEditor
|
|||||||
{
|
{
|
||||||
internal class TextEditor
|
internal class TextEditor
|
||||||
{
|
{
|
||||||
private readonly YesNtInterpreter yesNtInterpreter = new();
|
private readonly InputHandler inputHandler;
|
||||||
private readonly SyntaxHighlighter syntaxHighlighter;
|
private readonly SyntaxHighlighter syntaxHighlighter;
|
||||||
private int lineOffset = 0;
|
|
||||||
private readonly List<string> lines = new();
|
|
||||||
private readonly List<string> debugOutput = new();
|
private readonly List<string> debugOutput = new();
|
||||||
private readonly Point cursorPosition = new(0, 0);
|
|
||||||
private Mode mode = Mode.Command;
|
|
||||||
|
|
||||||
private string currentPath = string.Empty;
|
public YesNtInterpreter yesNtInterpreter { get; } = new();
|
||||||
|
|
||||||
|
public int LineOffset { get; set; } = 0;
|
||||||
|
public List<string> Lines { get; } = new();
|
||||||
|
public Point CursorPosition { get; } = new(0, 0);
|
||||||
|
public Mode EditMode { get; set; } = Mode.Command;
|
||||||
|
public string CurrentPath { get; set; } = string.Empty;
|
||||||
|
|
||||||
public TextEditor(string path) : this()
|
public TextEditor(string path) : this()
|
||||||
{
|
{
|
||||||
@@ -32,6 +34,7 @@ namespace YesNt.CodeEditor
|
|||||||
yesNtInterpreter.OnDebugOutput += YesNtInterpreter_OnDebugOutput;
|
yesNtInterpreter.OnDebugOutput += YesNtInterpreter_OnDebugOutput;
|
||||||
yesNtInterpreter.OnLineExecuted += YesNtInterpreter_OnLineExecuted;
|
yesNtInterpreter.OnLineExecuted += YesNtInterpreter_OnLineExecuted;
|
||||||
syntaxHighlighter = new(yesNtInterpreter.StatementInformation);
|
syntaxHighlighter = new(yesNtInterpreter.StatementInformation);
|
||||||
|
inputHandler = new InputHandler(this);
|
||||||
Console.CancelKeyPress += Console_CancelKeyPress;
|
Console.CancelKeyPress += Console_CancelKeyPress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,33 +46,45 @@ namespace YesNt.CodeEditor
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
Display(false);
|
Display(false);
|
||||||
} while (HandleInput());
|
} while (inputHandler.HandleInput());
|
||||||
|
Console.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Display(bool drawAll)
|
public void Display(bool drawAll)
|
||||||
{
|
{
|
||||||
Console.CursorVisible = false;
|
Console.CursorVisible = false;
|
||||||
|
|
||||||
Console.SetCursorPosition(0, 0);
|
Console.SetCursorPosition(0, 0);
|
||||||
int padding = (Console.WindowHeight + lineOffset - 3).ToString().Length;
|
|
||||||
padding = Math.Max(padding, lines.Count.ToString().Length);
|
|
||||||
padding += 1;
|
|
||||||
for (int i = lineOffset; i < Console.WindowHeight + lineOffset - 2; i++)
|
|
||||||
{
|
|
||||||
Console.SetCursorPosition(0, i - lineOffset);
|
|
||||||
|
|
||||||
string lineCountString = $"{i + 1}".PadRight(padding, ' ') + "| ";
|
if (SizeChanged())
|
||||||
if (i < lines.Count)
|
{
|
||||||
|
drawAll = true;
|
||||||
|
inputHandler.WriteStatus(string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LineOffset < 0 || CursorPosition.Y < 0 || CursorPosition.Y < 0)
|
||||||
|
{
|
||||||
|
LineOffset = 0;
|
||||||
|
CursorPosition.Y = 0;
|
||||||
|
CursorPosition.X = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = LineOffset; i < Console.WindowHeight + LineOffset - 2; i++)
|
||||||
|
{
|
||||||
|
Console.SetCursorPosition(0, i - LineOffset);
|
||||||
|
|
||||||
|
string lineCountString = $"{i + 1}".PadRight(GetSpacing(), ' ') + "| ";
|
||||||
|
if (i < Lines.Count)
|
||||||
{
|
{
|
||||||
if (cursorPosition.Y == i || drawAll)
|
if (CursorPosition.Y == i || drawAll)
|
||||||
{
|
{
|
||||||
Console.Write(lineCountString);
|
Console.Write(lineCountString);
|
||||||
string printLine = $"{lines[i].Substring(0, Math.Min(lines[i].Length, Console.WindowWidth))}".TrimEnd();
|
string printLine = $"{Lines[i].Substring(0, Math.Min(Lines[i].Length, Console.WindowWidth))}".TrimEnd();
|
||||||
syntaxHighlighter.Write(printLine);
|
syntaxHighlighter.Write(printLine);
|
||||||
Console.Write(new string(' ', Math.Max(Console.WindowWidth - lineCountString.Length - printLine.Length, 0)));
|
Console.Write(new string(' ', Math.Max(Console.WindowWidth - lineCountString.Length - printLine.Length, 0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (drawAll || cursorPosition.Y == i)
|
else if (drawAll || CursorPosition.Y == i)
|
||||||
{
|
{
|
||||||
Console.Write(lineCountString + new string(' ', Console.WindowWidth - lineCountString.Length));
|
Console.Write(lineCountString + new string(' ', Console.WindowWidth - lineCountString.Length));
|
||||||
}
|
}
|
||||||
@@ -80,233 +95,12 @@ namespace YesNt.CodeEditor
|
|||||||
Console.SetCursorPosition(0, Console.WindowHeight - 2);
|
Console.SetCursorPosition(0, Console.WindowHeight - 2);
|
||||||
Console.Write(">>>" + new string(' ', Console.WindowWidth - 3));
|
Console.Write(">>>" + new string(' ', Console.WindowWidth - 3));
|
||||||
|
|
||||||
Console.SetCursorPosition(Math.Min(cursorPosition.X + padding + 2, Console.WindowWidth - 1), cursorPosition.Y - lineOffset);
|
Console.SetCursorPosition(Math.Min(CursorPosition.X + GetSpacing() + 2, Console.WindowWidth - 1), CursorPosition.Y - LineOffset);
|
||||||
|
|
||||||
Console.CursorVisible = true;
|
Console.CursorVisible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HandleInput()
|
public bool Load(string path)
|
||||||
{
|
|
||||||
if (mode == Mode.Edit)
|
|
||||||
{
|
|
||||||
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
|
|
||||||
|
|
||||||
if ((ConsoleModifiers.Alt & keyInfo.Modifiers) != 0 && keyInfo.Key == ConsoleKey.C)
|
|
||||||
{
|
|
||||||
mode = Mode.Command;
|
|
||||||
}
|
|
||||||
else if (keyInfo.Key == ConsoleKey.DownArrow)
|
|
||||||
{
|
|
||||||
cursorPosition.Y++;
|
|
||||||
if (cursorPosition.Y - lineOffset >= Console.WindowHeight - 3)
|
|
||||||
{
|
|
||||||
lineOffset++;
|
|
||||||
Display(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (keyInfo.Key == ConsoleKey.UpArrow)
|
|
||||||
{
|
|
||||||
if (cursorPosition.Y > 0)
|
|
||||||
{
|
|
||||||
cursorPosition.Y--;
|
|
||||||
if (cursorPosition.Y - lineOffset < 0 && lineOffset > 0)
|
|
||||||
{
|
|
||||||
lineOffset--;
|
|
||||||
Display(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (keyInfo.Key == ConsoleKey.LeftArrow)
|
|
||||||
{
|
|
||||||
if (cursorPosition.X > 0)
|
|
||||||
{
|
|
||||||
cursorPosition.X--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (keyInfo.Key == ConsoleKey.RightArrow)
|
|
||||||
{
|
|
||||||
if (cursorPosition.X + 6 < Console.WindowWidth - 1)
|
|
||||||
{
|
|
||||||
cursorPosition.X++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (keyInfo.Key == ConsoleKey.Enter)
|
|
||||||
{
|
|
||||||
while (lines.Count <= cursorPosition.Y)
|
|
||||||
{
|
|
||||||
lines.Add("");
|
|
||||||
}
|
|
||||||
lines.Insert(cursorPosition.Y, "");
|
|
||||||
|
|
||||||
string line = lines[cursorPosition.Y + 1];
|
|
||||||
|
|
||||||
lines[cursorPosition.Y] = line.Substring(0, Math.Min(cursorPosition.X, line.Length));
|
|
||||||
lines[cursorPosition.Y + 1] = line.Substring(Math.Min(cursorPosition.X, line.Length));
|
|
||||||
|
|
||||||
cursorPosition.X = 0;
|
|
||||||
cursorPosition.Y++;
|
|
||||||
|
|
||||||
if (cursorPosition.Y - lineOffset >= Console.WindowHeight - 3)
|
|
||||||
{
|
|
||||||
lineOffset++;
|
|
||||||
}
|
|
||||||
Display(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (lines.Count <= cursorPosition.Y)
|
|
||||||
{
|
|
||||||
lines.Add("");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (lines[cursorPosition.Y].Length <= cursorPosition.X)
|
|
||||||
{
|
|
||||||
lines[cursorPosition.Y] += " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyInfo.Key == ConsoleKey.Backspace)
|
|
||||||
{
|
|
||||||
if (cursorPosition.X > 0)
|
|
||||||
{
|
|
||||||
lines[cursorPosition.Y] = lines[cursorPosition.Y].Remove(cursorPosition.X - 1, 1);
|
|
||||||
cursorPosition.X--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cursorPosition.Y > 0)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(lines[cursorPosition.Y - 1]))
|
|
||||||
{
|
|
||||||
lines.RemoveAt(--cursorPosition.Y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cursorPosition.Y--;
|
|
||||||
cursorPosition.X = lines[cursorPosition.Y].TrimEnd().Length;
|
|
||||||
lines[cursorPosition.Y] += lines[cursorPosition.Y + 1];
|
|
||||||
lines.RemoveAt(cursorPosition.Y + 1);
|
|
||||||
}
|
|
||||||
if (cursorPosition.Y - lineOffset < 0 && lineOffset > 0)
|
|
||||||
{
|
|
||||||
lineOffset--;
|
|
||||||
}
|
|
||||||
Display(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (lines.Count > 0 && string.IsNullOrWhiteSpace(lines[lines.Count - 1]))
|
|
||||||
{
|
|
||||||
lines.RemoveAt(lines.Count - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char input = keyInfo.KeyChar;
|
|
||||||
if (!char.IsControl(input))
|
|
||||||
{
|
|
||||||
lines[cursorPosition.Y] = lines[cursorPosition.Y].Insert(cursorPosition.X, input.ToString());
|
|
||||||
cursorPosition.X++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mode == Mode.Command)
|
|
||||||
{
|
|
||||||
Console.SetCursorPosition(3, Console.WindowHeight - 2);
|
|
||||||
|
|
||||||
string input = Console.ReadLine() ?? string.Empty;
|
|
||||||
string command = input.Split(' ')[0].Trim();
|
|
||||||
string path;
|
|
||||||
|
|
||||||
switch (command)
|
|
||||||
{
|
|
||||||
case "edit":
|
|
||||||
WriteStatus(string.Empty);
|
|
||||||
mode = Mode.Edit;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "save":
|
|
||||||
Save(input, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "run":
|
|
||||||
if (Save(input, true))
|
|
||||||
{
|
|
||||||
mode = Mode.Debug;
|
|
||||||
Console.Clear();
|
|
||||||
yesNtInterpreter.Execute(currentPath);
|
|
||||||
while (Console.KeyAvailable)
|
|
||||||
{
|
|
||||||
Console.ReadKey(true);
|
|
||||||
}
|
|
||||||
Console.ReadKey();
|
|
||||||
WriteStatus(string.Empty);
|
|
||||||
mode = Mode.Command;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "debug":
|
|
||||||
if (Save(input, true))
|
|
||||||
{
|
|
||||||
mode = Mode.Debug;
|
|
||||||
Console.Clear();
|
|
||||||
yesNtInterpreter.Execute(currentPath, true);
|
|
||||||
while (Console.KeyAvailable)
|
|
||||||
{
|
|
||||||
Console.ReadKey(true);
|
|
||||||
}
|
|
||||||
Console.ReadKey();
|
|
||||||
WriteStatus(string.Empty);
|
|
||||||
mode = Mode.Command;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "load":
|
|
||||||
if (input.Split(' ').Length == 2)
|
|
||||||
{
|
|
||||||
path = input.Split(' ')[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteStatus("Invalid arguments!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Load(path);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
WriteStatus(ex.Message);
|
|
||||||
}
|
|
||||||
lineOffset = 0;
|
|
||||||
cursorPosition.X = 0;
|
|
||||||
cursorPosition.Y = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "new":
|
|
||||||
|
|
||||||
lineOffset = 0;
|
|
||||||
cursorPosition.X = 0;
|
|
||||||
cursorPosition.Y = 0;
|
|
||||||
currentPath = string.Empty;
|
|
||||||
lines.Clear();
|
|
||||||
WriteStatus(string.Empty);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "exit":
|
|
||||||
return false;
|
|
||||||
|
|
||||||
default:
|
|
||||||
WriteStatus("Command not found!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Display(true);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool Load(string path)
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||||
{
|
{
|
||||||
@@ -315,25 +109,25 @@ namespace YesNt.CodeEditor
|
|||||||
|
|
||||||
if (!File.Exists(path))
|
if (!File.Exists(path))
|
||||||
{
|
{
|
||||||
WriteStatus("File does not exist!");
|
inputHandler.WriteStatus("File does not exist!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.Clear();
|
Lines.Clear();
|
||||||
foreach (string line in File.ReadAllLines(path))
|
foreach (string line in File.ReadAllLines(path))
|
||||||
{
|
{
|
||||||
lines.Add(line.Replace("\n", ""));
|
Lines.Add(line.Replace("\n", ""));
|
||||||
}
|
}
|
||||||
currentPath = path;
|
CurrentPath = path;
|
||||||
WriteStatus("File Loaded!");
|
inputHandler.WriteStatus("File Loaded!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Save(string input, bool loadIfExists)
|
public bool Save(string input, bool loadIfExists)
|
||||||
{
|
{
|
||||||
string text = "";
|
string text = "";
|
||||||
|
|
||||||
foreach (string line in lines)
|
foreach (string line in Lines)
|
||||||
{
|
{
|
||||||
text += line + "\n";
|
text += line + "\n";
|
||||||
}
|
}
|
||||||
@@ -344,7 +138,7 @@ namespace YesNt.CodeEditor
|
|||||||
{
|
{
|
||||||
path = input.Split(' ')[1];
|
path = input.Split(' ')[1];
|
||||||
|
|
||||||
if (currentPath.Trim() != path.Trim() && loadIfExists)
|
if (CurrentPath.Trim() != path.Trim() && loadIfExists)
|
||||||
{
|
{
|
||||||
if (Load(path))
|
if (Load(path))
|
||||||
{
|
{
|
||||||
@@ -355,20 +149,20 @@ namespace YesNt.CodeEditor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentPath = path;
|
CurrentPath = path;
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrWhiteSpace(currentPath))
|
else if (!string.IsNullOrWhiteSpace(CurrentPath))
|
||||||
{
|
{
|
||||||
path = currentPath;
|
path = CurrentPath;
|
||||||
}
|
}
|
||||||
else if (input.Split(' ').Length > 2)
|
else if (input.Split(' ').Length > 2)
|
||||||
{
|
{
|
||||||
WriteStatus("Invalid arguments!");
|
inputHandler.WriteStatus("Invalid arguments!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteStatus("File path is empty!");
|
inputHandler.WriteStatus("File path is empty!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,22 +174,16 @@ namespace YesNt.CodeEditor
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.WriteAllText(path, text);
|
File.WriteAllText(path, text);
|
||||||
WriteStatus("File Saved!");
|
inputHandler.WriteStatus("File Saved!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
WriteStatus(ex.Message);
|
inputHandler.WriteStatus(ex.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteStatus(string input)
|
|
||||||
{
|
|
||||||
Console.SetCursorPosition(0, Console.WindowHeight - 1);
|
|
||||||
Console.Write(input + new string(' ', Console.WindowWidth - input.Length - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void YesNtInterpreter_OnDebugOutput(string output)
|
private void YesNtInterpreter_OnDebugOutput(string output)
|
||||||
{
|
{
|
||||||
debugOutput.Add(output);
|
debugOutput.Add(output);
|
||||||
@@ -403,33 +191,61 @@ namespace YesNt.CodeEditor
|
|||||||
|
|
||||||
private void YesNtInterpreter_OnLineExecuted(Interpreter.Runtime.DebugEventArgs e)
|
private void YesNtInterpreter_OnLineExecuted(Interpreter.Runtime.DebugEventArgs e)
|
||||||
{
|
{
|
||||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
lock (Console.Out)
|
||||||
if (e.OriginalLine == e.CurrentLine)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{Environment.NewLine}[{e.LineNumber}] [{e.CurrentLine}] ==>");
|
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||||
}
|
if (e.OriginalLine == e.CurrentLine)
|
||||||
else
|
{
|
||||||
{
|
Console.WriteLine($"{Environment.NewLine}[{e.LineNumber}] [{e.CurrentLine}] ==>");
|
||||||
Console.WriteLine($"{Environment.NewLine}[{e.LineNumber}] [{e.OriginalLine}] => [{e.CurrentLine}] ==>");
|
}
|
||||||
}
|
else
|
||||||
Console.ResetColor();
|
{
|
||||||
|
Console.WriteLine($"{Environment.NewLine}[{e.LineNumber}] [{e.OriginalLine}] => [{e.CurrentLine}] ==>");
|
||||||
|
}
|
||||||
|
Console.ResetColor();
|
||||||
|
|
||||||
foreach (string output in debugOutput)
|
string[] outputs = debugOutput.ToArray();
|
||||||
{
|
debugOutput.Clear();
|
||||||
Console.Write(output);
|
|
||||||
|
foreach (string output in outputs)
|
||||||
|
{
|
||||||
|
Console.Write(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
debugOutput.Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
|
private void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
|
||||||
{
|
{
|
||||||
e.Cancel = true;
|
e.Cancel = true;
|
||||||
if (mode == Mode.Debug)
|
switch (EditMode)
|
||||||
{
|
{
|
||||||
yesNtInterpreter.Stop();
|
case Mode.Debug:
|
||||||
mode = Mode.Command;
|
yesNtInterpreter.Stop();
|
||||||
|
EditMode = Mode.Command;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetSpacing()
|
||||||
|
{
|
||||||
|
int padding = (Console.WindowHeight + LineOffset - 3).ToString().Length;
|
||||||
|
padding = Math.Max(padding, Lines.Count.ToString().Length);
|
||||||
|
padding += 1;
|
||||||
|
return padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point oldSize = new Point(0, 0);
|
||||||
|
|
||||||
|
private bool SizeChanged()
|
||||||
|
{
|
||||||
|
if (oldSize.X != Console.WindowWidth && oldSize.Y != Console.WindowHeight)
|
||||||
|
{
|
||||||
|
oldSize.X = Console.WindowWidth;
|
||||||
|
oldSize.Y = Console.WindowHeight;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Point
|
internal class Point
|
||||||
|
|||||||
@@ -0,0 +1,293 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace YesNt.CodeEditor
|
||||||
|
{
|
||||||
|
internal class InputHandler
|
||||||
|
{
|
||||||
|
private TextEditor textEditor;
|
||||||
|
|
||||||
|
public InputHandler(TextEditor textEditor)
|
||||||
|
{
|
||||||
|
this.textEditor = textEditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HandleInput()
|
||||||
|
{
|
||||||
|
if (textEditor.EditMode == Mode.Edit)
|
||||||
|
{
|
||||||
|
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
|
||||||
|
|
||||||
|
if ((ConsoleModifiers.Alt & keyInfo.Modifiers) == ConsoleModifiers.Alt)
|
||||||
|
{
|
||||||
|
switch (keyInfo.Key)
|
||||||
|
{
|
||||||
|
case ConsoleKey.C:
|
||||||
|
textEditor.EditMode = Mode.Command;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConsoleKey.S:
|
||||||
|
textEditor.CursorPosition.X = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConsoleKey.E:
|
||||||
|
if (textEditor.Lines.Count > textEditor.CursorPosition.Y)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.X = textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.X = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keyInfo.Key == ConsoleKey.DownArrow)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.Y++;
|
||||||
|
if (textEditor.CursorPosition.Y - textEditor.LineOffset >= Console.WindowHeight - 3)
|
||||||
|
{
|
||||||
|
textEditor.LineOffset++;
|
||||||
|
textEditor.Display(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keyInfo.Key == ConsoleKey.UpArrow)
|
||||||
|
{
|
||||||
|
if (textEditor.CursorPosition.Y > 0)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.Y--;
|
||||||
|
if (textEditor.CursorPosition.Y - textEditor.LineOffset < 0 && textEditor.LineOffset > 0)
|
||||||
|
{
|
||||||
|
textEditor.LineOffset--;
|
||||||
|
textEditor.Display(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keyInfo.Key == ConsoleKey.LeftArrow)
|
||||||
|
{
|
||||||
|
if (textEditor.CursorPosition.X > 0)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.X--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keyInfo.Key == ConsoleKey.RightArrow)
|
||||||
|
{
|
||||||
|
if (textEditor.CursorPosition.X + textEditor.GetSpacing() + 3 < Console.WindowWidth)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.X++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (keyInfo.Key == ConsoleKey.Enter)
|
||||||
|
{
|
||||||
|
while (textEditor.Lines.Count <= textEditor.CursorPosition.Y)
|
||||||
|
{
|
||||||
|
textEditor.Lines.Add("");
|
||||||
|
}
|
||||||
|
textEditor.Lines.Insert(textEditor.CursorPosition.Y, "");
|
||||||
|
|
||||||
|
string line = textEditor.Lines[textEditor.CursorPosition.Y + 1];
|
||||||
|
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y] = line.Substring(0, Math.Min(textEditor.CursorPosition.X, line.Length));
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y + 1] = line.Substring(Math.Min(textEditor.CursorPosition.X, line.Length));
|
||||||
|
|
||||||
|
textEditor.CursorPosition.X = 0;
|
||||||
|
textEditor.CursorPosition.Y++;
|
||||||
|
|
||||||
|
if (textEditor.CursorPosition.Y - textEditor.LineOffset >= Console.WindowHeight - 3)
|
||||||
|
{
|
||||||
|
textEditor.LineOffset++;
|
||||||
|
}
|
||||||
|
textEditor.Display(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (textEditor.Lines.Count <= textEditor.CursorPosition.Y)
|
||||||
|
{
|
||||||
|
textEditor.Lines.Add("");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (textEditor.Lines[textEditor.CursorPosition.Y].Length <= textEditor.CursorPosition.X)
|
||||||
|
{
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y] += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyInfo.Key == ConsoleKey.Backspace)
|
||||||
|
{
|
||||||
|
if (textEditor.CursorPosition.X > 0)
|
||||||
|
{
|
||||||
|
if (textEditor.Lines[textEditor.CursorPosition.Y][textEditor.CursorPosition.X - 1] == ' ' && textEditor.CursorPosition.X > textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length)
|
||||||
|
{
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y] = textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd();
|
||||||
|
textEditor.CursorPosition.X = textEditor.Lines[textEditor.CursorPosition.Y].Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y] = textEditor.Lines[textEditor.CursorPosition.Y].Remove(textEditor.CursorPosition.X - 1, 1);
|
||||||
|
textEditor.CursorPosition.X--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (textEditor.CursorPosition.Y > 0)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(textEditor.Lines[textEditor.CursorPosition.Y - 1]))
|
||||||
|
{
|
||||||
|
textEditor.Lines.RemoveAt(--textEditor.CursorPosition.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.Y--;
|
||||||
|
textEditor.CursorPosition.X = textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length;
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y] += textEditor.Lines[textEditor.CursorPosition.Y + 1];
|
||||||
|
textEditor.Lines.RemoveAt(textEditor.CursorPosition.Y + 1);
|
||||||
|
}
|
||||||
|
if (textEditor.CursorPosition.Y - textEditor.LineOffset < 0 && textEditor.LineOffset > 0)
|
||||||
|
{
|
||||||
|
textEditor.LineOffset--;
|
||||||
|
}
|
||||||
|
textEditor.Display(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (textEditor.Lines.Count > 0 && string.IsNullOrWhiteSpace(textEditor.Lines[textEditor.Lines.Count - 1]))
|
||||||
|
{
|
||||||
|
textEditor.Lines.RemoveAt(textEditor.Lines.Count - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (textEditor.CursorPosition.X + textEditor.GetSpacing() + 3 < Console.WindowWidth)
|
||||||
|
{
|
||||||
|
char input = keyInfo.KeyChar;
|
||||||
|
if (!char.IsControl(input))
|
||||||
|
{
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y] = textEditor.Lines[textEditor.CursorPosition.Y].Insert(textEditor.CursorPosition.X, input.ToString());
|
||||||
|
textEditor.CursorPosition.X++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (textEditor.EditMode == Mode.Command)
|
||||||
|
{
|
||||||
|
Console.SetCursorPosition(3, Console.WindowHeight - 2);
|
||||||
|
|
||||||
|
string input = Console.ReadLine() ?? string.Empty;
|
||||||
|
string command = input.Split(' ')[0].Trim();
|
||||||
|
string path;
|
||||||
|
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case "edit":
|
||||||
|
WriteStatus(string.Empty);
|
||||||
|
textEditor.EditMode = Mode.Edit;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "line":
|
||||||
|
WriteStatus(string.Empty);
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
int lineNumber = 0;
|
||||||
|
if (input.Split(' ').Length == 2)
|
||||||
|
{
|
||||||
|
success = int.TryParse(input.Split(' ')[1], out lineNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success && lineNumber > 0)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.Y = lineNumber - 1;
|
||||||
|
textEditor.CursorPosition.X = 0;
|
||||||
|
textEditor.LineOffset = lineNumber - 1;
|
||||||
|
textEditor.EditMode = Mode.Edit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteStatus("Invalid line number!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "save":
|
||||||
|
textEditor.Save(input, false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "run":
|
||||||
|
if (textEditor.Save(input, true))
|
||||||
|
{
|
||||||
|
textEditor.EditMode = Mode.Debug;
|
||||||
|
Console.Clear();
|
||||||
|
textEditor.yesNtInterpreter.Execute(textEditor.CurrentPath);
|
||||||
|
while (Console.KeyAvailable)
|
||||||
|
{
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
Console.ReadKey();
|
||||||
|
WriteStatus(string.Empty);
|
||||||
|
textEditor.EditMode = Mode.Command;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "debug":
|
||||||
|
if (textEditor.Save(input, true))
|
||||||
|
{
|
||||||
|
textEditor.EditMode = Mode.Debug;
|
||||||
|
Console.Clear();
|
||||||
|
textEditor.yesNtInterpreter.Execute(textEditor.CurrentPath, true);
|
||||||
|
while (Console.KeyAvailable)
|
||||||
|
{
|
||||||
|
Console.ReadKey(true);
|
||||||
|
}
|
||||||
|
Console.ReadKey();
|
||||||
|
WriteStatus(string.Empty);
|
||||||
|
textEditor.EditMode = Mode.Command;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "load":
|
||||||
|
if (input.Split(' ').Length == 2)
|
||||||
|
{
|
||||||
|
path = input.Split(' ')[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteStatus("Invalid arguments!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
textEditor.Load(path);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
WriteStatus(ex.Message);
|
||||||
|
}
|
||||||
|
textEditor.LineOffset = 0;
|
||||||
|
textEditor.CursorPosition.X = 0;
|
||||||
|
textEditor.CursorPosition.Y = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "new":
|
||||||
|
|
||||||
|
textEditor.LineOffset = 0;
|
||||||
|
textEditor.CursorPosition.X = 0;
|
||||||
|
textEditor.CursorPosition.Y = 0;
|
||||||
|
textEditor.CurrentPath = string.Empty;
|
||||||
|
textEditor.Lines.Clear();
|
||||||
|
WriteStatus(string.Empty);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "exit":
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WriteStatus("Command not found!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
textEditor.Display(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteStatus(string input)
|
||||||
|
{
|
||||||
|
Console.SetCursorPosition(0, Console.WindowHeight - 1);
|
||||||
|
Console.Write(input + new string(' ', Console.WindowWidth - input.Length - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user