jacobslusser / ScintillaNET

A Windows Forms control, wrapper, and bindings for the Scintilla text editor.
MIT License
964 stars 242 forks source link

Save Folding state to a temporary file so that the folding can be rebuilt when the file.is loaded again #508

Open intech-paul opened 3 years ago

intech-paul commented 3 years ago

I am using scintilla to load .c files and want to save the states of the folded lines. I can do this successfully with markers using line.MarkerGet(); and line.MarkerAddSet().

What are the best folding values to save this way ?

I also found that the folding state needs a delay between loading the TextArea.Text and calling TextArea.Lines[1].ToggleFold();

If this is called straight away, it does not work, thus:

TextArea.Text=ReadfromFile TextArea.Lines[1].ToggleFold(); fails,

TextArea.Text=ReadfromFile timer1.enabled

timer1() { TextArea.Lines[1].ToggleFold(); }

works.

Thanks for your time.

VPKSoft commented 3 years ago

For a quick test, this code seems to do the trick:

private string FoldingState { get; set; }

private void mnuTest1_Click(object sender, EventArgs e)
{
    FoldingState = string.Join(";", scintilla.Lines.Where(f => !f.Expanded).Select(f => f.Index).ToArray());
}

private void mnuTest2_Click(object sender, EventArgs e)
{
    scintilla.FoldAll(FoldAction.Expand);
    foreach (var index in FoldingState.Split(';').Select(int.Parse))
    {
        scintilla.Lines[index].ToggleFold();
    }
}

BTW, the idea is good, perhaps this should be included in the package 👍

intech-paul commented 3 years ago

Peter, thanks for your info, and I can get this working.

I did have to have a scintilla.Update() in between loading scintilla.Text and loading the folding state though which causes an annoying flicker when the windows is first displayed.

What you have provided below is quite new to me, what is the best place to learn this type of operation ? FoldingState = string.Join(";", scintilla.Lines.Where(f => !f.Expanded).Select(f => f.Index).ToArray());

I see in this example, it is saving the state for only lines that are folded,, can it be used to save both a line index and MarkerGet() for example ?

VPKSoft commented 3 years ago

Hi, The syntax is LINQ with Lambda expressions: The f => f... here is an instance of a single line in Scintilla control: image The code:

  private void mnuTest1_Click(object sender, EventArgs e)
  {
      FoldingState = string.Join(";", scintilla.Lines
          .Select(f => f.Index + "|" + scintilla.Markers[f.Index].Symbol + "|" + f.Expanded).ToArray());
  }

The resulting "save" string would in this case be like this from a small Json file with folding: 0|Circle|True;1|Circle|True;2|Circle|True;3|Circle|True;4|Circle|True;5|Circle|True;6|Circle|True;7|Circle|True;8|Circle|True;9|Circle|True;10|Circle|True;11|Circle|True;12|Circle|False;13|Circle|True;14|Circle|True;15|Circle|True;16|Circle|False;17|Circle|True;18|Circle|True;19|Circle|True;20|Circle|True;21|Circle|True;22|Circle|True;23|Circle|True;24|Circle|True;25|BoxPlusConnected|True;26|BoxMinusConnected|True;27|TCorner|True;28|LCorner|True;29|VLine|True;30|BoxPlus|True;31|BoxMinus|True

C# Corner seems to have some samples of how to learn LINQ.

For the flickering part I would need a small sample to try to fix it - no promises though 🙂