public override IReadOnlyList <TextChangeRange> GetChangeRanges(SourceText oldText) { if (oldText == null) { throw new ArgumentNullException("oldText"); } // if they are the same text there is no change. if (oldText == this) { return(TextChangeRange.NoChanges); } // first, check whether the text buffer is still alive. var container = this.Container as TextBufferContainer; if (container != null) { var lastEventArgs = container.LastEventArgs; if (lastEventArgs != null && lastEventArgs.OldText == oldText && lastEventArgs.NewText == this) { return(lastEventArgs.Changes); } } var oldSnapshot = oldText.FindCorrespondingEditorTextSnapshot(); var newSnapshot = this.FindCorrespondingEditorTextSnapshot(); return(GetChangeRanges(oldSnapshot, oldText.Length, newSnapshot)); }
private ImmutableArray<CompletionItem> GetItems(SourceText text, Document document, int position, CompletionTrigger triggerInfo, CancellationToken cancellationToken) { var line = text.Lines.GetLineFromPosition(position); var lineText = text.ToString(TextSpan.FromBounds(line.Start, position)); var match = s_directiveRegex.Match(lineText); if (!match.Success) { return ImmutableArray<CompletionItem>.Empty; } var quotedPathGroup = match.Groups[1]; var quotedPath = quotedPathGroup.Value; var endsWithQuote = PathCompletionUtilities.EndsWithQuote(quotedPath); if (endsWithQuote && (position >= line.Start + match.Length)) { return ImmutableArray<CompletionItem>.Empty; } var buffer = text.Container.GetTextBuffer(); var snapshot = text.FindCorrespondingEditorTextSnapshot(); if (snapshot == null) { return ImmutableArray<CompletionItem>.Empty; } var fileSystem = CurrentWorkingDirectoryDiscoveryService.GetService(snapshot); // TODO: https://github.com/dotnet/roslyn/issues/5263 // Avoid dependency on a specific resolver. // The search paths should be provided by specialized workspaces: // - InteractiveWorkspace for interactive window // - ScriptWorkspace for loose .csx files (we don't have such workspace today) var searchPaths = (document.Project.CompilationOptions.SourceReferenceResolver as SourceFileResolver)?.SearchPaths ?? ImmutableArray<string>.Empty; var helper = new FileSystemCompletionHelper( this, GetTextChangeSpan(text, position, quotedPathGroup), fileSystem, Glyph.OpenFolder, Glyph.CSharpFile, searchPaths: searchPaths, allowableExtensions: new[] { ".csx" }, itemRules: s_rules); var pathThroughLastSlash = this.GetPathThroughLastSlash(text, position, quotedPathGroup); return helper.GetItems(pathThroughLastSlash, documentPath: null); }
private ImmutableArray<CompletionItem> GetItems(SourceText text, int position, CompletionTriggerInfo triggerInfo, CancellationToken cancellationToken) { var line = text.Lines.GetLineFromPosition(position); var lineText = text.ToString(TextSpan.FromBounds(line.Start, position)); var match = s_directiveRegex.Match(lineText); if (!match.Success) { return ImmutableArray<CompletionItem>.Empty; } var quotedPathGroup = match.Groups[1]; var quotedPath = quotedPathGroup.Value; var endsWithQuote = PathCompletionUtilities.EndsWithQuote(quotedPath); if (endsWithQuote && (position >= line.Start + match.Length)) { return ImmutableArray<CompletionItem>.Empty; } var buffer = text.Container.GetTextBuffer(); var snapshot = text.FindCorrespondingEditorTextSnapshot(); if (snapshot == null) { return ImmutableArray<CompletionItem>.Empty; } var fileSystem = PathCompletionUtilities.GetCurrentWorkingDirectoryDiscoveryService(snapshot); var searchPaths = ImmutableArray.Create<string>(fileSystem.CurrentDirectory); var helper = new FileSystemCompletionHelper( this, GetTextChangeSpan(text, position, quotedPathGroup), fileSystem, Glyph.OpenFolder, Glyph.CSharpFile, searchPaths: searchPaths, allowableExtensions: new[] { ".csx" }, itemRules: ItemRules.Instance); var pathThroughLastSlash = this.GetPathThroughLastSlash(text, position, quotedPathGroup); return helper.GetItems(pathThroughLastSlash, documentPath: null); }
public void UpdateActiveStatementSpans(SourceText source, IEnumerable<KeyValuePair<ActiveStatementId, TextSpan>> spans) { bool leafUpdated = false; bool updated = false; ITrackingSpan[] documentSpans; lock (_trackingSpans) { foreach (var span in spans) { ActiveStatementId id = span.Key; if (_trackingSpans.TryGetValue(id.DocumentId, out documentSpans) && documentSpans != null) { var snapshot = source.FindCorrespondingEditorTextSnapshot(); // Avoid updating spans if the buffer has changed. // Buffer change is handled by DocumentOpened event. if (snapshot != null && snapshot.TextBuffer == documentSpans[id.Ordinal].TextBuffer) { documentSpans[id.Ordinal] = snapshot.CreateTrackingSpan(span.Value.ToSpan(), SpanTrackingMode.EdgeExclusive); if (!leafUpdated) { var baseStatements = _editSession.BaseActiveStatements[id.DocumentId]; leafUpdated = (baseStatements[id.Ordinal].Flags & ActiveStatementFlags.LeafFrame) != 0; } updated = true; } } } } if (updated) { _service.OnTrackingSpansChanged(leafUpdated); } }
public IEnumerable<ActiveStatementTextSpan> GetSpans(SourceText source) { var document = source.GetOpenDocumentInCurrentContextWithChanges(); if (document == null) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } // We might be asked for spans in a different workspace than // the one we maintain tracking spans for (for example, a preview). if (document.Project.Solution.Workspace != _editSession.BaseSolution.Workspace) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } ITrackingSpan[] documentTrackingSpans; lock (_trackingSpans) { if (!_trackingSpans.TryGetValue(document.Id, out documentTrackingSpans) || documentTrackingSpans == null) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } } Debug.Assert(documentTrackingSpans.Length > 0); var snapshot = source.FindCorrespondingEditorTextSnapshot(); // The document might have been reopened with a new text buffer // and we haven't created tracking spans for the new text buffer yet. if (snapshot == null || snapshot.TextBuffer != documentTrackingSpans[0].TextBuffer) { return SpecializedCollections.EmptyEnumerable<ActiveStatementTextSpan>(); } var baseStatements = _editSession.BaseActiveStatements[document.Id]; Debug.Assert(documentTrackingSpans.Length == baseStatements.Length); var result = new ActiveStatementTextSpan[documentTrackingSpans.Length]; for (int i = 0; i < documentTrackingSpans.Length; i++) { Debug.Assert(documentTrackingSpans[i].TextBuffer == snapshot.TextBuffer); result[i] = new ActiveStatementTextSpan( baseStatements[i].Flags, documentTrackingSpans[i].GetSpan(snapshot).Span.ToTextSpan()); } return result; }
public bool TryGetSpan(ActiveStatementId id, SourceText source, out TextSpan span) { ITrackingSpan[] documentSpans; lock (_trackingSpans) { if (_trackingSpans.TryGetValue(id.DocumentId, out documentSpans) && documentSpans != null) { var trackingSpan = documentSpans[id.Ordinal]; var snapshot = source.FindCorrespondingEditorTextSnapshot(); if (snapshot != null && snapshot.TextBuffer == trackingSpan.TextBuffer) { span = trackingSpan.GetSpan(snapshot).Span.ToTextSpan(); return true; } } } span = default(TextSpan); return false; }
public override IReadOnlyList<TextChangeRange> GetChangeRanges(SourceText oldText) { if (oldText == null) { throw new ArgumentNullException(nameof(oldText)); } // if they are the same text there is no change. if (oldText == this) { return TextChangeRange.NoChanges; } // first, check whether the text buffer is still alive. var container = this.Container as TextBufferContainer; if (container != null) { var lastEventArgs = container.LastEventArgs; if (lastEventArgs != null && lastEventArgs.OldText == oldText && lastEventArgs.NewText == this) { return lastEventArgs.Changes; } } var oldSnapshot = oldText.FindCorrespondingEditorTextSnapshot(); var newSnapshot = this.FindCorrespondingEditorTextSnapshot(); return GetChangeRanges(oldSnapshot, oldText.Length, newSnapshot); }