IEnumerable<ITextSnapshotLine> GetLinesToAlign(ITextSnapshot snapshot)
        {
            int start = snapshot.GetLineNumberFromPosition(m_view.Selection.Start.Position);
            int end   = snapshot.GetLineNumberFromPosition(m_view.Selection.End.Position);

            if (start == end)
            {
                start = 0;
                end   = snapshot.LineCount -1;
            }

            return start.UpTo(end).Select(x => snapshot.GetLineFromLineNumber(x));
        }
Пример #2
0
        /// <summary>
        /// Determines if range is large enough to be outlined
        /// </summary>
        private static bool OutlineRange(ITextSnapshot snapshot, ITextRange range, out int startLineNumber, out int endLineNumber)
        {
            int start = Math.Max(0, range.Start);
            int end   = Math.Min(range.End, snapshot.Length);

            startLineNumber = endLineNumber = 0;
            if (start < end)
            {
                startLineNumber = snapshot.GetLineNumberFromPosition(start);
                endLineNumber   = snapshot.GetLineNumberFromPosition(end);

                return(endLineNumber - startLineNumber + 1 >= _minLinesToOutline);
            }
            return(false);
        }
Пример #3
0
        protected override TeXCommentAdornment CreateAdornment(TeXCommentTag dataTag, ITextSnapshot snapshot)
        {
            var lineSpan = new LineSpan(
                snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.Start),
                snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.End));

            var lastLine = snapshot.GetLineFromLineNumber(lineSpan.LastLine);
            var lastLineWidthWithoutStartWhiteSpaces = (lastLine.Extent.Length - dataTag.TeXBlock.LastLineWhiteSpacesAtStart) * TextView.FormattedLineSource?.ColumnWidth;

            var adornment = new TeXCommentAdornment(
                TextView,
                dataTag,
                lineSpan,
                lastLineWidthWithoutStartWhiteSpaces ?? 0,
                textHasBeenEdited ? TeXCommentAdornmentState.EditingAndRenderingPreview : TeXCommentAdornmentState.Rendering,
                span =>
            {
                //var blockSpans = texCommentBlocks.GetBlockSpansWithLastLineBreakIntersectedBy(Snapshot, span);
                //foreach (var blockSpan in blockSpans)
                //{
                //    RaiseTagsChanged(new SnapshotSpan(Snapshot, blockSpan));
                //}

                //RaiseTagsChanged(new SnapshotSpan(Snapshot, 0, Snapshot.Length));

                InvalidateSpans(new List <SnapshotSpan>()
                {
                    new SnapshotSpan(Snapshot, 0, Snapshot.Length)
                });
            },
                isInEditMode =>
            {
                ForAllCurrentlyUsedAdornments(a => a.CurrentState = isInEditMode ? TeXCommentAdornmentState.EditingAndRenderingPreview : TeXCommentAdornmentState.Rendering, false);
            },
                (tag, attributeText) =>
            {
                var pos = tag.Span.Start + tag.TeXBlock.FirstLineWhiteSpacesAtStart + tag.TeXBlock.TeXCommentPrefix.Length + tag.TeXBlock.PropertiesSegmentLength;
                Snapshot.TextBuffer.Insert(pos, $"[{attributeText}]");
            },
                renderingManager,
                vsSettings);

            TextView.TextBuffer.Changed += adornment.HandleTextBufferChanged;

            MarkAdornmentLines(lineSpan, adornment);

            return(adornment);
        }
Пример #4
0
        private static int DetermineIndentationColumn(
            IEditorOptions editorOptions,
            IEnumerable <SnapshotSpan> spans)
        {
            int?indentationColumn = null;

            foreach (SnapshotSpan span in spans)
            {
                ITextSnapshot snapshot        = span.Snapshot;
                int           startLineNumber = snapshot.GetLineNumberFromPosition(span.Start);
                int           endLineNumber   = snapshot.GetLineNumberFromPosition(span.End);

                // If the span starts after the first non-whitespace of the first line, we'll
                // exclude that line to avoid throwing off the calculation. Otherwise, the
                // incorrect indentation will be returned for lambda cases like so:
                //
                // void M()
                // {
                //     Func<int> f = () =>
                //         {
                //             return 1;
                //         };
                // }
                //
                // Without throwing out the first line in the example above, the indentation column
                // used will be 4, rather than 8.
                int?startLineFirstNonWhitespace = snapshot.GetLineFromLineNumber(startLineNumber).GetFirstNonWhitespacePosition();
                if (startLineFirstNonWhitespace.HasValue && startLineFirstNonWhitespace.Value < span.Start)
                {
                    startLineNumber++;
                }

                for (int lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++)
                {
                    ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNumber);
                    if (string.IsNullOrWhiteSpace(line.GetText()))
                    {
                        continue;
                    }

                    indentationColumn = indentationColumn.HasValue
                        ? Math.Min(indentationColumn.Value, line.GetText().GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(editorOptions.GetTabSize()))
                        : line.GetText().GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(editorOptions.GetTabSize());
                }
            }

            return(indentationColumn ?? 0);
        }
Пример #5
0
        /// <summary>
        /// Gets the number of tabs from the beginning of the line.
        /// </summary>
        /// <param name="lastSlashPosition"></param>
        /// <param name="capture">The snapshot to use as the context of the line.</param>
        /// <returns></returns>
        public static string GetIndention(int lastSlashPosition, ITextSnapshot capture, bool isAboveFunction = false)
        {
            int lineNum = capture.GetLineNumberFromPosition(lastSlashPosition);

            if (isAboveFunction)
            {
                lineNum++;
            }
            else
            {
                lineNum--;
            }

            lineNum = GetFunctionDeclarationLineNumber(capture, lineNum, isAboveFunction);
            string space        = capture.GetLineFromLineNumber(lineNum).GetText();
            int    leadingSpace = space.Length - space.TrimStart().Length;

            space = space.Substring(0, leadingSpace);

            if (isAboveFunction)
            {
                return(space);
            }

            return(space + GetTab());
        }
Пример #6
0
        private void FormatLine()
        {
            ITextSnapshot snapshot = this.wpfTextView.TextSnapshot;

            if (snapshot != snapshot.TextBuffer.CurrentSnapshot)
            {
                return;
            }

            using (ITextEdit edit = this.wpfTextView.TextBuffer.CreateEdit())
            {
                var lineNum = snapshot.GetLineNumberFromPosition(this.wpfTextView.Caret.Position.BufferPosition);

                if (lineNum > 0)
                {
                    var line = snapshot.GetLineFromLineNumber(lineNum - 1);

                    if (!edit.Replace(new Span(line.Start, line.End - line.Start), FormatLine(new Tokenizer(), line.GetText())))
                    {
                        return;
                    }

                    edit.Apply();
                }
            }
        }
Пример #7
0
        private void TokenFromPosition(ITextSnapshot snapshot, int position, out int itemIndex, out int offset)
        {
            // Normally token stream does not change after formatting so we can simply rely on the fact
            // that caret position is going to remain relative to the same token index
            itemIndex = -1;
            offset    = 0;

            // Expand range to include the next line. This is needed when user introduces line break.
            var lineNumber = snapshot.GetLineNumberFromPosition(_changingRange.End);

            if (lineNumber < snapshot.LineCount - 1)
            {
                var end = snapshot.GetLineFromLineNumber(lineNumber + 1).End;
                _changingRange = TextRange.FromBounds(_changingRange.Start, end);
            }

            var tokenizer = new RTokenizer();
            IReadOnlyTextRangeCollection <RToken> tokens =
                tokenizer.Tokenize(new TextProvider(snapshot), _changingRange.Start, _changingRange.Length, true);

            // Check if position is adjacent to previous token
            int prevItemIndex = tokens.GetFirstItemBeforePosition(position);

            if (prevItemIndex >= 0 && tokens[prevItemIndex].End == position)
            {
                itemIndex = prevItemIndex;
                offset    = -tokens[itemIndex].Length;
                return;
            }

            int nextItemIndex = tokens.GetFirstItemAfterOrAtPosition(position);

            if (nextItemIndex >= 0)
            {
                // If two tokens are adjacent, gravity is negative, i.e. caret travels
                // with preceding token so it won't just to aniother line if, say,
                // formatter decides to insert a new line between tokens.

                if (nextItemIndex > 0 && tokens[nextItemIndex - 1].End == tokens[nextItemIndex].Start)
                {
                    nextItemIndex--;
                }

                offset    = tokens[nextItemIndex].Start - position;
                itemIndex = nextItemIndex;
                return;
            }

            // We are past last token
            if (tokens.Count > 0)
            {
                itemIndex = tokens.Count - 1;
                offset    = tokens[itemIndex].Start - position;
            }
            else
            {
                itemIndex = -1;
                offset    = position;
            }
        }
