Skip to content

Commit

Permalink
feat(Studio): add 'Integrate Read Files' menu
Browse files Browse the repository at this point in the history
  • Loading branch information
DemoJameson committed Jun 30, 2023
1 parent 54792a2 commit 3ec7e9a
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Studio/DialogUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ void GoToLine(int line) {
ComboBox roomComboBox = new();

Regex labelRegex = new(@"^\s*#[^\s#]");
Regex commentCommandRegex = new(@"^\s*#(play|read|console|set)(\s|,)", RegexOptions.IgnoreCase);
Regex commentCommandRegex = new(@"^\s*#(play|console|set)(\s|,)", RegexOptions.IgnoreCase);
Regex roomRegex = new(@"^\s*#(lvl_)?");
for (int i = 0; i < richText.Lines.Count; i++) {
string lineText = richText.Lines[i];
Expand Down
147 changes: 147 additions & 0 deletions Studio/IntegrateReadFiles.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace CelesteStudio;

internal static class IntegrateReadFiles {
public static void Generate() {
string mainFilePath = Studio.Instance.richText.CurrentFileName;
if (!File.Exists(mainFilePath)) {
MessageBox.Show(mainFilePath, "Opened file does not exist");
return;
}

string saveFilePath = ShowSaveDialog(mainFilePath);
if (saveFilePath == null) {
return;
}

try {
string integratedText = ReadAllFiles(mainFilePath);
File.WriteAllText(saveFilePath, integratedText);
Studio.Instance.OpenFile(saveFilePath);
} catch (ReadFileNotExistException e) {
MessageBox.Show(e.Message, "Read file does not exist");
}
}

private static string ShowSaveDialog(string filePath) {
using SaveFileDialog dialog = new();
dialog.DefaultExt = ".tas";
dialog.AddExtension = true;
dialog.Filter = "TAS|*.tas";
dialog.FilterIndex = 0;
dialog.InitialDirectory = Path.GetDirectoryName(filePath);
dialog.FileName = Path.GetFileNameWithoutExtension(filePath) + "_Integrated.tas";

if (dialog.ShowDialog() == DialogResult.OK) {
return dialog.FileName;
} else {
return null;
}
}

private static string ReadAllFiles(string filePath, IEnumerable<string> lines = null) {
StringBuilder result = new();
lines ??= File.ReadLines(filePath);
foreach (string lineText in lines) {
if (TryParseReadCommand(filePath, lineText, out string readText)) {
result.AppendLine($"#{lineText.Trim()}");
result.AppendLine(readText);
} else {
result.AppendLine(lineText);
}
}

return result.ToString();
}

private static bool TryParseReadCommand(string filePath, string readCommand, out string readText) {
readText = null;
readCommand = readCommand.Trim();
if (!readCommand.StartsWith("read", StringComparison.InvariantCultureIgnoreCase)) {
return false;
}

Regex spaceRegex = new(@"^[^,]+?\s+[^,]");
string[] args = spaceRegex.IsMatch(readCommand) ? readCommand.Split() : readCommand.Split(',');
args = args.Select(text => text.Trim()).ToArray();
if (!args[0].Equals("read", StringComparison.InvariantCultureIgnoreCase) || args.Length < 2) {
return false;
}

string readFilePath = args[1];
string fileDirectory = Path.GetDirectoryName(filePath);
readFilePath = FindReadFile(filePath, fileDirectory, readFilePath);

if (!File.Exists(readFilePath)) {
// for compatibility with tas files downloaded from discord
// discord will replace spaces in the file name with underscores
readFilePath = args[1].Replace(" ", "_");
readFilePath = FindReadFile(filePath, fileDirectory, readFilePath);
}

if (!File.Exists(readFilePath)) {
throw new ReadFileNotExistException(readCommand, filePath);
}

int startLine = 0;
int endLine = int.MaxValue - 1;

if (args.Length >= 3) {
startLine = GetLineNumber(readFilePath, args[2]);
}

if (args.Length >= 4) {
endLine = GetLineNumber(readFilePath, args[3]);
}

readText = ReadAllFiles(filePath, File.ReadLines(readFilePath).Take(endLine + 1).Skip(startLine));
return true;
}

private static string FindReadFile(string filePath, string fileDirectory, string readFilePath) {
// Check for full and shortened Read versions
if (fileDirectory != null) {
// Path.Combine can handle the case when filePath is an absolute path
string absoluteOrRelativePath = Path.Combine(fileDirectory, readFilePath);
if (File.Exists(absoluteOrRelativePath) && absoluteOrRelativePath != filePath) {
readFilePath = absoluteOrRelativePath;
} else if (Directory.GetParent(absoluteOrRelativePath) is { } directoryInfo && Directory.Exists(directoryInfo.ToString())) {
string[] files = Directory.GetFiles(directoryInfo.ToString(), $"{Path.GetFileName(readFilePath)}*.tas");
if (files.FirstOrDefault(path => path != filePath) is { } shortenedFilePath) {
readFilePath = shortenedFilePath;
}
}
}

return readFilePath;
}

private static int GetLineNumber(string path, string labelOrLineNumber) {
if (int.TryParse(labelOrLineNumber, out int lineNumber)) {
return lineNumber - 1;
}

int currentLine = 0;
foreach (string readLine in File.ReadLines(path)) {
string line = readLine.Trim();
if (line == $"#{labelOrLineNumber}") {
return currentLine;
}

currentLine++;
}

return 0;
}
}

class ReadFileNotExistException : Exception {
public ReadFileNotExistException(string readCommand, string filePath) : base($"{readCommand}\n{filePath}") { }
}
11 changes: 5 additions & 6 deletions Studio/RichText/RichText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2769,15 +2769,14 @@ protected override void OnKeyDown(KeyEventArgs e) {

private void ExpandLine() {
Selection.Expand();
int line = Selection.End.iLine;
if (LinesCount <= 1) {
// ignored
} else if (line < LinesCount - 1) {
Selection.End = new Place(0, line + 1);
} else {
} else if (Selection.End.iLine is var endLine && endLine < LinesCount - 1) {
Selection.End = new Place(0, endLine + 1);
} else if (Selection.Start.iLine > 0) {
Place end = Selection.End;
line = Selection.Start.iLine - 1;
Selection.Start = new Place(line == -1 ? 0 : Lines[line].Length, line == -1 ? 0 : line);
int startLine = Selection.Start.iLine - 1;
Selection.Start = new Place(Lines[startLine].Length, startLine);
Selection.End = end;
}
}
Expand Down
12 changes: 11 additions & 1 deletion Studio/Studio.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions Studio/Studio.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ private static bool TryGetExactCasePath(string path, out string exactPath) {
return result;
}

private void OpenFile(string fileName = null, int startLine = 0) {
public void OpenFile(string fileName = null, int startLine = 0) {
if (fileName == CurrentFileName && fileName != null) {
return;
}
Expand Down Expand Up @@ -609,11 +609,11 @@ private static int GetLine(string path, string labelOrLineNumber) {

int curLine = 0;
foreach (string readLine in File.ReadLines(path)) {
curLine++;
string line = readLine.Trim();
if (line == $"#{labelOrLineNumber}") {
return curLine - 1;
return curLine;
}
curLine++;
}

return 0;
Expand Down Expand Up @@ -1431,6 +1431,10 @@ private void saveAsToolStripMenuItem_Click(object sender, EventArgs e) {
SaveAsFile();
}

private void integrateReadFilesToolStripMenuItem_Click(object sender, EventArgs e) {
IntegrateReadFiles.Generate();
}

private void commentUncommentTextToolStripMenuItem_Click(object sender, EventArgs e) {
CommentText(true);
}
Expand Down

0 comments on commit 3ec7e9a

Please sign in to comment.