Ejemplo n.º 1
0
        private static IEnumerable <string> MakeQuickInfos(
            IEnumerable <IRFunctionQuickInfo> infos,
            IEditorBufferSnapshot snapshot,
            int position,
            out ITrackingSpan applicableSpan)
        {
            applicableSpan = null;
            var list = new List <string>();
            int s = 0, e = 0, length = int.MaxValue;

            foreach (var info in infos)
            {
                var start = info.ApplicableToRange.GetStartPoint(snapshot);
                var end   = info.ApplicableToRange.GetEndPoint(snapshot);
                if (start <= position && position < end)
                {
                    var content = info.Content.FirstOrDefault();
                    if (!string.IsNullOrEmpty(content))
                    {
                        list.Add(content);

                        s = Math.Max(s, start);
                        e = Math.Min(e, end);
                        var l = e - s;
                        if (l < length)
                        {
                            applicableSpan = info.ApplicableToRange.As <ITrackingSpan>();
                            length         = l;
                        }
                    }
                }
            }
            return(list);
        }
Ejemplo n.º 2
0
 public SearchParams(Uri uri, IEditorBufferSnapshot snapshot, AstRoot ast)
 {
     Symbols  = new List <SymbolInformation>();
     Uri      = uri;
     Snapshot = snapshot;
     Ast      = ast;
 }