Пример #8
0
        private static void IndentCaretInNewScope(ITextView textView, IScope scope, SnapshotPoint caretBufferPoint, RFormatOptions options)
        {
            if (scope == null || scope.OpenCurlyBrace == null)
            {
                return;
            }
            ITextSnapshot rSnapshot      = caretBufferPoint.Snapshot;
            ITextBuffer   rTextBuffer    = rSnapshot.TextBuffer;
            int           rCaretPosition = caretBufferPoint.Position;

            var caretLine       = rSnapshot.GetLineFromPosition(rCaretPosition);
            int innerIndentSize = SmartIndenter.InnerIndentSizeFromNode(rTextBuffer, scope, options);

            int openBraceLineNumber = rSnapshot.GetLineNumberFromPosition(scope.OpenCurlyBrace.Start);
            var braceLine           = rSnapshot.GetLineFromLineNumber(openBraceLineNumber);
            var indentLine          = rSnapshot.GetLineFromLineNumber(openBraceLineNumber + 1);

            string lineBreakText = braceLine.GetLineBreakText();

            rTextBuffer.Insert(indentLine.Start, lineBreakText);

            // Fetch the line again since snapshot has changed when line break was inserted
            indentLine = rTextBuffer.CurrentSnapshot.GetLineFromLineNumber(openBraceLineNumber + 1);

            // Map new caret position back to the view
            var positionInView = textView.MapUpToView(indentLine.Start);

            if (positionInView.HasValue)
            {
                var viewIndentLine = textView.TextBuffer.CurrentSnapshot.GetLineFromPosition(positionInView.Value);
                textView.Caret.MoveTo(new VirtualSnapshotPoint(viewIndentLine.Start, innerIndentSize));
            }
        }
Пример #9
0
        private IEnumerable <ITagSpan <IOutliningRegionTag> > ProcessHeadingBlocks(IEnumerable <MarkdownObject> descendants, ITextSnapshot snapshot)
        {
            var headingBlocks = descendants.OfType <HeadingBlock>();

            foreach (var block in headingBlocks)
            {
                var next = headingBlocks.FirstOrDefault(h => h.Level <= block.Level && h.Line > block.Line);

                // Treat Setext Heading or ATX Heading uniformly
                var lineNumber = (next != null ?
                                  snapshot.GetLineNumberFromPosition(next.Span.Start) :
                                  snapshot.LineCount) - 1;

                var length = GetSectionEnding(snapshot.GetLineFromLineNumber(lineNumber)) - block.Span.Start;

                if (snapshot.Length >= block.Span.Start + block.Span.Length)
                {
                    string text     = snapshot.GetText(block.ToSimpleSpan());
                    var    span     = new SnapshotSpan(snapshot, block.Span.Start, length);
                    var    spanText = span.GetText();

                    if (spanText.Contains('\r') || spanText.Contains('\n'))
                    {
                        yield return(CreateTag(span, text, spanText));
                    }
                }
            }
        }
        public T GetState(ITextSnapshot snapshot, int startPosition)
        {
            int numberFromPosition = snapshot.GetLineNumberFromPosition(startPosition);

            if (numberFromPosition == 0)
            {
                return(default(T));
            }
            int val2 = numberFromPosition - 1;

            if (this._states[val2].HasValue)
            {
                return(this._states[val2].Value);
            }
            int endLine = val2;

            do
            {
                ;
            }while (val2-- > 0 && !this._states[val2].HasValue);
            T state = val2 < 0 ? default(T) : this._states[val2].Value;

            this.CacheLineStates(snapshot, Math.Max(0, val2), endLine, state);
            return(this._states[endLine].Value);
        }
Пример #11
0
            private static TagSpan GetOutlineSpan(ITextSnapshot snapshot, IOutlinableResult outlineResult)
            {
                TagSpan tagSpan = null;

                try
                {
                    int length = outlineResult.EndIndex - outlineResult.StartIndex;
                    if (length > 0)
                    {
                        var headerLength = outlineResult.DecoratorEnd - outlineResult.DecoratorStart;
                        ITextSnapshotLine startLine;
                        if ((startLine = snapshot.GetLineFromPosition(outlineResult.DecoratorStart)).LineNumber !=
                            snapshot.GetLineNumberFromPosition(outlineResult.DecoratorEnd))
                        {
                            // the decorator range spans multiple lines, so we want to truncate that
                            headerLength = startLine.End.Position - outlineResult.DecoratorStart;
                        }

                        Span headerSpan = new Span(outlineResult.DecoratorStart, headerLength);
                        var  span       = GetFinalSpan(snapshot, outlineResult.StartIndex, length);

                        tagSpan = new TagSpan(
                            new SnapshotSpan(snapshot, span),
                            new OutliningTag(snapshot, headerSpan, span, true)
                            );
                    }
                }
                catch (ArgumentException)
                {
                    // sometimes Python's parser gives us bad spans, ignore those and fix the parser
                    Debug.Assert(false, "bad argument when making span/tag");
                }

                return(tagSpan);
            }
Пример #12
0
        /// <summary>
        /// Gets the caret column position when moving caret vertically.
        /// If the Caret is already on first or last line the caret is set
        /// to the start of file or to the end of the file, respectively.
        /// If the Caret is positioned left off the stored column position
        /// the caret is set to the stored column position or the end of line.
        /// </summary>
        /// <param name="caretPosition"></param>
        /// <param name="snapshot"></param>
        /// <returns></returns>
        internal int GetCaretColumnPosition(int caretPosition, ITextSnapshot snapshot)
        {
            var previousLineNumber = snapshot.GetLineNumberFromPosition(Caret.GetPosition(snapshot));
            var caretLine          = snapshot.GetLineFromPosition(caretPosition);

            if (caretLine.LineNumber == previousLineNumber && caretLine.LineNumber == 0)
            {
                return(0);
            }
            else if (caretLine.LineNumber == previousLineNumber &&
                     caretLine.LineNumber == snapshot.LineCount - 1)
            {
                return(snapshot.Length);
            }
            else if (ColumnPosition > (caretPosition - caretLine.Start.Position))
            {
                var correctColumnPosition = (ColumnPosition > caretLine.Length) ?
                                            caretLine.Length
                    : ColumnPosition;
                return(caretLine.Start.Position + correctColumnPosition);
            }
            else
            {
                return(caretPosition);
            }
        }
