Example #1
0
        private static void CommentRegion(ITextView view, SnapshotPoint start, SnapshotPoint end)
        {
            using (var edit = view.TextBuffer.CreateEdit()) {
                int minColumn = Int32.MaxValue;
                // first pass, determine the position to place the comment
                for (int i = start.GetContainingLine().LineNumber; i <= end.GetContainingLine().LineNumber; i++) {
                    var curLine = view.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(i);
                    var text = curLine.GetText();

                    minColumn = Math.Min(GetMinimumColumn(text), minColumn);
                }

                // second pass, place the comment
                for (int i = start.GetContainingLine().LineNumber; i <= end.GetContainingLine().LineNumber; i++) {
                    var curLine = view.TextBuffer.CurrentSnapshot.GetLineFromLineNumber(i);
                    if (curLine.Length < minColumn) {
                        // need extra white space
                        edit.Insert(curLine.Start.Position + curLine.Length, new String(' ', minColumn - curLine.Length) + "#");
                    } else {
                        edit.Insert(curLine.Start.Position + minColumn, "#");
                    }
                }

                edit.Apply();
            }

            // select the full region we just commented
            UpdateSelection(view, start, end);
        }
		private static string GetIndentationPrependText(SnapshotPoint startPoint)
		{
			if (startPoint.Position <= startPoint.GetContainingLine().Start.Position)
			{
				return string.Empty;
			}
			int num = startPoint.Position - startPoint.GetContainingLine().Start.Position;
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < num; i++)
			{
				stringBuilder.Append(' ');
			}
			return stringBuilder.ToString();
		}
Example #3
0
		static SnapshotSpan GetWordSpan(SnapshotPoint currentPosition, WordKind kind) {
			Debug.Assert(GetWordKind(currentPosition) == kind);
			var line = currentPosition.GetContainingLine();
			int column = currentPosition.Position - line.Start.Position;
			var start = GetStartSpanBefore(line, column, kind);
			var end = GetEndSpanAfter(line, column, kind);
			return new SnapshotSpan(start, end);
		}
        private static SnapshotSpan? GetExtentOfWord(SnapshotPoint point)
        {
            var line = point.GetContainingLine();

            if (line == null) return null;

            var text = line.GetText();
            var index = point - line.Start;

            var start = index;
            var length = 0;

            if (index > 0 && index < line.Length)
            {
                for (var i = index; i >= 0; i--)
                {
                    var current = text[i];
                    if (current == '$')
                    {
                        start = i;
                        length++;
                        break;
                    }

                    if (current != '_' && char.IsLetterOrDigit(current) == false) break;

                    start = i;
                    length++;
                }
            }

            if (length > 0)
            {
                index++;

                if (index < line.Length)
                {
                    for (var i = index; i < line.Length; i++)
                    {
                        var current = text[i];
                        if (current != '_' && char.IsLetterOrDigit(current) == false) break;

                        length++;
                    }
                }

                var span = new SnapshotSpan(point.Snapshot, start + line.Start, length);

                //Log.Debug("[" + span.GetText() + "]");

                return span;
            }

            return null;
        }
Example #5
0
        /// <summary>
        /// Adds comment characters (//) to the start of each line.  If there is a selection the comment is applied
        /// to each selected line.  Otherwise the comment is applied to the current line.
        /// </summary>
        private static void CommentRegion(ITextView view, SnapshotPoint start, SnapshotPoint end)
        {
            Debug.Assert(start.Snapshot == end.Snapshot);
            var snapshot = start.Snapshot;

            using (var edit = snapshot.TextBuffer.CreateEdit())
            {
                int minColumn = int.MaxValue;

                // First pass, determine the position to place the comment.
                // This is done as we want all of the comment lines to line up at the end.
                // We also should ignore whitelines in this calculation.
                for (int i = start.GetContainingLine().LineNumber; i <= end.GetContainingLine().LineNumber; i++)
                {
                    var curLine = snapshot.GetLineFromLineNumber(i);
                    var text    = curLine.GetText();

                    int firstNonWhitespace = IndexOfNonWhitespaceCharacter(text);
                    if (firstNonWhitespace >= 0 && firstNonWhitespace < minColumn)
                    {
                        minColumn = firstNonWhitespace;
                    }
                }

                // Second pass, place the comment.
                for (int i = start.GetContainingLine().LineNumber; i <= end.GetContainingLine().LineNumber; i++)
                {
                    var curLine = snapshot.GetLineFromLineNumber(i);
                    if (string.IsNullOrWhiteSpace(curLine.GetText()))
                    {
                        continue;
                    }

                    Debug.Assert(curLine.Length >= minColumn);

                    edit.Insert(curLine.Start.Position + minColumn, "//");
                }

                edit.Apply();
            }
        }
Example #6
0
        private static bool FindMatchingCloseChar(SnapshotPoint startPoint, char open, char close, int maxLines, out SnapshotSpan pairSpan)
        {
            pairSpan = new SnapshotSpan(startPoint.Snapshot, 1, 1);
            ITextSnapshotLine line     = startPoint.GetContainingLine();
            string            lineText = line.GetText();
            int lineNumber             = line.LineNumber;
            int offset = startPoint.Position - line.Start.Position + 1;

            int stopLineNumber = startPoint.Snapshot.LineCount - 1;

            if (maxLines > 0)
            {
                stopLineNumber = Math.Min(stopLineNumber, lineNumber + maxLines);
            }
            int openCount = 0;

            while (true)
            {
                //walk the entire line
                while (offset < line.Length)
                {
                    char currentChar = lineText[offset];
                    if (currentChar == close)
                    { //found the close character
                        if (openCount > 0)
                        {
                            openCount--;
                        }
                        else
                        {   //found the matching close
                            pairSpan = new SnapshotSpan(startPoint.Snapshot, line.Start + offset, 1);
                            return(true);
                        }
                    }
                    else if (currentChar == open)
                    { // this is another open
                        openCount++;
                    }
                    offset++;
                }

                //move on to the next line
                if (++lineNumber > stopLineNumber)
                {
                    break;
                }
                line     = line.Snapshot.GetLineFromLineNumber(lineNumber);
                lineText = line.GetText();
                offset   = 0;
            }

            return(false);
        }
Example #7
0
        private static bool IsFollowedByComment(SnapshotPoint point, ISplitCommentService splitCommentService)
        {
            var line = point.GetContainingLine();

            // skip past following whitespace.
            while (point < line.End && char.IsWhiteSpace(point.GetChar()))
            {
                point += 1;
            }

            return(MatchesCommentStart(splitCommentService.CommentStart, point));
        }
        private ITrackingSpan GetApplicableToSpan(ITextSnapshot snapshot, SnapshotPoint triggerPoint)
        {
            var line = triggerPoint.GetContainingLine();

            SnapshotPoint start = triggerPoint;
            while (start > line.Start && !char.IsWhiteSpace((start - 1).GetChar()))
            {
                start -= 1;
            }

            return snapshot.CreateTrackingSpan(new SnapshotSpan(start, line.End), SpanTrackingMode.EdgeInclusive);
        }
