Skip to content

Commit

Permalink
fold labels (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
elringus committed Aug 9, 2023
1 parent 56a9f92 commit 5ad0a6c
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public void DoesntRemoveDiagnosticsOfOtherContexts ()
Docs.SetupScript("other.nani", "#");
Meta.SetupCommandWithEndpoint("goto");
Assert.Equal(2, Diagnose("@goto other.label p:").Count);
Assert.Equal(1, Diagnose("@goto other.label p:v").Count);
Assert.Single(Diagnose("@goto other.label p:v"));
Handler.HandleDocumentRemoved(DefaultUri);
Handler.HandleDocumentRemoved("other.nani");
Assert.Empty(GetDiagnostics());
Expand Down
21 changes: 14 additions & 7 deletions backend/Naninovel.Language.Test/FoldingTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,25 @@ public void CommentLineIsFolded ()
}

[Fact]
public void OtherLinesAreNotFolded ()
public void LabelLineIsFolded ()
{
Assert.Empty(GetRanges("generic", "# label", ""));
var ranges = GetRanges("# label");
Assert.Single(ranges);
Assert.Equal(new FoldingRange(0, 0), ranges[0]);
}

[Fact]
public void GenericLinesAreNotFolded ()
{
Assert.Empty(GetRanges("generic 1", "generic 2", ""));
}

[Fact]
public void FoldingRangesAreCorrect ()
public void IntersectingRangesAreCorrect ()
{
var ranges = GetRanges(";", "@c", "#l", "", ";");
Assert.Equal(2, ranges.Count);
Assert.Equal(new FoldingRange(0, 1), ranges[0]);
Assert.Equal(new FoldingRange(4, 4), ranges[1]);
Assert.Equal(
new FoldingRange[] { new(0, 1), new(2, 2), new(5, 5), new(6, 7), new(3, 7), new(8, 8) },
GetRanges(";", ";", "@c", "#l", "", ";", "@c", "@c", "#l"));
}

private IReadOnlyList<FoldingRange> GetRanges (params string[] lines)
Expand Down
69 changes: 52 additions & 17 deletions backend/Naninovel.Language/Folding/FoldingHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ namespace Naninovel.Language;
public class FoldingHandler : IFoldingHandler
{
private readonly IDocumentRegistry registry;
private readonly List<FoldingRange> ranges = new();
private readonly List<FoldingRange> closed = new();
private readonly Dictionary<LineType, int> open = new();

private int lineIndex;
private FoldingRange? range;

public FoldingHandler (IDocumentRegistry registry)
{
Expand All @@ -21,34 +21,69 @@ public IReadOnlyList<FoldingRange> GetFoldingRanges (string documentUri)
ResetState();
var doc = registry.Get(documentUri);
for (; lineIndex < doc.LineCount; lineIndex++)
if (ShouldFold(doc[lineIndex].Script))
FoldLine(doc[lineIndex].Script);
if (range is not null) AddRange();
return ranges.ToArray();
VisitLine(doc[lineIndex].Script);
CloseAll();
return closed.ToArray();
}

private void ResetState ()
{
ranges.Clear();
closed.Clear();
open[LineType.Comment] = -1;
open[LineType.Command] = -1;
open[LineType.Label] = -1;
lineIndex = 0;
range = null;
}

private bool ShouldFold (IScriptLine line)
private void VisitLine (IScriptLine line)
{
return line is CommentLine or CommandLine;
if (line is CommentLine) VisitComment();
else if (line is CommandLine) VisitCommand();
else if (line is LabelLine) VisitLabel();
else VisitGeneric();
}

private void FoldLine (IScriptLine line)
private void VisitComment ()
{
if (!range.HasValue) range = new(lineIndex, lineIndex);
else if (lineIndex > range.Value.EndLine + 1) AddRange();
else range = new FoldingRange(range.Value.StartLine, lineIndex);
Close(LineType.Command);
Open(LineType.Comment);
}

private void AddRange ()
private void VisitCommand ()
{
ranges.Add(range!.Value);
range = new(lineIndex, lineIndex);
Close(LineType.Comment);
Open(LineType.Command);
}

private void VisitLabel ()
{
CloseAll();
Open(LineType.Label);
}

private void VisitGeneric ()
{
Close(LineType.Comment);
Close(LineType.Command);
}

private void Open (LineType type)
{
if (open[type] < 0)
open[type] = lineIndex;
}

private void Close (LineType type)
{
if (open[type] < 0) return;
closed.Add(new(open[type], lineIndex - 1));
open[type] = -1;
}

private void CloseAll ()
{
Close(LineType.Comment);
Close(LineType.Command);
Close(LineType.Label);
}
}

0 comments on commit 5ad0a6c

Please sign in to comment.