Пример #13
0
        private static void IndentCaretInNewScope(ITextView textView, ITextBuffer textBuffer, IScope scope, RFormatOptions options)
        {
            ITextSnapshot snapshot = textBuffer.CurrentSnapshot;

            SnapshotPoint?positionInBuffer = textView.MapDownToBuffer(textView.Caret.Position.BufferPosition, textBuffer);

            if (!positionInBuffer.HasValue || scope == null || scope.OpenCurlyBrace == null)
            {
                return;
            }

            int position = positionInBuffer.Value.Position;
            ITextSnapshotLine caretLine = snapshot.GetLineFromPosition(position);

            int innerIndentSize = SmartIndenter.InnerIndentSizeFromNode(textBuffer, scope, options);

            int openBraceLineNumber         = snapshot.GetLineNumberFromPosition(scope.OpenCurlyBrace.Start);
            ITextSnapshotLine braceLine     = snapshot.GetLineFromLineNumber(openBraceLineNumber);
            ITextSnapshotLine indentLine    = snapshot.GetLineFromLineNumber(openBraceLineNumber + 1);
            string            lineBreakText = braceLine.GetLineBreakText();

            textBuffer.Insert(indentLine.Start, lineBreakText);

            positionInBuffer = textView.MapUpToBuffer(indentLine.Start.Position, textView.TextBuffer);
            if (!positionInBuffer.HasValue)
            {
                return;
            }

            indentLine = textView.TextBuffer.CurrentSnapshot.GetLineFromPosition(positionInBuffer.Value);
            textView.Caret.MoveTo(new VirtualSnapshotPoint(indentLine, innerIndentSize));
        }
Пример #14
0
        internal static SnapshotPoint GetSnapshotPositionFromProtocolPosition(this ITextSnapshot textSnapshot, Position position)
        {
            var line             = textSnapshot.GetLineNumberFromPosition(position.Line);
            var snapshotPosition = textSnapshot.GetLineFromLineNumber(position.Line).Start + position.Character;

            return(new SnapshotPoint(textSnapshot, snapshotPosition));
        }
Пример #15
0
            private void OutlineBlock(IToken startToken, IToken stopToken, object collapsedForm)
            {
                Span span = new Span(startToken.StartIndex, stopToken.StopIndex - startToken.StartIndex + 1);

                // don't collapse blocks that don't span multiple lines
                if (_snapshot.GetLineNumberFromPosition(span.Start) == _snapshot.GetLineNumberFromPosition(span.End))
                {
                    return;
                }

                SnapshotSpan                  snapshotSpan = new SnapshotSpan(_snapshot, span);
                IOutliningRegionTag           tag          = new OutliningRegionTag(false, false, collapsedForm, snapshotSpan.GetText());
                TagSpan <IOutliningRegionTag> tagSpan      = new TagSpan <IOutliningRegionTag>(snapshotSpan, tag);

                _outliningRegions.Add(tagSpan);
            }
Пример #16
0
        protected override void UpdateAdornment(TeXCommentAdornment adornment, TeXCommentTag dataTag, ITextSnapshot snapshot)
        {
            var lineSpan = new LineSpan(
                snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.Start),
                snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.End));

            if (adornment.LineSpan != lineSpan)
            {
                MarkAdornmentLines(adornment.LineSpan, null); //remove old
                MarkAdornmentLines(lineSpan, adornment);      //add new
            }

            var lastLine = snapshot.GetLineFromLineNumber(lineSpan.LastLine);
            var lastLineWidthWithoutStartWhiteSpaces = (lastLine.Extent.Length - dataTag.TeXBlock.LastLineWhiteSpacesAtStart) * TextView.FormattedLineSource?.ColumnWidth;

            adornment.Update(dataTag, lineSpan, lastLineWidthWithoutStartWhiteSpaces);
        }
Пример #17
0
        /// <summary>
        /// Rescans the part of the buffer affected by a change.
        /// Scans a contiguous sub-<paramref name="span"/> of a larger code span which starts at <paramref name="codeStartLine"/>.
        /// </summary>
        private void ApplyChange(Tokenizer tokenizer, ITextSnapshot snapshot, Span span, int codeStartLine, int codeStartLineOffset)
        {
            int firstLine = snapshot.GetLineNumberFromPosition(span.Start);
            int lastLine  = snapshot.GetLineNumberFromPosition(span.Length > 0 ? span.End - 1 : span.End);

            Contract.Assert(codeStartLineOffset >= 0);
            Contract.Assert(firstLine >= codeStartLine);

            // find the closest line preceding firstLine for which we know categorizer state, stop at the codeStartLine:
            LineTokenization lineTokenization;

            firstLine = _tokenCache.IndexOfPreviousTokenization(firstLine, codeStartLine, out lineTokenization) + 1;
            object state = lineTokenization.State;

            int    currentLine = firstLine;
            object previousState;

            while (currentLine < snapshot.LineCount)
            {
                previousState            = _tokenCache.TryGetTokenization(currentLine, out lineTokenization) ? lineTokenization.State : null;
                _tokenCache[currentLine] = lineTokenization = TokenizeLine(tokenizer, snapshot, state, currentLine, (currentLine == codeStartLine) ? codeStartLineOffset : 0);
                state = lineTokenization.State;

                // stop if we visted all affected lines and the current line has no tokenization state or its previous state is the same as the new state:
                if (currentLine > lastLine && (previousState == null || previousState.Equals(state)))
                {
                    break;
                }

                currentLine++;
            }

            // classification spans might have changed between the start of the first and end of the last visited line:
            int changeStart = snapshot.GetLineFromLineNumber(firstLine).Start;
            int changeEnd   = (currentLine < snapshot.LineCount) ? snapshot.GetLineFromLineNumber(currentLine).End : snapshot.Length;

            if (changeStart < changeEnd)
            {
                var classificationChanged = ClassificationChanged;
                if (classificationChanged != null)
                {
                    var args = new ClassificationChangedEventArgs(new SnapshotSpan(snapshot, new Span(changeStart, changeEnd - changeStart)));
                    classificationChanged(this, args);
                }
            }
        }
        public static Task <bool> CheckAvailabilityAsync(SnapshotSpan range, CancellationToken ct)
        {
            bool          result    = false;
            ITextSnapshot snapshot  = range.Snapshot;
            int           startLine = snapshot.GetLineNumberFromPosition(range.Start);
            int           endLine   = snapshot.GetLineNumberFromPosition(range.End);

            for (int i = startLine; i <= endLine; i++)
            {
                if (LineIsInclude(snapshot, i))
                {
                    result = true;
                    break;
                }
            }
            return(Task.FromResult(result));
        }
Пример #19
0
        private ITextViewLine CreateAndAddLineFromPosition(SnapshotPoint position)
        {
            int lineNumber1Based = textSnapshot.GetLineNumberFromPosition(position) + 1;
            var line             = textEditor.Document.GetLine(lineNumber1Based);
            var wrapper          = textEditor.TextViewMargin.GetLayout(line);

            return(Add(lineNumber1Based, line, wrapper));
        }
Пример #20
0
        public void UpdateErrorList(ITextSnapshot snapshot)
        {
            lock (this)
            {
                if (_errorProvider != null && !m_disposed)
                {
                    _errorProvider.SuspendRefresh(); // reduce flickering
                    _errorProvider.Tasks.Clear();
                    foreach (var err in AllErrors)
                    {
                        var lineNum   = 0;
                        var columnNum = 0;
                        if (err.Span != null)
                        {
                            var span = err.Span.GetSpan(snapshot);
                            lineNum = snapshot.GetLineNumberFromPosition(span.Start.Position);
                            var line = snapshot.GetLineFromPosition(span.Start.Position);
                            columnNum = span.Start - line.Start;
                        }
                        else
                        {
                            lineNum   = err.Line;
                            columnNum = err.Column;
                        }

                        ErrorTask task = new ErrorTask()
                        {
                            Category      = TaskCategory.BuildCompile,
                            ErrorCategory = CategoryConversion(err.Category),
                            Text          = err.Message,
                            Line          = lineNum,
                            Column        = columnNum
                        };
                        if (err.Filename != null)
                        {
                            task.Document = err.Filename;
                        }
                        else if (_document != null)
                        {
                            task.Document = _document.FilePath;
                        }
                        if (err.Category != ErrorCategory.ProcessError && err.Category != ErrorCategory.InternalError)
                        {
                            task.Navigate += new EventHandler(NavigateHandler);
                        }
                        _errorProvider.Tasks.Add(task);
                    }
                    _errorProvider.ResumeRefresh();
                }
            }
            var chng = TagsChanged;

            if (chng != null)
            {
                chng(this, new SnapshotSpanEventArgs(new SnapshotSpan(snapshot, 0, snapshot.Length)));
            }
        }
