mirror of
https://github.com/Stone-Red-Code/YesNt-Interpreter.git
synced 2026-09-09 16:06:08 +02:00
Reformatting and reimperilment escape codes
This commit is contained in:
+222
-224
@@ -4,265 +4,263 @@ using System.IO;
|
|||||||
|
|
||||||
using YesNt.Interpreter.Runtime;
|
using YesNt.Interpreter.Runtime;
|
||||||
|
|
||||||
namespace YesNt.CodeEditor
|
namespace YesNt.CodeEditor;
|
||||||
|
|
||||||
|
internal class TextEditor
|
||||||
{
|
{
|
||||||
internal class TextEditor
|
private readonly InputHandler inputHandler;
|
||||||
|
private readonly SyntaxHighlighter syntaxHighlighter;
|
||||||
|
private readonly List<string> debugOutput = new();
|
||||||
|
|
||||||
|
private readonly Point oldSize = new Point(0, 0);
|
||||||
|
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()
|
||||||
{
|
{
|
||||||
private readonly InputHandler inputHandler;
|
if (File.Exists(path))
|
||||||
private readonly SyntaxHighlighter syntaxHighlighter;
|
|
||||||
private readonly List<string> debugOutput = new();
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
if (File.Exists(path))
|
_ = Load(path);
|
||||||
{
|
}
|
||||||
_ = Load(path);
|
}
|
||||||
}
|
|
||||||
|
public TextEditor()
|
||||||
|
{
|
||||||
|
YesNtInterpreter.Initialize();
|
||||||
|
YesNtInterpreter.OnDebugOutput += YesNtInterpreter_OnDebugOutput;
|
||||||
|
YesNtInterpreter.OnLineExecuted += YesNtInterpreter_OnLineExecuted;
|
||||||
|
syntaxHighlighter = new(YesNtInterpreter.StatementInformation);
|
||||||
|
inputHandler = new InputHandler(this);
|
||||||
|
Console.CancelKeyPress += Console_CancelKeyPress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
Console.Clear();
|
||||||
|
|
||||||
|
Display(true);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Display(false);
|
||||||
|
} while (inputHandler.HandleInput());
|
||||||
|
|
||||||
|
Console.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Display(bool drawAll)
|
||||||
|
{
|
||||||
|
Console.CursorVisible = false;
|
||||||
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
Console.BackgroundColor = ConsoleColor.Black;
|
||||||
|
|
||||||
|
Console.SetCursorPosition(0, 0);
|
||||||
|
|
||||||
|
if (SizeChanged())
|
||||||
|
{
|
||||||
|
drawAll = true;
|
||||||
|
InputHandler.WriteStatus(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextEditor()
|
if (LineOffset < 0 || CursorPosition.Y < 0 || CursorPosition.Y < 0)
|
||||||
{
|
{
|
||||||
YesNtInterpreter.Initialize();
|
LineOffset = 0;
|
||||||
YesNtInterpreter.OnDebugOutput += YesNtInterpreter_OnDebugOutput;
|
CursorPosition.Y = 0;
|
||||||
YesNtInterpreter.OnLineExecuted += YesNtInterpreter_OnLineExecuted;
|
CursorPosition.X = 0;
|
||||||
syntaxHighlighter = new(YesNtInterpreter.StatementInformation);
|
|
||||||
inputHandler = new InputHandler(this);
|
|
||||||
Console.CancelKeyPress += Console_CancelKeyPress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run()
|
for (int i = LineOffset; i < Console.WindowHeight + LineOffset - 2; i++)
|
||||||
{
|
{
|
||||||
Console.Clear();
|
Console.SetCursorPosition(0, i - LineOffset);
|
||||||
|
|
||||||
Display(true);
|
string lineCountString = $"{i + 1}".PadRight(GetSpacing(), ' ') + "| ";
|
||||||
do
|
if (i < Lines.Count)
|
||||||
{
|
{
|
||||||
Display(false);
|
if (CursorPosition.Y == i || drawAll)
|
||||||
} while (inputHandler.HandleInput());
|
|
||||||
|
|
||||||
Console.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Display(bool drawAll)
|
|
||||||
{
|
|
||||||
Console.CursorVisible = false;
|
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
|
||||||
Console.BackgroundColor = ConsoleColor.Black;
|
|
||||||
|
|
||||||
Console.SetCursorPosition(0, 0);
|
|
||||||
|
|
||||||
if (SizeChanged())
|
|
||||||
{
|
|
||||||
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)
|
Console.Write(lineCountString);
|
||||||
{
|
string printLine = $"{Lines[i][..Math.Min(Lines[i].Length, Console.WindowWidth)]}".TrimEnd();
|
||||||
Console.Write(lineCountString);
|
syntaxHighlighter.Write(printLine);
|
||||||
string printLine = $"{Lines[i][..Math.Min(Lines[i].Length, Console.WindowWidth)]}".TrimEnd();
|
Console.Write(new string(' ', Math.Max(Console.WindowWidth - lineCountString.Length - printLine.Length, 0)));
|
||||||
syntaxHighlighter.Write(printLine);
|
|
||||||
Console.Write(new string(' ', Math.Max(Console.WindowWidth - lineCountString.Length - printLine.Length, 0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (drawAll || CursorPosition.Y == i)
|
|
||||||
{
|
|
||||||
Console.Write(lineCountString + new string(' ', Console.WindowWidth - lineCountString.Length));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (drawAll || CursorPosition.Y == i)
|
||||||
Console.SetCursorPosition(0, Console.WindowHeight - 3);
|
{
|
||||||
Console.Write(new string('-', Console.WindowWidth));
|
Console.Write(lineCountString + new string(' ', Console.WindowWidth - lineCountString.Length));
|
||||||
Console.SetCursorPosition(0, Console.WindowHeight - 2);
|
}
|
||||||
Console.Write(">>>" + new string(' ', Console.WindowWidth - 3));
|
|
||||||
|
|
||||||
Console.SetCursorPosition(Math.Min(CursorPosition.X + GetSpacing() + 2, Console.WindowWidth - 1), CursorPosition.Y - LineOffset);
|
|
||||||
|
|
||||||
Console.CursorVisible = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Load(string path)
|
Console.SetCursorPosition(0, Console.WindowHeight - 3);
|
||||||
|
Console.Write(new string('-', Console.WindowWidth));
|
||||||
|
Console.SetCursorPosition(0, Console.WindowHeight - 2);
|
||||||
|
Console.Write(">>>" + new string(' ', Console.WindowWidth - 3));
|
||||||
|
|
||||||
|
Console.SetCursorPosition(Math.Min(CursorPosition.X + GetSpacing() + 2, Console.WindowWidth - 1), CursorPosition.Y - LineOffset);
|
||||||
|
|
||||||
|
Console.CursorVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Load(string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||||
{
|
{
|
||||||
|
path = Path.ChangeExtension(path, "ynt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!File.Exists(path))
|
||||||
|
{
|
||||||
|
InputHandler.WriteStatus("File does not exist!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lines.Clear();
|
||||||
|
Lines.AddRange(File.ReadAllLines(path));
|
||||||
|
CurrentPath = path;
|
||||||
|
InputHandler.WriteStatus("File Loaded!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Save(string input, bool loadIfExists)
|
||||||
|
{
|
||||||
|
string path;
|
||||||
|
if (input.Split(' ').Length == 2)
|
||||||
|
{
|
||||||
|
path = input.Split(' ')[1];
|
||||||
|
|
||||||
|
if (CurrentPath.Trim() != path.Trim() && loadIfExists)
|
||||||
|
{
|
||||||
|
return Load(path);
|
||||||
|
}
|
||||||
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||||
{
|
{
|
||||||
path = Path.ChangeExtension(path, "ynt");
|
path = Path.ChangeExtension(path, "ynt");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File.Exists(path))
|
|
||||||
{
|
|
||||||
InputHandler.WriteStatus("File does not exist!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Lines.Clear();
|
|
||||||
Lines.AddRange(File.ReadAllLines(path));
|
|
||||||
CurrentPath = path;
|
CurrentPath = path;
|
||||||
InputHandler.WriteStatus("File Loaded!");
|
}
|
||||||
|
else if (!string.IsNullOrWhiteSpace(CurrentPath))
|
||||||
|
{
|
||||||
|
path = CurrentPath;
|
||||||
|
}
|
||||||
|
else if (input.Split(' ').Length > 2)
|
||||||
|
{
|
||||||
|
InputHandler.WriteStatus("Invalid arguments!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InputHandler.WriteStatus("File path is empty! (Save the file before you can use this command)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
||||||
|
{
|
||||||
|
path = Path.ChangeExtension(path, "ynt");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (Lines.Count > 0 && string.IsNullOrWhiteSpace(Lines[^1]))
|
||||||
|
{
|
||||||
|
Lines.RemoveAt(Lines.Count - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllLines(path, Lines);
|
||||||
|
InputHandler.WriteStatus("File Saved!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
public bool Save(string input, bool loadIfExists)
|
|
||||||
{
|
{
|
||||||
string path;
|
InputHandler.WriteStatus(ex.Message);
|
||||||
if (input.Split(' ').Length == 2)
|
|
||||||
{
|
|
||||||
path = input.Split(' ')[1];
|
|
||||||
|
|
||||||
if (CurrentPath.Trim() != path.Trim() && loadIfExists)
|
|
||||||
{
|
|
||||||
return Load(path);
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
|
||||||
{
|
|
||||||
path = Path.ChangeExtension(path, "ynt");
|
|
||||||
}
|
|
||||||
CurrentPath = path;
|
|
||||||
}
|
|
||||||
else if (!string.IsNullOrWhiteSpace(CurrentPath))
|
|
||||||
{
|
|
||||||
path = CurrentPath;
|
|
||||||
}
|
|
||||||
else if (input.Split(' ').Length > 2)
|
|
||||||
{
|
|
||||||
InputHandler.WriteStatus("Invalid arguments!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InputHandler.WriteStatus("File path is empty! (Save the file before you can use this command)");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(Path.GetExtension(path)))
|
|
||||||
{
|
|
||||||
path = Path.ChangeExtension(path, "ynt");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (Lines.Count > 0 && string.IsNullOrWhiteSpace(Lines[^1]))
|
|
||||||
{
|
|
||||||
Lines.RemoveAt(Lines.Count - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.WriteAllLines(path, Lines);
|
|
||||||
InputHandler.WriteStatus("File Saved!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
InputHandler.WriteStatus(ex.Message);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void YesNtInterpreter_OnDebugOutput(string output)
|
|
||||||
{
|
|
||||||
debugOutput.Add(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void YesNtInterpreter_OnLineExecuted(Interpreter.Runtime.DebugEventArgs e)
|
|
||||||
{
|
|
||||||
lock (Console.Out)
|
|
||||||
{
|
|
||||||
if (e is not null)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Magenta;
|
|
||||||
|
|
||||||
string sharedString = (Console.CursorLeft != 0) ? Environment.NewLine : string.Empty;
|
|
||||||
sharedString += (e.IsTask ? $"[Task: {e.TaskId}]" : string.Empty) + $"[{e.LineNumber}]";
|
|
||||||
|
|
||||||
if (e.OriginalLine == e.CurrentLine)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{sharedString}[{e.CurrentLine}] ==>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{sharedString}[{e.OriginalLine}] => [{e.CurrentLine}] ==>");
|
|
||||||
}
|
|
||||||
Console.ForegroundColor = ConsoleColor.Gray;
|
|
||||||
}
|
|
||||||
string[] outputs = debugOutput.ToArray();
|
|
||||||
debugOutput.Clear();
|
|
||||||
|
|
||||||
foreach (string output in outputs)
|
|
||||||
{
|
|
||||||
Console.Write(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
|
|
||||||
{
|
|
||||||
e.Cancel = true;
|
|
||||||
switch (EditMode)
|
|
||||||
{
|
|
||||||
case Mode.Debug:
|
|
||||||
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 readonly 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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class Point
|
public int GetSpacing()
|
||||||
{
|
{
|
||||||
public int X { get; set; }
|
int padding = (Console.WindowHeight + LineOffset - 3).ToString().Length;
|
||||||
public int Y { get; set; }
|
padding = Math.Max(padding, Lines.Count.ToString().Length);
|
||||||
|
padding += 1;
|
||||||
|
return padding;
|
||||||
|
}
|
||||||
|
|
||||||
public Point(int x, int y)
|
private void YesNtInterpreter_OnDebugOutput(string output)
|
||||||
|
{
|
||||||
|
debugOutput.Add(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void YesNtInterpreter_OnLineExecuted(Interpreter.Runtime.DebugEventArgs e)
|
||||||
|
{
|
||||||
|
lock (Console.Out)
|
||||||
{
|
{
|
||||||
X = x;
|
if (e is not null)
|
||||||
Y = y;
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Magenta;
|
||||||
|
|
||||||
|
string sharedString = (Console.CursorLeft != 0) ? Environment.NewLine : string.Empty;
|
||||||
|
sharedString += (e.IsTask ? $"[Task: {e.TaskId}]" : string.Empty) + $"[{e.LineNumber}]";
|
||||||
|
|
||||||
|
if (e.OriginalLine == e.CurrentLine)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{sharedString}[{e.CurrentLine}] ==>");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{sharedString}[{e.OriginalLine}] => [{e.CurrentLine}] ==>");
|
||||||
|
}
|
||||||
|
Console.ForegroundColor = ConsoleColor.Gray;
|
||||||
|
}
|
||||||
|
string[] outputs = debugOutput.ToArray();
|
||||||
|
debugOutput.Clear();
|
||||||
|
|
||||||
|
foreach (string output in outputs)
|
||||||
|
{
|
||||||
|
Console.Write(output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal enum Mode
|
private void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
|
||||||
{
|
{
|
||||||
Edit,
|
e.Cancel = true;
|
||||||
Command,
|
switch (EditMode)
|
||||||
Debug
|
{
|
||||||
|
case Mode.Debug:
|
||||||
|
YesNtInterpreter.Stop();
|
||||||
|
EditMode = Mode.Command;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
public int X { get; set; }
|
||||||
|
public int Y { get; set; }
|
||||||
|
|
||||||
|
public Point(int x, int y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum Mode
|
||||||
|
{
|
||||||
|
Edit,
|
||||||
|
Command,
|
||||||
|
Debug
|
||||||
|
}
|
||||||
+278
-274
@@ -1,313 +1,317 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace YesNt.CodeEditor
|
namespace YesNt.CodeEditor;
|
||||||
|
|
||||||
|
internal class InputHandler
|
||||||
{
|
{
|
||||||
internal class InputHandler
|
private readonly TextEditor textEditor;
|
||||||
|
|
||||||
|
public InputHandler(TextEditor textEditor)
|
||||||
{
|
{
|
||||||
private readonly TextEditor textEditor;
|
this.textEditor = textEditor;
|
||||||
|
}
|
||||||
|
|
||||||
public InputHandler(TextEditor textEditor)
|
public bool HandleInput()
|
||||||
|
{
|
||||||
|
while (Console.KeyAvailable)
|
||||||
{
|
{
|
||||||
this.textEditor = textEditor;
|
_ = Console.ReadKey(true);
|
||||||
}
|
}
|
||||||
|
if (textEditor.EditMode == Mode.Edit)
|
||||||
public bool HandleInput()
|
|
||||||
{
|
{
|
||||||
while (Console.KeyAvailable)
|
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
|
||||||
{
|
|
||||||
_ = Console.ReadKey(true);
|
|
||||||
}
|
|
||||||
if (textEditor.EditMode == Mode.Edit)
|
|
||||||
{
|
|
||||||
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
|
|
||||||
|
|
||||||
if ((ConsoleModifiers.Alt & keyInfo.Modifiers) == ConsoleModifiers.Alt)
|
if ((ConsoleModifiers.Alt & keyInfo.Modifiers) == ConsoleModifiers.Alt)
|
||||||
|
{
|
||||||
|
switch (keyInfo.Key)
|
||||||
{
|
{
|
||||||
switch (keyInfo.Key)
|
case ConsoleKey.C:
|
||||||
{
|
textEditor.EditMode = Mode.Command;
|
||||||
case ConsoleKey.C:
|
return true;
|
||||||
textEditor.EditMode = Mode.Command;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case ConsoleKey.B:
|
case ConsoleKey.B:
|
||||||
int position = textEditor.Lines.Count;
|
int position = textEditor.Lines.Count;
|
||||||
textEditor.CursorPosition.Y = position - 1;
|
textEditor.CursorPosition.Y = position - 1;
|
||||||
textEditor.LineOffset = Math.Max(position - Console.WindowHeight + 3, 0);
|
textEditor.LineOffset = Math.Max(position - Console.WindowHeight + 3, 0);
|
||||||
|
|
||||||
textEditor.Display(true);
|
textEditor.Display(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ConsoleKey.T:
|
case ConsoleKey.T:
|
||||||
textEditor.CursorPosition.Y = 0;
|
textEditor.CursorPosition.Y = 0;
|
||||||
textEditor.LineOffset = 0;
|
textEditor.LineOffset = 0;
|
||||||
|
|
||||||
textEditor.Display(true);
|
textEditor.Display(true);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case ConsoleKey.S:
|
case ConsoleKey.S:
|
||||||
textEditor.CursorPosition.X = 0;
|
textEditor.CursorPosition.X = 0;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
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;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (keyInfo.Key == ConsoleKey.DownArrow)
|
}
|
||||||
|
if (keyInfo.Key == ConsoleKey.DownArrow)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.Y++;
|
||||||
|
if (textEditor.CursorPosition.Y - textEditor.LineOffset >= Console.WindowHeight - 3)
|
||||||
{
|
{
|
||||||
textEditor.CursorPosition.Y++;
|
textEditor.LineOffset++;
|
||||||
if (textEditor.CursorPosition.Y - textEditor.LineOffset >= Console.WindowHeight - 3)
|
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.LineOffset--;
|
||||||
textEditor.Display(true);
|
textEditor.Display(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (keyInfo.Key == ConsoleKey.UpArrow)
|
}
|
||||||
|
else if (keyInfo.Key == ConsoleKey.LeftArrow)
|
||||||
|
{
|
||||||
|
if (textEditor.CursorPosition.X > 0)
|
||||||
{
|
{
|
||||||
if (textEditor.CursorPosition.Y > 0)
|
textEditor.CursorPosition.X--;
|
||||||
{
|
|
||||||
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[..Math.Min(textEditor.CursorPosition.X, line.Length)];
|
|
||||||
textEditor.Lines[textEditor.CursorPosition.Y + 1] = line[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("");
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuilder lineBuilder = new StringBuilder(textEditor.Lines[textEditor.CursorPosition.Y]);
|
|
||||||
while (lineBuilder.Length <= textEditor.CursorPosition.X)
|
|
||||||
{
|
|
||||||
_ = lineBuilder.Append(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
textEditor.Lines[textEditor.CursorPosition.Y] = lineBuilder.ToString();
|
|
||||||
|
|
||||||
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[^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)
|
else if (keyInfo.Key == ConsoleKey.RightArrow)
|
||||||
{
|
{
|
||||||
Console.SetCursorPosition(3, Console.WindowHeight - 2);
|
if (textEditor.CursorPosition.X + textEditor.GetSpacing() + 3 < Console.WindowWidth)
|
||||||
|
|
||||||
string input = Console.ReadLine() ?? string.Empty;
|
|
||||||
string command = input.Split(' ')[0].Trim();
|
|
||||||
string path;
|
|
||||||
|
|
||||||
Console.CursorVisible = false;
|
|
||||||
|
|
||||||
switch (command)
|
|
||||||
{
|
{
|
||||||
case "edit":
|
textEditor.CursorPosition.X++;
|
||||||
WriteStatus(string.Empty);
|
}
|
||||||
textEditor.EditMode = Mode.Edit;
|
}
|
||||||
break;
|
else if (keyInfo.Key == ConsoleKey.Enter)
|
||||||
|
{
|
||||||
|
while (textEditor.Lines.Count <= textEditor.CursorPosition.Y)
|
||||||
|
{
|
||||||
|
textEditor.Lines.Add("");
|
||||||
|
}
|
||||||
|
textEditor.Lines.Insert(textEditor.CursorPosition.Y, "");
|
||||||
|
|
||||||
case "line":
|
string line = textEditor.Lines[textEditor.CursorPosition.Y + 1];
|
||||||
WriteStatus(string.Empty);
|
|
||||||
|
|
||||||
bool success = false;
|
textEditor.Lines[textEditor.CursorPosition.Y] = line[..Math.Min(textEditor.CursorPosition.X, line.Length)];
|
||||||
int lineNumber = 0;
|
textEditor.Lines[textEditor.CursorPosition.Y + 1] = line[Math.Min(textEditor.CursorPosition.X, line.Length)..];
|
||||||
if (input.Split(' ').Length == 2)
|
|
||||||
{
|
|
||||||
success = int.TryParse(input.Split(' ')[1], out lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success && lineNumber > 0)
|
textEditor.CursorPosition.X = 0;
|
||||||
{
|
textEditor.CursorPosition.Y++;
|
||||||
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":
|
if (textEditor.CursorPosition.Y - textEditor.LineOffset >= Console.WindowHeight - 3)
|
||||||
_ = textEditor.Save(input, false);
|
{
|
||||||
break;
|
textEditor.LineOffset++;
|
||||||
|
|
||||||
case "run":
|
|
||||||
if (textEditor.Save(input, true))
|
|
||||||
{
|
|
||||||
textEditor.EditMode = Mode.Debug;
|
|
||||||
Console.Clear();
|
|
||||||
Console.CursorVisible = true;
|
|
||||||
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();
|
|
||||||
Console.CursorVisible = true;
|
|
||||||
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);
|
textEditor.Display(true);
|
||||||
}
|
}
|
||||||
return true;
|
else
|
||||||
}
|
{
|
||||||
|
while (textEditor.Lines.Count <= textEditor.CursorPosition.Y)
|
||||||
|
{
|
||||||
|
textEditor.Lines.Add("");
|
||||||
|
}
|
||||||
|
|
||||||
internal static void WriteStatus(string input)
|
StringBuilder lineBuilder = new StringBuilder(textEditor.Lines[textEditor.CursorPosition.Y]);
|
||||||
{
|
while (lineBuilder.Length <= textEditor.CursorPosition.X)
|
||||||
Console.SetCursorPosition(0, Console.WindowHeight - 1);
|
{
|
||||||
Console.Write(input + new string(' ', Console.WindowWidth - input.Length - 1));
|
_ = lineBuilder.Append(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
textEditor.Lines[textEditor.CursorPosition.Y] = lineBuilder.ToString();
|
||||||
|
|
||||||
|
if (keyInfo.Key is ConsoleKey.Backspace or ConsoleKey.Delete)
|
||||||
|
{
|
||||||
|
if (keyInfo.Key == ConsoleKey.Delete)
|
||||||
|
{
|
||||||
|
textEditor.CursorPosition.X++;
|
||||||
|
}
|
||||||
|
|
||||||
|
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[^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;
|
||||||
|
|
||||||
|
Console.CursorVisible = false;
|
||||||
|
|
||||||
|
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();
|
||||||
|
Console.CursorVisible = true;
|
||||||
|
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();
|
||||||
|
Console.CursorVisible = true;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void WriteStatus(string input)
|
||||||
|
{
|
||||||
|
Console.SetCursorPosition(0, Console.WindowHeight - 1);
|
||||||
|
Console.Write(input + new string(' ', Console.WindowWidth - input.Length - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,4 @@
|
|||||||
namespace YesNt.CodeEditor
|
using YesNt.CodeEditor;
|
||||||
{
|
|
||||||
internal static class Program
|
TextEditor textEditor = args.Length > 0 ? new TextEditor(args[0]) : new TextEditor();
|
||||||
{
|
textEditor.Run();
|
||||||
private static void Main(string[] args)
|
|
||||||
{
|
|
||||||
TextEditor textEditor = args.Length > 0 ? new TextEditor(args[0]) : new TextEditor();
|
|
||||||
textEditor.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using YesNt.Interpreter.Enums;
|
using YesNt.Interpreter.Enums;
|
||||||
@@ -11,10 +12,12 @@ namespace YesNt.CodeEditor;
|
|||||||
internal partial class SyntaxHighlighter
|
internal partial class SyntaxHighlighter
|
||||||
{
|
{
|
||||||
private readonly ReadOnlyCollection<StatementInformation> statementInformation;
|
private readonly ReadOnlyCollection<StatementInformation> statementInformation;
|
||||||
|
private readonly string[] replacementValues;
|
||||||
|
|
||||||
public SyntaxHighlighter(ReadOnlyCollection<StatementInformation> statementInformation)
|
public SyntaxHighlighter(ReadOnlyCollection<StatementInformation> statementInformation)
|
||||||
{
|
{
|
||||||
this.statementInformation = statementInformation;
|
this.statementInformation = statementInformation;
|
||||||
|
replacementValues = StringExtentions.ReplacementRules.Values.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Base64Encode(string plainText)
|
public static string Base64Encode(string plainText)
|
||||||
@@ -39,10 +42,9 @@ internal partial class SyntaxHighlighter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MatchCollection matches = EscapeSequenceRegex().Matches(input);
|
for (int i = 0; i < replacementValues.Length; i++)
|
||||||
for (int i = 0; i < matches.Count; i++)
|
|
||||||
{
|
{
|
||||||
input = AddColorInformation(input, matches[i].Value, ConsoleColor.DarkYellow, SearchMode.Contains);
|
input = AddColorInformation(input, replacementValues[i], ConsoleColor.Blue, SearchMode.Contains);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (StatementInformation statement in statementInformation)
|
foreach (StatementInformation statement in statementInformation)
|
||||||
@@ -110,7 +112,7 @@ internal partial class SyntaxHighlighter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
matches = VariableRegex().Matches(input);
|
MatchCollection matches = VariableRegex().Matches(input);
|
||||||
for (int i = 0; i < matches.Count; i++)
|
for (int i = 0; i < matches.Count; i++)
|
||||||
{
|
{
|
||||||
input = AddColorInformation(input, matches[i].Value, ConsoleColor.Cyan, SearchMode.Contains);
|
input = AddColorInformation(input, matches[i].Value, ConsoleColor.Cyan, SearchMode.Contains);
|
||||||
@@ -171,9 +173,6 @@ internal partial class SyntaxHighlighter
|
|||||||
return reult;
|
return reult;
|
||||||
}
|
}
|
||||||
|
|
||||||
[GeneratedRegex("!!.")]
|
|
||||||
private static partial Regex EscapeSequenceRegex();
|
|
||||||
|
|
||||||
[GeneratedRegex("^<[a-zA-Z0-9]+")]
|
[GeneratedRegex("^<[a-zA-Z0-9]+")]
|
||||||
private static partial Regex VariableDeclarationRegex();
|
private static partial Regex VariableDeclarationRegex();
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ public class CodeFlowTests
|
|||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void CalculationsTest()
|
public void CalculationsTest()
|
||||||
{
|
{
|
||||||
Assert.Inconclusive();
|
YesNtAssert.IsLineEqual("10 * 10 !calc", 100.ToString());
|
||||||
YesNtAssert.IsLineEqual("10 * 10 !calc", 20.ToString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -60,4 +60,26 @@ internal static class YesNtAssert
|
|||||||
|
|
||||||
Assert.AreEqual(expected, debugEventArgs.CurrentLine);
|
Assert.AreEqual(expected, debugEventArgs.CurrentLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void IsLineNotEqual(string line, string expected, int timeout = 1000)
|
||||||
|
{
|
||||||
|
AutoResetEvent onDone = new AutoResetEvent(false);
|
||||||
|
List<string> lines = new List<string>()
|
||||||
|
{
|
||||||
|
line
|
||||||
|
};
|
||||||
|
|
||||||
|
DebugEventArgs debugEventArgs = new DebugEventArgs();
|
||||||
|
yesNtInterpreter.OnLineExecuted += (er) =>
|
||||||
|
{
|
||||||
|
debugEventArgs = er ?? debugEventArgs;
|
||||||
|
_ = onDone.Set();
|
||||||
|
};
|
||||||
|
|
||||||
|
yesNtInterpreter.Execute(lines, true);
|
||||||
|
|
||||||
|
_ = onDone.WaitOne(TimeSpan.FromMilliseconds(timeout));
|
||||||
|
|
||||||
|
Assert.AreNotEqual(expected, debugEventArgs.CurrentLine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -38,23 +38,6 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
|
|||||||
RuntimeInfo.CurrentLine = args.FromSafeString();
|
RuntimeInfo.CurrentLine = args.FromSafeString();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Statement("!!", SearchMode.Contains, SpaceAround.None, ConsoleColor.DarkYellow, Priority = Priority.PreProcessing, KeepStatementInArgs = true)]
|
|
||||||
public void DontEvaluate(string args)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
while ((index = args.IndexOf("!!")) != -1)
|
|
||||||
{
|
|
||||||
args = args.Remove(index, 2);
|
|
||||||
if (index < args.Length)
|
|
||||||
{
|
|
||||||
char charToEscape = args[index];
|
|
||||||
args = args.Remove(index, 1);
|
|
||||||
args = args.Insert(index, charToEscape.ToString().ToSafeString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RuntimeInfo.CurrentLine = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
|
[Statement("!task", SearchMode.EndOfLine, SpaceAround.Start, ConsoleColor.DarkYellow, Priority = Priority.VeryHigh)]
|
||||||
public void RunTask(string line)
|
public void RunTask(string line)
|
||||||
{
|
{
|
||||||
@@ -77,8 +60,14 @@ internal partial class ProcessingStatements : StatementRuntimeInformation
|
|||||||
[Statement("slp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
|
[Statement("slp", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
|
||||||
public void Sleep(string args)
|
public void Sleep(string args)
|
||||||
{
|
{
|
||||||
_ = int.TryParse(args, out int millisecondsTimeout);
|
if (int.TryParse(args, out int millisecondsTimeout))
|
||||||
ConsoleExtentions.Sleep(millisecondsTimeout, RuntimeInfo);
|
{
|
||||||
|
ConsoleExtentions.Sleep(millisecondsTimeout, RuntimeInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RuntimeInfo.Exit($"\"{args}\" is not a valid time-out value", true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Statement("len", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
|
[Statement("len", SearchMode.StartOfLine, SpaceAround.End, ConsoleColor.Magenta)]
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ internal partial class VariableStatements : StatementRuntimeInformation
|
|||||||
|
|
||||||
MatchCollection matches = VariableStatementRegex().Matches(RuntimeInfo.CurrentLine);
|
MatchCollection matches = VariableStatementRegex().Matches(RuntimeInfo.CurrentLine);
|
||||||
|
|
||||||
|
if (matches.Count <= 0)
|
||||||
|
{
|
||||||
|
RuntimeInfo.Exit("Invalid syntax", true);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < matches.Count; i++)
|
for (int i = 0; i < matches.Count; i++)
|
||||||
{
|
{
|
||||||
string varName = matches[i].Value.Replace(">", string.Empty);
|
string varName = matches[i].Value.Replace(">", string.Empty);
|
||||||
|
|||||||
@@ -1,11 +1,34 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace YesNt.Interpreter.Utilities;
|
namespace YesNt.Interpreter.Utilities;
|
||||||
|
|
||||||
public static class StringExtentions
|
public static class StringExtentions
|
||||||
{
|
{
|
||||||
|
private static readonly Dictionary<string, string> reverseReplacementRules;
|
||||||
|
|
||||||
|
public static Dictionary<string, string> ReplacementRules { get; } = new()
|
||||||
|
{
|
||||||
|
{"~", "~til" },
|
||||||
|
{" ", "~spc" },
|
||||||
|
{"%", "~per" },
|
||||||
|
{"<", "~let" },
|
||||||
|
{">", "~grt" },
|
||||||
|
{",", "~com" },
|
||||||
|
{"!", "~exm" },
|
||||||
|
{"|", "~pip" }
|
||||||
|
};
|
||||||
|
|
||||||
|
[SuppressMessage("Minor Code Smell", "S3963:\"static\" fields should be initialized inline", Justification = "Doesn't work because it throws a TypeInitializationException")]
|
||||||
|
static StringExtentions()
|
||||||
|
{
|
||||||
|
reverseReplacementRules = ReplacementRules.ToDictionary(x => x.Value, x => x.Key);
|
||||||
|
}
|
||||||
|
|
||||||
public static string ToSafeString(this string input)
|
public static string ToSafeString(this string input)
|
||||||
{
|
{
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
@@ -13,16 +36,32 @@ public static class StringExtentions
|
|||||||
{
|
{
|
||||||
_ = output.Append($"\v{c}\v");
|
_ = output.Append($"\v{c}\v");
|
||||||
}
|
}
|
||||||
return output
|
|
||||||
.ToString()
|
return ReplaceOnce(output.ToString(), ReplacementRules);
|
||||||
.Replace(' ', '~');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FromSafeString(this string input)
|
public static string FromSafeString(this string input)
|
||||||
{
|
{
|
||||||
return input
|
return ReplaceOnce(input.Replace("\v", ""), reverseReplacementRules);
|
||||||
.Replace("\v", "")
|
}
|
||||||
.Replace('~', ' ');
|
|
||||||
|
public static string ReplaceOnce(string input, Dictionary<string, string> replacementRules)
|
||||||
|
{
|
||||||
|
IEnumerable<KeyValuePair<string, string>> matches = replacementRules.Where(rule => input.Contains(rule.Key));
|
||||||
|
if (!matches.Any())
|
||||||
|
{
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValuePair<string, string> match = matches.First();
|
||||||
|
int startIndex = input.IndexOf(match.Key);
|
||||||
|
int endIndex = startIndex + match.Key.Length;
|
||||||
|
|
||||||
|
string before = ReplaceOnce(input[..startIndex], replacementRules);
|
||||||
|
string replaced = match.Value;
|
||||||
|
string after = ReplaceOnce(input[endIndex..], replacementRules);
|
||||||
|
|
||||||
|
return before + replaced + after;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ToStandardizedNumber(this string input, out double result)
|
public static bool ToStandardizedNumber(this string input, out double result)
|
||||||
|
|||||||
Reference in New Issue
Block a user