Example #9
0
 private static void UpdateSelection(ITextView view, SnapshotPoint start, SnapshotPoint end)
 {
     // Select the full region that is commented, do not select if in projection buffer
     // (the selection might span non-language buffer regions)
     view.Selection.Select(
         new SnapshotSpan(
             start.GetContainingLine().Start.TranslateTo(view.TextBuffer.CurrentSnapshot, PointTrackingMode.Negative),
             end.GetContainingLine().End.TranslateTo(view.TextBuffer.CurrentSnapshot, PointTrackingMode.Positive)
             ),
         false
         );
 }
        private ITrackingSpan FindApplicableSpan(ICompletionSession session)
        {
            // We eventually want to use an ITextStructureNavigator to expand the current point, but
            // first we have to teach it what out structure is.  For now, we just understand the Rtype
            // syntax directly.
            ////ITextStructureNavigator navigator = this.sourceProvider.NavigatorService.GetTextStructureNavigator(this.textBuffer);

            ITextSnapshot  snapshot     = session.TextView.TextSnapshot;
            ITrackingPoint triggerPoint = session.GetTriggerPoint(session.TextView.TextBuffer);

            // Look left and right until we're at a contextual break.
            SnapshotPoint initialPoint = triggerPoint.GetPoint(snapshot);
            SnapshotPoint leftPoint    = initialPoint;
            SnapshotPoint rightPoint   = initialPoint;

            ITextSnapshotLine line = leftPoint.GetContainingLine();

            // look left...
            if (leftPoint > line.Start)
            {
                leftPoint -= 1;
                while (leftPoint > line.Start && CompletionSource.IsTokenTermCharacter(leftPoint.GetChar()))
                {
                    leftPoint -= 1;
                }

                // If we bailed because of the character, advance back to the right.
                if (!CompletionSource.IsTokenTermCharacter(leftPoint.GetChar()))
                {
                    leftPoint += 1;
                }
            }

            // look right...
            // In theory, we might need to include spaces that are inside a quoted region, but we don't know if we've
            // just added the start-quote and might over-extend the selection.  It's safer to be conservative even if
            // it means leaving cruft in the buffer... it's easier for the user to delete the extra than to recover it if
            // we removed it.
            while (rightPoint < line.End && CompletionSource.IsTokenTermCharacter(rightPoint.GetChar()))
            {
                rightPoint += 1;
            }

            ITrackingSpan applicableSpan = snapshot.CreateTrackingSpan(
                leftPoint,
                rightPoint - leftPoint,
                SpanTrackingMode.EdgeInclusive);

            ////System.Diagnostics.Debug.WriteLine("**FindApplicableSpan: final span={0} ('{1}')", applicableSpan, applicableSpan.GetText(leftPoint.Snapshot));

            return(applicableSpan);
        }
Example #11
0
        private void FormatLine()
        {
            //
            getEditorPreferences(TextView);
            //
            SnapshotPoint     caret = this.TextView.Caret.Position.BufferPosition;
            ITextSnapshotLine line  = caret.GetContainingLine();
            // On what line are we ?
            bool alignOnPrev = false;
            int  lineNumber  = line.LineNumber;
            int  indentation = -1;

            // we calculate the indent based on the previous line so we must be on the second line
            if (lineNumber > 0)
            {
                if (caret.Position < line.End.Position)
                {
                    alignOnPrev = true;
                }

                // wait until we can work
                while (_buffer.EditInProgress)
                {
                    System.Threading.Thread.Sleep(100);
                }
                var editSession = _buffer.CreateEdit();
                // This will calculate the desired indentation of the current line, based on the previous one
                // and may de-Indent the previous line if needed
                indentation = getDesiredIndentation(line, editSession, alignOnPrev);
                //
                try
                {
                    // but we may need to re-Format the previous line for Casing and Identifiers
                    // so, do it before indenting the current line.
                    lineNumber = lineNumber - 1;
                    ITextSnapshotLine prevLine = line.Snapshot.GetLineFromLineNumber(lineNumber);
                    this.formatLineCase(editSession, prevLine);
                    CommandFilterHelper.FormatLineIndent(this.TextView, editSession, line, indentation);
                }
                finally
                {
                    if (editSession.HasEffectiveChanges)
                    {
                        editSession.Apply();
                    }
                    else
                    {
                        editSession.Cancel();
                    }
                }
            }
        }
Example #12
0
        private static SnapshotPoint NonIdentifierPositionBefore(SnapshotPoint triggerPoint)
        {
            var line = triggerPoint.GetContainingLine();

            SnapshotPoint start = triggerPoint;

            while (start > line.Start && GlslSpecification.IsIdentifierChar((start - 1).GetChar()))
            {
                start -= 1;
            }

            return(start);
        }
Example #13
0
        public static int GetIndentation(this IndentationResult result, ITextView textView, ITextSnapshotLine lineToBeIndented)
        {
            var position = new SnapshotPoint(lineToBeIndented.Snapshot, result.BasePosition);
            var pointInSurfaceSnapshot = textView.BufferGraph.MapUpToSnapshot(position, PointTrackingMode.Positive, PositionAffinity.Successor, textView.TextSnapshot);
            if (!pointInSurfaceSnapshot.HasValue)
            {
                return position.GetContainingLine().GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(textView.Options);
            }

            var lineInSurfaceSnapshot = pointInSurfaceSnapshot.Value.Snapshot.GetLineFromPosition(pointInSurfaceSnapshot.Value.Position);
            var offsetInLine = pointInSurfaceSnapshot.Value.Position - lineInSurfaceSnapshot.Start.Position;
            return lineInSurfaceSnapshot.GetColumnFromLineOffset(offsetInLine, textView.Options) + result.Offset;
        }
        public static Position AsPosition(this SnapshotPoint point)
        {
            var line       = point.GetContainingLine();
            var character  = point.Position - line.Start.Position;
            var lineNumber = line.LineNumber;
            var position   = new Position()
            {
                Character = character,
                Line      = lineNumber,
            };

            return(position);
        }
Example #15
0
		public static string GetLineBreak(this IEditorOptions editorOptions, SnapshotPoint pos) {
			if (editorOptions.GetReplicateNewLineCharacter()) {
				var line = pos.GetContainingLine();
				if (line.LineBreakLength != 0)
					return pos.Snapshot.GetText(line.Extent.End.Position, line.LineBreakLength);
				if (line.LineNumber != 0) {
					line = pos.Snapshot.GetLineFromLineNumber(line.LineNumber - 1);
					return pos.Snapshot.GetText(line.Extent.End.Position, line.LineBreakLength);
				}
			}
			var linebreak = editorOptions.GetNewLineCharacter();
			return linebreak.Length != 0 ? linebreak : Environment.NewLine;
		}
Example #16
0
        private ITrackingSpan GetApplicableToSpan(ITextSnapshot snapshot, SnapshotPoint triggerPoint)
        {
            var line = triggerPoint.GetContainingLine();

            SnapshotPoint start = triggerPoint;

            while (start > line.Start && !char.IsWhiteSpace((start - 1).GetChar()))
            {
                start -= 1;
            }

            return(snapshot.CreateTrackingSpan(new SnapshotSpan(start, line.End), SpanTrackingMode.EdgeInclusive));
        }
Example #17
0
        private List <Completion> CreateCompletions(string filterText, ClassificationSpan span, SnapshotPoint point, MessageData context)
        {
            List <Completion> completions = new List <Completion>();

            // TODO: figure out which kind of completions to offer...
            if ((span != null && span.ClassificationType.IsOfType(TypeConstants.MessageType)) ||
                (span == null && point.Position == point.GetContainingLine().Start))
            {
                AddMessageTypeCompletions(context, completions);
            }

            return(completions);
        }
Example #18
0
        private double CalculateLeftOfFirstChar(SnapshotPoint open, IFormattedLineSource fls)
        {
            var line  = open.GetContainingLine();
            var x     = 0d;
            var start = line.Start;

            while (Char.IsWhiteSpace(start.GetChar()))
            {
                x    += start.GetChar() == '\t' ? fls.TabSize * fls.ColumnWidth : fls.ColumnWidth;
                start = start + 1;
            }
            return(x);
        }
Example #19
0
        private GherkinStep GetCurrentStep()
        {
            var fileScope = languageService.GetFileScope();

            if (fileScope == null)
            {
                return(null);
            }

            SnapshotPoint caret = textView.Caret.Position.BufferPosition;

            return(fileScope.GetStepAtPosition(caret.GetContainingLine().LineNumber));
        }