Пример #21
0
        private static ImmutableArray <BlockSpan> GetMultiLineRegions(
#pragma warning disable IDE0060 // Remove unused parameter
            BlockStructureService service,
#pragma warning restore IDE0060 // Remove unused parameter
            ImmutableArray <BlockSpan> regions, ITextSnapshot snapshot)
        {
            // Remove any spans that aren't multiline.
            var multiLineRegions = ArrayBuilder <BlockSpan> .GetInstance();

            foreach (var region in regions)
            {
                if (region.TextSpan.Length > 0)
                {
                    // Check if any clients produced an invalid OutliningSpan.  If so, filter them
                    // out and report a non-fatal watson so we can attempt to determine the source
                    // of the issue.
                    var snapshotSpan = snapshot.GetFullSpan().Span;
                    var regionSpan   = region.TextSpan.ToSpan();
                    if (!snapshotSpan.Contains(regionSpan))
                    {
                        if (!s_exceptionReported)
                        {
                            s_exceptionReported = true;
                        }
                        continue;
                    }

                    var startLine = snapshot.GetLineNumberFromPosition(region.TextSpan.Start);
                    var endLine   = snapshot.GetLineNumberFromPosition(region.TextSpan.End);
                    if (startLine != endLine)
                    {
                        multiLineRegions.Add(region);
                    }
                }
            }

            // Make sure the regions are lexicographically sorted.  This is needed
            // so we can appropriately parent them for BlockTags.
            //
            // Note we pass a IComparer instead of a Comparison to work around this
            // issue in ImmutableArray.Builder: https://github.com/dotnet/corefx/issues/11173
            multiLineRegions.Sort(s_blockSpanComparer);
            return(multiLineRegions.ToImmutableAndFree());
        }
        private static ImmutableArray <BlockSpan> GetMultiLineRegions(
            BlockStructureService service,
            ImmutableArray <BlockSpan> regions, ITextSnapshot snapshot)
        {
            // Remove any spans that aren't multiline.
            var multiLineRegions = ArrayBuilder <BlockSpan> .GetInstance();

            foreach (var region in regions)
            {
                if (region.TextSpan.Length > 0)
                {
                    // Check if any clients produced an invalid OutliningSpan.  If so, filter them
                    // out and report a non-fatal watson so we can attempt to determine the source
                    // of the issue.
                    var snapshotSpan = snapshot.GetFullSpan().Span;
                    var regionSpan   = region.TextSpan.ToSpan();
                    if (!snapshotSpan.Contains(regionSpan))
                    {
                        if (!s_exceptionReported)
                        {
                            s_exceptionReported = true;
                            try
                            {
                                throw new InvalidOutliningRegionException(service, snapshot, snapshotSpan, regionSpan);
                            }
                            catch (InvalidOutliningRegionException e) when(FatalError.ReportAndCatch(e))
                            {
                            }
                        }
                        continue;
                    }

                    var startLine = snapshot.GetLineNumberFromPosition(region.TextSpan.Start);
                    var endLine   = snapshot.GetLineNumberFromPosition(region.TextSpan.End);
                    if (startLine != endLine)
                    {
                        multiLineRegions.Add(region);
                    }
                }
            }

            return(multiLineRegions.ToImmutableAndFree());
        }
Пример #23
0
        // Find the lines that surround the span of the difference.  Try to expand the span to
        // include both the previous and next lines so that we can show more context to the
        // user.
        private LineSpan GetLineSpan(
            ITextSnapshot snapshot,
            Span span)
        {
            var startLine = snapshot.GetLineNumberFromPosition(span.Start);
            var endLine   = snapshot.GetLineNumberFromPosition(span.End);

            if (startLine > 0)
            {
                startLine--;
            }

            if (endLine < snapshot.LineCount)
            {
                endLine++;
            }

            return(LineSpan.FromBounds(startLine, endLine));
        }
        private void OnCaretPositionChanged(object sender, CaretPositionChangedEventArgs args)
        {
            SnapshotPoint oldPosition = args.OldPosition.BufferPosition;
            SnapshotPoint newPosition = args.NewPosition.BufferPosition;

            ITextSnapshot snapshot = this.textView.TextSnapshot;

            if (snapshot.GetLineNumberFromPosition(newPosition) != snapshot.GetLineNumberFromPosition(oldPosition))
            {
                // Is the caret on a line that has been formatted by the view?
                ITextViewLine line = this.textView.Caret.ContainingTextViewLine;

                if (line.VisibilityState != VisibilityState.Unattached)
                {
                    // Force the view to redraw so that (top of) the caret line has exactly the same position.
                    this.textView.DisplayTextLineContainingBufferPosition(line.Start, line.Top, ViewRelativePosition.Top);
                }
            }
        }
        private int FindLineAfterWhichToInsertDeclaration(ITextSnapshot snapshot, int p)
        {
            CodeNavigator     navigator = new CodeNavigator(snapshot);
            IEnumerator <int> point     = navigator.UpFrom(p).GetEnumerator();
            int  originalLine           = snapshot.GetLineNumberFromPosition(p);
            int  lineNumber             = -1;
            bool notEOF;

            do
            {
                notEOF     = point.MoveNext();
                lineNumber = snapshot.GetLineNumberFromPosition(point.Current);
            }while(lineNumber == originalLine && notEOF);
            if (lineNumber == originalLine)
            {
                lineNumber = -1;
            }
            return(lineNumber);
        }
        public LineTransform GetLineTransform(ITextViewLine line, double yposition, ViewRelativePosition placement)
        {
            // Vertically compress lines that are far from the caret (based on buffer lines, not view lines).
            ITextSnapshot snapshot        = this.textView.TextSnapshot;
            int           caretLineNumber = snapshot.GetLineNumberFromPosition(this.textView.Caret.Position.BufferPosition);
            int           lineNumber      = snapshot.GetLineNumberFromPosition(line.Start);
            int           delta           = Math.Abs(caretLineNumber - lineNumber);

            // Idea: Provide options to control these factors. [Bill, 7/17/2015]
            // Idea: Optionally, compress whitespace and non-alphanumeric lines more. [Bill, 7/17/2015]
            const int    Group1Lines          = 3;
            const int    Group2Lines          = Group1Lines + 5;
            const int    Group3Lines          = Group2Lines + 10;
            const double Group1ScaleFactor    = 1.0;
            const double Group2ScaleFactor    = 0.9;
            const double Group3ScaleFactor    = 0.8;
            const double Group2ScaleDecrement = (Group1ScaleFactor - Group2ScaleFactor) / (Group2Lines - Group1Lines);
            const double Group3ScaleDecrement = (Group2ScaleFactor - Group3ScaleFactor) / (Group3Lines - Group2Lines);

            double scale;

            if (delta <= Group1Lines)
            {
                scale = Group1ScaleFactor;
            }
            else if (delta <= Group2Lines)
            {
                scale = Group1ScaleFactor - ((delta - (double)Group1Lines) * Group2ScaleDecrement);
            }
            else if (delta <= Group3Lines)
            {
                scale = Group2ScaleFactor - ((delta - (double)Group2Lines) * Group3ScaleDecrement);
            }
            else
            {
                scale = Group3ScaleFactor;
            }

            LineTransform result = new LineTransform(0.0, 0.0, scale);

            return(result);
        }
