public void R_OutlineToggleAll() { string text = _files.LoadDestinationFile("lsfit.r"); using (var script = new TestScript(text, RContentTypeDefinition.ContentType)) { script.DoIdle(500); IOutliningManagerService svc = EditorShell.Current.ExportProvider.GetExportedValue <IOutliningManagerService>(); IOutliningManager mgr = svc.GetOutliningManager(EditorWindow.CoreEditor.View); var snapshot = EditorWindow.TextBuffer.CurrentSnapshot; var viewLines = EditorWindow.CoreEditor.View.TextViewLines; viewLines.Count.Should().Be(40); script.DoIdle(500); EditorWindow.ExecCommand(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_ALL); script.DoIdle(1000); IEnumerable <ICollapsed> collapsed = mgr.GetCollapsedRegions(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); collapsed.Count().Should().Be(20); EditorWindow.ExecCommand(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_ALL); script.DoIdle(500); viewLines = EditorWindow.CoreEditor.View.TextViewLines; viewLines.Count.Should().Be(40); EditorWindow.ExecCommand(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_STOP_HIDING_ALL); script.DoIdle(200); mgr.Enabled.Should().Be(false); EditorWindow.ExecCommand(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_START_AUTOHIDING); script.DoIdle(200); mgr.Enabled.Should().Be(true); script.MoveDown(9); EditorWindow.ExecCommand(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_CURRENT); script.DoIdle(500); collapsed = mgr.GetCollapsedRegions(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); collapsed.Count().Should().Be(1); EditorWindow.ExecCommand(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_CURRENT); script.DoIdle(200); collapsed = mgr.GetCollapsedRegions(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); collapsed.Count().Should().Be(0); } }
public async Task R_OutlineToggleAll() { string text = _files.LoadDestinationFile("lsfit.r"); using (var script = await _editorHost.StartScript(_exportProvider, text, "filename", RContentTypeDefinition.ContentType, null)) { script.DoIdle(500); IOutliningManagerService svc = _exportProvider.GetExportedValue <IOutliningManagerService>(); IOutliningManager mgr = svc.GetOutliningManager(script.View); var snapshot = script.TextBuffer.CurrentSnapshot; var viewLines = script.View.TextViewLines; viewLines.Count.Should().Be(22); script.DoIdle(500); script.Execute(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_ALL); script.DoIdle(1000); IEnumerable <ICollapsed> collapsed = mgr.GetCollapsedRegions(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); collapsed.Count().Should().Be(20); script.Execute(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_ALL); script.DoIdle(500); viewLines = script.View.TextViewLines; viewLines.Count.Should().Be(22); script.Execute(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_STOP_HIDING_ALL); script.DoIdle(200); mgr.Enabled.Should().Be(false); script.Execute(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_START_AUTOHIDING); script.DoIdle(200); mgr.Enabled.Should().Be(true); script.MoveDown(9); script.Execute(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_CURRENT); script.DoIdle(500); collapsed = mgr.GetCollapsedRegions(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); collapsed.Count().Should().Be(1); script.Execute(VSConstants.VSStd2K, (int)VSConstants.VSStd2KCmdID.OUTLN_TOGGLE_CURRENT); script.DoIdle(200); collapsed = mgr.GetCollapsedRegions(new SnapshotSpan(snapshot, new Span(0, snapshot.Length))); collapsed.Count().Should().Be(0); } }
private int CountHiddenLines(int start, int end) { if (start > end) { return(0); } // outliningManager will be null when outlining is not supported, such as in a git diff view if (outliningManager == null) { return(0); } var hiddenLines = outliningManager.GetCollapsedRegions(new SnapshotSpan(textView.TextSnapshot, start, end - start), true); var hiddenLineCount = 0; foreach (var hiddenLine in hiddenLines) { var span = hiddenLine.Extent.GetSpan(textView.TextBuffer.CurrentSnapshot); var strtLine = textView.TextSnapshot.GetLineNumberFromPosition(span.Start); var endLine = textView.TextSnapshot.GetLineNumberFromPosition(span.End); hiddenLineCount = hiddenLineCount + (endLine - strtLine); } return(hiddenLineCount); }
private async Task ExpandAllRegionsContainingSpanAsync(SnapshotSpan selectedSpan, IWpfTextView textView) { IOutliningManager outliningManager = await ServiceProvider.GetOutliningManagerAsync(textView); if (outliningManager == null) { return; } outliningManager.GetCollapsedRegions(selectedSpan, exposedRegionsOnly: false) .ForEach(region => outliningManager.Expand(region)); }
/// <summary> /// Maps the line number to the real line number as it's currently displayed in the text view. /// So if a region is collapsed, all diagnostics in this region should be mapped to the same line. /// </summary> /// <param name="textView">The <see cref="IWpfTextView"/>.</param> /// <param name="lineNumber">The number of the line.</param> /// <param name="outliningManager">The <see cref="IOutliningManager"/>.</param> /// <returns>The real line number.</returns> public static int GetRealLineNumber(IWpfTextView textView, int lineNumber, IOutliningManager outliningManager) { try { // a line could not get any further than 0 even by collapsing regions if (lineNumber == 0) { return(0); } // if no snapshot line found return 0 var lineSnapshot = textView.GetSnapshotForLineNumber(lineNumber); if (lineSnapshot == null) { return(0); } // if no collapsed region than line number fits as normal var snapshotSpan = lineSnapshot.Extent; var region = outliningManager?.GetCollapsedRegions(snapshotSpan) ?? Enumerable.Empty <ICollapsible>(); if (!region.Any()) { return(lineNumber); } // I assume that the longest collapsed region is the outermost var regionSnapshot = region .Select(x => x.Extent.GetSpan(textView.TextSnapshot)) .ToDictionary(x => x.Length) .OrderByDescending(x => x.Key) .First() .Value; var collapsedLineNumber = textView.TextSnapshot.GetLineNumberFromPosition(regionSnapshot.End.Position); return(collapsedLineNumber); } catch (ObjectDisposedException ex) { if (ex.ObjectName == "OutliningMnger") { // TODO: when we have a logger service add logging } // I assume that this case seems to happen, if the TextView gets closed and we receive a // DiagnosticChanged event right in the time frame before we dispose the whole container graph. return(lineNumber); } }
//===================================================================== /// <summary> /// Update the state of the controls based on the current issue /// </summary> private void UpdateState() { if (!updatingState) { updatingState = true; try { if (currentTextView != null) { var currentIssue = currentTagger.CurrentMisspellings.FirstOrDefault(); ucSpellCheck.UpdateState(false, currentTagger.Dictionary.DictionaryCount > 1, currentIssue); if (parentFocused && currentIssue != null) { var span = currentIssue.Span.GetSpan(currentIssue.Span.TextBuffer.CurrentSnapshot); // If in a collapsed region, expand the region if (outliningManager != null) { foreach (var region in outliningManager.GetCollapsedRegions(span, false)) { if (region.IsCollapsed) { outliningManager.Expand(region); } } } currentTextView.Caret.MoveTo(span.Start); currentTextView.ViewScroller.EnsureSpanVisible(span, EnsureSpanVisibleOptions.AlwaysCenter); currentTextView.Selection.Select(span, false); } } else { ucSpellCheck.UpdateState(true, false, null); } } finally { updatingState = false; } } }
public void MoveTo(SnapshotSpan span) { if (_outliningManager != null) { foreach (var region in _outliningManager.GetCollapsedRegions(span, false)) { _outliningManager.Expand(region); } } if (span.Snapshot != _view.TextSnapshot) { span = span.TranslateTo(_view.TextSnapshot, SpanTrackingMode.EdgeExclusive); } _view.Caret.MoveTo(span.Start); _view.Selection.Select(span, false); _view.ViewScroller.EnsureSpanVisible(span); }
void EvaluateAdornmentRegionDepth(IAdornment adornment) { Contract.Requires(adornment != null && adornment.Span != null); Contract.Requires(_outliningManager != null); Contract.Requires(_textView != null); try { var workingSnapshot = _textView.TextSnapshot; var collapsedRegionsAdornmentIsIn = _outliningManager.GetCollapsedRegions(adornment.Span.GetSpan(workingSnapshot)); Contract.Assume(collapsedRegionsAdornmentIsIn != null, "Let's make the assumption explicit"); adornment.CollapsedRegionDepth = collapsedRegionsAdornmentIsIn.Count(); } catch (ObjectDisposedException e) { if (e.ObjectName == "OutliningManager") { _logger.WriteToLog("Error: The 'OutliningManager' is disposed, adornments may not be formatted correctly."); } else { throw e; } } }
//===================================================================== /// <summary> /// Update the state of the controls based on the current issue /// </summary> private void UpdateState() { if (updatingState) { return; } try { updatingState = lbSuggestions.IsEnabled = true; btnReplace.IsEnabled = btnReplaceAll.IsEnabled = btnIgnoreOnce.IsEnabled = btnIgnoreAll.IsEnabled = btnAddWord.IsEnabled = btnUndo.IsEnabled = txtMisspelledWord.IsEnabled = false; lblIssue.Content = "_Misspelled Word"; txtMisspelledWord.Text = null; lbSuggestions.Items.Clear(); if (currentTextView == null) { lblDisabled.Visibility = Visibility.Visible; return; } lblDisabled.Visibility = Visibility.Collapsed; if (currentTextView == null) { return; } if (misspellings.Count == 0) { txtMisspelledWord.Text = "(No more issues)"; return; } var issue = misspellings[0]; if (issue.MisspellingType == MisspellingType.DoubledWord) { lblIssue.Content = "_Doubled Word"; btnReplace.IsEnabled = btnIgnoreOnce.IsEnabled = true; lbSuggestions.Items.Add("(Delete word)"); } else { txtMisspelledWord.IsEnabled = btnIgnoreOnce.IsEnabled = btnIgnoreAll.IsEnabled = true; switch (issue.MisspellingType) { case MisspellingType.CompoundTerm: lblIssue.Content = "Co_mpound Term"; break; case MisspellingType.DeprecatedTerm: lblIssue.Content = "_Deprecated Term"; break; case MisspellingType.UnrecognizedWord: lblIssue.Content = "Un_recognized Word"; break; default: break; } if (issue.Suggestions.Any()) { btnReplace.IsEnabled = btnReplaceAll.IsEnabled = true; btnAddWord.IsEnabled = (issue.MisspellingType == MisspellingType.MisspelledWord); foreach (var s in issue.Suggestions) { lbSuggestions.Items.Add(s); } lbSuggestions.SelectedIndex = issue.Suggestions.First().IsGroupHeader ? 1 : 0; } else { lbSuggestions.Items.Add("(No suggestions)"); } } txtMisspelledWord.Text = issue.Word; if (parentFocused) { var span = issue.Span.GetSpan(issue.Span.TextBuffer.CurrentSnapshot); // If in a collapsed region, expand the region if (outliningManager != null) { foreach (var region in outliningManager.GetCollapsedRegions(span, false)) { if (region.IsCollapsed) { outliningManager.Expand(region); } } } currentTextView.Caret.MoveTo(span.Start); currentTextView.ViewScroller.EnsureSpanVisible(span, EnsureSpanVisibleOptions.AlwaysCenter); currentTextView.Selection.Select(span, false); } } finally { updatingState = false; } }
public void DrawLines() { // Find the hidden regions IEnumerable <ICollapsed> collapsedRegions = new List <ICollapsed>(); if (_outliningManager != null) { collapsedRegions = _outliningManager.GetCollapsedRegions(new SnapshotSpan(_textView.TextBuffer.CurrentSnapshot, new Span(0, _textView.TextBuffer.CurrentSnapshot.Length))); } IEnumerator <ICollapsed> currentCollapsedRegion = collapsedRegions.GetEnumerator(); SnapshotSpan? currentCollapsedSnapshotSpan = null; if (currentCollapsedRegion.MoveNext()) { currentCollapsedSnapshotSpan = currentCollapsedRegion.Current.Extent.GetSpan(_textView.TextBuffer.CurrentSnapshot); } // Get the highlights List <SnapshotSpan> highlightList = new List <SnapshotSpan>(); if (HighlightWordTaggerProvider.Taggers.ContainsKey(_textView)) { IEnumerable <ITagSpan <HighlightWordTag> > highlightsEnumerable = HighlightWordTaggerProvider.Taggers[_textView].GetTags(new NormalizedSnapshotSpanCollection(new SnapshotSpan(_textView.TextSnapshot, 0, _textView.TextSnapshot.Length))); foreach (ITagSpan <HighlightWordTag> highlight in highlightsEnumerable) { highlightList.Add(highlight.Span); } } NormalizedSnapshotSpanCollection highlights = new NormalizedSnapshotSpanCollection(highlightList); int highlightIndex = 0; // Create the image buffer _width = Options.ScrollBarWidth; _height = Math.Min(NumLines, MaxBitmapHeight); _stride = (_width * _pixelFormat.BitsPerPixel + 7) / 8; _pixels = new byte[_stride * _height]; _lineRatio = (double)(_height) / (double)(NumLines); string text = _textView.TextBuffer.CurrentSnapshot.GetText(); int wrapAfter = int.MaxValue; int tabSize = 4; CommentType commentType = CommentType.None; int multiLineCommentStart = -1; bool inKeyword = false; bool inString = false; int virtualLine = 0; int virtualColumn = 0; int realLine = 0; int realColumn = 0; bool isLineVisible = true; for (int i = 0; i < text.Length; ++i) { // Check for a real newline, a virtual newline (due to word wrapping) or the end of the text. bool isRealNewline = (text[i] == '\r') || (text[i] == '\n'); bool isVirtualNewline = (virtualColumn >= wrapAfter); bool isTextEnd = (i == text.Length - 1); if (isRealNewline || isVirtualNewline || isTextEnd) { virtualColumn = 0; if (isLineVisible) { // Advance the virtual line. ++virtualLine; } if (isTextEnd) { break; } if (isRealNewline) { ++realLine; realColumn = 0; inKeyword = false; inString = false; // In case of CRLF, eat the next character too. if ((text[i] == '\r') && (i + 1 < text.Length) && (text[i + 1] == '\n')) { ++i; } if (i + 1 < text.Length) { if (currentCollapsedSnapshotSpan.HasValue && (i + 1 > currentCollapsedSnapshotSpan.Value.End.Position)) { if (currentCollapsedRegion.MoveNext()) { currentCollapsedSnapshotSpan = currentCollapsedRegion.Current.Extent.GetSpan(_textView.TextBuffer.CurrentSnapshot); } else { currentCollapsedSnapshotSpan = null; } } isLineVisible = !(currentCollapsedSnapshotSpan.HasValue && (i + 1 > currentCollapsedSnapshotSpan.Value.Start.Position)); } if (commentType == CommentType.SingleLine) { commentType = CommentType.None; } continue; } } int numChars = 1; if (!System.Char.IsWhiteSpace(text[i])) { switch (commentType) { case CommentType.None: { if (!inString && (text.Substring(i, 2) == "//")) { commentType = CommentType.SingleLine; inKeyword = false; } else if (!inString && (text.Substring(i, 2) == "/*")) { commentType = CommentType.MultiLine; multiLineCommentStart = i; inKeyword = false; } else if (text[i] == '"') { inKeyword = false; if (inString) { int backslashStart = i - 1; while (i >= 0 && text[i] == '\\') { --backslashStart; } int numBackslashes = i - backslashStart - 1; if (numBackslashes % 2 == 0) { inString = false; } } else { inString = true; } } else if (!inKeyword && !inString && IsCppIdStart(text[i]) && ((i == 0) || IsCppIdSeparator(text[i - 1]))) { int keywordEnd = i + 1; while (keywordEnd < text.Length && !IsCppIdSeparator(text[keywordEnd])) { ++keywordEnd; } int len = keywordEnd - i; inKeyword = IsKeyword(text.Substring(i, len)); } else if (inKeyword && IsCppIdSeparator(text[i])) { inKeyword = false; } } break; case CommentType.MultiLine: { if (text.Substring(i - 1, 2) == "*/" && i > multiLineCommentStart + 2) // Make sure we don't detect "/*/" as opening and closing a comment. { commentType = CommentType.None; } } break; } while (highlightIndex < highlights.Count && i >= highlights[highlightIndex].End.Position) { ++highlightIndex; } if (isLineVisible) { if (highlightIndex < highlights.Count && i >= highlights[highlightIndex].Start.Position) { SetPixel(virtualColumn, virtualLine, _progressiveScroll.Colors.HighlightsBrush.Color); } else if (commentType != CommentType.None) { SetPixel(virtualColumn, virtualLine, _progressiveScroll.Colors.CommentsBrush.Color); } else if (inString) { SetPixel(virtualColumn, virtualLine, _progressiveScroll.Colors.StringsBrush.Color); } else { SetPixel(virtualColumn, virtualLine, _progressiveScroll.Colors.TextBrush.Color); } } } else { inKeyword = false; if (text[i] == '\t') { numChars = tabSize - (virtualColumn % tabSize); } if (isLineVisible) { SetPixels(virtualColumn, virtualLine, _progressiveScroll.Colors.WhitespaceBrush.Color, numChars); } } ++realColumn; virtualColumn += numChars; } }