Example #20
0
    // Loosely based on NaturalLanguageNavigator
    // ITextStructureNavigator.GetExtentOfWord freezes Visual Studio when run on a C/C++ file,
    // so we need to reimplement it ourselves.
    internal static SnapshotSpan?GetWordExtentSpan(this SnapshotPoint snapshot)
    {
        var line         = snapshot.GetContainingLine();
        var lineContents = line.GetText();
        var start        = FindStartOfWord(snapshot, line, lineContents);
        var end          = FindEndOfWord(snapshot, line, lineContents);

        if (start > end)
        {
            return(null);
        }
        return(new SnapshotSpan(start, end));
    }
        /// <summary>
        /// Adds comment characters (#) to the start of each line.  If there is a selection the comment is applied
        /// to each selected line.  Otherwise the comment is applied to the current line.
        /// </summary>
        /// <param name="view"></param>
        private static void CommentRegion(ITextView view, SnapshotPoint start, SnapshotPoint end)
        {
            Debug.Assert(start.Snapshot == end.Snapshot);
            var snapshot = start.Snapshot;

            using (var edit = snapshot.TextBuffer.CreateEdit())
            {
                int minColumn = Int32.MaxValue;
                // first pass, determine the position to place the comment
                for (int i = start.GetContainingLine().LineNumber; i <= end.GetContainingLine().LineNumber; i++)
                {
                    var curLine = snapshot.GetLineFromLineNumber(i);
                    var text    = curLine.GetText();

                    int firstNonWhitespace = IndexOfNonWhitespaceCharacter(text);
                    if (firstNonWhitespace >= 0 && firstNonWhitespace < minColumn)
                    {
                        // ignore blank lines
                        minColumn = firstNonWhitespace;
                    }
                }

                // second pass, place the comment
                for (int i = start.GetContainingLine().LineNumber; i <= end.GetContainingLine().LineNumber; i++)
                {
                    var curLine = snapshot.GetLineFromLineNumber(i);
                    if (String.IsNullOrWhiteSpace(curLine.GetText()))
                    {
                        continue;
                    }

                    Debug.Assert(curLine.Length >= minColumn);

                    edit.Insert(curLine.Start.Position + minColumn, "#");
                }

                edit.Apply();
            }
        }
        void UpdateWordAdornments()
        {
            SnapshotPoint currentRequest = RequestedPoint;
            TextExtent    word           = TextStructureNavigator.GetExtentOfWord(currentRequest);
            bool          foundWord      = true;

            //If we've selected something not worth highlighting, we might have missed a "word" by a little bit
            if (!WordExtentIsValid(currentRequest, word))
            {
                //Before we retry, make sure it is worthwhile
                if (word.Span.Start != currentRequest ||
                    currentRequest == currentRequest.GetContainingLine().Start ||
                    char.IsWhiteSpace((currentRequest - 1).GetChar()))
                {
                    foundWord = false;
                }
                else
                {
                    //Try again, one character previous.
                    //If looking at the end of a word, pick up the word.
                    word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1);

                    //If the word still isn't valid, we're done
                    if (!WordExtentIsValid(currentRequest, word))
                    {
                        foundWord = false;
                    }
                }
            }

            if (!foundWord)
            {
                //If we couldn't find a word, clear out the existing markers
                SynchronousUpdate(currentRequest, null);
                return;
            }

            SnapshotSpan currentWord = word.Span;

            //If this is the current word, and the user's eyes moved within a word, we're done.
            if (CurrentWord.HasValue && currentWord == CurrentWord)
            {
                return;
            }

            //If another change hasn't happened, do a real update
            if (currentRequest == RequestedPoint)
            {
                SynchronousUpdate(currentRequest, currentWord);
            }
        }
        private CodeElement GetCodeElement(DTE dte, SnapshotPoint  point, CodeElements codeElements, vsCMElement elementType)
        {
            foreach (CodeElement ce in codeElements)
            {
                if (ce.Kind.ToString() == "vsCMElementImportStmt")
                {
                    continue;
                }
                try
                {
                    _log.Debug("Searching " + ce.Name);
                    Debug.WriteLine(string.Format("Searching {0}:{1}", ce.Kind.ToString(), ce.Name));
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Exception getting object name: " + e.Message );
                }

                var sp = getStartPoint(ce);
                var pointLine = point.GetContainingLine().LineNumber;

                if (sp != null)
                {
                    if (sp.Line > pointLine )
                    {
                        // code element starts after the droplocation, ignore it
                    }
                    else if (ce.EndPoint.Line  < pointLine )
                    {
                        // code element finishes before the droplocation, ignore it
                    }
                    else
                    {

                        if (elementType == ce.Kind)
                        {

                            return ce;
                        }

                        var childElements = getCodeElements(ce);
                        if (childElements != null)
                        {
                            var ret = GetCodeElement(dte, point, childElements, elementType);
                            if (ret != null) return ret;
                        }
                    }
                }
            }
            return null;
        }
Example #24
0
        private async Task AddMissingImports(List <string> importList, SnapshotPoint point)
        {
            if (importList.Count == 0)
            {
                return;
            }

            AnalysisEntry entry;

            if (_entryService == null || !_entryService.TryGetAnalysisEntry(_textView, _textView.TextBuffer, out entry))
            {
                return;
            }

            foreach (var import in importList)
            {
                var isMissing = await entry.Analyzer.IsMissingImportAsync(
                    entry,
                    import,
                    new SourceLocation(
                        point.Position,
                        point.Position - point.GetContainingLine().Start + 1,
                        point.GetContainingLine().LineNumber
                        )
                    );

                if (isMissing)
                {
                    await VsProjectAnalyzer.AddImportAsync(
                        entry,
                        null,
                        import,
                        _textView,
                        _textView.TextBuffer
                        );
                }
            }
        }
Example #25
0
 public static string GetItemBeforeCaret(this ITextView textView, Func <char, bool> charSelector, out Span span)
 {
     if (!textView.Caret.InVirtualSpace)
     {
         SnapshotPoint     position = textView.Caret.Position.BufferPosition;
         ITextSnapshotLine line     = position.GetContainingLine();
         if (position.Position > line.Start)
         {
             return(GetItem(line, position.Position - 1, charSelector, out span));
         }
     }
     span = Span.FromBounds(0, 0);
     return(string.Empty);
 }
Example #26
0
        public static string GetLineString(SnapshotPoint triggerPoint, int startPosition)
        {
            ITextSnapshotLine currentLine = triggerPoint.GetContainingLine();

            int tempStartPos = startPosition;

            if (tempStartPos < 0)
            {
                tempStartPos = currentLine.End.Position;
            }
            ITrackingSpan span = currentLine.Snapshot.CreateTrackingSpan(currentLine.Start.Position, tempStartPos - currentLine.Start.Position, SpanTrackingMode.EdgeInclusive);

            return(span.GetText(currentLine.Snapshot));
        }
Example #27
0
        public bool TryGetCompletionList(SnapshotPoint triggerLocation, string attrName, out IEnumerable <CompletionItem> completions)
        {
            completions = null;

            SnapshotSpan extent = triggerLocation.GetContainingLine().Extent;
            string       line   = extent.GetText();

            if (TryGetXmlFragment(line, out XPathNavigator navigator))
            {
                completions = GetCompletions(ReadXmlDocument(triggerLocation.Snapshot), navigator, attrName).ToArray();
            }

            return(completions != null);
        }
Example #28
0
        protected virtual async Task CommandCallbackAsync()
        {
            IWpfTextView textView = await ServiceProvider.GetWpfTextViewAsync();

            if (textView == null)
            {
                return;
            }

            SnapshotPoint     caretPosition = textView.Caret.Position.BufferPosition;
            ITextSnapshotLine caretLine     = caretPosition.GetContainingLine();

            if (caretLine == null)
            {
                return;
            }

            Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null || !document.SupportsSyntaxTree /*|| document.SourceCodeKind ==*/)
            {
                return;
            }

            Task <SyntaxNode>    syntaxRootTask    = document.GetSyntaxRootAsync(Package.DisposalToken);
            Task <SemanticModel> semanticModelTask = document.GetSemanticModelAsync(Package.DisposalToken);
            await Task.WhenAll(syntaxRootTask, semanticModelTask);