Пример #27
0
        // parse the document from the start, and try to
        // figure out where the opening tag matching our closing tag starts
        private SnapshotSpan?FindOpeningTag(ITextSnapshot snapshot, int searchEnd, string searchFor)
        {
            String textToSearch = snapshot.GetText(0, searchEnd);
            int    origLineNum  = snapshot.GetLineNumberFromPosition(searchEnd);

            using (SgmlReader reader = new SgmlReader()) {
                reader.InputStream        = new StringReader(textToSearch);
                reader.WhitespaceHandling = WhitespaceHandling.All;
                try {
                    Stack <int> openingPositions = new Stack <int>();
                    while (reader.Read())
                    {
                        if (reader.LocalName != searchFor)
                        {
                            continue;
                        }
                        if (reader.NodeType == XmlNodeType.Element && !reader.IsEmptyElement)
                        {
                            // find close to where the tag starts
                            int lineNum  = reader.LineNumber - 1;
                            var line     = snapshot.GetLineFromLineNumber(lineNum);
                            int position = line.Start.Position + reader.LinePosition - searchFor.Length;
                            position = BacktrackToLessThan(snapshot, position);
                            String textFound = snapshot.GetText(position, 10);
                            openingPositions.Push(position);
                        }
                        else if (reader.NodeType == XmlNodeType.EndElement)
                        {
                            if (openingPositions.Count <= 0)
                            {
                                // document is malformed, so just get the heck out
                                return(null);
                            }
                            var line     = snapshot.GetLineFromLineNumber(reader.LineNumber - 1);
                            int position = line.Start.Position + reader.LinePosition;
                            if (position >= searchEnd)
                            {
                                break;
                            }
                            openingPositions.Pop();
                        }
                    }
                    // done, last
                    if (openingPositions.Count > 0)
                    {
                        int position = openingPositions.Pop();
                        return(new SnapshotSpan(snapshot, position, searchFor.Length + 2));
                    }
                } catch (Exception ex) {
                    Trace.WriteLine(String.Format("Exception while parsing document: {0}.", ex.ToString()));
                }
            }
            return(null);
        }
            private IList <OutliningSpan> GetMultiLineRegions(IList <OutliningSpan> regions, ITextSnapshot snapshot)
            {
                // Remove any spans that aren't multiline.
                var multiLineRegions = new List <OutliningSpan>(regions.Count);

                foreach (var region in regions)
                {
                    if (region != null && region.TextSpan.Length > 0)
                    {
                        var startLine = snapshot.GetLineNumberFromPosition(region.TextSpan.Start);
                        var endLine   = snapshot.GetLineNumberFromPosition(region.TextSpan.End);
                        if (startLine != endLine)
                        {
                            multiLineRegions.Add(region);
                        }
                    }
                }

                return(multiLineRegions);
            }
Пример #29
0
        private IList <OutliningSpan> GetMultiLineRegions(IOutliningService service, IList <OutliningSpan> regions, ITextSnapshot snapshot)
        {
            // Remove any spans that aren't multiline.
            var multiLineRegions = new List <OutliningSpan>(regions.Count);

            foreach (var region in regions)
            {
                if (region != null && region.TextSpan.Length > 0)
                {
                    // Check if any clients produced an invalid OutliningSpan.  If so, filter them
                    // out and report a non-fatal watson so we can attempt to determine the source
                    // of the issue.
                    var snapshotSpan = snapshot.GetFullSpan().Span;
                    var regionSpan   = region.TextSpan.ToSpan();
                    if (!snapshotSpan.Contains(regionSpan))
                    {
                        if (!exceptionReported)
                        {
                            exceptionReported = true;
                            try
                            {
                                throw new InvalidOutliningRegionException(service, snapshot, snapshotSpan, regionSpan);
                            }
                            catch (InvalidOutliningRegionException e) when(FatalError.ReportWithoutCrash(e))
                            {
                            }
                        }
                        continue;
                    }

                    var startLine = snapshot.GetLineNumberFromPosition(region.TextSpan.Start);
                    var endLine   = snapshot.GetLineNumberFromPosition(region.TextSpan.End);
                    if (startLine != endLine)
                    {
                        multiLineRegions.Add(region);
                    }
                }
            }

            return(multiLineRegions);
        }
        public int GetMinNumberOfWhitespacesBeforeCommentPrefixes(ITextSnapshot snapshot)
        {
            var firstLineIndex = snapshot.GetLineNumberFromPosition(Span.Start);
            var lastLineIndex  = snapshot.GetLineNumberFromPosition(Span.End);

            int min = int.MaxValue;

            for (int lineIndex = firstLineIndex; lineIndex <= lastLineIndex; lineIndex++)
            {
                var line = snapshot.GetLineFromLineNumber(lineIndex);

                //TODO perf
                int whitespaces = line.GetText().NumberOfWhiteSpaceCharsOnStartOfLine();
                if (whitespaces < min)
                {
                    min = whitespaces;
                }
            }

            return(min);
        }
Пример #31
0
        protected static IEnumerable <ITextSnapshotLine> GetSpanLines(SnapshotSpan span)
        {
            ITextSnapshot snapshot = span.Snapshot;

            if (!snapshot.TextBuffer.EditInProgress)
            {
                // Note: The snapshot is usually for the entire file.  We only need to (re)classify a small span of it usually,
                // so we should not use snapshot.Lines.  We'll just get the lines covered by the span's [Start, End) range.
                int startLineNumber = snapshot.GetLineNumberFromPosition(span.Start.Position);
                int endLineNumber   = snapshot.GetLineNumberFromPosition(span.End.Position - 1);

                for (int lineNumber = startLineNumber; lineNumber <= endLineNumber; lineNumber++)
                {
                    ITextSnapshotLine line = snapshot.GetLineFromLineNumber(lineNumber);
                    if (line.Length > 0)
                    {
                        yield return(line);
                    }
                }
            }
        }
        private static IProjectionBuffer CreateProjectionBuffer(
            IProjectionBufferFactoryService factoryService,
            IContentTypeRegistryService registryService,
            IEditorOptions editorOptions,
            ITextSnapshot snapshot,
            string separator,
            object suffixOpt,
            bool trim,
            params LineSpan[] exposedLineSpans)
        {
            var spans = new List<object>();
            if (exposedLineSpans.Length > 0)
            {
                if (exposedLineSpans[0].Start > 0 && !string.IsNullOrEmpty(separator))
                {
                    spans.Add(separator);
                    spans.Add(editorOptions.GetNewLineCharacter());
                }

                var snapshotSpanRanges = CreateSnapshotSpanRanges(snapshot, exposedLineSpans);
                var indentColumn = trim
                    ? DetermineIndentationColumn(editorOptions, snapshotSpanRanges.Flatten())
                    : 0;

                foreach (var snapshotSpanRange in snapshotSpanRanges)
                {
                    foreach (var snapshotSpan in snapshotSpanRange)
                    {
                        var line = snapshotSpan.Snapshot.GetLineFromPosition(snapshotSpan.Start);
                        var indentPosition = line.GetLineOffsetFromColumn(indentColumn, editorOptions) + line.Start;
                        var mappedSpan = new SnapshotSpan(snapshotSpan.Snapshot,
                            Span.FromBounds(indentPosition, snapshotSpan.End));

                        var trackingSpan = mappedSpan.CreateTrackingSpan(SpanTrackingMode.EdgeExclusive);

                        spans.Add(trackingSpan);

                        // Add a newline between every line.
                        if (snapshotSpan != snapshotSpanRange.Last())
                        {
                            spans.Add(editorOptions.GetNewLineCharacter());
                        }
                    }

                    // Add a separator between every set of lines.
                    if (snapshotSpanRange != snapshotSpanRanges.Last())
                    {
                        spans.Add(editorOptions.GetNewLineCharacter());
                        spans.Add(separator);
                        spans.Add(editorOptions.GetNewLineCharacter());
                    }
                }

                if (snapshot.GetLineNumberFromPosition(snapshotSpanRanges.Last().Last().End) < snapshot.LineCount - 1)
                {
                    spans.Add(editorOptions.GetNewLineCharacter());
                    spans.Add(separator);
                }
            }

            if (suffixOpt != null)
            {
                if (spans.Count >= 0)
                {
                    if (!separator.Equals(spans.Last()))
                    {
                        spans.Add(editorOptions.GetNewLineCharacter());
                        spans.Add(separator);
                    }

                    spans.Add(editorOptions.GetNewLineCharacter());
                }

                spans.Add(suffixOpt);
            }

            return factoryService.CreateProjectionBuffer(
                projectionEditResolver: null,
                sourceSpans: spans,
                options: ProjectionBufferOptions.None,
                contentType: registryService.GetContentType(ShaderPreviewContentType));
        }