Ejemplo n.º 3
0
        public static ITextRange ToTextRange(this Range range, IEditorBufferSnapshot snapshot)
        {
            var start = range.Start.ToStreamPosition(snapshot);
            var end   = range.End.ToStreamPosition(snapshot);

            return(TextRange.FromBounds(start, end));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Given position in the buffer finds index of the function parameter.
        /// </summary>
        public static int ComputeCurrentParameter(this ISignatureInfo signatureInfo, IEditorBufferSnapshot snapshot, AstRoot ast, int position, IREditorSettings settings)
        {
            var parameterInfo = ast.GetSignatureInfoFromBuffer(snapshot, position);
            var index         = 0;

            if (parameterInfo != null)
            {
                index = parameterInfo.ParameterIndex;
                if (parameterInfo.NamedParameter)
                {
                    // A function f <- function(foo, bar) is said to have formal parameters "foo" and "bar",
                    // and the call f(foo=3, ba=13) is said to have (actual) arguments "foo" and "ba".
                    // R first matches all arguments that have exactly the same name as a formal parameter.
                    // Two identical argument names cause an error. Then, R matches any argument names that
                    // partially matches a(yet unmatched) formal parameter. But if two argument names partially
                    // match the same formal parameter, that also causes an error. Also, it only matches
                    // formal parameters before ... So formal parameters after ... must be specified using
                    // their full names. Then the unnamed arguments are matched in positional order to
                    // the remaining formal arguments.

                    var argumentIndexInSignature = signatureInfo.GetArgumentIndex(parameterInfo.ParameterName, settings.PartialArgumentNameMatch);
                    if (argumentIndexInSignature >= 0)
                    {
                        index = argumentIndexInSignature;
                    }
                }
            }
            return(index);
        }
Ejemplo n.º 5
0
 public EditorLine(IEditorBufferSnapshot snapshot, int start, int length, int lineBreakLength, int lineNumber) :
     base(start, length)
 {
     LineBreakLength = lineBreakLength;
     Snapshot        = snapshot;
     LineNumber      = lineNumber;
 }
Ejemplo n.º 6
0
        public static Position ToLinePosition(this IEditorBufferSnapshot snapshot, int position)
        {
            var line = snapshot.GetLineFromPosition(position);

            return(new Position {
                Line = line.LineNumber, Character = position - line.Start
            });
        }
Ejemplo n.º 7
0
        public Task <TextEdit[]> FormatRangeAsync(IEditorBufferSnapshot snapshot, Range range)
        {
            var editorBuffer   = snapshot.EditorBuffer;
            var editorView     = new EditorView(editorBuffer, range.ToTextRange(snapshot).Start);
            var rangeFormatter = new RangeFormatter(_services, editorView, editorBuffer, new IncrementalTextChangeHandler());

            return(DoFormatActionAsync(snapshot, () => rangeFormatter.FormatRange(range.ToTextRange(snapshot))));
        }
Ejemplo n.º 8
0
        public ISnapshotPoint MapToView(IEditorBufferSnapshot snapshot, int position)
        {
            var target = _textView.BufferGraph
                         .MapUpToBuffer(
                new SnapshotPoint(snapshot.As <ITextSnapshot>(), position),
                PointTrackingMode.Positive, PositionAffinity.Successor, _textView.TextBuffer);

            return(target.HasValue ? new EditorSnapshotPoint(_textView.TextBuffer.CurrentSnapshot, target.Value) : null);
        }
Ejemplo n.º 9
0
        public Task <TextEdit[]> FormatAsync(IEditorBufferSnapshot snapshot)
        {
            var settings = _services.GetService <IREditorSettings>();

            return(DoFormatActionAsync(snapshot, () => {
                var formattedText = new RFormatter(settings.FormatOptions).Format(snapshot.GetText());
                snapshot.EditorBuffer.Replace(TextRange.FromBounds(0, snapshot.Length), formattedText);
            }));
        }
Ejemplo n.º 10
0
 private static IEditorLine FindFirstNonEmptyLine(IEditorBufferSnapshot snapshot, int lineNumber)
 {
     for (int i = lineNumber; i < snapshot.LineCount; i++)
     {
         var line = snapshot.GetLineFromLineNumber(i);
         if (!string.IsNullOrWhiteSpace(line.GetText()))
         {
             return(line);
         }
     }
     return(null);
 }
Ejemplo n.º 11
0
 public static bool IsPositionInNamespace(this IEditorBufferSnapshot snapshot, int position)
 {
     if (position > 0)
     {
         var line = snapshot.GetLineFromPosition(position);
         if (line.Length > 2 && position - line.Start > 2)
         {
             return(snapshot[position - 1] == ':');
         }
     }
     return(false);
 }
Ejemplo n.º 12
0
        private void FireChanged(int start, int oldLength, int newLength)
        {
            var oldTextProvider = new TextStream(CurrentSnapshot.GetText());

            _version++;
            _currentSnapshot = new EditorBufferSnapshot(this, _content.ToString(), _version);

            var newTextProvider = new TextStream(_currentSnapshot.GetText());
            var change          = new TextChange(start, oldLength, newLength, oldTextProvider, newTextProvider);
            var args            = new TextChangeEventArgs(change);

            ChangedHighPriority?.Invoke(this, args);
            Changed?.Invoke(this, args);
        }
Ejemplo n.º 13
0
        private TextEdit[] DoFormatAction(IEditorBufferSnapshot snapshot, Action action)
        {
            if (snapshot == null)
            {
                return(new TextEdit[0]);
            }

            var before = snapshot;

            action();
            var after = snapshot.EditorBuffer.CurrentSnapshot;

            return(GetDifference(before, after));
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Processes text buffer changed accumulated so far.
        /// Typically called on idle.
        /// </summary>
        /// <param name="snapshot">New text buffer content</param>
        /// <param name="async">True if processing is to be done asynchronously.
        /// Non-async processing is typically used in unit tests only.</param>
        internal void ProcessPendingTextBufferChanges(IEditorBufferSnapshot snapshot, bool async)
        {
            Check.InvalidOperation(() => Thread.CurrentThread.ManagedThreadId == _ownerThreadId, _threadCheckMessage);

            if (ChangesPending)
            {
                if (async && (IsTaskRunning() || _backgroundParsingResults.Count > 0))
                {
                    // Try next time or we may end up spawning a lot of tasks
                    return;
                }

                Run(isCancelledCallback => ProcessTextChange(snapshot, async, isCancelledCallback), async);
            }
        }
Ejemplo n.º 15
0
        private async Task <TextEdit[]> DoFormatActionAsync(IEditorBufferSnapshot snapshot, Action action)
        {
            if (snapshot == null)
            {
                return(new TextEdit[0]);
            }
            await _services.MainThread().SwitchToAsync();

            var before = snapshot;

            action();
            var after = snapshot.EditorBuffer.CurrentSnapshot;

            return(GetDifference(before, after));
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Determines whitespace difference between two snapshots
        /// </summary>
        /// <param name="before">Snapshot before the change</param>
        /// <param name="after">Snapshot after the change</param>
        /// <returns></returns>
        private static TextEdit[] GetDifference(IEditorBufferSnapshot before, IEditorBufferSnapshot after)
        {
            var tokenizer = new RTokenizer();
            var oldTokens = tokenizer.Tokenize(before.GetText());
            var newTokens = tokenizer.Tokenize(after.GetText());

            if (newTokens.Count != oldTokens.Count)
            {
                return(new[] { new TextEdit {
                                   newText = after.GetText(),
                                   range = TextRange.FromBounds(0, before.Length).ToLineRange(before)
                               } });
            }

            var edits  = new List <TextEdit>();
            var oldEnd = before.Length;
            var newEnd = after.Length;

            for (var i = newTokens.Count - 1; i >= 0; i--)
            {
                var oldText = before.GetText(TextRange.FromBounds(oldTokens[i].End, oldEnd));
                var newText = after.GetText(TextRange.FromBounds(newTokens[i].End, newEnd));
                if (oldText != newText)
                {
                    var range = new TextRange(oldTokens[i].End, oldEnd - oldTokens[i].End);
                    edits.Add(new TextEdit {
                        range   = range.ToLineRange(before),
                        newText = newText
                    });
                }
                oldEnd = oldTokens[i].Start;
                newEnd = newTokens[i].Start;
            }

            var r = TextRange.FromBounds(0, oldEnd);
            var oldTextBeforeFitstToken = before.GetText(r);
            var newTextBeforeFirstToken = after.GetText(TextRange.FromBounds(0, newEnd));

            if (oldTextBeforeFitstToken != newTextBeforeFirstToken)
            {
                edits.Add(new TextEdit {
                    newText = newTextBeforeFirstToken,
                    range   = r.ToLineRange(before)
                });
            }

            return(edits.ToArray());
        }
Ejemplo n.º 17
0
        public Task <TextEdit[]> AutoformatAsync(IEditorBufferSnapshot snapshot, Position position, string typedChar)
        {
            var editorBuffer = snapshot.EditorBuffer;
            var editorView   = new EditorView(editorBuffer, position.ToStreamPosition(snapshot));
            var formatter    = new AutoFormat(_services, editorView, editorBuffer, new IncrementalTextChangeHandler());

            // AST build happens asynchronously, give it a chance to finish since
            // up -to-date AST improves outcome of the on-type formatting.
            var document = editorBuffer.GetEditorDocument <IREditorDocument>();

            if (!document.EditorTree.IsReady)
            {
                SpinWait.SpinUntil(() => document.EditorTree.IsReady, 50);
            }

            return(DoFormatActionAsync(snapshot, () => formatter.HandleTyping(typedChar[0], position.ToStreamPosition(snapshot))));
        }
Ejemplo n.º 18
0
        private static ITextRange GetRoxygenBlockPosition(IEditorBufferSnapshot snapshot, int definitionStart)
        {
            var line = snapshot.GetLineFromPosition(definitionStart);

            for (var i = line.LineNumber - 1; i >= 0; i--)
            {
                var currentLine = snapshot.GetLineFromLineNumber(i);
                var lineText    = currentLine.GetText().TrimStart();
                if (lineText.Length > 0)
                {
                    if (lineText.EqualsOrdinal("##"))
                    {
                        return(currentLine);
                    }
                    if (lineText.EqualsOrdinal("#'"))
                    {
                        return(null);
                    }
                    break;
                }
            }
            return(new TextRange(line.Start, 0));
        }
Ejemplo n.º 19
0
 public int GetStartPoint(IEditorBufferSnapshot snapshot) => _range.Start;
 public SearchParams(Uri uri, IEditorBufferSnapshot snapshot, AstRoot ast)
 {
     Uri      = uri;
     Snapshot = snapshot;
     Ast      = ast;
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Main asyncronous task body
        /// </summary>
        private void ProcessTextChange(IEditorBufferSnapshot snapshot, bool async, Func <bool> isCancelledCallback)
        {
            lock (_disposeLock) {
                if (_editorTree == null || _disposed || isCancelledCallback())
                {
                    return;
                }
                EditorTreeChangeCollection treeChanges;
                // Cache id since it can change if task is canceled
                var taskId = TaskId;

                try {
                    // We only need read lock since changes will be applied from the main thread
                    if (async)
                    {
                        _editorTree.AcquireReadLock(_treeUserId);
                    }
                    else
                    {
                        _editorTree.GetAstRootUnsafe();
                    }

                    treeChanges = new EditorTreeChangeCollection(snapshot.Version, true);
                    var newTree = RParser.Parse(snapshot, _editorTree.ExpressionTermFilter);
                    treeChanges.Append(new EditorTreeChange_NewTree(newTree));
                } finally {
                    if (async)
                    {
                        _editorTree?.ReleaseReadLock(_treeUserId);
                    }
                }

                // Lock should be released at this point since actual application
                // of tree changes is going to be happen from the main thread.

                if (!isCancelledCallback() && treeChanges.Changes.Any())
                {
                    // Queue results for the main thread application. This must be done before
                    // signaling that the task is complete since if EnsureProcessingComplete
                    // is waiting it will want to apply changes itself rather than wait for
                    // the DispatchOnUIThread to go though and hence it will need all changes
                    // stored and ready for application.
                    _backgroundParsingResults.Enqueue(treeChanges);
                }

                // Signal task complete now so if main thread is waiting
                // it can proceed and appy the changes immediately.
                SignalTaskComplete(taskId);

                if (_backgroundParsingResults.Count > 0)
                {
                    // It is OK to post results while main thread might be working
                    // on them since if if it does, by the time posted request comes
                    // queue will already be empty.
                    if (async)
                    {
                        // Post request to apply tree changes to the main thread.
                        // This must NOT block or else task will never enter 'RanToCompletion' state.
                        _services.MainThread().Post(ApplyBackgroundProcessingResults);
                    }
                    else
                    {
                        // When processing is synchronous, apply changes and fire events right away.
                        ApplyBackgroundProcessingResults();
                    }
                }
            }
        }
Ejemplo n.º 22
0
        public static int ToStreamPosition(this IEditorBufferSnapshot snapshot, int lineNumber, int charNumber)
        {
            var line = snapshot.GetLineFromLineNumber(lineNumber);

            return(line?.Start + charNumber ?? 0);
        }
Ejemplo n.º 23
0
 public static int ToStreamPosition(this Position position, IEditorBufferSnapshot snapshot)
 => snapshot.ToStreamPosition(position.Line, position.Character);
Ejemplo n.º 24
0
 public SnapshotPoint(IEditorBufferSnapshot snapshot, int position)
 {
     Snapshot = snapshot;
     Position = position;
 }
Ejemplo n.º 25
0
 public static Range ToLineRange(this ITextRange textRange, IEditorBufferSnapshot snapshot)
 => new Range
 {
     Start = snapshot.ToLinePosition(textRange.Start), End = snapshot.ToLinePosition(textRange.End)
 };
Ejemplo n.º 26
0
 public static Range ToLineRange(this IEditorBufferSnapshot snapshot, int start, int end)
 => new Range
 {
     Start = snapshot.ToLinePosition(start), End = snapshot.ToLinePosition(end)
 };
Ejemplo n.º 27
0
 public int GetStartPoint(IEditorBufferSnapshot snapshot) => _span.GetStartPoint(snapshot.As <ITextSnapshot>());
Ejemplo n.º 28
0
 public ViewCaretPosition(IEditorBufferSnapshot snapshot, int position)
     : base(snapshot, position)
 {
 }
Ejemplo n.º 29
0
 public int GetEndPoint(IEditorBufferSnapshot snapshot) => _range.End;
Ejemplo n.º 30
0
 public ISnapshotPoint MapToView(IEditorBufferSnapshot snapshot, int position)
 => new SnapshotPoint(EditorBuffer.CurrentSnapshot, position);