#pragma warning disable VSTHRD002, VSTHRD103 // Avoid problematic synchronous waits - the results are already obtained
            SyntaxNode    syntaxRoot    = syntaxRootTask.Result;
            SemanticModel semanticModel = semanticModelTask.Result;
#pragma warning restore VSTHRD002, VSTHRD103

            if (syntaxRoot == null || semanticModel == null || !IsPlatformReferenced(semanticModel) ||
                Package.DisposalToken.IsCancellationRequested)
            {
                return;
            }

            TextSpan caretSpan = GetTextSpanFromCaret(caretPosition, caretLine);
            List <DiagnosticData> diagnosticData = await GetDiagnosticsAsync(document, caretSpan);

            SyntaxNode nodeWithDiagnostic = syntaxRoot.FindNode(caretSpan);

            if (nodeWithDiagnostic != null)
            {
                await SuppressDiagnosticsAsync(diagnosticData, document, syntaxRoot, semanticModel, nodeWithDiagnostic);
            }
        }
Example #29
0
        /// <summary>
        /// Gets the indentation level that we want to be at, in spaces.
        /// </summary>
        private static int GetTargetIndentation(IWpfTextView view, SnapshotPoint point)
        {
            var caretLine = point.GetContainingLine();
            int curLine   = caretLine.LineNumber;
            var snapshot  = point.Snapshot;

            int startLine = curLine;

            // skip blank lines as far as calculating indentation goes...
            bool              hasNonWhiteSpace = false;
            string            lineText;
            ITextSnapshotLine line;

            do
            {
                line = snapshot.GetLineFromLineNumber(curLine);
                if (curLine == startLine)
                {
                    // if we're in the middle of a line only consider text to the left for white space detection
                    lineText = line.GetText().Substring(0, point.Position - caretLine.Start);
                }
                else
                {
                    lineText = line.GetText();
                }
                foreach (char c in lineText)
                {
                    if (!Char.IsWhiteSpace(c))
                    {
                        hasNonWhiteSpace = true;
                        break;
                    }
                }
                if (!hasNonWhiteSpace)
                {
                    curLine--;
                }
            } while (!hasNonWhiteSpace && curLine > 0);

            var classifier  = point.Snapshot.TextBuffer.GetPythonClassifier();
            int indentation = CalculateIndentation(lineText, line, view, classifier);

            if (curLine != startLine)
            {
                // enter on a blank line, don't re-indent instead just maintain the current indentation
                indentation = Math.Min(indentation, GetIndentation(caretLine.GetText(), view.Options.GetIndentSize()));
            }
            return(indentation);
        }
Example #30
0
        private void AddMissingImports(List <string> importList, SnapshotPoint point)
        {
            if (importList.Count == 0)
            {
                return;
            }

            var bi    = _services.GetBufferInfo(_textView.TextBuffer);
            var entry = bi?.AnalysisEntry;

            if (entry == null)
            {
                return;
            }

            SourceLocation loc;

            try {
                var line = point.GetContainingLine();
                loc = new SourceLocation(
                    point.Position,
                    line.LineNumber + 1,
                    point.Position - line.Start + 1
                    );
            } catch (ArgumentException ex) {
                Debug.Fail(ex.ToUnhandledExceptionMessage(GetType()));
                return;
            }

            foreach (var import in importList)
            {
                var isMissing = entry.Analyzer.WaitForRequest(
                    entry.Analyzer.IsMissingImportAsync(entry, import, loc),
                    "ExpansionClient.IsMissingImportAsync",
                    false
                    );

                if (isMissing)
                {
                    VsProjectAnalyzer.AddImport(
                        entry,
                        null,
                        import,
                        _textView,
                        _textView.TextBuffer
                        );
                }
            }
        }
        protected override void CommandCallback(object sender, EventArgs e)
        {
            IWpfTextView textView = ServiceProvider.GetWpfTextView();

            if (textView == null)
            {
                return;
            }

            SnapshotPoint     caretPosition = textView.Caret.Position.BufferPosition;
            ITextSnapshotLine caretLine     = caretPosition.GetContainingLine();

            if (caretLine == null)
            {
                return;
            }

            Document document = caretPosition.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document == null)
            {
                return;
            }

            (SyntaxNode syntaxRoot, SemanticModel semanticModel) = ThreadHelper.JoinableTaskFactory.Run(
                async() => (await document.GetSyntaxRootAsync(), await document.GetSemanticModelAsync()));

            if (syntaxRoot == null || semanticModel == null)
            {
                return;
            }

            TextSpan lineSpan   = TextSpan.FromBounds(caretLine.Start.Position, caretLine.End.Position);
            var      memberNode = syntaxRoot.FindNode(lineSpan) as MemberDeclarationSyntax;

            if (memberNode == null)
            {
                return;
            }

            ISymbol memberSymbol = GetMemberSymbol(memberNode, semanticModel, caretPosition);

            if (!CheckMemberSymbol(memberSymbol))
            {
                return;
            }

            NavigateToHandlerOrDeclaration(document, textView, memberSymbol, memberNode, semanticModel);
        }
        //---------------------------------------------------------------------------
        // FindCurrentWordCoords
        //---------------------------------------------------------------------------
        public static bool FindCurrentWordCoords(SnapshotPoint currentPosition, out SnapshotSpan span)
        {
            span = new SnapshotSpan(currentPosition, 0);

            ITextSnapshotLine textSnapshotLine = currentPosition.GetContainingLine();
            LineBuffer        lineText         = new LineBuffer(textSnapshotLine);
            int lineLength = textSnapshotLine.LengthIncludingLineBreak;
            int iCol       = (currentPosition - textSnapshotLine.Start);

            // scan left for base char
            while ((iCol > 0) && !IsGraphemeBreak(lineText, iCol))
            {
                iCol--;
            }

            if ((iCol == lineLength) || !IsWordChar(lineText[iCol]))
            {
                if (iCol == 0 || !IsWordChar(lineText[iCol - 1]))
                {
                    return(false);
                }
                iCol--;
            }

            // Find the beginning
            int iBeg;

            for (iBeg = iCol; iBeg >= 0; --iBeg)
            {
                if (IsWordBreak(lineText, iBeg, false))
                {
                    break;
                }
            }

            // Find the end
            for (++iCol; iCol < lineLength; ++iCol)
            {
                if (IsWordBreak(lineText, iCol, false))
                {
                    break;
                }
            }

            // Done -- fill in the data
            span = new SnapshotSpan(currentPosition.Snapshot, (textSnapshotLine.Start + iBeg), (iCol - iBeg));

            return(true);
        }
        /// <summary>
        /// Expands a given span of lines (usually one) to a virtual line that accounts for
        /// continuation characters
        /// </summary>
        static public Span GetContinuedLinesSpan(SnapshotPoint start, SnapshotPoint end)
        {
            ITextSnapshot snapshot = start.Snapshot;

            int startLineNumber = start.GetContainingLine().LineNumber;
            int endLineNumber   = (end <= start.GetContainingLine().EndIncludingLineBreak) ? startLineNumber : snapshot.GetLineNumberFromPosition(end);

            // Find the first line
            bool lineContinuedUp = (startLineNumber > 0) && snapshot.GetLineFromLineNumber(startLineNumber - 1).GetText().EndsWith("\\");

            while (lineContinuedUp && (startLineNumber > 0))
            {
                startLineNumber--;
                lineContinuedUp = (startLineNumber > 0) && snapshot.GetLineFromLineNumber(startLineNumber - 1).GetText().EndsWith("\\");
            }

            // Find the last line
            while ((endLineNumber < snapshot.LineCount - 1) && (snapshot.GetLineFromLineNumber(endLineNumber).GetText().EndsWith("\\")))
            {
                endLineNumber++;
            }

            return(new Span(startLineNumber, endLineNumber - startLineNumber));
        }