Пример #33
0
        /// <summary>
        /// Parse a text snapshot into markdown sections.  This is only part of the markdown parser that is really aware of the editor,
        /// but it keeps us from re-creating all the "GetLineFromLineNumber"-type methods.
        /// </summary>
        /// <param name="snapshot"></param>
        /// <returns></returns>
        public static IEnumerable<Token> ParseMarkdownSections(ITextSnapshot snapshot)
        {
            string text = snapshot.GetText();

            List<Tuple<int, TokenType>> startPoints =
                   new List<Tuple<int, TokenType>>(ParseMarkdownParagraph(text).Where(t => IsHeaderToken(t))
                                                                               .Select(t => Tuple.Create(t.Span.Start, t.TokenType)));

            List<Token> sections = new List<Token>();
            Stack<Tuple<int, TokenType>> regions = new Stack<Tuple<int, TokenType>>();

            foreach (var start in startPoints)
            {
                int previousLineNumber = Math.Max(0, snapshot.GetLineNumberFromPosition(start.Item1) - 1);
                int end = snapshot.GetLineFromLineNumber(previousLineNumber).End;

                while (regions.Count > 0 && regions.Peek().Item2 >= start.Item2)
                {
                    var region = regions.Pop();
                    var span = Span.FromBounds(region.Item1, end);
                    sections.Add(new Token(region.Item2, span));
                }

                regions.Push(start);
            }

            while (regions.Count > 0)
            {
                var region = regions.Pop();
                var span = Span.FromBounds(region.Item1, snapshot.Length);
                sections.Add(new Token(region.Item2, span));
            }

            sections.Sort((left, right) =>
                {
                    if (left.Span.Start != right.Span.Start)
                        return left.Span.Start.CompareTo(right.Span.Start);

                    return right.Span.Length.CompareTo(left.Span.Length);
                });

            return sections;
        }
 private static bool TokensSkippedLines(ITextSnapshot snapshot, int endLinePrevious, IToken token)
 {
     int startLineCurrent = snapshot.GetLineNumberFromPosition(token.StartIndex);
     return startLineCurrent > endLinePrevious + 1;
 }
Пример #35
0
        public static Parameter[] GetFunctionParameters(int position, ITextSnapshot capture, bool isAboveFunction = false)
        {
            int openFunctionLine = capture.GetLineNumberFromPosition(position - 1);
            if (isAboveFunction)
            {
                openFunctionLine += 1;
            }
            else
            {
                openFunctionLine -= 1;
            }

            ITextSnapshotLine line = capture.GetLineFromLineNumber(openFunctionLine);
            string curLine = line.Extent.GetText();
            openFunctionLine = StubUtils.GetFunctionDeclarationLineNumber(capture, openFunctionLine, isAboveFunction);
            //Not immediately after a function declaration
            if (openFunctionLine == -1) return new Parameter[0];

            curLine = capture.GetLineFromLineNumber(openFunctionLine).GetText();

            int ftnIndex = StubUtils.javaScriptFnRegex.Match(curLine).Index;
            int firstParenPosition = -1;
            if (curLine.IndexOf('(', ftnIndex) > -1)
            {
                firstParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start +
                                 curLine.IndexOf('(', ftnIndex) + 1;
            }
            else
            {
                do
                {
                    openFunctionLine++;
                    curLine = capture.GetLineFromLineNumber(openFunctionLine).GetText();
                } while (!curLine.Contains("("));

                firstParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start
                                     + curLine.IndexOf('(')
                                     + 1;
            }

            var parenBlock = GetCompleteParenBlock(capture, openFunctionLine, firstParenPosition);
            if (parenBlock == null)
            {
                return new Parameter[0];
            }

            parenBlock = RemoveComments(parenBlock);
            return parenBlock
                .Split(',')
                .Select(param =>
                {
                    var result = Parameter.Parse(param);
                    if (StubUtils.contentTypeName.Equals("JavaScript"))
                    {
                        result.Type = "type";
                    }

                    return result;
                })
                .ToArray();
        }
 private int FindLineAfterWhichToInsertFieldDeclaration(ITextSnapshot snapshot, int p)
 {
     CodeNavigator navigator = new CodeNavigator(snapshot);
     foreach (int significantPoint in navigator.UpFrom(p))
     {
         if (navigator.IsInClassScope(significantPoint)) return snapshot.GetLineNumberFromPosition(significantPoint);
     }
     return -1;
 }
        protected virtual bool IsMultilineToken(ITextSnapshot snapshot, ITokenSource lexer, IToken token)
        {
            Lexer lexerLexer = lexer as Lexer;
            if (lexerLexer != null && lexerLexer.Line >= token.Line)
                return false;

            int startLine = snapshot.GetLineNumberFromPosition(token.StartIndex);
            int stopLine = snapshot.GetLineNumberFromPosition(token.StopIndex + 1);
            return startLine != stopLine;
        }
Пример #38
0
    public void ReportParseErrors(IParseResult parseResult, ITextSnapshot snapshot)
    {
      _errorListProvider.SuspendRefresh();
      try
      {
        // remove any previously created errors to get a clean start
        ClearErrors();

        var messages = (CompilerMessageList)parseResult.CompilerMessages;

        foreach (var error in messages.GetMessages())
        {
          // creates the instance that will be added to the Error List
          var nSpan = error.Location.Span;
          var span = new Span(nSpan.StartPos, nSpan.Length);
          if (span.Start >= snapshot.Length)
            continue;
          ErrorTask task = new ErrorTask();
          task.Category = TaskCategory.All;
          task.Priority = TaskPriority.Normal;
          task.Document = _textBuffer.Properties.GetProperty<ITextDocument>(typeof(ITextDocument)).FilePath;
          task.ErrorCategory = TranslateErrorCategory(error);
          task.Text = error.Text;
          task.Line = snapshot.GetLineNumberFromPosition(span.Start);
          task.Column = span.Start - snapshot.GetLineFromLineNumber(task.Line).Start;
          task.Navigate += OnTaskNavigate;
          _errorListProvider.Tasks.Add(task);
          _previousErrors.Add(task);

          var trackingSpan = snapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeNegative);
          _squiggleTagger.CreateTagSpan(trackingSpan, new ErrorTag("syntax error", error.Text));
          _previousSquiggles.Add(new TrackingTagSpan<IErrorTag>(trackingSpan, new ErrorTag("syntax error", error.Text)));
        }
      }
      finally { _errorListProvider.ResumeRefresh(); }
    }
