jacobslusser / ScintillaNET

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

Working with multiple selections at one time #436

Closed tobeypeters closed 5 years ago

tobeypeters commented 5 years ago

How do you select multiple ranges of text and do operations on each selection? For example, I got:

public static Scintilla SelectedTextToUpper(this Scintilla value)
        {
            foreach(var sel in value.Selections)
            {
                int start = sel.Start;
                int end = sel.End;

                Debug.Print($"{sel.ToString()}");

                value.ReplaceSelection(value.GetTextRange(start, end - start).ToUpper());

                value.SetSelection(start, end);
            }

            //int start = value.SelectionStart;
            //int end = value.SelectionEnd;

            //value.ReplaceSelection(value.GetTextRange(start, end - start).ToUpper());

            //value.SetSelection(start, end);

            return value;
        }

Before I execute this particular extension I have:

capture1

After I execute this particular extension I get:

capture2

I assume I'm missing something obvious. I know, this control isn't supposed to conform to true .NET fashion. But, if you can't really do anything with something. Just make those things Private.

tobeypeters commented 5 years ago

No, um, in Scintilla you can turn on "multiple selection" mode by doing MultipleSelection = true; So, in the control, I'm selecting multiple or separate lines of texts which I want to "work" on. In the example I posted, I was trying to implement a Comment line option. I got a partially working version here:

public struct SelectionItem { public int start; public int end; public string text; }

static class ScintillaExtensions
{
    public static List<SelectionItem> SelectedItemList(this Scintilla value)
    {
        List<SelectionItem> SelectedItemBuffer = new List<SelectionItem>();

        for (int i = 0; i < value.Selections.Count; i++)
        {
            SelectedItemBuffer.Add(new SelectionItem()
            {
                start = value.Selections[i].Start,
                end = value.Selections[i].End,
                text = value.GetTextRange(value.Selections[i].Start, value.Selections[i].End - value.Selections[i].Start).ToUpper()
            });
        }

        return SelectedItemBuffer;
    }

    public static Scintilla Comment(this Scintilla value, bool inRemoveMarkers = false)
    {
        List<int> lineIndexes;

        Line LookupLine;

        string LineText = "";

        string GetLineText(int inIndex) => value.GetTextRange(value.Lines[inIndex].Position,
                                          (value.Lines[inIndex].EndPosition - value.Lines[inIndex].Position));

        string StripCommentMarkers(string inStripIt)
        {
            inStripIt = inStripIt.Replace("//", ""); inStripIt = inStripIt.Replace("/*", ""); inStripIt = inStripIt.Replace("*/", "");

            return inStripIt;
        }

        List<SelectionItem> CommentThem = value.SelectedItemList();

        for (int i = (CommentThem.Count - 1); i > -1; i--)
        {
            int lineIndexTemp = -1, lineIndex = -1;

            lineIndexes = new List<int>();

            for (int j = 0; j < CommentThem[i].text.Length; j++)
            {
                lineIndexTemp = value.LineFromPosition((CommentThem[i].start + j));

                if (lineIndex != lineIndexTemp)
                {
                    lineIndex = lineIndexTemp;
                    lineIndexes.Add(lineIndexTemp);
                }
            }

            if (lineIndexes.Count == 1)
            {
                if (!inRemoveMarkers)
                {
                    string Line = Regex.Replace(value.GetTextRange(value.Lines[lineIndexes[0]].Position,
                        (value.Lines[lineIndexes[0]].EndPosition - value.Lines[lineIndexes[0]].Position)),
                        "[^0-9a-zA-Z]+", "");
                    string Comment = Regex.Replace(CommentThem[i].text, "[^0-9a-zA-Z]+", "");

                    if (Comment.Length < Line.Length)
                    {
                        value.InsertText(CommentThem[i].start, "/*"); value.InsertText((CommentThem[i].end + 2), "*/");
                        lineIndexes.Clear();
                    }
                }

                if (inRemoveMarkers)
                {
                    LineText = GetLineText(lineIndexes[0]);

                    if (CommentThem[i].text.Length < LineText.Length)
                    {
                        LineText = StripCommentMarkers(LineText);
                        {
                            LookupLine = value.Lines[lineIndexes[0]];

                            value.SetSel(LookupLine.Position, LookupLine.EndPosition);
                            value.ReplaceSelection(LineText);

                            lineIndexes.Clear();
                        }
                    }
                }
            }

            for (int k = 0; k < lineIndexes.Count; k++)
            {
                if (!inRemoveMarkers) { value.InsertText(value.Lines[lineIndexes[k]].Position, "//"); }

                if (inRemoveMarkers)
                {
                    LineText = GetLineText(lineIndexes[k]);

                    LineText = StripCommentMarkers(LineText);
                    {
                        LookupLine = value.Lines[lineIndexes[k]];

                        value.SetSel(LookupLine.Position, LookupLine.EndPosition);
                        value.ReplaceSelection(LineText);
                    }
                }
            }

            for (int k = 0; k < lineIndexes.Count; k++)
            {
                LookupLine = value.Lines[lineIndexes[k]];

                //value.AddSelection(LookupLine.Position, LookupLine.EndPosition);
            }
        }

        return value;
    }
}

It's not perfect.


From: justinbittner11 notifications@github.com Sent: Sunday, March 10, 2019 9:23 AM To: jacobslusser/ScintillaNET Cc: tobeypeters; Author Subject: Re: [jacobslusser/ScintillaNET] Working with multiple selections at one time (#436)

I'm not entirely sure what you're trying to do here, If you can give more insight. Are you trying to make all 3 of the boxes the same when you change one? If so, I would use the text changed event for each, and have it set the other 2 to the same text. So if textBox1 is changed, set textBox2 = textBox1.Text; textBox3 = textBox1.Text;. But I'm not entirely sure if I understood the problem, or the goal.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/jacobslusser/ScintillaNET/issues/436#issuecomment-471302483, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AiRv-76KhVdFmU5O14OKhdPuSZ5hAfaKks5vVQdfgaJpZM4bOGeO.