Example #34
0
 /// <summary>
 /// Extracts identifier or a keyword before caret. Typically used when inserting
 /// expansions (aka code snippets) at the caret location.
 /// </summary>
 public static string GetItemBeforeCaret(this ITextView textView, out Span span, Func <RTokenType, bool> tokenTypeCheck = null)
 {
     if (!textView.Caret.InVirtualSpace)
     {
         SnapshotPoint     position = textView.Caret.Position.BufferPosition;
         ITextSnapshotLine line     = position.GetContainingLine();
         tokenTypeCheck = tokenTypeCheck ?? new Func <RTokenType, bool>((x) => x == RTokenType.Identifier);
         if (position.Position > line.Start)
         {
             return(GetItemAtPosition(line, position.Position - 1, tokenTypeCheck, out span));
         }
     }
     span = Span.FromBounds(0, 0);
     return(string.Empty);
 }
Example #35
0
        public static int GetIndentation(this IndentationResult result, ITextView textView, ITextSnapshotLine lineToBeIndented)
        {
            var position = new SnapshotPoint(lineToBeIndented.Snapshot, result.BasePosition);
            var pointInSurfaceSnapshot = textView.BufferGraph.MapUpToSnapshot(position, PointTrackingMode.Positive, PositionAffinity.Successor, textView.TextSnapshot);

            if (!pointInSurfaceSnapshot.HasValue)
            {
                return(position.GetContainingLine().GetColumnOfFirstNonWhitespaceCharacterOrEndOfLine(textView.Options));
            }

            var lineInSurfaceSnapshot = pointInSurfaceSnapshot.Value.Snapshot.GetLineFromPosition(pointInSurfaceSnapshot.Value.Position);
            var offsetInLine          = pointInSurfaceSnapshot.Value.Position - lineInSurfaceSnapshot.Start.Position;

            return(lineInSurfaceSnapshot.GetColumnFromLineOffset(offsetInLine, textView.Options) + result.Offset);
        }