Пример #39
0
        public static bool ShouldCreateReturnTag(int position, ITextSnapshot capture, bool isAboveFunction = false)
        {
            if (Options.ReturnGenerationOption == ReturnTagGenerationSetting.Always) return true;
            if (Options.ReturnGenerationOption == ReturnTagGenerationSetting.Never) return false;

            bool hasReturn = false;
            bool newFunction = false;
            bool functionClosed = false;
            bool hasComment = false;
            int lineNumber = capture.GetLineNumberFromPosition(position - 1);
            string lineText = capture.GetLineFromLineNumber(lineNumber).GetText();

            if (isAboveFunction) { lineNumber++; }
            else { lineNumber--; }

            bool inFunction = GetFunctionDeclarationLineNumber(capture, lineNumber, isAboveFunction) >= 0;
            if (!inFunction) return false;

            if (isAboveFunction) { lineNumber = GetNextOpenCurlyBrace(lineNumber, capture); }

            if (lineNumber == -1) { return false; }

            int functionsOpen = 0;
            int openBracket = 0;

            for (int i = lineNumber; i < capture.LineCount; i++)
            {
                lineText = capture.GetLineFromLineNumber(i).GetText();
                //HANDLE COMMENTS
                if (lineText.Contains("/*") && lineText.Contains("*/") && lineText.LastIndexOf("/*") > lineText.LastIndexOf("*/"))
                {
                    hasComment = true;
                }
                else if (lineText.Contains("/*") && lineText.Contains("*/"))
                {
                    hasComment = false;
                }
                else if (lineText.Contains("/*"))
                {
                    hasComment = true;
                }

                if (hasComment && lineText.Contains("*/"))
                {
                    if (!lineText.Contains("/*") || lineText.LastIndexOf("/*") <= lineText.LastIndexOf("*/"))
                        hasComment = false;
                }
                else if (hasComment || String.IsNullOrEmpty(lineText.Trim())) { continue; }

                lineText = RemoveComments(lineText);

                //END COMMENT HANDLING

                //HANDLE BRACKETS - "{ }"
                if (javaScriptFnRegex.IsMatch(lineText) && lineText.Contains("{"))
                {
                    //adds an open function and an open bracket.
                    functionsOpen++;
                }
                else if (javaScriptFnRegex.IsMatch(lineText))
                {
                    //states that there is a new function open without an open bracket.
                    newFunction = true;
                }
                else if (newFunction && lineText.Contains("{"))
                {
                    //states that there is no longer a new function and adds an open
                    //bracket and open function.
                    newFunction = false;
                    functionsOpen++;
                }

                if (lineText.Contains("{"))
                {
                    //Adds an open bracket.
                    openBracket++;
                }
                bool isInlineFunction = false;

                if (lineText.Contains("}"))
                {
                    //If function is closed on same line as closing bracket
                    if (functionsOpen == 1 && returnRegex.IsMatch(lineText))
                    {
                        hasReturn = true;
                        break;
                    }
                    else if (returnRegex.IsMatch(lineText))
                    {
                        isInlineFunction = true;
                    }

                    //Decrements both the number of open brackets and functions if they are equal.
                    //This means the number of open brackets are the same as the number of open functions.
                    //Otherwise it just decrements the number of open brackets.
                    if (openBracket == functionsOpen)
                    {
                        functionsOpen--;
                    }

                    openBracket--;
                }
                if (functionsOpen == 0) functionClosed = true;

                if (functionsOpen == 1 && returnRegex.IsMatch(lineText) && !isInlineFunction)
                {
                    hasReturn = true;
                    break;
                }
                else if (functionClosed)
                {
                    break;
                }
            }
            return hasReturn;
        }
Пример #40
0
        /// <summary>
        /// Gets the number of tabs from the beginning of the line.
        /// </summary>
        /// <param name="lastSlashPosition"></param>
        /// <param name="capture">The snapshot to use as the context of the line.</param>
        /// <returns></returns>
        public static string GetIndention(int lastSlashPosition, ITextSnapshot capture, bool isAboveFunction = false)
        {
            int lineNum = capture.GetLineNumberFromPosition(lastSlashPosition);
            if (isAboveFunction) { lineNum++; }
            else { lineNum--; }

            lineNum = GetFunctionDeclarationLineNumber(capture, lineNum, isAboveFunction);
            string space = capture.GetLineFromLineNumber(lineNum).GetText();
            int leadingSpace = space.Length - space.TrimStart().Length;
            space = space.Substring(0, leadingSpace);

            if (isAboveFunction) { return space; }

            return space + GetTab();
        }
 private int FindLineAfterWhichToInsertDeclaration(ITextSnapshot snapshot, int p)
 {
     CodeNavigator navigator = new CodeNavigator(snapshot);
     IEnumerator<int> point = navigator.UpFrom(p).GetEnumerator();
     int originalLine = snapshot.GetLineNumberFromPosition(p);
     int lineNumber = -1;
     bool notEOF;
     do
     {
         notEOF = point.MoveNext();
         lineNumber = snapshot.GetLineNumberFromPosition(point.Current);
     }
     while( lineNumber == originalLine && notEOF) ;
     if (lineNumber == originalLine) lineNumber = -1;
     return lineNumber;
 }
Пример #42
0
        /// <summary>
        /// Rescans the part of the buffer affected by a change. 
        /// Scans a contiguous sub-<paramref name="span"/> of a larger code span which starts at <paramref name="codeStartLine"/>.
        /// </summary>
        private void ApplyChange(Tokenizer tokenizer, ITextSnapshot snapshot, Span span)
        {
            int firstLine = snapshot.GetLineNumberFromPosition(span.Start);
            int lastLine = snapshot.GetLineNumberFromPosition(span.Length > 0 ? span.End - 1 : span.End);

            Contract.Assert(firstLine >= 0);

            // find the closest line preceding firstLine for which we know categorizer state, stop at the codeStartLine:
            LineTokenization lineTokenization;
            firstLine = _tokenCache.IndexOfPreviousTokenization(firstLine, 0, out lineTokenization) + 1;
            object state = lineTokenization.State;

            int currentLine = firstLine;
            object previousState;
            while (currentLine < snapshot.LineCount) {
                previousState = _tokenCache.TryGetTokenization(currentLine, out lineTokenization) ? lineTokenization.State : null;
                _tokenCache[currentLine] = lineTokenization = TokenizeLine(tokenizer, snapshot, state, currentLine);
                state = lineTokenization.State;

                // stop if we visted all affected lines and the current line has no tokenization state or its previous state is the same as the new state:
                if (currentLine > lastLine && (previousState == null || previousState.Equals(state))) {
                    break;
                }

                currentLine++;
            }

            // classification spans might have changed between the start of the first and end of the last visited line:
            int changeStart = snapshot.GetLineFromLineNumber(firstLine).Start;
            int changeEnd = (currentLine < snapshot.LineCount) ? snapshot.GetLineFromLineNumber(currentLine).End : snapshot.Length;
            if (changeStart < changeEnd) {
                var classificationChanged = ClassificationChanged;
                if (classificationChanged != null) {
                    var args = new ClassificationChangedEventArgs(new SnapshotSpan(snapshot, new Span(changeStart, changeEnd - changeStart)));
                    classificationChanged(this, args);
                }
            }
        }
