/// <summary> /// Given a string, returns start and end points in the buffer that contain that text /// </summary> public int FindText(string txt) { LastSearch = txt; CurrentSearchResult = -1; if (string.IsNullOrEmpty(txt)) { LastSearchResults = Array.Empty <SearchResult> (); return(0); } // simple search for now, we might be able to just do a single scan of the buffer // but if we want to support regex then this might be the better way // a quick look at xterm.js and they still get a copy of the buffer and translate it to string // so this is similar, maybe(?) caching more than we ultimately need. var results = new List <SearchResult> (); int baseLineIndex = 0; int baseCount = 0; var index = Text.IndexOf(txt, 0, StringComparison.CurrentCultureIgnoreCase); while (index >= 0) { // found a result var result = new SearchResult(); // whats the start and end pos of this text // we can assume that it's on the same line, unless we are doing a regex because // the user can't enter a \n as part of the seach term without regex // count the lines up to index int count = baseCount; for (int i = baseLineIndex; i < lines.Length; i++) { count += lines [i].Length; if (count > index) { // found text is on line i // the x position is the delta between the line start and index // we can assume for now that the end is on the same line, since we do not yet support regex int lineStartCount = count - lines [i].Length; // we need to offset the points depending on whether the line fragment is wrapped or not int startFragmentIndex = lines [i].GetFragmentIndexForPosition(index - lineStartCount); LineFragment startFragment = lines [i].GetFragment(startFragmentIndex); // number of chars before this fragment, but on this line int startOffset = 0; for (int fi = 0; fi < startFragmentIndex; fi++) { startOffset += lines [i].GetFragment(fi).Length; } result.Start = new Point(index - lineStartCount - startOffset, startFragment.Line); int endFragmentIndex = lines [i].GetFragmentIndexForPosition(index - lineStartCount + txt.Length - 1); LineFragment endFragment = lines [i].GetFragment(endFragmentIndex); int endOffset = 0; for (int fi = 0; fi < endFragmentIndex; fi++) { endOffset += lines [i].GetFragment(fi).Length; } result.End = new Point(index - lineStartCount + txt.Length - endOffset, endFragment.Line); // now, we need to fix up the end points because we might be on wrapped line // which line fragment is the text on results.Add(result); break; } // update base counts so that next time we loop we don't have to count these lines again baseCount += lines [i].Length; baseLineIndex++; } // search again index = Text.IndexOf(txt, index + txt.Length, StringComparison.CurrentCultureIgnoreCase); } LastSearchResults = results.ToArray(); CurrentSearchResult = -1; return(LastSearchResults.Length); }
public void Add(LineFragment fragment) { fragments.Add(fragment); Length += fragment.Length; }