Example #36
0
        private static bool LineProbablyContainsComment(ISplitCommentService service, SnapshotPoint position)
        {
            var commentStart = service.CommentStart;
            var line         = position.GetContainingLine();

            for (var p = line.Start.Position; p < position; p++)
            {
                if (MatchesCommentStart(commentStart, line, p))
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Displays completion after typing a space after a step keyword
        /// </summary>
        protected override bool ShouldCompletionBeDiplayed(SnapshotPoint caret)
        {
            var lineStart = caret.GetContainingLine().Start.Position;
            var lineBeforeCaret = caret.Snapshot.GetText(lineStart, caret.Position - lineStart);

            if (lineBeforeCaret.Length > 0 &&
                char.IsWhiteSpace(lineBeforeCaret[lineBeforeCaret.Length - 1]))
            {
                string keyword = lineBeforeCaret.Substring(0, lineBeforeCaret.Length - 1).TrimStart();
                var languageService = GherkinProcessorServices.GetLanguageService(caret.Snapshot.TextBuffer);
                return languageService.IsStepKeyword(keyword);
            }

            return false;
        }
Example #38
0
            internal static TagSpan GetTagSpan(SnapshotPoint start, SnapshotPoint end)
            {
                TagSpan tagSpan  = null;
                var     snapshot = start.Snapshot;

                try {
                    SnapshotPoint hintEnd = end;
                    if (start.GetContainingLine().LineNumber + 5 < hintEnd.GetContainingLine().LineNumber)
                    {
                        hintEnd = start.Snapshot.GetLineFromLineNumber(start.GetContainingLine().LineNumber + 5).End;
                    }

                    return(new TagSpan(
                               new SnapshotSpan(start, end),
                               new SnapshotSpan(start, hintEnd)
                               ));
                } 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");
                }

                Debug.Assert(tagSpan != null, "failed to create tag span with start={0} and end={0}".FormatUI(start, end));
                return(tagSpan);
            }
        private GherkinStep GetCurrentStepForAtguments()
        {
            var fileScope = languageService.GetFileScope();

            if (fileScope == null)
            {
                return(null);
            }

            SnapshotPoint caret             = textView.Caret.Position.BufferPosition;
            var           triggerLineNumber = caret.GetContainingLine().LineNumber;
            var           stepBlock         = fileScope.GetStepBlockFromStepPosition(triggerLineNumber);

            return(stepBlock.Steps.LastOrDefault(s => s.BlockRelativeLine + stepBlock.KeywordLine < triggerLineNumber));
        }
        /// <summary>
        /// Displays completion after typing a space after a step keyword
        /// </summary>
        protected override bool ShouldCompletionBeDiplayed(SnapshotPoint caret)
        {
            var lineStart = caret.GetContainingLine().Start.Position;
            var lineBeforeCaret = caret.Snapshot.GetText(lineStart, caret.Position - lineStart);

            if (lineBeforeCaret.Length > 0 &&
                char.IsWhiteSpace(lineBeforeCaret[lineBeforeCaret.Length - 1]))
            {
                string keyword = lineBeforeCaret.Substring(0, lineBeforeCaret.Length - 1).TrimStart();

                var fileScope = languageService.GetFileScope(waitForParsingSnapshot: caret.Snapshot);
                if (fileScope != null && fileScope.GherkinDialect != null)
                    return fileScope.GherkinDialect.IsStepKeyword(keyword);
            }

            return false;
        }
        private bool IsReplCommandLocation(SnapshotPoint characterPoint)
        {
            // TODO(cyrusn): We don't need to do this textually.  We could just defer this to
            // IsTriggerCharacter and just check the syntax tree.
            var line = characterPoint.GetContainingLine();
            var text = characterPoint.Snapshot.GetText(line.Start.Position, characterPoint.Position - line.Start.Position);

            // TODO (tomat): REPL commands should have their own handlers:
            if (characterPoint.Snapshot.ContentType.IsOfType(ContentTypeNames.CSharpContentType))
            {
                if (s_referenceRegex.IsMatch(text))
                {
                    return true;
                }
            }

            return false;
        }
        // Inspired by NodejsTools
        /// <summary>
        /// Enumerates the classifications in the first code line preceding a point.
        /// Skips blank lines or comment-only lines.
        /// </summary>
        private static IEnumerable<ClassificationSpan> EnumeratePrecedingLineTokens(SnapshotPoint start)
        {
            var tagger = start.Snapshot.TextBuffer.Properties.GetProperty<ITagger<ClassificationTag>>(jsTaggerType);

            var curLine = start.GetContainingLine();
            if (curLine.LineNumber == 0)
                yield break;

            bool foundCode = false;
            do
            {
                curLine = start.Snapshot.GetLineFromLineNumber(curLine.LineNumber - 1);
                var classifications = tagger.GetTags(new NormalizedSnapshotSpanCollection(curLine.Extent));
                foreach (var tag in classifications.Where(c => !c.Tag.ClassificationType.IsOfType("comment")))
                {
                    foundCode = true;
                    yield return new ClassificationSpan(tag.Span, tag.Tag.ClassificationType);
                }
            }
            while (!foundCode && curLine.LineNumber > 0);
        }
Example #43
0
        private static string GetVariableNameAndSpan(SnapshotPoint point, out SnapshotSpan span)
        {
            var line = point.GetContainingLine();
            var hoveredIndex = point.Position - line.Start.Position;

            var c = point.GetChar();
            if (!Char.IsDigit(c) && !Char.IsLetter(c) && (c != '_'))
            {
                span = new SnapshotSpan();
                return null;
            }

            // Find the name of the variable under the mouse pointer (ex: 'gesture.Pose.Name' when the mouse is hovering over the 'o' of pose)
            var match = m_variableExtractor.Matches(line.GetText()).OfType<Match>().SingleOrDefault(x => x.Index <= hoveredIndex && (x.Index + x.Length) >= hoveredIndex);
            if ((match == null) || (match.Value.Length == 0))
            {
                span = new SnapshotSpan();
                return null;
            }
            var name = match.Value;

            // Find the first '.' after the hoveredIndex and cut it off
            int relativeIndex = hoveredIndex - match.Index;
            var lastIndex = name.IndexOf('.', relativeIndex);
            if (lastIndex >= 0)
            {
                name = name.Substring(0, lastIndex);
            }
            else
            {
                lastIndex = name.Length;
            }

            var matchStartIndex = name.LastIndexOf('.', relativeIndex) + 1;
            span = new SnapshotSpan(line.Start.Add(match.Index + matchStartIndex), lastIndex - matchStartIndex);

            return name;
        }
        private void HandlePreprocessor(IQuickInfoSession session, SnapshotPoint point, Selector item, IList<object> qiContent)
        {
            if (item == null || !session.TextView.Properties.ContainsProperty("CssSourceMap"))
                return;

            CssSourceMap sourceMap;

            if (!session.TextView.Properties.TryGetProperty<CssSourceMap>("CssSourceMap", out sourceMap))
                return;

            var line = point.GetContainingLine().LineNumber;
            var column = item.Start - point.Snapshot.GetLineFromPosition(item.Start).Start;

            var node = sourceMap.MapNodes.FirstOrDefault(s =>
                           s.SourceFilePath == _buffer.GetFileName() &&
                           s.OriginalLine == line &&
                           s.OriginalColumn == column);

            if (node == null)
                return;

            qiContent.Add(GenerateContent(node.GeneratedSelector));
        }
        static internal bool IsKeywordPrefix(SnapshotPoint triggerPoint, GherkinLanguageService languageService)
        {
            var line = triggerPoint.GetContainingLine();
            SnapshotPoint start = line.Start;
            ForwardWhile(ref start, triggerPoint, p => char.IsWhiteSpace(p.GetChar()));
            SnapshotPoint end = start;
            ForwardWhile(ref end, triggerPoint, p => !char.IsWhiteSpace(p.GetChar()));
            if (start >= end)
                return true; // returns true for empty word
            if (end < triggerPoint)
                return false;

            var firstWord = triggerPoint.Snapshot.GetText(start, end.Position - start);
            GherkinDialect dialect = GetDialect(languageService);
            return dialect.GetKeywords().Any(k => k.StartsWith(firstWord, StringComparison.CurrentCultureIgnoreCase));
        }
        static private string GetFirstWord(SnapshotPoint triggerPoint)
        {
            var line = triggerPoint.GetContainingLine();
            SnapshotPoint start = line.Start;
            ForwardWhile(ref start, triggerPoint, p => char.IsWhiteSpace(p.GetChar()));
            SnapshotPoint end = start;
            ForwardWhile(ref end, triggerPoint, p => !char.IsWhiteSpace(p.GetChar()));
            if (start >= end)
                return null;

            return triggerPoint.Snapshot.GetText(start, end.Position - start);
        }
 static internal bool IsKeywordCompletion(SnapshotPoint triggerPoint)
 {
     var line = triggerPoint.GetContainingLine();
     SnapshotPoint start = line.Start;
     ForwardWhile(ref start, triggerPoint, p => char.IsWhiteSpace(p.GetChar()));
     ForwardWhile(ref start, triggerPoint, p => !char.IsWhiteSpace(p.GetChar()));
     return start == triggerPoint;
 }
        // TODO: Can we refactor FindMatchingCloseChar and FindMatchingOpenChar into a single method?

        static bool FindMatchingCloseChar(BlockSpan scriptBlock, IClassifier classifier, SnapshotPoint startPoint, char open, char close, int maxLines, ref bool maxLinesReached, out SnapshotSpan pairSpan)
        {
            var isHTML = startPoint.Snapshot.ContentType.TypeName.Equals("HTML", StringComparison.OrdinalIgnoreCase);
            pairSpan = new SnapshotSpan(startPoint.Snapshot, 1, 1);
            var line = startPoint.GetContainingLine();
            var lineText = line.GetText();
            var lineNumber = line.LineNumber;
            var offset = startPoint.Position - line.Start.Position + 1;
            var endOfScriptBlockReached = false;

            var stopLineNumber = startPoint.Snapshot.LineCount - 1;
            if (maxLines > 0)
                stopLineNumber = Math.Min(stopLineNumber, lineNumber + maxLines);
#if DEBUG
            var startTicks = DateTime.Now.Ticks;
            Util.Log("Looking for matching closing brace '{0}'", close);
#endif
            var openCount = 0;

            while (true)
            {
                // walk the entire line
                while (offset < line.Length)
                {
                    // Check if we've hit the end of the script block
                    if (scriptBlock.End < line.Start + offset)
                    {
                        // We've hit the end of a script block
                        endOfScriptBlockReached = true;
                        break;
                    }

                    char currentChar = lineText[offset];
                    var currentCharPoint = line.Start + offset;

                    if (currentChar == close) // found the close character
                    {
                        if (JScriptEditorUtil.IsClassifiedAs(classifier, currentCharPoint,
                                JScriptClassifications.Comment,
                                JScriptClassifications.String,
                                JScriptClassifications.Operator))
                        {
#if DEBUG
                            Util.Log("Candidate closing brace found but ignored because it was a comment, string or operator");
#endif
                        }
                        else if (openCount > 0)
                        {
                            openCount--;
                        }
                        else // found the matching close
                        {
#if DEBUG
                            Util.Log("Matching closing brace '{0}' found after {1}ms", close, TimeSpan.FromTicks(DateTime.Now.Ticks - startTicks).TotalMilliseconds);
#endif
                            pairSpan = new SnapshotSpan(startPoint.Snapshot, currentCharPoint, 1);
                            return true;
                        }
                    }
                    else if (currentChar == open) // this is another open
                    {
                        if (JScriptEditorUtil.IsClassifiedAs(classifier, currentCharPoint,
                                JScriptClassifications.Comment,
                                JScriptClassifications.String,
                                JScriptClassifications.Operator))
                        {
#if DEBUG
                            Util.Log("New opening brace found but ignored because it was a comment, string or operator");
#endif
                        }
                        else
                        {
                            openCount++;
                        }
                    }
                    offset++;
                }

                if (endOfScriptBlockReached)
                    break;

                // move on to the next line
                if (++lineNumber > stopLineNumber)
                {
#if DEBUG
                    Util.Log("Reached max lines ({0}), stopped looking at line {1} after {2}ms", maxLines, stopLineNumber, TimeSpan.FromTicks(DateTime.Now.Ticks - startTicks).TotalMilliseconds);
#endif
                    // Set maxLinesReached flag only if we actually hit max lines limit, not just end of buffer
                    maxLinesReached = stopLineNumber >= maxLines;
                    break;
                }

                // Move to next line
                line = line.Snapshot.GetLineFromLineNumber(lineNumber);
                lineText = line.GetText();
                offset = 0;
            }
#if DEBUG
            Util.Log("Matching closing brace '{0}' was not found. Open count: {1} after {2}ms", close, openCount, TimeSpan.FromTicks(DateTime.Now.Ticks - startTicks).TotalMilliseconds);
#endif
            return false;
        }
 private static void AssertLineColumn(SnapshotPoint point, int lineNumber, int column)
 {
     var line = point.GetContainingLine();
     Assert.AreEqual(lineNumber, line.LineNumber, "Invalid line number");
     Assert.AreEqual(column, point.Position - line.Start.Position, "Invalid column");
 }
Example #50
0
        internal static Tuple<IToken, IToken> GetTokensAtPosition(SnapshotPoint snapshotPoint)
        {
            var line = snapshotPoint.GetContainingLine();
            var tokens = Utils.LexString(line.GetText()).ToList();

            if (tokens.Count == 0)
                return Tuple.Create<IToken, IToken>(null, null);

            int col = snapshotPoint.Position - line.Start.Position;

            IToken leftToken;
            IToken currentToken = tokens.FirstOrDefault(t => col > t.StartIndex && col <= t.StopIndex);

            if (currentToken != null)
            {
                if (currentToken == tokens.First())
                    leftToken = null;
                else
                    leftToken = tokens[tokens.IndexOf(currentToken) - 1];
            }
            else
            {
                leftToken = tokens.Last();
            }

            return Tuple.Create(leftToken, currentToken);
        }
        private bool IsAllowed(SnapshotPoint triggerPoint, out ClassificationSpan classificationType)
        {
            var line = triggerPoint.GetContainingLine().Extent;
            var spans = _classifier.GetClassificationSpans(line).Where(c => c.Span.Contains(triggerPoint.Position - 1));
            classificationType = spans.LastOrDefault();

            if (spans.Any(c => c.ClassificationType.IsOfType(PredefinedClassificationTypeNames.SymbolDefinition)))
                return true;

            bool isComment = spans.Any(c => c.ClassificationType.IsOfType(PredefinedClassificationTypeNames.Comment));
            if (isComment) return false;

            bool isString = spans.Any(c => c.ClassificationType.IsOfType(PredefinedClassificationTypeNames.String));
            if (isString) return false;

            return true;
        }
        /// <summary>
        /// Checks if we are at a require statement where we can offer completions.
        /// 
        /// The bool flags are used to control when we are checking if we should provide
        /// the completions before updating the buffer the characters the user just typed.
        /// </summary>
        /// <param name="triggerPoint">The point where the completion session is being triggered</param>
        /// <param name="classifier">A classifier for getting the tokens</param>
        /// <param name="eatOpenParen">True if the open paren has been inserted and we should expect it</param>
        /// <param name="allowQuote">True if we will parse the require(' or require(" forms.</param>
        /// <returns></returns>
        internal static bool ShouldTriggerRequireIntellisense(SnapshotPoint triggerPoint, IClassifier classifier, bool eatOpenParen, bool allowQuote = false) {
            var classifications = EnumerateClassificationsInReverse(classifier, triggerPoint);
            bool atRequire = false;

            if (allowQuote && classifications.MoveNext()) {
                var curText = classifications.Current.Span.GetText();
                if (!curText.StartsWith("'") && !curText.StartsWith("\"")) {
                    // no leading quote, reset back to original classifications.
                    classifications = EnumerateClassificationsInReverse(classifier, triggerPoint);
                }
            }

            if ((!eatOpenParen || EatToken(classifications, "(")) && EatToken(classifications, "require")) {
                // start of a file or previous token to require is followed by an expression
                if (!classifications.MoveNext()) {
                    // require at beginning of the file
                    atRequire = true;
                } else {
                    var tokenText = classifications.Current.Span.GetText();

                    atRequire =
                        classifications.Current.Span.Start.GetContainingLine().LineNumber != triggerPoint.GetContainingLine().LineNumber ||
                        tokenText.EndsWith(";") || // f(x); has ); displayed as a single token
                        _allowRequireTokens.Contains(tokenText) || // require after a token which starts an expression
                        (tokenText.All(IsIdentifierChar) && !_keywords.Contains(tokenText));    // require after anything else that isn't a statement like keyword 
                    //      (including identifiers which are on the previous line)
                }
            }

            return atRequire;
        }
Example #53
0
 public void ParseMark3()
 {
     Create("foo", "bar");
     var point1 = new SnapshotPoint(_buffer.CurrentSnapshot, 2);
     var point2 = _buffer.CurrentSnapshot.GetLineFromLineNumber(1).EndIncludingLineBreak;
     var map = new MarkMap(new TrackingLineColumnService());
     map.SetLocalMark(point1, 'c');
     var range = Parse("'c,2", map);
     Assert.IsTrue(range.IsSucceeded);
     Assert.AreEqual(new SnapshotSpan(point1.GetContainingLine().Start, point2), RangeUtil.GetSnapshotSpan(range.AsSucceeded().Item1));
 }
Example #54
0
        private async Task AddMissingImports(List<string> importList, SnapshotPoint point) {
            if (importList.Count > 0) {
                var projEntry = _textView.GetAnalysisEntry(_textView.TextBuffer, _serviceProvider);
                if (projEntry != null) {
                    foreach (var import in importList) {
                        var isMissing = await projEntry.Analyzer.IsMissingImportAsync(
                            projEntry,
                            import,
                            new SourceLocation(
                                point.Position,
                                point.Position - point.GetContainingLine().Start + 1,
                                point.GetContainingLine().LineNumber
                            )
                        );

                        if (isMissing) {
                            await VsProjectAnalyzer.AddImportAsync(
                                projEntry,
                                null,
                                import,
                                _textView,
                                _textView.TextBuffer
                            );
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Enumerates all of the classifications in reverse starting at start to the beginning of the file.
        /// </summary>
        private static IEnumerator<ClassificationSpan> EnumerateClassificationsInReverse(IClassifier classifier, SnapshotPoint start) {
            var curLine = start.GetContainingLine();
            var spanEnd = start;

            for (;;) {
                var classifications = classifier.GetClassificationSpans(new SnapshotSpan(curLine.Start, spanEnd));
                for (int i = classifications.Count - 1; i >= 0; i--) {
                    yield return classifications[i];
                }

                if (curLine.LineNumber == 0) {
                    break;
                }

                curLine = start.Snapshot.GetLineFromLineNumber(curLine.LineNumber - 1);
                spanEnd = curLine.End;
            }
        }
        private ITrackingSpan GetApplicableToForStep(ITextSnapshot snapshot, SnapshotPoint triggerPoint)
        {
            var line = triggerPoint.GetContainingLine();

            SnapshotPoint start = line.Start;
            ForwardWhile(ref start, triggerPoint, p => char.IsWhiteSpace(p.GetChar()));
            ForwardWhile(ref start, triggerPoint, p => !char.IsWhiteSpace(p.GetChar()));
            if (start < triggerPoint)
                ForwardWhile(ref start, start + 1, p => char.IsWhiteSpace(p.GetChar()));

            return snapshot.CreateTrackingSpan(new SnapshotSpan(start, line.End), SpanTrackingMode.EdgeInclusive);
        }
Example #57
0
        internal static SourceLocation TranslateIndex(int index, ITextSnapshot fromSnapshot, ModuleAnalysis toAnalysisSnapshot) {
            SnapshotCookie snapshotCookie;
            // TODO: buffers differ in the REPL window case, in the future we should handle this better
            if (toAnalysisSnapshot != null &&
                fromSnapshot != null &&
                (snapshotCookie = toAnalysisSnapshot.AnalysisCookie as SnapshotCookie) != null &&
                snapshotCookie.Snapshot != null &&
                snapshotCookie.Snapshot.TextBuffer == fromSnapshot.TextBuffer) {

                var fromPoint = new SnapshotPoint(fromSnapshot, index);
                var fromLine = fromPoint.GetContainingLine();
                var toPoint = fromPoint.TranslateTo(snapshotCookie.Snapshot, PointTrackingMode.Negative);
                var toLine = toPoint.GetContainingLine();

                Debug.Assert(fromLine != null, "Unable to get 'from' line from " + fromPoint.ToString());
                Debug.Assert(toLine != null, "Unable to get 'to' line from " + toPoint.ToString());

                return new SourceLocation(
                    toPoint.Position,
                    (toLine != null ? toLine.LineNumber : fromLine != null ? fromLine.LineNumber : 0) + 1,
                    index - (fromLine != null ? fromLine.Start.Position : 0) + 1
                );
            } else if (fromSnapshot != null) {
                var fromPoint = new SnapshotPoint(fromSnapshot, index);
                var fromLine = fromPoint.GetContainingLine();

                return new SourceLocation(
                    index,
                    fromLine.LineNumber + 1,
                    index - fromLine.Start.Position + 1
                );
            } else {
                return new SourceLocation(index, 1, 1);
            }
        }
        static bool FindMatchingOpenChar(BlockSpan scriptBlock, IClassifier classifier, SnapshotPoint startPoint, char open, char close, int maxLines, ref bool maxLinesReached, out SnapshotSpan pairSpan)
        {
            var isHTML = startPoint.Snapshot.ContentType.TypeName.Equals("HTML", StringComparison.OrdinalIgnoreCase);
            pairSpan = new SnapshotSpan(startPoint, startPoint);
            ITextSnapshotLine line = startPoint.GetContainingLine();
            var lineNumber = line.LineNumber;
            var offset = startPoint - line.Start - 1; // move the offset to the character before this one
            var startOfScriptBlockReached = false;

            // if the offset is negative, move to the previous line
            if (offset < 0)
            {
                line = line.Snapshot.GetLineFromLineNumber(--lineNumber);
                offset = line.Length - 1;
            }

            var lineText = line.GetText();

            var stopLineNumber = 0;
            var nominalStopLineNumber = lineNumber - maxLines;
            if (maxLines > 0)
                stopLineNumber = Math.Max(stopLineNumber, nominalStopLineNumber);
#if DEBUG
            var startTicks = DateTime.Now.Ticks;
            Util.Log("Looking for matching opening brace '{0}'", open);
#endif
            var closeCount = 0;

            Debug.Assert(scriptBlock != null);

            while (true)
            {
                // Walk the entire line
                while (offset >= 0)
                {
                    // Check if we've hit the start of the script block
                    if (scriptBlock.Start > line.Start + offset)
                    {
                        // We've hit the end of a script block
                        startOfScriptBlockReached = true;
                        break;
                    }

                    char currentChar = lineText[offset];
                    var currentCharPoint = line.Start + offset;

                    if (currentChar == open) // found the open character
                    {
                        if (JScriptEditorUtil.IsClassifiedAs(classifier, currentCharPoint,
                                JScriptClassifications.Comment,
                                JScriptClassifications.String,
                                JScriptClassifications.Operator))
                        {
#if DEBUG
                            Util.Log("Candidate opening brace found but ignored because it was a comment, string or operator");
#endif
                        }
                        else if (closeCount > 0)
                        {
                            closeCount--;
                        }
                        else // We've found the matching open character
                        {
#if DEBUG
                            Util.Log("Matching opening brace '{0}' found in {1}ms", open, TimeSpan.FromTicks(DateTime.Now.Ticks - startTicks).TotalMilliseconds);
#endif
                            pairSpan = new SnapshotSpan(currentCharPoint, 1); // we just want the character itself
                            return true;
                        }
                    }
                    else if (currentChar == close)
                    {
                        if (JScriptEditorUtil.IsClassifiedAs(classifier, currentCharPoint,
                                JScriptClassifications.Comment,
                                JScriptClassifications.String,
                                JScriptClassifications.Operator))
                        {
#if DEBUG
                            Util.Log("New closing brace found but ignored because it was a comment, string or operator");
#endif
                        }
                        else
                        {
                            closeCount++;
                        }
                    }
                    offset--;
                }

                if (startOfScriptBlockReached)
                    break;

                // Move to the previous line
                if (--lineNumber < stopLineNumber)
                {
                    // Set maxLinesReached flag only if we actually hit max lines limit, not just start of buffer
                    maxLinesReached = stopLineNumber == nominalStopLineNumber;
#if DEBUG
                    Util.Log("Reached max lines ({0}, stopped looking at line {1} after {2}ms", maxLines, stopLineNumber, TimeSpan.FromTicks(DateTime.Now.Ticks - startTicks).TotalMilliseconds);
#endif
                    break;
                }

                line = line.Snapshot.GetLineFromLineNumber(lineNumber);
                lineText = line.GetText();
                offset = line.Length - 1;
            }
#if DEBUG
            Util.Log("Matching opening brace '{0}' was not found. Open count: {1} after {2}ms", open, closeCount, TimeSpan.FromTicks(DateTime.Now.Ticks - startTicks).TotalMilliseconds);
#endif
            return false;
        }
        protected override string GetExteriorTextForNextLine(SnapshotPoint caretPosition)
        {
            var currentLine = caretPosition.GetContainingLine();

            var firstNonWhitespacePosition = currentLine.GetFirstNonWhitespacePosition() ?? -1;
            if (firstNonWhitespacePosition == -1)
            {
                return null;
            }

            var currentLineStartsWithBlockCommentStartString = currentLine.StartsWith(firstNonWhitespacePosition, "/*", ignoreCase: false);
            var currentLineStartsWithBlockCommentEndString = currentLine.StartsWith(firstNonWhitespacePosition, "*/", ignoreCase: false);
            var currentLineStartsWithBlockCommentMiddleString = currentLine.StartsWith(firstNonWhitespacePosition, "*", ignoreCase: false);

            if (!currentLineStartsWithBlockCommentStartString && !currentLineStartsWithBlockCommentMiddleString)
            {
                return null;
            }

            if (!IsCaretInsideBlockCommentSyntax(caretPosition))
            {
                return null;
            }

            if (currentLineStartsWithBlockCommentStartString)
            {
                if (BlockCommentEndsRightAfterCaret(caretPosition))
                {
                    //      /*|*/
                    return " ";
                }
                else if (caretPosition == firstNonWhitespacePosition + 1)
                {
                    //      /|*
                    return null; // The newline inserted could break the syntax in a way that this handler cannot fix, let's leave it.
                }
                else
                {
                    //      /*|
                    return " *" + GetPaddingOrIndentation(currentLine, caretPosition, firstNonWhitespacePosition, "/*");
                }
            }

            if (currentLineStartsWithBlockCommentEndString)
            {
                if (BlockCommentEndsRightAfterCaret(caretPosition))
                {
                    //      /*
                    //      |*/
                    return " ";
                }
                else if (caretPosition == firstNonWhitespacePosition + 1)
                {
                    //      *|/
                    return "*";
                }
                else
                {
                    //      /*
                    //   |   */
                    return " * ";
                }
            }

            if (currentLineStartsWithBlockCommentMiddleString)
            {
                if (BlockCommentEndsRightAfterCaret(caretPosition))
                {
                    //      *|*/
                    return "";
                }
                else if (caretPosition > firstNonWhitespacePosition)
                {
                    //      *|
                    return "*" + GetPaddingOrIndentation(currentLine, caretPosition, firstNonWhitespacePosition, "*");
                }
                else
                {
                    //      /*
                    //   |   *
                    return " * ";
                }
            }

            return null;
        }
Example #60
0
        /// <summary>
        /// Enumerates all of the classifications in reverse starting at start to the beginning of the file.
        /// </summary>
        private static IEnumerator<ITagSpan<ClassificationTag>> EnumerateClassificationsInReverse(ITagger<ClassificationTag> classifier, SnapshotPoint start) {
            if (classifier == null) {
                yield break;
            }

            var curLine = start.GetContainingLine();
            var spanEnd = start;

            for (; ; ) {
                var classifications = classifier.GetTags(
                    new NormalizedSnapshotSpanCollection(new SnapshotSpan(curLine.Start, spanEnd))
                );
                foreach (var classification in classifications.Reverse()) {
                    yield return classification;
                }

                yield return null;

                if (curLine.LineNumber == 0) {
                    break;
                }

                curLine = start.Snapshot.GetLineFromLineNumber(curLine.LineNumber - 1);
                spanEnd = curLine.End;
            }
        }