Пример #43
0
        public static string[] GetFunctionParameters(int position, ITextSnapshot capture, bool isAboveFunction = false)
        {
            int openFunctionLine = capture.GetLineNumberFromPosition(position - 1);
            if (isAboveFunction)
            {
                openFunctionLine += 1;
            }
            else
            {
                openFunctionLine -= 1;
            }

            ITextSnapshotLine line = capture.GetLineFromLineNumber(openFunctionLine);
            string prevLine = line.Extent.GetText();
            openFunctionLine = StubUtils.GetFunctionDeclarationLineNumber(capture, openFunctionLine, isAboveFunction);
            //Not immediately after a function declaration
            if (openFunctionLine == -1) return new string[0];

            prevLine = capture.GetLineFromLineNumber(openFunctionLine).GetText();

            int ftnIndex = StubUtils.javaScriptFnRegex.Match(prevLine).Index;
            int firstParenPosition = -1;
            if (prevLine.IndexOf('(', ftnIndex) > -1)
            {
                firstParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start +
                                 prevLine.IndexOf('(', ftnIndex) + 1;
            }
            else
            {
                do
                {
                    openFunctionLine++;
                    prevLine = capture.GetLineFromLineNumber(openFunctionLine).GetText();
                } while (!prevLine.Contains("("));

                firstParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start
                                     + prevLine.IndexOf('(')
                                     + 1;
            }

            int lastParenPosition = -1;
            if (prevLine.IndexOf(')') > 0)
            {
                lastParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start
                                    + prevLine.IndexOf(')', prevLine.IndexOf('('));
            }
            else
            {
                do
                {
                    openFunctionLine++;
                    prevLine = capture.GetLineFromLineNumber(openFunctionLine).GetText();
                } while (!prevLine.Contains(")"));

                lastParenPosition = capture.GetLineFromLineNumber(openFunctionLine).Start +
                                        prevLine.IndexOf(")");
            }

            return StubUtils
                .RemoveComments(capture
                    .GetText()
                    .Substring(firstParenPosition, (lastParenPosition - firstParenPosition)))
                .Split(',')
                .Select(param => param.Trim())
                .ToArray();
        }
 private int FindLineBeforeWhichToInsertMethodStatement(ITextSnapshot snapshot, int p)
 {
     CodeNavigator navigator = new CodeNavigator(snapshot);
     int lastLineOfMethod = -1;
     foreach (int significantPoint in navigator.DownFrom(p))
     {
         lastLineOfMethod = significantPoint;
     }
     if (lastLineOfMethod > 0) return snapshot.GetLineNumberFromPosition(lastLineOfMethod);
     return -1;
 }
Пример #45
0
        // Find the lines that surround the span of the difference.  Try to expand the span to
        // include both the previous and next lines so that we can show more context to the
        // user.
        private LineSpan GetLineSpan(
            ITextSnapshot snapshot,
            Span span)
        {
            var startLine = snapshot.GetLineNumberFromPosition(span.Start);
            var endLine = snapshot.GetLineNumberFromPosition(span.End);

            if (startLine > 0)
            {
                startLine--;
            }

            if (endLine < snapshot.LineCount)
            {
                endLine++;
            }

            return LineSpan.FromBounds(startLine, endLine);
        }
Пример #46
0
        private static bool ShouldWrapPrelim(
            bool optionsAutoWrapEnabled,
            int optionsAvoidWrappingBeforeLine,
            INormalizedTextChangeCollection changes,
            ITextSnapshot snapshot,
            ITextBuffer buffer,
            CaretPosition caretPosition,
            out SnapshotPoint caretPoint,
            out int firstLine)
        {
            caretPoint = default(SnapshotPoint);
            firstLine = -1;

            if (!optionsAutoWrapEnabled)
            {
                return false;
            }

            if (!buffer.CheckEditAccess())
            {
                return false;
            }

            // The auto-wrap should only apply during simple typing.  Region
            // edits (simultaneous multi-line typing) could lead to truly bizarre
            // wrapping behavior, so it really doesn't make sense.
            if (changes.Count > 1)
            {
                return false;
            }

            // Need a better (more testable!) way to get the editing state
            // (change, caret, etc.) out.  Perhaps we just take the hit and get
            // all of these up front instead of only calculating them as needed?
            var change = changes[0];
            caretPoint = caretPosition.Point.GetPoint(snapshot, caretPosition.Affinity).GetValueOrDefault();

            // If the caret isn't near the change, this was an undo, or other operation
            // we shouldn't wrap on!
            if ((caretPoint.Snapshot != snapshot) ||
                (caretPoint < change.NewPosition) ||
                (caretPoint > change.NewEnd))
            {
                return false;
            }

            firstLine = snapshot.GetLineNumberFromPosition(change.NewPosition);

            // If we're in the "don't auto-wrap" leading lines, bail.
            if (firstLine < optionsAvoidWrappingBeforeLine)
            {
                return false;
            }

            return true;
        }
Пример #47
0
        /// <summary>
        /// Determines if range is large enough to be outlined
        /// </summary>
        private static bool OutlineRange(ITextSnapshot snapshot, ITextRange range, out int startLineNumber, out int endLineNumber) {
            int start = Math.Max(0, range.Start);
            int end = Math.Min(range.End, snapshot.Length);

            startLineNumber = endLineNumber = 0;
            if (start < end) {
                startLineNumber = snapshot.GetLineNumberFromPosition(start);
                endLineNumber = snapshot.GetLineNumberFromPosition(end);

                return endLineNumber - startLineNumber + 1 >= _minLinesToOutline;
            }
            return false;
        }
        private static void BuildRegions(OutlineRegionCollection newRegions, ITextSnapshot snapshot) {
            // Figure out regions based on line indent
            if (snapshot.LineCount == 0)
                return;

            var regionStack = new Stack<CodeBlock>();
            var lineLengths = new int[snapshot.LineCount];

            int lastBlockIndent = 0;

            for (int i = 0; i < snapshot.LineCount; i++) {
                var line = snapshot.GetLineFromLineNumber(i);

                var lineText = line.GetText();
                if (String.IsNullOrWhiteSpace(lineText)) {
                    lineLengths[i] = 0;
                    continue;
                }

                lineLengths[i] = line.Length;
                int indent = GetLineIndent(line);

                if (regionStack.Count > 0)
                    lastBlockIndent = regionStack.Peek().Indent;
                else
                    lastBlockIndent = 0;

                if (indent <= lastBlockIndent) {
                    // We add regions optimistically since any line can
                    // start a new region if lines below it are indented
                    // deeper that this line.
                    while (regionStack.Count > 0) {
                        // If we have line with the same indent, remove previously added region
                        // and replace it with a new one potentially starting with the current line.
                        var prevCodeBlock = regionStack.Pop();
                        int startLine = snapshot.GetLineNumberFromPosition(prevCodeBlock.Start);

                        // Trim empty lines
                        int j = i - 1;
                        for (; j >= 0; j--) {
                            if (lineLengths[j] > 0)
                                break;
                        }

                        j++;

                        if (j > 0 && j - startLine >= _minLinesToOutline) {
                            var prevLine = snapshot.GetLineFromLineNumber(j - 1);

                            if (prevCodeBlock.Start < prevLine.End)
                                newRegions.Add(OutlineRegion.FromBounds(snapshot.TextBuffer, prevCodeBlock.Start, prevLine.End));
                        }

                        if (regionStack.Count > 0) {
                            prevCodeBlock = regionStack.Peek();
                            if (prevCodeBlock.Indent < indent)
                                break;
                        }
                    }
                }

                lastBlockIndent = indent;
                regionStack.Push(new CodeBlock(line.Start, indent));
            }

            // Note that last region may be bogus since we add regions optimistically.
            // Remove last region if its indent is the same as the line before it
            if (regionStack.Count > 0) {
                var codeBlock = regionStack.Peek();
                var lineNumber = snapshot.GetLineNumberFromPosition(codeBlock.Start);
                if (lineNumber > 0) {
                    var prevLine = snapshot.GetLineFromLineNumber(lineNumber - 1);
                    int indent = GetLineIndent(prevLine);

                    if (indent == codeBlock.Indent)
                        regionStack.Pop();
                }
            }

            while (regionStack.Count > 0) {
                var codeBlock = regionStack.Pop();

                int startLine = snapshot.GetLineNumberFromPosition(codeBlock.Start);
                if (snapshot.LineCount - startLine >= _minLinesToOutline) {
                    newRegions.Add(OutlineRegion.FromBounds(snapshot.TextBuffer, codeBlock.Start, snapshot.Length));
                }
            }
        }