private void OnTextDocumentDisposed(object sender, TextDocumentEventArgs e)
        {
            FrugalList <PersistentSpan> spans;

            lock (_spansOnDocuments)
            {
                if (_spansOnDocuments.TryGetValue(e.TextDocument, out spans))
                {
                    foreach (var span in spans)
                    {
                        span.DocumentClosed();
                    }

                    _spansOnDocuments.Remove(e.TextDocument);

                    var path = new FileNameKey(e.TextDocument.FilePath);
                    FrugalList <PersistentSpan> existingSpansOnPath;
                    if (_spansOnDocuments.TryGetValue(path, out existingSpansOnPath))
                    {
                        //Handle (badly) the case where a document is renamed to an existing closed document & then closed.
                        existingSpansOnPath.AddRange(spans);
                    }
                    else
                    {
                        _spansOnDocuments.Add(path, spans);
                    }
                }
            }
        }
예제 #2
0
        internal PersistentSpanSet(FileNameKey filePath, ITextDocument document, PersistentSpanFactory factory)
        {
            this.FileKey  = filePath;
            this.Document = document;
            this.Factory  = factory;

            if (document != null)
            {
                document.FileActionOccurred += this.OnFileActionOccurred;
            }
        }
예제 #3
0
 private void OnFileActionOccurred(object sender, TextDocumentFileActionEventArgs e)
 {
     if (e.FileActionType == FileActionTypes.ContentSavedToDisk)
     {
         _savedSnapshot = this.Document.TextBuffer.CurrentSnapshot;
     }
     else if (e.FileActionType == FileActionTypes.DocumentRenamed)
     {
         this.FileKey = new FileNameKey(this.Document.FilePath);
         this.Factory.DocumentRenamed(this);
     }
 }
예제 #4
0
        public IPersistentSpan Create(string filePath, Span span, SpanTrackingMode trackingMode)
        {
            Requires.NotNullOrEmpty(filePath, nameof(filePath));
            Requires.Range(((int)trackingMode >= (int)SpanTrackingMode.EdgeExclusive) || ((int)trackingMode <= (int)(SpanTrackingMode.EdgeNegative)), nameof(trackingMode));

            var key = new FileNameKey(filePath);

            lock (_spansOnDocuments)
            {
                var spanSet = this.GetOrCreateSpanSet(key, null);
                return(spanSet.Create(span, trackingMode));
            }
        }
예제 #5
0
        internal void DocumentClosed()
        {
            Assumes.NotNull(this.Document);

            this.FileKey = new FileNameKey(this.Document.FilePath);

            foreach (var s in this.Spans)
            {
                s.DocumentClosed(_savedSnapshot);
            }

            this.Document.FileActionOccurred -= this.OnFileActionOccurred;
            this.Document = null;
        }
예제 #6
0
        private void OnTextDocumentCreated(object sender, TextDocumentEventArgs e)
        {
            var path = new FileNameKey(e.TextDocument.FilePath);

            lock (_spansOnDocuments)
            {
                if (_spansOnDocuments.TryGetValue(path, out PersistentSpanSet spanSet))
                {
                    spanSet.DocumentReopened(e.TextDocument);

                    _spansOnDocuments.Remove(path);
                    _spansOnDocuments.Add(e.TextDocument, spanSet);
                }
            }
        }
예제 #7
0
        public IPersistentSpan Create(string filePath, int startLine, int startIndex, int endLine, int endIndex, SpanTrackingMode trackingMode)
        {
            Requires.NotNullOrEmpty(filePath, nameof(filePath));
            Requires.Argument(startLine >= 0, nameof(startLine), "Must be non-negative.");
            Requires.Argument(startIndex >= 0, nameof(startIndex), "Must be non-negative.");
            Requires.Argument(endLine >= startLine, nameof(endLine), "Must be >= startLine.");
            Requires.Argument((endIndex >= 0) && ((startLine != endLine) || (endIndex >= startIndex)), nameof(endIndex), "Must be non-negative and (endLine,endIndex) may not be before (startLine,startIndex).");
            Requires.Range(((int)trackingMode >= (int)SpanTrackingMode.EdgeExclusive) || ((int)trackingMode <= (int)(SpanTrackingMode.EdgeNegative)), nameof(trackingMode));

            var key = new FileNameKey(filePath);

            lock (_spansOnDocuments)
            {
                var spanSet = this.GetOrCreateSpanSet(key, null);
                return(spanSet.Create(startLine, startIndex, endLine, endIndex, trackingMode));
            }
        }
        internal void Delete(PersistentSpan span)
        {
            lock (_spansOnDocuments)
            {
                ITextDocument document = span.Document;
                if (document != null)
                {
                    FrugalList <PersistentSpan> spans;
                    if (_spansOnDocuments.TryGetValue(document, out spans))
                    {
                        spans.Remove(span);

                        if (spans.Count == 0)
                        {
                            //Last one ... remove all references to document.
                            _spansOnDocuments.Remove(document);
                        }
                    }
                    else
                    {
                        Debug.Fail("There should have been an entry in SpanOnDocuments.");
                    }
                }
                else
                {
                    var path = new FileNameKey(span.FilePath);
                    FrugalList <PersistentSpan> spans;
                    if (_spansOnDocuments.TryGetValue(path, out spans))
                    {
                        spans.Remove(span);

                        if (spans.Count == 0)
                        {
                            //Last one ... remove all references to path.
                            _spansOnDocuments.Remove(path);
                        }
                    }
                    else
                    {
                        Debug.Fail("There should have been an entry in SpanOnDocuments.");
                    }
                }
            }
        }
        private void OnTextDocumentCreated(object sender, TextDocumentEventArgs e)
        {
            var path = new FileNameKey(e.TextDocument.FilePath);
            FrugalList <PersistentSpan> spans;

            lock (_spansOnDocuments)
            {
                if (_spansOnDocuments.TryGetValue(path, out spans))
                {
                    foreach (var span in spans)
                    {
                        span.DocumentReopened(e.TextDocument);
                    }

                    _spansOnDocuments.Remove(path);
                    _spansOnDocuments.Add(e.TextDocument, spans);
                }
            }
        }
예제 #10
0
        }                                                                      //For unit tests

        private PersistentSpanSet GetOrCreateSpanSet(FileNameKey filePath, ITextDocument document)
        {
            object key = ((object)document) ?? filePath;

            if (!_spansOnDocuments.TryGetValue(key, out PersistentSpanSet spanSet))
            {
                if (!_eventsHooked)
                {
                    _eventsHooked = true;

                    this.TextDocumentFactoryService.TextDocumentCreated  += OnTextDocumentCreated;
                    this.TextDocumentFactoryService.TextDocumentDisposed += OnTextDocumentDisposed;
                }

                spanSet = new PersistentSpanSet(filePath, document, this);
                _spansOnDocuments.Add(key, spanSet);
            }

            return(spanSet);
        }