Reformatting and reimperilment escape codes

This commit is contained in:
Stone_Red
2023-09-27 17:17:28 +02:00
parent 79df5c9b97
commit ce3715c1b5
9 changed files with 591 additions and 543 deletions
+222 -224
View File
@@ -4,265 +4,263 @@ using System.IO;
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;
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))
{
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();
YesNtInterpreter.OnDebugOutput += YesNtInterpreter_OnDebugOutput;
YesNtInterpreter.OnLineExecuted += YesNtInterpreter_OnLineExecuted;
syntaxHighlighter = new(YesNtInterpreter.StatementInformation);
inputHandler = new InputHandler(this);
Console.CancelKeyPress += Console_CancelKeyPress;
LineOffset = 0;
CursorPosition.Y = 0;
CursorPosition.X = 0;
}
public void Run()
for (int i = LineOffset; i < Console.WindowHeight + LineOffset - 2; i++)
{
Console.Clear();
Console.SetCursorPosition(0, i - LineOffset);
Display(true);
do
string lineCountString = $"{i + 1}".PadRight(GetSpacing(), ' ') + "| ";
if (i < Lines.Count)
{
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);
}
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);
string printLine = $"{Lines[i][..Math.Min(Lines[i].Length, Console.WindowWidth)]}".TrimEnd();
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));
Console.Write(lineCountString);
string printLine = $"{Lines[i][..Math.Min(Lines[i].Length, Console.WindowWidth)]}".TrimEnd();
syntaxHighlighter.Write(printLine);
Console.Write(new string(' ', Math.Max(Console.WindowWidth - lineCountString.Length - printLine.Length, 0)));
}
}
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;
else if (drawAll || CursorPosition.Y == i)
{
Console.Write(lineCountString + new string(' ', Console.WindowWidth - lineCountString.Length));
}
}
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)))
{
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!");
}
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;
}
public bool Save(string input, bool loadIfExists)
catch (Exception ex)
{
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)))
{
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;
}
InputHandler.WriteStatus(ex.Message);
return false;
}
}
internal class Point
public int GetSpacing()
{
public int X { get; set; }
public int Y { get; set; }
int padding = (Console.WindowHeight + LineOffset - 3).ToString().Length;
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;
Y = y;
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);
}
}
}
internal enum Mode
private void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
Edit,
Command,
Debug
e.Cancel = true;
switch (EditMode)
{
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
View File
@@ -1,313 +1,317 @@
using System;
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);
}
public bool HandleInput()
if (textEditor.EditMode == Mode.Edit)
{
while (Console.KeyAvailable)
{
_ = Console.ReadKey(true);
}
if (textEditor.EditMode == Mode.Edit)
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
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;
return true;
case ConsoleKey.C:
textEditor.EditMode = Mode.Command;
return true;
case ConsoleKey.B:
int position = textEditor.Lines.Count;
textEditor.CursorPosition.Y = position - 1;
textEditor.LineOffset = Math.Max(position - Console.WindowHeight + 3, 0);
case ConsoleKey.B:
int position = textEditor.Lines.Count;
textEditor.CursorPosition.Y = position - 1;
textEditor.LineOffset = Math.Max(position - Console.WindowHeight + 3, 0);
textEditor.Display(true);
return true;
textEditor.Display(true);
return true;
case ConsoleKey.T:
textEditor.CursorPosition.Y = 0;
textEditor.LineOffset = 0;
case ConsoleKey.T:
textEditor.CursorPosition.Y = 0;
textEditor.LineOffset = 0;
textEditor.Display(true);
return true;
textEditor.Display(true);
return true;
case ConsoleKey.S:
textEditor.CursorPosition.X = 0;
return true;
case ConsoleKey.S:
textEditor.CursorPosition.X = 0;
return true;
case ConsoleKey.E:
textEditor.CursorPosition.X = textEditor.Lines.Count > textEditor.CursorPosition.Y ? textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length : 0;
return true;
}
case ConsoleKey.E:
textEditor.CursorPosition.X = textEditor.Lines.Count > textEditor.CursorPosition.Y ? textEditor.Lines[textEditor.CursorPosition.Y].TrimEnd().Length : 0;
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++;
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.LineOffset--;
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.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++;
}
}
textEditor.CursorPosition.X--;
}
}
else if (textEditor.EditMode == Mode.Command)
else if (keyInfo.Key == ConsoleKey.RightArrow)
{
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)
if (textEditor.CursorPosition.X + textEditor.GetSpacing() + 3 < Console.WindowWidth)
{
case "edit":
WriteStatus(string.Empty);
textEditor.EditMode = Mode.Edit;
break;
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, "");
case "line":
WriteStatus(string.Empty);
string line = textEditor.Lines[textEditor.CursorPosition.Y + 1];
bool success = false;
int lineNumber = 0;
if (input.Split(' ').Length == 2)
{
success = int.TryParse(input.Split(' ')[1], out lineNumber);
}
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)..];
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;
textEditor.CursorPosition.X = 0;
textEditor.CursorPosition.Y++;
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;
if (textEditor.CursorPosition.Y - textEditor.LineOffset >= Console.WindowHeight - 3)
{
textEditor.LineOffset++;
}
textEditor.Display(true);
}
return true;
}
else
{
while (textEditor.Lines.Count <= textEditor.CursorPosition.Y)
{
textEditor.Lines.Add("");
}
internal static void WriteStatus(string input)
{
Console.SetCursorPosition(0, Console.WindowHeight - 1);
Console.Write(input + new string(' ', Console.WindowWidth - input.Length - 1));
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 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));
}
}
+4 -11
View File
@@ -1,11 +1,4 @@
namespace YesNt.CodeEditor
{
internal static class Program
{
private static void Main(string[] args)
{
TextEditor textEditor = args.Length > 0 ? new TextEditor(args[0]) : new TextEditor();
textEditor.Run();
}
}
}
using YesNt.CodeEditor;
TextEditor textEditor = args.Length > 0 ? new TextEditor(args[0]) : new TextEditor();
textEditor.Run();
+6 -7
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.RegularExpressions;
using YesNt.Interpreter.Enums;
@@ -11,10 +12,12 @@ namespace YesNt.CodeEditor;
internal partial class SyntaxHighlighter
{
private readonly ReadOnlyCollection<StatementInformation> statementInformation;
private readonly string[] replacementValues;
public SyntaxHighlighter(ReadOnlyCollection<StatementInformation> statementInformation)
{
this.statementInformation = statementInformation;
replacementValues = StringExtentions.ReplacementRules.Values.ToArray();
}
public static string Base64Encode(string plainText)
@@ -39,10 +42,9 @@ internal partial class SyntaxHighlighter
}
else
{
MatchCollection matches = EscapeSequenceRegex().Matches(input);
for (int i = 0; i < matches.Count; i++)
for (int i = 0; i < replacementValues.Length; 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)
@@ -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++)
{
input = AddColorInformation(input, matches[i].Value, ConsoleColor.Cyan, SearchMode.Contains);
@@ -171,9 +173,6 @@ internal partial class SyntaxHighlighter
return reult;
}
[GeneratedRegex("!!.")]
private static partial Regex EscapeSequenceRegex();
[GeneratedRegex("^<[a-zA-Z0-9]+")]
private static partial Regex VariableDeclarationRegex();