예제 #1
0
        /// <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);
        }
예제 #2
0
        public void Add(LineFragment fragment)
        {
            fragments.Add(fragment);

            Length += fragment.Length;
        }