private bool IsValidTextBuffer() { IProjectionBuffer textBuffer = _view.TextBuffer as IProjectionBuffer; if (textBuffer != null) { SnapshotPoint bufferPosition = _view.Caret.Position.BufferPosition; var buffers = from s in textBuffer.SourceBuffers where (((!s.ContentType.IsOfType("html") && !s.ContentType.IsOfType("inert")) && (!s.ContentType.IsOfType("CSharp") && !s.ContentType.IsOfType("VisualBasic"))) && !s.ContentType.IsOfType("RoslynCSharp")) && !s.ContentType.IsOfType("RoslynVisualBasic") select s; foreach (ITextBuffer buffer2 in buffers) { if (_view.BufferGraph.MapDownToBuffer(bufferPosition, PointTrackingMode.Negative, buffer2, PositionAffinity.Predecessor).HasValue) { return(false); } } } return(true); }
/// <summary> /// Gets content type of the text buffer that has the caret. /// </summary> public string GetContentTypeInActiveBuffer() { IContentType retVal = _wpfView.TextBuffer.ContentType; IProjectionBuffer projection = _wpfView.TextBuffer as IProjectionBuffer; if (null == projection) { return(retVal?.TypeName?.ToLowerInvariant()); } // Current view has several buffers (e.g. html file with css code), get the one that has the caret var caretPosition = _wpfView.Caret.Position.BufferPosition; var buffers = projection.SourceBuffers; var bufferGraph = _wpfView.BufferGraph; foreach (ITextBuffer buffer in buffers) { SnapshotPoint?point = bufferGraph.MapDownToBuffer( caretPosition, PointTrackingMode.Negative, buffer, PositionAffinity.Predecessor); if (!point.HasValue) { continue; } // Several matches possible, we are interested in the last one. retVal = buffer.ContentType; } return(retVal?.TypeName?.ToLowerInvariant()); }
public TemplateProjectionBuffer(IContentTypeRegistryService contentRegistry, IProjectionBufferFactoryService bufferFactory, ITextBuffer diskBuffer, IBufferGraphFactoryService bufferGraphFactory, IContentType contentType) { _diskBuffer = diskBuffer; _contentRegistry = contentRegistry; _contentType = contentType; _projBuffer = bufferFactory.CreateProjectionBuffer( this, new object[0], ProjectionBufferOptions.None ); _projBuffer.Properties.AddProperty(typeof(TemplateProjectionBuffer), this); _bufferGraph = bufferGraphFactory.CreateBufferGraph(_projBuffer); _htmlBuffer = CreateHtmlBuffer(bufferFactory); _templateBuffer = CreateTemplateBuffer(bufferFactory); IVsTextBuffer buffer; if (_diskBuffer.Properties.TryGetProperty <IVsTextBuffer>(typeof(IVsTextBuffer), out buffer)) { // keep the Venus HTML classifier happy - it wants to find a site via IVsTextBuffer _htmlBuffer.Properties.AddProperty(typeof(IVsTextBuffer), buffer); } var reader = new SnapshotSpanSourceCodeReader(new SnapshotSpan(diskBuffer.CurrentSnapshot, new Span(0, diskBuffer.CurrentSnapshot.Length))); UpdateTemplateSpans(reader); }
private bool IsValidTextBuffer() { IProjectionBuffer projection = _view.TextBuffer as IProjectionBuffer; if (projection != null) { SnapshotPoint snapshotPoint = _view.Caret.Position.BufferPosition; System.Collections.Generic.IEnumerable <ITextBuffer> buffers = projection.SourceBuffers.Where( s => !s.ContentType.IsOfType("html") && !s.ContentType.IsOfType("htmlx") && !s.ContentType.IsOfType("inert") && !s.ContentType.IsOfType("CSharp") && !s.ContentType.IsOfType("VisualBasic") && !s.ContentType.IsOfType("RoslynCSharp") && !s.ContentType.IsOfType("RoslynVisualBasic")); foreach (ITextBuffer buffer in buffers) { SnapshotPoint?point = _view.BufferGraph.MapDownToBuffer(snapshotPoint, PointTrackingMode.Negative, buffer, PositionAffinity.Predecessor); if (point.HasValue) { return(false); } } } return(true); }
private void SetContentType(ITextBuffer buffer, IContentType contentType) { this.isCodeContentType = Utilities.IsContentOfType(contentType, "code"); // In VS 2013-2017 the HTML language service doesn't provide the correct tabs/spaces options // from IEditorOptions, so we have to read them from IVsTextManager. Unfortunately, this means // we won't get OptionChanged notifications for them. this.textManagerLanguageName = null; if (Utilities.IsContentOfType(contentType, "HTML")) { this.textManagerLanguageName = "HTML"; } else if (Utilities.IsContentOfType(contentType, "HTMLX")) { this.textManagerLanguageName = "HTMLX"; } else { // If an HTML editor has embedded sections using other languages (e.g., JavaScript, C#, Basic, CSS) // then the HTML editor will also give us incorrect IEditorOptions for them. IProjectionBuffer projection = buffer as IProjectionBuffer; if (projection != null && projection.SourceBuffers.Any( source => Utilities.IsContentOfType(source.ContentType, "HTML") || Utilities.IsContentOfType(source.ContentType, "HTMLX"))) { this.textManagerLanguageName = buffer.ContentType.TypeName; } } }
private void TextView_Closed(object sender, EventArgs e) { IWpfTextView textView = sender as IWpfTextView; if (textView != null) { if (textView.BufferGraph != null) { textView.BufferGraph.GraphBuffersChanged -= OnGraphBuffersChanged; } IProjectionBuffer pb = textView.TextBuffer as IProjectionBuffer; if (pb != null) { pb.SourceBuffersChanged -= OnSourceBuffersChanged; } textView.Closed -= TextView_Closed; ReplCommandController controller = ReplCommandController.FromTextView(textView); if (controller != null) { controller.Dispose(); } } }
public IOleCommandTarget GetCommandTarget(IWpfTextView textView, IOleCommandTarget nextTarget) { IOleCommandTarget target = ServiceManager.GetService <IOleCommandTarget>(textView); if (target == null) { ReplCommandController controller = ReplCommandController.Attach(textView, textView.TextBuffer); // Wrap controller into OLE command target target = VsAppShell.Current.TranslateToHostCommandTarget(textView, controller) as IOleCommandTarget; Debug.Assert(target != null); ServiceManager.AddService(target, textView, _shell); // Wrap next OLE target in the chain into ICommandTarget so we can have // chain like: OLE Target -> Shim -> ICommandTarget -> Shim -> Next OLE target ICommandTarget nextCommandTarget = VsAppShell.Current.TranslateCommandTarget(textView, nextTarget); controller.ChainedController = nextCommandTarget; // We need to listed when R projected buffer is attached and // create R editor document over it. textView.BufferGraph.GraphBuffersChanged += OnGraphBuffersChanged; IProjectionBuffer pb = textView.TextBuffer as IProjectionBuffer; if (pb != null) { pb.SourceBuffersChanged += OnSourceBuffersChanged; } textView.Closed += TextView_Closed; } return(target); }
public PhpProjectionBuffer( IContentTypeRegistryService contentRegistry, IProjectionBufferFactoryService bufferFactory, IBufferTagAggregatorFactoryService bufferTagAggregatorFactory, ITextBuffer diskBuffer, IBufferGraphFactoryService bufferGraphFactory, IContentType contentType) { _diskBuffer = diskBuffer; _contentRegistry = contentRegistry; _contentType = contentType; _projBuffer = CreateProjectionBuffer(bufferFactory); _htmlBuffer = CreateHtmlBuffer(bufferFactory); _templateBuffer = CreateTemplateBuffer(bufferFactory); _bufferGraph = bufferGraphFactory.CreateBufferGraph(_projBuffer); _contentTypeTagger = bufferTagAggregatorFactory.CreateTagAggregator <ContentTypeTag>(_diskBuffer); _contentTypeTagger.TagsChanged += HandleContentTypeTagsChanged; IVsTextBuffer buffer; if (_diskBuffer.Properties.TryGetProperty <IVsTextBuffer>(typeof(IVsTextBuffer), out buffer)) { // keep the Venus HTML classifier happy - it wants to find a site via IVsTextBuffer _htmlBuffer.Properties.AddProperty(typeof(IVsTextBuffer), buffer); } HandleContentTypeTagsChanged(); }
private void EndTracking() { if (_textView != null) { ClearHighlight(); if (_projectionBuffer != null) { _projectionBuffer.SourceSpansChanged -= OnSourceSpansChanged; _projectionBuffer = null; } if (_projectionsChanged || _adornmentRemoved) { _projectionsChanged = false; _adornmentRemoved = false; } _textView.TextBuffer.Changed -= OnTextBufferChanged; _textView.TextBuffer.PostChanged -= OnPostChanged; _textView.Caret.PositionChanged -= OnCaretPositionChanged; _textView = null; if (OnClose != null) { OnClose(this, EventArgs.Empty); } } }
/// <summary> /// IProjectionBuffer instances can compose recursively. This will look recursively down the /// source buffers to find all of the critical ones /// </summary> public static IEnumerable <ITextBuffer> GetSourceBuffersRecursive(this IProjectionBuffer projectionBuffer) { var toVisit = new Queue <IProjectionBuffer>(); toVisit.Enqueue(projectionBuffer); var found = new HashSet <ITextBuffer>(); while (toVisit.Count > 0) { var current = toVisit.Dequeue(); if (found.Contains(current)) { continue; } found.Add(current); foreach (var sourceBuffer in current.SourceBuffers) { if (sourceBuffer is IProjectionBuffer sourceProjection) { toVisit.Enqueue(sourceProjection); } else { found.Add(sourceBuffer); } } } return(found.Where(x => !(x is IProjectionBuffer))); }
/// <summary> /// Given text view locates R document in underlying text buffer graph. /// In REPL window there may be multiple R text buffers but usually /// only last one (the one active at the > prompt) has attached R document. /// Other R buffers represent previously typed commands. They still have /// colorizer attached but no active R documents. /// </summary> /// <param name="viewBuffer"></param> /// <returns></returns> public static IREditorDocument FindInProjectedBuffers(ITextBuffer viewBuffer) { IREditorDocument document = null; if (viewBuffer.ContentType.IsOfType(RContentTypeDefinition.ContentType)) { return(ServiceManager.GetService <REditorDocument>(viewBuffer)); } // Try locating R buffer ITextBuffer rBuffer = null; IProjectionBuffer pb = viewBuffer as IProjectionBuffer; if (pb != null) { rBuffer = pb.SourceBuffers.FirstOrDefault((ITextBuffer tb) => { if (tb.ContentType.IsOfType(RContentTypeDefinition.ContentType)) { document = ServiceManager.GetService <REditorDocument>(tb); if (document != null) { return(true); } } return(false); }); } return(document); }
/// <summary> /// To be called from the derived class constructor! /// </summary> protected void SetDataBuffer(IProjectionBuffer dataBuffer) { if (dataBuffer == null) { throw new ArgumentNullException("dataBuffer"); } this.DataBuffer = dataBuffer; }
/// <summary> /// To be called from the derived class constructor! /// </summary> protected void SetDataBuffer(IProjectionBuffer dataBuffer) { if (dataBuffer == null) { throw new ArgumentNullException("dataBuffer"); } this.DataBuffer = dataBuffer; }
private async Task <object> CreateNewDifferenceViewerAsync( IProjectionBuffer originalBuffer, IProjectionBuffer newBuffer, string description, FrameworkElement additionalContent) { IDifferenceBuffer diffBuffer = this.differenceBufferFactoryService.CreateDifferenceBuffer( originalBuffer, newBuffer, options: default,
public ITagger <T> CreateTagger <T>(ITextBuffer buffer) where T : ITag { IProjectionBuffer projectionBuffer = buffer as IProjectionBuffer; if (projectionBuffer == null) { return(null); } return(new ProjectionWorkaroundTagger(projectionBuffer) as ITagger <T>); }
public void AddClassifier(IProjectionBuffer projectionBuffer, ITextBuffer textBuffer, IClassifier classifer) { var elisionInfo = new ElisionInfo(textBuffer, classifer, _bufGraphFact.CreateBufferGraph(projectionBuffer)); _elisionBuffers.Add(elisionInfo); classifer.ClassificationChanged += (sender, args) => { var classChanged = ClassificationChanged; if (classChanged != null) { foreach (var span in elisionInfo.BufferGraph.MapDownToBuffer(args.ChangeSpan, SpanTrackingMode.EdgeExclusive, projectionBuffer)) { classChanged(this, new ClassificationChangedEventArgs(span)); } } }; }
public ITextViewModel CreateTextViewModel(ITextDataModel dataModel, ITextViewRoleSet roles) { //var tempFolder = Path.Combine(Path.GetTempPath(), "dotvvmTemp"); //if (!Directory.Exists(tempFolder)) // Directory.CreateDirectory(tempFolder); //javascriptFilePath = Path.Combine(tempFolder, Guid.NewGuid().ToString("N") + ".js"); //File.Create(javascriptFilePath); IProjectionBuffer projectionBuffer = ParseDataModelToProjection(dataModel); textViewModel = new DothtmlProjectionTextViewModel(dataModel, projectionBuffer); return(textViewModel); }
private async ValueTask <DifferenceViewerPreview> CreateNewDifferenceViewerAsync( PreviewWorkspace?leftWorkspace, PreviewWorkspace?rightWorkspace, IProjectionBuffer originalBuffer, IProjectionBuffer changedBuffer, double zoomLevel, CancellationToken cancellationToken) { // IWpfDifferenceViewerFactoryService is a Visual Studio API which is not documented as free-threaded await ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); // leftWorkspace can be null if the change is adding a document. // rightWorkspace can be null if the change is removing a document. // However both leftWorkspace and rightWorkspace can't be null at the same time. Contract.ThrowIfTrue((leftWorkspace == null) && (rightWorkspace == null)); var diffBuffer = _differenceBufferService.CreateDifferenceBuffer( originalBuffer, changedBuffer, new StringDifferenceOptions(), disableEditing: true); var mode = leftWorkspace == null ? DifferenceViewMode.RightViewOnly : rightWorkspace == null ? DifferenceViewMode.LeftViewOnly : DifferenceViewMode.Inline; var diffViewer = await CreateDifferenceViewAsync(diffBuffer, _previewRoleSet, mode, zoomLevel, cancellationToken).ConfigureAwait(true); diffViewer.Closed += (s, e) => { // Workaround Editor bug. The editor has an issue where they sometimes crash when // trying to apply changes to projection buffer. So, when the user actually invokes // a SuggestedAction we may then edit a text buffer, which the editor will then // try to propagate through the projections we have here over that buffer. To ensure // that that doesn't happen, we clear out the projections first so that this crash // won't happen. originalBuffer.DeleteSpans(0, originalBuffer.CurrentSnapshot.SpanCount); changedBuffer.DeleteSpans(0, changedBuffer.CurrentSnapshot.SpanCount); leftWorkspace?.Dispose(); leftWorkspace = null; rightWorkspace?.Dispose(); rightWorkspace = null; }; if (_globalOptions.GetOption(SolutionCrawlerRegistrationService.EnableSolutionCrawler)) { leftWorkspace?.EnableSolutionCrawler(); rightWorkspace?.EnableSolutionCrawler(); } return(new DifferenceViewerPreview(diffViewer)); }
private void AdjustIndentation(IProjectionBuffer subjectBuffer, IEnumerable <int> visibleSpanIndex) { if (!visibleSpanIndex.Any()) { return; } var snapshot = subjectBuffer.CurrentSnapshot; var document = _workspace.CurrentSolution.GetDocument(this.Id); if (!document.SupportsSyntaxTree) { return; } var originalText = document.GetTextSynchronously(CancellationToken.None); Debug.Assert(object.ReferenceEquals(originalText, snapshot.AsText())); var root = document.GetSyntaxRootSynchronously(CancellationToken.None); var editorOptionsFactory = _componentModel.GetService <IEditorOptionsFactoryService>(); var editorOptions = editorOptionsFactory.GetOptions(DataBuffer); var options = _workspace.Options .WithChangedOption(FormattingOptions.NewLine, root.Language, editorOptions.GetNewLineCharacter()) .WithChangedOption(FormattingOptions.UseTabs, root.Language, !editorOptions.IsConvertTabsToSpacesEnabled()) .WithChangedOption(FormattingOptions.TabSize, root.Language, editorOptions.GetTabSize()) .WithChangedOption(FormattingOptions.IndentationSize, root.Language, editorOptions.GetIndentSize()); using (var pooledObject = SharedPools.Default <List <TextSpan> >().GetPooledObject()) { var spans = pooledObject.Object; spans.AddRange(this.GetEditorVisibleSpans()); using (var edit = subjectBuffer.CreateEdit(s_venusEditOptions, reiteratedVersionNumber: null, editTag: null)) { foreach (var spanIndex in visibleSpanIndex) { var rule = GetBaseIndentationRule(root, originalText, spans, spanIndex); var visibleSpan = spans[spanIndex]; AdjustIndentationForSpan(document, edit, visibleSpan, rule, options); } edit.Apply(); } } }
public static IEnumerable<ITextBuffer> GetContributingBuffers(this ITextBuffer textBuffer) { List<ITextBuffer> allBuffers = new List<ITextBuffer>(); allBuffers.Add(textBuffer); for (int i = 0; i < allBuffers.Count; i++) { IProjectionBuffer currentBuffer = allBuffers[i] as IProjectionBuffer; if (currentBuffer != null) { foreach (ITextBuffer sourceBuffer in currentBuffer.SourceBuffers) { if (!allBuffers.Contains(sourceBuffer)) allBuffers.Add(sourceBuffer); } } } return allBuffers; }
/// <summary> /// Creates a new tab stops tagger instance. /// </summary> /// <param name="textView">View to create tagger for.</param> /// <param name="buffer">Text buffer to create tagger for.</param> public ITagger <T> CreateTagger <T>(ITextView textView, ITextBuffer buffer) where T : ITag { // Make sure that each view has only one tagger associated with it. If view has several buffers // (e.g. html file with css code) only the top level buffer will have a tagger associated with it. IProjectionBuffer projectionBuffer = textView.TextBuffer as IProjectionBuffer; if (null == projectionBuffer || buffer == projectionBuffer.SourceBuffers[0]) { return(new TabStopsTagger(textView, buffer) as ITagger <T>); } else { return(null); } }
public void AddClassifier(IProjectionBuffer projectionBuffer, ITextBuffer textBuffer, IClassifier classifer) { var elisionInfo = new ElisionInfo(textBuffer, classifer, _bufGraphFact.CreateBufferGraph(projectionBuffer)); _elisionBuffers.Add(elisionInfo); classifer.ClassificationChanged += (sender, args) => { var classChanged = ClassificationChanged; if (classChanged != null) { foreach (var span in elisionInfo.BufferGraph.MapDownToBuffer(args.ChangeSpan, SpanTrackingMode.EdgeExclusive, projectionBuffer)) { classChanged(this, new ClassificationChangedEventArgs(span)); } } }; }
// return type Task<object> is required by ISuggestedAction.GetPreviewAsync public Task <object> CreateChangePreviewAsync( SarifErrorListItem errorListItem, ITextBuffer buffer, Action <ITextBuffer, ITextSnapshot> applyEdit, string description = null, FrameworkElement additionalContent = null) { ITextBuffer bufferClone = this.CloneBuffer(buffer); applyEdit(bufferClone, buffer.CurrentSnapshot); IHierarchicalDifferenceCollection diffResult = this.ComputeDifferences(buffer, bufferClone); NormalizedSpanCollection originalSpans = this.GetOriginalSpans(diffResult); NormalizedSpanCollection changedSpans = this.GetChangedSpans(diffResult); List <LineSpan> originalLineSpans = this.CreateLineSpans(buffer.CurrentSnapshot, originalSpans); List <LineSpan> changedLineSpans = this.CreateLineSpans(bufferClone.CurrentSnapshot, changedSpans); if (!originalLineSpans.Any()) { originalLineSpans = changedLineSpans; } if (!(originalLineSpans.Any() && changedLineSpans.Any())) { return(Task.FromResult <object>(null)); } const string Separator = "\u2026"; // Horizontal ellipsis. IProjectionBuffer originalProjectionBuffer = this.projectionBufferFactoryService.CreateProjectionBufferWithoutIndentation( this.editorOptionsFactoryService.GlobalOptions, buffer.CurrentSnapshot, Separator, originalLineSpans.ToArray()); IProjectionBuffer newProjectionBuffer = this.projectionBufferFactoryService.CreateProjectionBufferWithoutIndentation( this.editorOptionsFactoryService.GlobalOptions, bufferClone.CurrentSnapshot, Separator, changedLineSpans.ToArray()); return(this.CreateNewDifferenceViewerAsync(errorListItem, originalProjectionBuffer, newProjectionBuffer, description, additionalContent)); }
private MonoDevelopContainedDocument(ITextBuffer languageBuffer, IProjectionBuffer dataBuffer, IMonoDevelopContainedLanguageHost containedLanguageHost) { LanguageBuffer = languageBuffer; DataBuffer = dataBuffer; ContainedLanguageHost = containedLanguageHost; _differenceSelectorService = CompositionManager.GetExportedValue <ITextDifferencingSelectorService> (); var container = languageBuffer.CurrentSnapshot.AsText().Container; var registration = Workspace.GetWorkspaceRegistration(container); if (registration.Workspace == null) { registration.WorkspaceChanged += Registration_WorkspaceChanged; } else { FinishInitialization(); } }
/// <summary> /// Locates first R buffer in the projection buffer graph. /// Note that in REPL this may not be the active buffer. /// In REPL used <see cref="FindInProjectedBuffers"/>. /// </summary> /// <param name="viewBuffer"></param> /// <returns></returns> public static ITextBuffer FindRBuffer(ITextBuffer viewBuffer) { if (viewBuffer.ContentType.IsOfType(RContentTypeDefinition.ContentType)) { return(viewBuffer); } // Try locating R buffer ITextBuffer rBuffer = null; IProjectionBuffer pb = viewBuffer as IProjectionBuffer; if (pb != null) { rBuffer = pb.SourceBuffers.FirstOrDefault((ITextBuffer tb) => { return(tb.ContentType.IsOfType(RContentTypeDefinition.ContentType)); }); } return(rBuffer); }
public VenusMargin(IWpfTextView textView, ITextEditorFactoryService textEditorFactory) { _projectionBuffer = (IProjectionBuffer)textView.TextBuffer; _control = new ProjectionBufferMargin { DataContext = _viewModel, TextEditorFactory = textEditorFactory, TextView = textView, }; _projectionBuffer.Changed += OnProjectionBufferChanged; _projectionBuffer.SourceSpansChanged += this.OnProjectionBufferSourceSpansChanged; _projectionBuffer.SourceBuffersChanged += OnProjectionBufferSourceBuffersChanged; foreach (var b in _projectionBuffer.SourceBuffers) { _viewModel.SourceBuffers.Add(b); } }
public IList <ClassificationSpan> GetClassificationSpans(SnapshotSpan span) { if (span.IsEmpty || _view == null) { return(_empty); } IList <ClassificationSpan> list = new List <ClassificationSpan>(); ITextSnapshotLine line = span.Snapshot.GetLineFromPosition(span.Start.Position); if (_caret > 0 && (line.Extent.Contains(_caret.Position) || line.Extent.End.Position == _caret.Position)) { _span = span.Snapshot.CreateTrackingSpan(line.Extent, SpanTrackingMode.EdgeExclusive); return(_empty); } IProjectionBuffer projection = span.Snapshot.TextBuffer as IProjectionBuffer; if (projection != null) { SnapshotPoint point = projection.CurrentSnapshot.MapToSourceSnapshot(line.Start + line.Length); ITextSnapshotLine basePoint = point.Snapshot.GetLineFromPosition(point.Position); if (basePoint.Length > line.Length) { return(_empty); } } string text = line.GetText(); string trimmed = text.TrimEnd(); int diff = text.Length - trimmed.Length; if (diff > 0) { SnapshotSpan ss = new SnapshotSpan(span.Snapshot, line.Start + line.Length - diff, diff); list.Add(new ClassificationSpan(ss, _whitespace)); } return(list); }
/// <summary> /// Initializes a new instance of the <see cref="ProjectionHighlightAdornment"/> class. /// </summary> /// <param name="view">Text view to create the adornment for</param> public ProjectionHighlightAdornment(IWpfTextView view) { if (view == null) { throw new ArgumentNullException("view"); } _layer = view.GetAdornmentLayer(ProjectionAdornmentTextViewCreationListener.LayerName); _view = view; _projectionBuffer = view.TextBuffer as IProjectionBuffer; _view.LayoutChanged += OnLayoutChanged; // Create the pen and brush to color the box behind the a's _brushes = new Brush[5]; _pens = new Pen[5]; _brushes[0] = new SolidColorBrush(Color.FromArgb(0x20, 0x00, 0x00, 0xff)); _brushes[0].Freeze(); _pens[0] = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0x00, 0xff)), 0.5); _pens[0].Freeze(); _brushes[1] = new SolidColorBrush(Color.FromArgb(0x20, 0x00, 0xff, 0x00)); _brushes[1].Freeze(); _pens[1] = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xff, 0x00)), 0.5); _pens[1].Freeze(); _brushes[2] = new SolidColorBrush(Color.FromArgb(0x20, 0xff, 0x00, 0x00)); _brushes[2].Freeze(); _pens[2] = new Pen(new SolidColorBrush(Color.FromRgb(0xff, 0x00, 0x00)), 0.5); _pens[2].Freeze(); _brushes[3] = new SolidColorBrush(Color.FromArgb(0x20, 0xff, 0x00, 0xff)); _brushes[3].Freeze(); _pens[3] = new Pen(new SolidColorBrush(Color.FromRgb(0xff, 0x00, 0xff)), 0.5); _pens[3].Freeze(); _brushes[4] = new SolidColorBrush(Color.FromArgb(0x20, 0x00, 0xff, 0xff)); _brushes[4].Freeze(); _pens[4] = new Pen(new SolidColorBrush(Color.FromRgb(0x00, 0xff, 0xff)), 0.5); _pens[4].Freeze(); }
public VenusMargin(IWpfTextView textView, ITextEditorFactoryService textEditorFactory) { _textView = textView; _projectionBuffer = (IProjectionBuffer)textView.TextBuffer; _control = new ProjectionBufferMargin { DataContext = _viewModel, TextEditorFactory = textEditorFactory, TextView = textView, }; _projectionBuffer.Changed += OnProjectionBufferChanged; _projectionBuffer.SourceSpansChanged += this.OnProjectionBufferSourceSpansChanged; _projectionBuffer.SourceBuffersChanged += OnProjectionBufferSourceBuffersChanged; foreach (var b in _projectionBuffer.SourceBuffers) { _viewModel.SourceBuffers.Add(b); } }
private static void ApplyChanges( IProjectionBuffer subjectBuffer, IEnumerable <TextChange> changes, IList <TextSpan> visibleSpansInOriginal, out IEnumerable <int> affectedVisibleSpansInNew) { using var edit = subjectBuffer.CreateEdit(s_venusEditOptions, reiteratedVersionNumber: null, editTag: null); var affectedSpans = SharedPools.Default <HashSet <int> >().AllocateAndClear(); affectedVisibleSpansInNew = affectedSpans; var currentVisibleSpanIndex = 0; foreach (var change in changes) { // Find the next visible span that either overlaps or intersects with while (currentVisibleSpanIndex < visibleSpansInOriginal.Count && visibleSpansInOriginal[currentVisibleSpanIndex].End < change.Span.Start) { currentVisibleSpanIndex++; } // no more place to apply text changes if (currentVisibleSpanIndex >= visibleSpansInOriginal.Count) { break; } var newText = change.NewText; var span = change.Span.ToSpan(); edit.Replace(span, newText); affectedSpans.Add(currentVisibleSpanIndex); } edit.ApplyAndLogExceptions(); }
/// <summary> /// Initializes a new instance of the <see cref="EditorMargin1"/> class for a given <paramref name="textView"/>. /// </summary> /// <param name="textView">The <see cref="IWpfTextView"/> to attach the margin to.</param> public ProjectionViewerMargin(IWpfTextView textView) { _textView = textView; _projectionBuffer = _textView.TextBuffer as IProjectionBuffer; Debug.Assert(_projectionBuffer != null); this.Height = 20; // Margin height sufficient to have the label this.ClipToBounds = true; this.Background = new SolidColorBrush(Colors.LightGreen); // Add a green colored label that says "Hello EditorMargin1" _label = new Label { Background = new SolidColorBrush(Colors.LightGreen), Content = $"This text view contains {_projectionBuffer.SourceBuffers.Count} projection buffers and {_projectionBuffer.CurrentSnapshot.SpanCount} projection spans.", }; this.Children.Add(_label); _projectionBuffer.SourceBuffersChanged += OnSourceBuffersChanged; }
private ITextBuffer GetTextBuffer(out SnapshotPoint?point) { IProjectionBuffer projection = _textView.TextBuffer as IProjectionBuffer; if (projection != null) { var snapshotPoint = _textView.Caret.Position.BufferPosition; foreach (ITextBuffer buffer in projection.SourceBuffers.Where(s => !s.ContentType.IsOfType("htmlx"))) { point = _textView.BufferGraph.MapDownToBuffer(snapshotPoint, PointTrackingMode.Negative, buffer, PositionAffinity.Predecessor); if (point.HasValue) { return(buffer); } } } point = _textView.Caret.Position.BufferPosition; return(_textView.TextBuffer); }
internal static string GetFilePath(this ITextBuffer textBuffer) { string filePath = GetFilePathFromTextDocument(textBuffer); if (!string.IsNullOrEmpty(filePath)) { return(filePath); } IProjectionBuffer projectionBuffer = textBuffer as IProjectionBuffer; if (projectionBuffer == null) { return(null); } List <string> filePaths = new List <string>(); foreach (ITextBuffer buffer in projectionBuffer.SourceBuffers) { filePath = GetFilePathFromTextDocument(buffer); if (!string.IsNullOrEmpty(filePath)) { filePaths.Add(filePath); } } Debug.Assert(filePaths.Count <= 1, "Why is there more than one buffer with a file path?"); if (filePaths.Count > 0) { return(filePaths[0]); } return(null); }
public UIThreadOnly( InteractiveWindow window, IInteractiveWindowEditorFactoryService factory, IContentTypeRegistryService contentTypeRegistry, ITextBufferFactoryService bufferFactory, IProjectionBufferFactoryService projectionBufferFactory, IEditorOperationsFactoryService editorOperationsFactory, ITextEditorFactoryService editorFactory, IRtfBuilderService rtfBuilderService, IIntellisenseSessionStackMapService intellisenseSessionStackMap, ISmartIndentationService smartIndenterService, IInteractiveEvaluator evaluator, IWaitIndicator waitIndicator) { _window = window; _factory = factory; _rtfBuilderService = (IRtfBuilderService2)rtfBuilderService; _intellisenseSessionStackMap = intellisenseSessionStackMap; _smartIndenterService = smartIndenterService; _waitIndicator = waitIndicator; Evaluator = evaluator; var replContentType = contentTypeRegistry.GetContentType(PredefinedInteractiveContentTypes.InteractiveContentTypeName); var replOutputContentType = contentTypeRegistry.GetContentType(PredefinedInteractiveContentTypes.InteractiveOutputContentTypeName); OutputBuffer = bufferFactory.CreateTextBuffer(replOutputContentType); StandardInputBuffer = bufferFactory.CreateTextBuffer(); _inertType = bufferFactory.InertContentType; _projectionBuffer = projectionBufferFactory.CreateProjectionBuffer( new EditResolver(window), Array.Empty<object>(), ProjectionBufferOptions.None, replContentType); _projectionBuffer.Properties.AddProperty(typeof(InteractiveWindow), window); AppendNewOutputProjectionBuffer(); _projectionBuffer.Changed += new EventHandler<TextContentChangedEventArgs>(ProjectionBufferChanged); var roleSet = editorFactory.CreateTextViewRoleSet( PredefinedTextViewRoles.Analyzable, PredefinedTextViewRoles.Editable, PredefinedTextViewRoles.Interactive, PredefinedTextViewRoles.Zoomable, PredefinedInteractiveTextViewRoles.InteractiveTextViewRole); TextView = factory.CreateTextView(window, _projectionBuffer, roleSet); TextView.Caret.PositionChanged += CaretPositionChanged; var options = TextView.Options; options.SetOptionValue(DefaultTextViewHostOptions.HorizontalScrollBarId, true); options.SetOptionValue(DefaultTextViewHostOptions.LineNumberMarginId, false); options.SetOptionValue(DefaultTextViewHostOptions.OutliningMarginId, false); options.SetOptionValue(DefaultTextViewHostOptions.GlyphMarginId, false); options.SetOptionValue(DefaultTextViewOptions.WordWrapStyleId, WordWrapStyles.None); _lineBreakString = options.GetNewLineCharacter(); EditorOperations = editorOperationsFactory.GetEditorOperations(TextView); _buffer = new OutputBuffer(window); OutputWriter = new InteractiveWindowWriter(window, spans: null); SortedSpans errorSpans = new SortedSpans(); ErrorOutputWriter = new InteractiveWindowWriter(window, errorSpans); OutputClassifierProvider.AttachToBuffer(OutputBuffer, errorSpans); }
private async Task<object> CreateNewDifferenceViewerAsync(PreviewWorkspace leftWorkspace, PreviewWorkspace rightWorkspace, IProjectionBuffer originalBuffer, IProjectionBuffer changedBuffer, double zoomLevel, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // leftWorkspace can be null if the change is adding a document. // rightWorkspace can be null if the change is removing a document. // However both leftWorkspace and rightWorkspace can't be null at the same time. Contract.ThrowIfTrue((leftWorkspace == null) && (rightWorkspace == null)); var diffBuffer = _differenceBufferService.CreateDifferenceBuffer( originalBuffer, changedBuffer, new StringDifferenceOptions(), disableEditing: true); var diffViewer = _differenceViewerService.CreateDifferenceView(diffBuffer, _previewRoleSet); diffViewer.Closed += (s, e) => { if (leftWorkspace != null) { leftWorkspace.Dispose(); leftWorkspace = null; } if (rightWorkspace != null) { rightWorkspace.Dispose(); rightWorkspace = null; } }; const string DiffOverviewMarginName = "deltadifferenceViewerOverview"; if (leftWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.RightViewOnly; diffViewer.RightView.ZoomLevel *= zoomLevel; diffViewer.RightHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else if (rightWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.LeftViewOnly; diffViewer.LeftView.ZoomLevel *= zoomLevel; diffViewer.LeftHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else { diffViewer.ViewMode = DifferenceViewMode.Inline; diffViewer.InlineView.ZoomLevel *= zoomLevel; diffViewer.InlineHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } // Disable focus / tab stop for the diff viewer. diffViewer.RightView.VisualElement.Focusable = false; diffViewer.LeftView.VisualElement.Focusable = false; diffViewer.InlineView.VisualElement.Focusable = false; // This code path must be invoked on UI thread. AssertIsForeground(); // We use ConfigureAwait(true) to stay on the UI thread. await diffViewer.SizeToFitAsync().ConfigureAwait(true); if (leftWorkspace != null) { leftWorkspace.EnableDiagnostic(); } if (rightWorkspace != null) { rightWorkspace.EnableDiagnostic(); } return new DifferenceViewerPreview(diffViewer); }
private static void ApplyChanges( IProjectionBuffer subjectBuffer, IEnumerable<TextChange> changes, IList<TextSpan> visibleSpansInOriginal, out IEnumerable<int> affectedVisibleSpansInNew) { using (var edit = subjectBuffer.CreateEdit(s_venusEditOptions, reiteratedVersionNumber: null, editTag: null)) { var affectedSpans = SharedPools.Default<HashSet<int>>().AllocateAndClear(); affectedVisibleSpansInNew = affectedSpans; var currentVisibleSpanIndex = 0; foreach (var change in changes) { // Find the next visible span that either overlaps or intersects with while (currentVisibleSpanIndex < visibleSpansInOriginal.Count && visibleSpansInOriginal[currentVisibleSpanIndex].End < change.Span.Start) { currentVisibleSpanIndex++; } // no more place to apply text changes if (currentVisibleSpanIndex >= visibleSpansInOriginal.Count) { break; } var newText = change.NewText; var span = change.Span.ToSpan(); edit.Replace(span, newText); affectedSpans.Add(currentVisibleSpanIndex); } edit.Apply(); } }
private void AdjustIndentation(IProjectionBuffer subjectBuffer, IEnumerable<int> visibleSpanIndex) { if (!visibleSpanIndex.Any()) { return; } var snapshot = subjectBuffer.CurrentSnapshot; var document = _workspace.CurrentSolution.GetDocument(this.Id); if (!document.SupportsSyntaxTree) { return; } var originalText = document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None); Contract.Requires(object.ReferenceEquals(originalText, snapshot.AsText())); var root = document.GetSyntaxRootAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None); var editorOptionsFactory = _componentModel.GetService<IEditorOptionsFactoryService>(); var editorOptions = editorOptionsFactory.GetOptions(_containedLanguage.DataBuffer); var options = _workspace.Options .WithChangedOption(FormattingOptions.UseTabs, root.Language, !editorOptions.IsConvertTabsToSpacesEnabled()) .WithChangedOption(FormattingOptions.TabSize, root.Language, editorOptions.GetTabSize()) .WithChangedOption(FormattingOptions.IndentationSize, root.Language, editorOptions.GetIndentSize()); using (var pooledObject = SharedPools.Default<List<TextSpan>>().GetPooledObject()) { var spans = pooledObject.Object; spans.AddRange(this.GetEditorVisibleSpans()); using (var edit = subjectBuffer.CreateEdit(s_venusEditOptions, reiteratedVersionNumber: null, editTag: null)) { foreach (var spanIndex in visibleSpanIndex) { var rule = GetBaseIndentationRule(root, originalText, spans, spanIndex); var visibleSpan = spans[spanIndex]; AdjustIndentationForSpan(document, edit, visibleSpan, rule, options); } edit.Apply(); } } }
private bool TrySetContext( bool isImmediateWindow) { // Get the workspace, and from there, the solution and document containing this buffer. // If there's an ExternalSource, we won't get a document. Give up in that case. Document document = ContextBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); if (document == null) { _projectionBuffer = null; _debuggerTextView = null; _workspace = null; _immediateWindowContext = null; return false; } var solution = document.Project.Solution; // Get the appropriate ITrackingSpan for the window the user is typing in var viewSnapshot = _textView.TextSnapshot; _immediateWindowContext = null; var debuggerMappedSpan = isImmediateWindow ? CreateImmediateWindowProjectionMapping(document, out _immediateWindowContext) : viewSnapshot.CreateFullTrackingSpan(SpanTrackingMode.EdgeInclusive); // Wrap the original ContextBuffer in a projection buffer that we can make read-only this.ContextBuffer = this.ProjectionBufferFactoryService.CreateProjectionBuffer(null, new object[] { this.ContextBuffer.CurrentSnapshot.CreateFullTrackingSpan(SpanTrackingMode.EdgeInclusive) }, ProjectionBufferOptions.None, _contentType); // Make projection readonly so we can't edit it by mistake. using (var regionEdit = this.ContextBuffer.CreateReadOnlyRegionEdit()) { regionEdit.CreateReadOnlyRegion(new Span(0, this.ContextBuffer.CurrentSnapshot.Length), SpanTrackingMode.EdgeInclusive, EdgeInsertionMode.Deny); regionEdit.Apply(); } // Adjust the context point to ensure that the right information is in scope. // For example, we may need to move the point to the end of the last statement in a method body // in order to be able to access all local variables. var contextPoint = this.ContextBuffer.CurrentSnapshot.GetLineFromLineNumber(CurrentStatementSpan.iEndLine).Start + CurrentStatementSpan.iEndIndex; var adjustedContextPoint = GetAdjustedContextPoint(contextPoint, document); // Get the previous span/text. We might have to insert another newline or something. var previousStatementSpan = GetPreviousStatementBufferAndSpan(adjustedContextPoint, document); // Build the tracking span that includes the rest of the file var restOfFileSpan = ContextBuffer.CurrentSnapshot.CreateTrackingSpanFromIndexToEnd(adjustedContextPoint, SpanTrackingMode.EdgePositive); // Put it all into a projection buffer _projectionBuffer = this.ProjectionBufferFactoryService.CreateProjectionBuffer(null, new object[] { previousStatementSpan, debuggerMappedSpan, this.StatementTerminator, restOfFileSpan }, ProjectionBufferOptions.None, _contentType); // fork the solution using this new primary buffer var forkedSolution = solution.WithDocumentText(document.Id, _projectionBuffer.CurrentSnapshot.AsText(), PreservationMode.PreserveIdentity); // put it into a new workspace _workspace = new DebuggerIntelliSenseWorkspace(forkedSolution); _workspace.OpenDocument(document.Id, _projectionBuffer.AsTextContainer()); // Start getting the compilation so the PartialSolution will be ready when the user starts typing in the window _workspace.CurrentSolution.GetCompilationAsync(document.Project.Id, System.Threading.CancellationToken.None); _textView.TextBuffer.ChangeContentType(_contentType, null); var bufferGraph = _bufferGraphFactoryService.CreateBufferGraph(_projectionBuffer); _debuggerTextView = new DebuggerTextView(_textView, bufferGraph, this.InImmediateWindow); return true; }
private void EndTracking() { if (_textView != null) { ClearHighlight(); if (_projectionBuffer != null) { _projectionBuffer.SourceSpansChanged -= OnSourceSpansChanged; _projectionBuffer = null; } if (_projectionsChanged || _adornmentRemoved) { _projectionsChanged = false; _adornmentRemoved = false; } _textView.TextBuffer.Changed -= OnTextBufferChanged; _textView.TextBuffer.PostChanged -= OnPostChanged; _textView.Caret.PositionChanged -= OnCaretPositionChanged; _textView = null; if (OnClose != null) OnClose(this, EventArgs.Empty); } }
private async Task<object> CreateNewDifferenceViewerAsync( PreviewWorkspace leftWorkspace, PreviewWorkspace rightWorkspace, IProjectionBuffer originalBuffer, IProjectionBuffer changedBuffer, double zoomLevel, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // leftWorkspace can be null if the change is adding a document. // rightWorkspace can be null if the change is removing a document. // However both leftWorkspace and rightWorkspace can't be null at the same time. Contract.ThrowIfTrue((leftWorkspace == null) && (rightWorkspace == null)); var diffBuffer = _differenceBufferService.CreateDifferenceBuffer( originalBuffer, changedBuffer, new StringDifferenceOptions(), disableEditing: true); var diffViewer = _differenceViewerService.CreateDifferenceView(diffBuffer, _previewRoleSet); diffViewer.Closed += (s, e) => { // Workaround Editor bug. The editor has an issue where they sometimes crash when // trying to apply changes to projection buffer. So, when the user actually invokes // a SuggestedAction we may then edit a text buffer, which the editor will then // try to propagate through the projections we have here over that buffer. To ensure // that that doesn't happen, we clear out the projections first so that this crash // won't happen. originalBuffer.DeleteSpans(0, originalBuffer.CurrentSnapshot.SpanCount); changedBuffer.DeleteSpans(0, changedBuffer.CurrentSnapshot.SpanCount); leftWorkspace?.Dispose(); leftWorkspace = null; rightWorkspace?.Dispose(); rightWorkspace = null; }; const string DiffOverviewMarginName = "deltadifferenceViewerOverview"; if (leftWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.RightViewOnly; diffViewer.RightView.ZoomLevel *= zoomLevel; diffViewer.RightHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else if (rightWorkspace == null) { diffViewer.ViewMode = DifferenceViewMode.LeftViewOnly; diffViewer.LeftView.ZoomLevel *= zoomLevel; diffViewer.LeftHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } else { diffViewer.ViewMode = DifferenceViewMode.Inline; diffViewer.InlineView.ZoomLevel *= zoomLevel; diffViewer.InlineHost.GetTextViewMargin(DiffOverviewMarginName).VisualElement.Visibility = Visibility.Collapsed; } // Disable focus / tab stop for the diff viewer. diffViewer.RightView.VisualElement.Focusable = false; diffViewer.LeftView.VisualElement.Focusable = false; diffViewer.InlineView.VisualElement.Focusable = false; // This code path must be invoked on UI thread. AssertIsForeground(); // We use ConfigureAwait(true) to stay on the UI thread. await diffViewer.SizeToFitAsync().ConfigureAwait(true); leftWorkspace?.EnableDiagnostic(); rightWorkspace?.EnableDiagnostic(); return new DifferenceViewerPreview(diffViewer); }
public ProjectionTextViewModel(ITextDataModel dataModel, IProjectionBuffer projectionBuffer) { this._dataModel = dataModel; this._projectionBuffer = projectionBuffer; this._properties = new PropertyCollection(); }