internal XSharpFormattingCommandHandler(IVsTextView textViewAdapter, ITextView textView, IBufferTagAggregatorFactoryService aggregator) { this._textView = textView; this._textView.Closed += OnClosed; this._aggregator = aggregator; //add this to the filter chain _linesToSync = new List <int>(); // _buffer = _textView.TextBuffer; if (_buffer != null) { _buffer.ChangedLowPriority += Textbuffer_Changed; _buffer.Changing += Textbuffer_Changing; _file = _buffer.GetFile(); if (_buffer.CheckEditAccess()) { //formatCaseForWholeBuffer(); } } if (_file != null) { _settings = EditorConfigReader.ReadSettings(_buffer, _file.FullPath); } textViewAdapter.AddCommandFilter(this, out m_nextCommandHandler); registerClassifier(); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == typeof(VSConstants.VSStd97CmdID).GUID && _cmds.Contains(nCmdID)) { ITextBuffer buffer = textView.TextBuffer; if (buffer.CheckEditAccess()) { RemoveTrailingWhitespace(buffer); } } return(NextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == new Guid("1496A755-94DE-11D0-8C3F-00C04FC2AAE2") && nCmdID == (uint)VSConstants.VSStd2KCmdID.DELETEWHITESPACE) { ITextBuffer buffer = textView.TextBuffer; if (buffer.CheckEditAccess()) { RemoveTrailingWhitespace(buffer); return VSConstants.S_OK; } } return NextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == new Guid("1496A755-94DE-11D0-8C3F-00C04FC2AAE2") && nCmdID == 64) { ITextBuffer buffer = _view.TextBuffer; if (buffer.CheckEditAccess()) { RemoveTrailingWhitespace(buffer); return(VSConstants.S_OK); } } return(_nextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == _cmdGgroup && _cmdId.Contains(nCmdID)) { if (!IsEnabled()) { return(_nextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } ITextBuffer buffer = _view.TextBuffer; if (buffer != null && buffer.CheckEditAccess()) { RemoveTrailingWhitespace(buffer); } } return(_nextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
private AsyncCompletionData.CommitBehavior Commit( Document document, CompletionService completionService, ITextView view, ITextBuffer subjectBuffer, RoslynCompletionItem roslynItem, TextSpan completionListSpan, char?commitCharacter, ITextSnapshot triggerSnapshot, CompletionRules rules, string filterText, CancellationToken cancellationToken) { AssertIsForeground(); bool includesCommitCharacter; if (!subjectBuffer.CheckEditAccess()) { // We are on the wrong thread. FatalError.ReportWithoutCrash(new InvalidOperationException("Subject buffer did not provide Edit Access")); return(AsyncCompletionData.CommitBehavior.None); } if (subjectBuffer.EditInProgress) { FatalError.ReportWithoutCrash(new InvalidOperationException("Subject buffer is editing by someone else.")); return(AsyncCompletionData.CommitBehavior.None); } var change = completionService.GetChangeAsync( document, roslynItem, completionListSpan, commitCharacter, cancellationToken).WaitAndGetResult(cancellationToken); var textChange = change.TextChange; var triggerSnapshotSpan = new SnapshotSpan(triggerSnapshot, textChange.Span.ToSpan()); var mappedSpan = triggerSnapshotSpan.TranslateTo(subjectBuffer.CurrentSnapshot, SpanTrackingMode.EdgeInclusive); using (var edit = subjectBuffer.CreateEdit(EditOptions.DefaultMinimalChange, reiteratedVersionNumber: null, editTag: null)) { edit.Replace(mappedSpan.Span, change.TextChange.NewText); // edit.Apply() may trigger changes made by extensions. // updatedCurrentSnapshot will contain changes made by Roslyn but not by other extensions. var updatedCurrentSnapshot = edit.Apply(); if (change.NewPosition.HasValue) { // Roslyn knows how to positionate the caret in the snapshot we just created. // If there were more edits made by extensions, TryMoveCaretToAndEnsureVisible maps the snapshot point to the most recent one. view.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(updatedCurrentSnapshot, change.NewPosition.Value)); } else { // Or, If we're doing a minimal change, then the edit that we make to the // buffer may not make the total text change that places the caret where we // would expect it to go based on the requested change. In this case, // determine where the item should go and set the care manually. // Note: we only want to move the caret if the caret would have been moved // by the edit. i.e. if the caret was actually in the mapped span that // we're replacing. var caretPositionInBuffer = view.GetCaretPoint(subjectBuffer); if (caretPositionInBuffer.HasValue && mappedSpan.IntersectsWith(caretPositionInBuffer.Value)) { view.TryMoveCaretToAndEnsureVisible(new SnapshotPoint(subjectBuffer.CurrentSnapshot, mappedSpan.Start.Position + textChange.NewText.Length)); } else { view.Caret.EnsureVisible(); } } includesCommitCharacter = change.IncludesCommitCharacter; if (roslynItem.Rules.FormatOnCommit) { // The edit updates the snapshot however other extensions may make changes there. // Therefore, it is required to use subjectBuffer.CurrentSnapshot for further calculations rather than the updated current snapsot defined above. document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); var spanToFormat = triggerSnapshotSpan.TranslateTo(subjectBuffer.CurrentSnapshot, SpanTrackingMode.EdgeInclusive); var formattingService = document?.GetLanguageService <IEditorFormattingService>(); if (formattingService != null) { var changes = formattingService.GetFormattingChangesAsync( document, spanToFormat.Span.ToTextSpan(), CancellationToken.None).WaitAndGetResult(CancellationToken.None); document.Project.Solution.Workspace.ApplyTextChanges(document.Id, changes, CancellationToken.None); } } } if (includesCommitCharacter) { return(AsyncCompletionData.CommitBehavior.SuppressFurtherTypeCharCommandHandlers); } if (commitCharacter == '\n' && SendEnterThroughToEditor(rules, roslynItem, filterText)) { return(AsyncCompletionData.CommitBehavior.RaiseFurtherReturnKeyAndTabKeyCommandHandlers); } return(AsyncCompletionData.CommitBehavior.None); }
private static bool ShouldWrapPrelim( bool optionsAutoWrapEnabled, int optionsAvoidWrappingBeforeLine, INormalizedTextChangeCollection changes, ITextSnapshot snapshot, ITextBuffer buffer, CaretPosition caretPosition, out SnapshotPoint caretPoint, out int firstLine) { caretPoint = default(SnapshotPoint); firstLine = -1; if (!optionsAutoWrapEnabled) { return false; } if (!buffer.CheckEditAccess()) { return false; } // The auto-wrap should only apply during simple typing. Region // edits (simultaneous multi-line typing) could lead to truly bizarre // wrapping behavior, so it really doesn't make sense. if (changes.Count > 1) { return false; } // Need a better (more testable!) way to get the editing state // (change, caret, etc.) out. Perhaps we just take the hit and get // all of these up front instead of only calculating them as needed? var change = changes[0]; caretPoint = caretPosition.Point.GetPoint(snapshot, caretPosition.Affinity).GetValueOrDefault(); // If the caret isn't near the change, this was an undo, or other operation // we shouldn't wrap on! if ((caretPoint.Snapshot != snapshot) || (caretPoint < change.NewPosition) || (caretPoint > change.NewEnd)) { return false; } firstLine = snapshot.GetLineNumberFromPosition(change.NewPosition); // If we're in the "don't auto-wrap" leading lines, bail. if (firstLine < optionsAvoidWrappingBeforeLine) { return false; } return true; }
#pragma warning restore 67 /// <summary> /// Gets all the <see cref="ClassificationSpan"/> objects that intersect with the given range of text. /// </summary> /// <remarks> /// This method scans the given SnapshotSpan for potential matches for this classification. /// In this instance, it classifies everything and returns each span as a new ClassificationSpan. /// </remarks> /// <param name="span">The span currently being classified.</param> /// <returns>A list of ClassificationSpans that represent spans identified to be of this classification.</returns> public IList <ClassificationSpan> GetClassificationSpans(SnapshotSpan span) { List <ClassificationSpan> spans = null; if (span.Snapshot.ContentType.DisplayName == "BuildOutput") { spans = new List <ClassificationSpan>(); ITextBuffer textBuf = span.Snapshot.TextBuffer; var text = span.GetText(); int indFNameBegin = text.IndexOf("__cp__."); if (indFNameBegin >= 0) { if (text.IndexOf("__cp__.tracer.cpp") >= 0 || text.IndexOf("warning") >= 0) { if (textBuf.CheckEditAccess()) { ITextEdit te = textBuf.CreateEdit(); te.Delete(span); te.Apply(); } //textBuf.Delete(span); } else if (text.IndexOf(" error ") >= 0) { int indFNameEnd = 0; if ((indFNameEnd = text.IndexOf(' ', indFNameBegin)) < 0) { indFNameEnd = text.Length - 1; } string fName = text.Substring(indFNameBegin, indFNameEnd - indFNameBegin); if (textBuf.CheckEditAccess()) { ITextEdit te = textBuf.CreateEdit(); te.Replace(span, "[ERROR]: Failed to add chartpoints to " + fName + ". Please first check successful build in non [ChartPoints] configuration\n"); te.Apply(); } //textBuf.Replace(span, "[ERROR]: Failed to add chartpoints to " + fName + ". Please first check successful build in non [ChartPoints] configuration\n"); } else { text = text.Replace("__cp__.", "Instrumenting chartpoints for "); if (textBuf.CheckEditAccess()) { ITextEdit te = textBuf.CreateEdit(); te.Replace(span, text); te.Apply(); } //textBuf.Replace(span, text); } } } else { spans = new List <ClassificationSpan>() { new ClassificationSpan(new SnapshotSpan(span.Snapshot, new Span(span.Start, span.Length)), this.classificationType) }; } return(spans); }
private void ApplyPendingChanges() { if (_settings == null || _settings.KeywordCase == KeywordCase.None) { return; } // do not update buffer from background thread if (!_buffer.CheckEditAccess()) { return; } if (_linesToSync.Count > 0) { int[] lines; lock (_linesToSync) { lines = _linesToSync.ToArray(); _linesToSync.Clear(); _linesToSync.Add(this.getCurrentLine()); Array.Sort(lines); } // wait until we can work while (_buffer.EditInProgress) { System.Threading.Thread.Sleep(100); } ThreadHelper.JoinableTaskFactory.Run(async delegate { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var editSession = _buffer.CreateEdit(); var snapshot = editSession.Snapshot; try { var end = DateTime.Now + new TimeSpan(0, 0, 2); int counter = 0; foreach (int nLine in lines) { if (nLine < snapshot.LineCount && nLine >= 0) { ITextSnapshotLine line = snapshot.GetLineFromLineNumber(nLine); FormatLineCase(editSession, line); } // when it takes longer than 2 seconds, then abort if (++counter > 100 && DateTime.Now > end) { break; } } } catch (Exception) { ; } finally { if (editSession.HasEffectiveChanges) { editSession.Apply(); } else { editSession.Cancel(); } } }); } }