FromBounds() private method

private FromBounds ( int start, int end ) : TextRange
start int
end int
return TextRange
Exemplo n.º 1
0
        /// <summary>
        /// Calculates range that is an intersection of the supplied ranges.
        /// </summary>
        /// <returns>Intersection or empty range if ranges don't intersect</returns>
        public static ITextRange Intersection(ITextRange range1, int rangeStart, int rangeLength)
        {
            int start = Math.Max(range1.Start, rangeStart);
            int end   = Math.Min(range1.End, rangeStart + rangeLength);

            return(start <= end?TextRange.FromBounds(start, end) : TextRange.EmptyRange);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Calculates range that is an intersection of the supplied ranges.
        /// </summary>
        /// <returns>Intersection or empty range if ranges don't intersect</returns>
        public static ITextRange Intersection(ITextRange range1, ITextRange range2)
        {
            var start = Math.Max(range1.Start, range2.Start);
            var end   = Math.Min(range1.End, range2.End);

            return(start <= end?TextRange.FromBounds(start, end) : TextRange.EmptyRange);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Calculates range that includes both supplied ranges.
        /// </summary>
        public static ITextRange Union(ITextRange range1, ITextRange range2)
        {
            int start = Math.Min(range1.Start, range2.Start);
            int end   = Math.Max(range1.End, range2.End);

            return(start <= end?TextRange.FromBounds(start, end) : TextRange.EmptyRange);
        }
Exemplo n.º 4
0
        private static ITextRange GetCodeBlockRange(ITextSnapshot snapshot, ITextRange block, ITextRange parametersRange)
        {
            // In
            // {r echo=FALSE}
            //    code
            //
            // we want to format just *code* section and not spill range into the line
            // with {r echo=FALSE} or the next (empty) line. I.e.
            //
            // {r echo=FALSE}
            //|    code|
            //
            // and not
            // {r echo=FALSE}|
            //     code|
            //|
            //
            var startLine = snapshot.GetLineFromPosition(parametersRange.End);
            var endline   = snapshot.GetLineFromPosition(block.End);

            if (endline.LineNumber > startLine.LineNumber)
            {
                endline = snapshot.GetLineFromLineNumber(endline.LineNumber - 1);
            }
            return(TextRange.FromBounds(startLine.EndIncludingLineBreak, endline.End));
        }
Exemplo n.º 5
0
        private void BuildLanguageBlockCollection()
        {
            var tokenizer   = new MdTokenizer();
            var tokens      = tokenizer.Tokenize(TextBuffer.CurrentSnapshot.GetText());
            var rCodeTokens = tokens.OfType <MarkdownCodeToken>().Where(t => t.LeadingSeparatorLength > 1);

            // TODO: incremental updates
            Blocks.Clear();
            _separators.Clear();

            foreach (var t in rCodeTokens)
            {
                // Verify that code block is properly terminated.
                // If not, it ends at the end of the buffer.
                _separators.Add(new TextRange(t.Start, t.LeadingSeparatorLength)); // ```{r or `r
                if (t.IsWellFormed)
                {
                    // Count backticks
                    Blocks.Add(new RLanguageBlock(TextRange.FromBounds(t.Start + t.LeadingSeparatorLength, t.End - t.TrailingSeparatorLength), t.LeadingSeparatorLength == 2));
                    _separators.Add(new TextRange(t.End - t.TrailingSeparatorLength, t.TrailingSeparatorLength));
                }
                else
                {
                    Blocks.Add(new RLanguageBlock(TextRange.FromBounds(t.Start + t.LeadingSeparatorLength, t.End), t.LeadingSeparatorLength == 2));
                }
            }
        }
Exemplo n.º 6
0
        public CharacterStream(ITextProvider textProvider, ITextRange range)
        {
            _text = textProvider;

            int end = Math.Min(_text.Length, range.End);

            _range = TextRange.FromBounds(range.Start, end);

            Position     = _range.Start;
            _currentChar = _text[_range.Start];
        }
Exemplo n.º 7
0
        public CharacterStream(ITextProvider textProvider, ITextRange range)
        {
            Text = textProvider;

            var end = Math.Min(Text.Length, range.End);

            _range = TextRange.FromBounds(range.Start, end);

            Position    = _range.Start;
            CurrentChar = Text.Length > 0 ? Text[_range.Start] : '\0';
        }
Exemplo n.º 8
0
        public static string GetLineLeadingWhitespace(this ITextProvider textProvider, int position)
        {
            int start = position;
            int firstNonWhitespacePosition = position;

            while (start > 0)
            {
                char ch = textProvider[start - 1];

                if (ch.IsLineBreak())
                {
                    break;
                }

                if (!Char.IsWhiteSpace(ch))
                {
                    firstNonWhitespacePosition = start - 1;
                }

                start -= 1;
            }

            return(textProvider.GetText(TextRange.FromBounds(start, firstNonWhitespacePosition)));
        }
Exemplo n.º 9
0
        protected virtual bool IsDestructiveChangeForSeparator(
            ISensitiveFragmentSeparatorsInfo separatorInfo,
            IReadOnlyList <T> itemsInRange,
            int start, int oldLength, int newLength,
            ITextProvider oldText, ITextProvider newText)
        {
            if (separatorInfo == null)
            {
                return(false);
            }

            if (separatorInfo.LeftSeparator.Length == 0 && separatorInfo.RightSeparator.Length == 0)
            {
                return(false);
            }

            // Find out if one of the existing fragments contains position
            // and if change damages fragment start or end separators
            var leftSeparator  = separatorInfo.LeftSeparator;
            var rightSeparator = separatorInfo.RightSeparator;

            // If no items are affected, change is unsafe only if new region contains separators.
            if (itemsInRange.Count == 0)
            {
                // Simple optimization for whitespace insertion
                if (oldLength == 0 && string.IsNullOrWhiteSpace(newText.GetText(new TextRange(start, newLength))))
                {
                    return(false);
                }

                // Take into account that user could have deleted space between existing
                // <! and -- or added - to the existing <!- so extend search range accordingly.
                var fragmentStart = Math.Max(0, start - leftSeparator.Length + 1);
                var fragmentEnd   = Math.Min(newText.Length, start + newLength + leftSeparator.Length - 1);

                var fragmentStartPosition = newText.IndexOf(leftSeparator, TextRange.FromBounds(fragmentStart, fragmentEnd), true);
                if (fragmentStartPosition >= 0)
                {
                    return(true);
                }

                fragmentStart = Math.Max(0, start - rightSeparator.Length + 1);
                fragmentEnd   = Math.Min(newText.Length, start + newLength + rightSeparator.Length - 1);

                fragmentStartPosition = newText.IndexOf(rightSeparator, TextRange.FromBounds(fragmentStart, fragmentEnd), true);
                if (fragmentStartPosition >= 0)
                {
                    return(true);
                }
                return(false);
            }

            // Is change completely inside an existing item?
            if (itemsInRange.Count == 1 && (itemsInRange[0].Contains(start) && itemsInRange[0].Contains(start + oldLength)))
            {
                // Check that change does not affect item left separator
                if (TextRange.Contains(itemsInRange[0].Start, leftSeparator.Length, start))
                {
                    return(true);
                }

                // Check that change does not affect item right separator. Note that we should not be using
                // TextRange.Intersect since in case oldLength is zero (like when user is typing right before %> or ?>)
                // TextRange.Intersect will determine that zero-length range intersects with the right separator
                // which is incorrect. Typing at position 10 does not change separator at position 10. Similarly,
                // deleting text right before %> or ?> does not make change destructive.
                var rightSeparatorStart = itemsInRange[0].End - rightSeparator.Length;
                if (start + oldLength > rightSeparatorStart)
                {
                    if (TextRange.Intersect(rightSeparatorStart, rightSeparator.Length, start, oldLength))
                    {
                        return(true);
                    }
                }

                // Touching left separator is destructive too, like when changing <% to <%@
                // Check that change does not affect item left separator (whitespace is fine)
                if (itemsInRange[0].Start + leftSeparator.Length == start)
                {
                    if (oldLength == 0)
                    {
                        var text = newText.GetText(new TextRange(start, newLength));
                        if (string.IsNullOrWhiteSpace(text))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }

                var fragmentStart = itemsInRange[0].Start + separatorInfo.LeftSeparator.Length;
                fragmentStart = Math.Max(fragmentStart, start - separatorInfo.RightSeparator.Length + 1);
                var changeLength = newLength - oldLength;
                var fragmentEnd  = itemsInRange[0].End + changeLength;
                fragmentEnd = Math.Min(fragmentEnd, start + newLength + separatorInfo.RightSeparator.Length - 1);

                if (newText.IndexOf(separatorInfo.RightSeparator, TextRange.FromBounds(fragmentStart, fragmentEnd), true) >= 0)
                {
                    return(true);
                }

                return(false);
            }

            return(true);
        }
 public IReadOnlyList <T> ItemsInRange(int start) => _collection.ItemsInRange(TextRange.FromBounds(start, start));
Exemplo n.º 11
0
        /// <summary>
        /// Compares two collections and calculates 'changed' range. In case this collection
        /// or comparand are empty, uses lowerBound and upperBound values as range
        /// delimiters. Typically lowerBound is 0 and upperBound is lentgh of the file.
        /// </summary>
        /// <param name="otherCollection">Collection to compare to</param>
        public virtual ITextRange RangeDifference(IEnumerable <ITextRange> otherCollection, int lowerBound, int upperBound)
        {
            if (otherCollection == null)
            {
                return(TextRange.FromBounds(lowerBound, upperBound));
            }

            var other = new TextRangeCollection <ITextRange>(otherCollection);

            if (this.Count == 0 && other.Count == 0)
            {
                return(TextRange.EmptyRange);
            }

            if (this.Count == 0)
            {
                return(TextRange.FromBounds(lowerBound, upperBound));
            }

            if (other.Count == 0)
            {
                return(TextRange.FromBounds(lowerBound, upperBound));
            }

            int minCount = Math.Min(this.Count, other.Count);
            int start = 0;
            int end = 0;
            int i, j;

            for (i = 0; i < minCount; i++)
            {
                start = Math.Min(this[i].Start, other[i].Start);

                if (this[i].Start != other[i].Start || this[i].Length != other[i].Length)
                {
                    break;
                }
            }

            if (i == minCount)
            {
                if (this.Count == other.Count)
                {
                    return(TextRange.EmptyRange);
                }

                if (this.Count > other.Count)
                {
                    return(TextRange.FromBounds(Math.Min(upperBound, other[minCount - 1].Start), upperBound));
                }
                else
                {
                    return(TextRange.FromBounds(Math.Min(this[minCount - 1].Start, upperBound), upperBound));
                }
            }

            for (i = this.Count - 1, j = other.Count - 1; i >= 0 && j >= 0; i--, j--)
            {
                end = Math.Max(this[i].End, other[j].End);

                if (this[i].Start != other[j].Start || this[i].Length != other[j].Length)
                {
                    break;
                }
            }

            if (start < end)
            {
                return(TextRange.FromBounds(start, end));
            }

            return(TextRange.FromBounds(lowerBound, upperBound));
        }
Exemplo n.º 12
0
 public CharacterStream(ITextProvider textProvider)
     : this(textProvider, TextRange.FromBounds(0, textProvider.Length))
 {
 }