internal override void Execute(EmacsCommandContext context) { SnapshotSpan?previousWord = context.TextStructureNavigator.GetPreviousWord(context.TextView); if (!previousWord.HasValue || !previousWord.Value.IntersectsWith(new Span(context.TextView.GetCaretPosition(), 1))) { return; } SnapshotSpan?nextWord = context.TextStructureNavigator.GetNextWord(previousWord.Value.End); if (!nextWord.HasValue) { return; } string text1 = context.TextView.TextSnapshot.GetText(previousWord.Value); string text2 = context.TextView.TextSnapshot.GetText(nextWord.Value); using (ITextEdit edit = context.TextView.TextBuffer.CreateEdit()) { edit.Replace(nextWord.Value, text1); edit.Replace(previousWord.Value, text2); edit.Apply(); } context.TextView.Caret.MoveTo(new SnapshotPoint(context.TextView.TextSnapshot, nextWord.Value.End)); context.TextView.Caret.EnsureVisible(); }
/// <summary> /// Incrementally applies whitespace change to the buffer /// having old and new tokens produced from the 'before formatting' /// and 'after formatting' versions of the same text. /// </summary> /// <param name="textBuffer">Text buffer to apply changes to</param> /// <param name="newTextProvider">Text provider of the text fragment before formatting</param> /// <param name="newTextProvider">Text provider of the formatted text</param> /// <param name="oldTokens">Tokens from the 'before' text fragment</param> /// <param name="newTokens">Tokens from the 'after' text fragment</param> /// <param name="formatRange">Range that is being formatted in the text buffer</param> /// <param name="transactionName">Name of the undo transaction to open</param> /// <param name="selectionTracker">Selection tracker object that will save, track /// <param name="additionalAction">Action to perform after changes are applies by undo unit is not yet closed.</param> /// and restore selection after changes have been applied.</param> public static void ApplyChangeByTokens( ITextBuffer textBuffer, ITextProvider oldTextProvider, ITextProvider newTextProvider, IReadOnlyList <ITextRange> oldTokens, IReadOnlyList <ITextRange> newTokens, ITextRange formatRange, string transactionName, ISelectionTracker selectionTracker, IEditorShell editorShell, Action additionalAction = null) { Debug.Assert(oldTokens.Count == newTokens.Count); if (oldTokens.Count == newTokens.Count) { ITextSnapshot snapshot = textBuffer.CurrentSnapshot; using (CreateSelectionUndo(selectionTracker, editorShell, transactionName)) { using (ITextEdit edit = textBuffer.CreateEdit()) { if (oldTokens.Count > 0) { // Replace whitespace between tokens in reverse so relative positions match int oldEnd = oldTextProvider.Length; int newEnd = newTextProvider.Length; string oldText, newText; for (int i = newTokens.Count - 1; i >= 0; i--) { oldText = oldTextProvider.GetText(TextRange.FromBounds(oldTokens[i].End, oldEnd)); newText = newTextProvider.GetText(TextRange.FromBounds(newTokens[i].End, newEnd)); if (oldText != newText) { edit.Replace(formatRange.Start + oldTokens[i].End, oldEnd - oldTokens[i].End, newText); } oldEnd = oldTokens[i].Start; newEnd = newTokens[i].Start; } newText = newTextProvider.GetText(TextRange.FromBounds(0, newEnd)); edit.Replace(formatRange.Start, oldEnd, newText); } else { string newText = newTextProvider.GetText(TextRange.FromBounds(0, newTextProvider.Length)); edit.Replace(formatRange.Start, formatRange.Length, newText); } edit.Apply(); additionalAction?.Invoke(); } } } }
private static void AlignRows(ITextEdit edit, int start, int end) { var lines = edit.Snapshot.Lines.Where(a => a.LineNumber >= start && a.LineNumber <= end && a.GetText().TrimStart().StartsWith("|") ).ToList(); var lineColumns = lines.Select(a => GetColumns(a.Extent)).ToList(); var maxColumns = lineColumns.Max(a => a.Count); foreach (var line in lines) { var lineText = line.GetText(); var firstPipe = lineText.IndexOf('|'); var existingText = lineText.Substring(0, firstPipe); var wantedText = new string('\t', 2); if (existingText.Equals(wantedText)) { continue; } var span = new Span(line.Start, firstPipe); edit.Replace(span, wantedText); } for (var column = 0; column < maxColumns; column++) { var cols = lineColumns.Where(a => a.Count >= column + 1).ToList(); var maxColLen = cols.Max(a => a[column].Item2.Length); foreach (var col in cols) { var currentText = col[column].Item2; var newText = $" {currentText}{new string(' ', maxColLen - currentText.Length)} "; if (col[column].Item3 != newText) { edit.Replace(col[column].Item1, newText); } } } }
public override bool TransposeLine(int lineNumber) { if ((lineNumber < 0) || (lineNumber > _textBuffer.AdvancedTextBuffer.CurrentSnapshot.LineCount)) { throw new ArgumentOutOfRangeException(nameof(lineNumber)); } ITextSnapshot currentSnapshot = _textBuffer.AdvancedTextBuffer.CurrentSnapshot; // If there is only a single line in this buffer, don't do anything. if (currentSnapshot.LineCount <= 1) { return(true); } ITextSnapshotLine currentLine = currentSnapshot.GetLineFromPosition(CurrentPosition); ITextSnapshotLine nextLine = currentSnapshot.GetLineFromLineNumber(lineNumber); using (ITextEdit edit = _textBuffer.AdvancedTextBuffer.CreateEdit()) { // Make sure that both replaces succeed before applying if ((edit.Replace(currentLine.Extent, nextLine.GetText())) && (edit.Replace(nextLine.Extent, currentLine.GetText()))) { edit.Apply(); if (edit.Canceled) { return(false); } } else { edit.Cancel(); return(false); } } int newLineNumber = nextLine.LineNumber; if (currentLine.LineNumber == currentSnapshot.LineCount - 1) { newLineNumber = currentLine.LineNumber; } MoveTo(_textBuffer.AdvancedTextBuffer.CurrentSnapshot.GetLineFromLineNumber(newLineNumber).Start); return(true); }
public override bool Capitalize() { int startPosition = _startPoint.CurrentPosition; if (IsEmpty) { int endPosition = _endPoint.CurrentPosition; TextRange currentWord = _startPoint.GetCurrentWord(); string nextCharacter = _startPoint.GetNextCharacter(); if (_startPoint.CurrentPosition == currentWord.GetStartPoint().CurrentPosition) { nextCharacter = nextCharacter.ToUpper(CultureInfo.CurrentCulture); } else { nextCharacter = nextCharacter.ToLower(CultureInfo.CurrentCulture); } if (!PrimitivesUtilities.Replace(TextBuffer.AdvancedTextBuffer, new Span(_startPoint.CurrentPosition, nextCharacter.Length), nextCharacter)) { return(false); } _endPoint.MoveTo(endPosition); } else { using (ITextEdit edit = TextBuffer.AdvancedTextBuffer.CreateEdit()) { TextRange currentWord = _startPoint.GetCurrentWord(); // If the current word extends past this range, go to the next word if (currentWord.GetStartPoint().CurrentPosition < _startPoint.CurrentPosition) { currentWord = currentWord.GetEndPoint().GetNextWord(); } while (currentWord.GetStartPoint().CurrentPosition < _endPoint.CurrentPosition) { string wordText = currentWord.GetText(); string startElement = StringInfo.GetNextTextElement(wordText); wordText = startElement.ToUpper(CultureInfo.CurrentCulture) + wordText.Substring(startElement.Length).ToLower(CultureInfo.CurrentCulture); if (!edit.Replace(currentWord.AdvancedTextRange.Span, wordText)) { edit.Cancel(); return(false); } currentWord = currentWord.GetEndPoint().GetNextWord(); } edit.Apply(); if (edit.Canceled) { return(false); } } } _startPoint.MoveTo(startPosition); return(true); }
public override void Invoke(CancellationToken cancellationToken) { var content = Element.GetText(Element.InnerRange).Trim(); int start = Element.Start; int length = content.Length; try { ProjectHelpers.DTE.UndoContext.Open(DisplayText); using (ITextEdit edit = TextBuffer.CreateEdit()) { edit.Replace(Element.OuterRange.ToSpan(), content); edit.Apply(); } SnapshotSpan span = new SnapshotSpan(TextView.TextBuffer.CurrentSnapshot, start, length); TextView.Selection.Select(span, false); ProjectHelpers.DTE.ExecuteCommand("Edit.FormatSelection"); TextView.Caret.MoveTo(new SnapshotPoint(TextView.TextBuffer.CurrentSnapshot, start)); TextView.Selection.Clear(); } finally { ProjectHelpers.DTE.UndoContext.Close(); } }
public bool ApplyChanges(ITextEdit textEdit, FormatLinesResult result) { var lineEnding = DetectLineEnding(textEdit.Snapshot); var sb = new StringBuilder(); var indent = new string(' ', result.Indent); foreach (var line in result.Lines) { if (sb.Length > 0) { sb.Append(lineEnding); } sb.Append(indent); sb.Append(result.CommentType.TextPrefix); sb.Append(line); } var commentText = sb.ToString(); var oldSpan = result.SnapshotSpan.Span; var oldText = textEdit.Snapshot.GetText(oldSpan); if (oldText == commentText) { return(false); } textEdit.Replace(oldSpan, commentText); return(true); }
private void CreateNewCommentLine(ITextChange change) { using (ITextEdit editor = this._view.TextBuffer.CreateEdit()) { try { ITextSnapshotLine line = this._view.TextSnapshot.GetLineFromPosition(change.OldEnd); string lineText = line.GetText(); string nextLine = this._view.TextSnapshot.GetLineFromLineNumber(line.LineNumber + 1).GetText(); if (lineText.Trim().StartsWith("///") && (nextLine.Trim().StartsWith("///") || change.OldEnd != line.End.Position)) { int slashIndex = lineText.IndexOf('/'); //Only add a new comment line if the newline char is after the triple slash //(how Visual Studio in C# works) if ((line.Start.Position + 3 + slashIndex) > change.OldEnd) { return; } string newTabs = lineText.Substring(0, slashIndex); editor.Replace(change.NewSpan, Environment.NewLine + newTabs + "/// "); editor.Apply(); } } catch (Exception) { } } }
/// <summary> /// Builds the comment stub and inserts it into the editor. /// </summary> /// <param name="position">The position of the last slash.</param> private void CreateStub(int position, ITextChange change) { string text = this._view.TextSnapshot.ToString(); using (ITextEdit editor = this._view.TextBuffer.CreateEdit()) { try { this.tabs = StubUtils.GetIndention(position, this._view.TextSnapshot); string summaryTag = generateSummaryTag(); string parameters = getFunctionParameters(position); string returnTag = getReturnTag(position); string autoComment = summaryTag + parameters + returnTag; int lineStart = this._view.TextSnapshot.GetLineFromPosition(position).Start.Position; var caretPosition = autoComment.IndexOf(StubUtils.CaretPlaceholder); Span firstLineSpan = new Span(lineStart, change.NewSpan.End - lineStart); autoComment = autoComment.Replace(StubUtils.CaretPlaceholder, ""); editor.Replace(firstLineSpan, autoComment); ITextSnapshotLine prevLine = this._view.TextSnapshot.GetLineFromPosition(position); StubUtils.MoveCaretAfterChange(this._view, this.editor, lineStart + caretPosition); var after = editor.Apply(); } catch (Exception ex) { Console.WriteLine(errorMsgPrefix + ex.Message); } } }
public void OnCharTyped(char @char) { // format on ':' if (@char == RobotsTxtSyntaxFacts.NameValueDelimiter) { ITextBuffer buffer = _textView.TextBuffer; SyntaxTree syntaxTree = buffer.GetSyntaxTree(); RobotsTxtDocumentSyntax root = syntaxTree.Root as RobotsTxtDocumentSyntax; // find in syntax tree var caret = _textView.Caret.Position.BufferPosition; RobotsTxtLineSyntax lineSyntax = root.Records .SelectMany(r => r.Lines) .FirstOrDefault(p => p.DelimiterToken.Span.Span.End == caret); if (lineSyntax != null) { using (ITextUndoTransaction transaction = _undoHistory.CreateTransaction("Automatic Formatting")) { using (ITextEdit edit = buffer.CreateEdit()) { // fix indent // find property before RobotsTxtLineSyntax before = lineSyntax.Record.Lines .TakeWhile(p => p != lineSyntax) .LastOrDefault(); // reference point if (before != null) { SnapshotPoint referencePoint = before.NameToken.Span.Span.Start; // compare ITextSnapshotLine referenceLine = referencePoint.GetContainingLine(); ITextSnapshotLine line = lineSyntax.DelimiterToken.Span.Span.End.GetContainingLine(); SnapshotSpan referenceIndent = new SnapshotSpan(referenceLine.Start, referencePoint); SnapshotSpan indent = new SnapshotSpan(line.Start, lineSyntax.NameToken.Span.Span.Start); if (indent.GetText() != referenceIndent.GetText()) { edit.Replace(indent, referenceIndent.GetText()); } } // remove white space before ':' if (lineSyntax.NameToken.Span.Span.End != lineSyntax.DelimiterToken.Span.Span.Start) { edit.Delete(new SnapshotSpan(lineSyntax.NameToken.Span.Span.End, lineSyntax.DelimiterToken.Span.Span.Start)); } edit.Apply(); } transaction.Complete(); } } } }
private void FormatLine() { ITextSnapshot snapshot = this.wpfTextView.TextSnapshot; if (snapshot != snapshot.TextBuffer.CurrentSnapshot) { return; } using (ITextEdit edit = this.wpfTextView.TextBuffer.CreateEdit()) { var lineNum = snapshot.GetLineNumberFromPosition(this.wpfTextView.Caret.Position.BufferPosition); if (lineNum > 0) { var line = snapshot.GetLineFromLineNumber(lineNum - 1); if (!edit.Replace(new Span(line.Start, line.End - line.Start), FormatLine(new Tokenizer(), line.GetText()))) { return; } edit.Apply(); } } }
private ITextEdit Fix(RobotsTxtLineSyntax line) { ITextBuffer buffer = line.Record.Document.Snapshot.TextBuffer; string value = line.ValueToken.Value; // fix string newValue = value; // example: * -> / if (value == "*") { newValue = "/"; } // example: /folder/* -> /folder/ else if (value.EndsWith("/*")) { newValue = value.Remove(value.Length - 1); } ITextEdit edit = buffer.CreateEdit(); edit.Replace( line.ValueToken.Span.Span, newValue ); return(edit); }
private void AdjustIndentationForSpan( Document document, ITextEdit edit, TextSpan visibleSpan, IFormattingRule baseIndentationRule, OptionSet options) { var root = document.GetSyntaxRootAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None); using (var rulePool = SharedPools.Default <List <IFormattingRule> >().GetPooledObject()) using (var spanPool = SharedPools.Default <List <TextSpan> >().GetPooledObject()) { var venusFormattingRules = rulePool.Object; var visibleSpans = spanPool.Object; venusFormattingRules.Add(baseIndentationRule); venusFormattingRules.Add(ContainedDocumentPreserveFormattingRule.Instance); var formattingRules = venusFormattingRules.Concat(Formatter.GetDefaultFormattingRules(document)); var workspace = document.Project.Solution.Workspace; var changes = Formatter.GetFormattedTextChanges( root, new TextSpan[] { CommonFormattingHelpers.GetFormattingSpan(root, visibleSpan) }, workspace, options, formattingRules, CancellationToken.None); visibleSpans.Add(visibleSpan); var newChanges = FilterTextChanges(document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None), visibleSpans, changes.ToReadOnlyCollection()).Where(t => visibleSpan.Contains(t.Span)); foreach (var change in newChanges) { edit.Replace(change.Span.ToSpan(), change.NewText); } } }
private void FormatProperty(Property property, int keywordLength, ITextEdit edit) { string originalText = edit.Snapshot.GetText(property.Span); string newText = property.Keyword.Text.PadRight(keywordLength); string spaceBeforeEquals = string.Empty.PadRight(_spaceBeforeEquals); string spaceAfterEquals = string.Empty.PadRight(_spaceAfterEquals); string spaceBeforeColon = string.Empty.PadRight(_spaceBeforeColon); string spaceAfterColon = string.Empty.PadRight(_spaceAfterColon); if (property.Value != null) { newText += $"{spaceBeforeEquals}={spaceAfterEquals}{property.Value.Text}"; } if (property.Severity != null) { newText += $"{spaceBeforeColon}:{spaceAfterColon}{property.Severity.Text}"; } if (originalText != newText) { edit.Replace(property.Span, newText); } }
private async Task <bool> MakePrettierAsync() { string input = _view.TextBuffer.CurrentSnapshot.GetText(); string output = await _node.ExecuteProcessAsync(input, _encoding, _filePath); VirtualSnapshotPoint snapshotPoint = _view.Selection.ActivePoint; if (string.IsNullOrEmpty(output) || input == output) { return(false); } using (ITextEdit edit = _view.TextBuffer.CreateEdit()) using (ITextUndoTransaction undo = _undoManager.TextBufferUndoHistory.CreateTransaction("Make Prettier")) { edit.Replace(0, _view.TextBuffer.CurrentSnapshot.Length, output); edit.Apply(); undo.Complete(); } var newSnapshotPoint = new SnapshotPoint(_view.TextBuffer.CurrentSnapshot, snapshotPoint.Position.Position); _view.Caret.MoveTo(newSnapshotPoint); _view.ViewScroller.EnsureSpanVisible(new SnapshotSpan(newSnapshotPoint, 0)); return(true); }
/// <inheritdoc /> public void Commit() { if (!session.SelectedCompletionSet.SelectionStatus.IsSelected) { return; } ITrackingSpan applicableTo = session.SelectedCompletionSet.ApplicableTo; using (ITextEdit edit = applicableTo.TextBuffer.CreateEdit()) { // The insertion text is inserted without the \xFF character (if any) string insertionText = InsertionText.Replace("\xFF", ""); edit.Replace(applicableTo.GetSpan(edit.Snapshot), insertionText); ITextSnapshot applied = edit.Apply(); // The original position of the \xFF character determines the placement of the caret int caretOffset = InsertionText.IndexOf('\xFF'); if (caretOffset >= 0) { SnapshotPoint startPoint = applicableTo.GetStartPoint(applied); SnapshotPoint caretPoint = startPoint + caretOffset; session.TextView.Caret.MoveTo(caretPoint, PositionAffinity.Predecessor); } } }
public void SuppressError(string errorCode) { if (string.IsNullOrEmpty(errorCode) || _document.Suppressions.Contains(errorCode)) { return; } var range = new Span(0, 0); IEnumerable <string> errorCodes = _document.Suppressions.Union(new[] { errorCode }).OrderBy(c => c); if (_document.Suppressions.Any()) { int position = _document.ParseItems.First().Span.Start; ITextSnapshotLine line = _document.TextBuffer.CurrentSnapshot.GetLineFromPosition(position); range = Span.FromBounds(line.Start, line.EndIncludingLineBreak); } string text = string.Format("# Suppress: {0}", string.Join(" ", errorCodes)) + Environment.NewLine; using (ITextEdit edit = _document.TextBuffer.CreateEdit()) { edit.Replace(range, text); edit.Apply(); } }
public void Edit(Project project) { string str = Path.Combine(ProjectExtensions.GetFullPath(project), "web.config"); if (project.DTE.SourceControl.IsItemUnderSCC(str) && !project.DTE.SourceControl.IsItemCheckedOut(str) && !project.DTE.SourceControl.CheckOutItem(str)) { return; } IEditorInterfaces orOpenDocument = this.VisualStudio.Editor.GetOrOpenDocument(str); Marshal.ThrowExceptionForHR(orOpenDocument.VsTextBuffer.Reload(1)); ITextBuffer textBuffer = orOpenDocument.TextBuffer; using (ITextEdit textEdit = textBuffer.CreateEdit()) { string editedText = this.GetEditedText(textEdit.Snapshot.GetText()); if (editedText != null) { textEdit.Replace(new Span(0, textBuffer.CurrentSnapshot.Length), editedText); textEdit.Apply(); this.VisualStudio.Editor.FormatDocument(str); Document document = project.DTE.Documents.Item(str); document.Save(""); } } }
public override void Invoke(CancellationToken cancellationToken) { string mimeType = FileHelpers.GetMimeTypeFromBase64(Attribute.Value); string extension = FileHelpers.GetExtension(mimeType) ?? "png"; string fileName = FileHelpers.ShowDialog(extension); if (!string.IsNullOrEmpty(fileName) && FileHelpers.SaveDataUriToFile(Attribute.Value, fileName)) { string relative = FileHelpers.RelativePath(TextBuffer.GetFileName(), fileName); try { ProjectHelpers.DTE.UndoContext.Open(DisplayText); using (ITextEdit edit = TextBuffer.CreateEdit()) { edit.Replace(Attribute.ValueRangeUnquoted.ToSpan(), relative.ToLowerInvariant()); edit.Apply(); } } finally { ProjectHelpers.DTE.UndoContext.Close(); } } }
private void CreateNewCommentLine(ITextChange change) { using (ITextEdit editor = this._view.TextBuffer.CreateEdit()) { try { ITextSnapshotLine line = this._view.TextSnapshot.GetLineFromPosition(change.OldEnd); string lineText = line.GetText(); string nextLine = this._view.TextSnapshot.GetLineFromLineNumber(line.LineNumber + 1).GetText(); if (commentLineStart.IsMatch(lineText) && (commentLineStart.IsMatch(nextLine) || change.OldEnd != line.End.Position)) { int asteriskIndex = lineText.IndexOf('*'); //Only add a new comment line if the newline char is after the triple slash //(how Visual Studio in C# works) if ((line.Start.Position + asteriskIndex) > change.OldEnd) { return; } int tabsStopIndex = -1; if (asteriskIndex >= 0 || lineText.Contains("/**")) { // There's no slash, or its open-comment line, so it's a jsdoc comment. We need asteriskIndex here. tabsStopIndex = asteriskIndex; } string newTabs = tabsStopIndex >= 0 ? lineText.Substring(0, tabsStopIndex) : ""; newTabs = newTabs.Replace('/', ' '); editor.Replace(change.NewSpan, Environment.NewLine + newTabs + "* "); editor.Apply(); } } catch (Exception) { } } }
public override void Invoke(CancellationToken cancellationToken) { if (_disabled) { return; } try { var dependencies = Dependencies.FromConfigFile(_provider.ConfigFilePath); IProvider provider = dependencies.GetProvider(_provider.InstallationState.ProviderId); ILibraryCatalog catalog = provider?.GetCatalog(); if (catalog == null) { return; } JSONMember member = _provider.LibraryObject.Children.OfType <JSONMember>().FirstOrDefault(m => m.UnquotedNameText == "id"); if (member != null) { using (ITextEdit edit = TextBuffer.CreateEdit()) { edit.Replace(new Span(member.Value.Start, member.Value.Length), "\"" + _updatedLibraryId + "\""); edit.Apply(); } } } catch (Exception ex) { Logger.LogEvent(ex.ToString(), LogLevel.Error); } }
public static void SortSection(Section section, ITextEdit edit) { Property first = section.Properties.FirstOrDefault(); Property last = section.Properties.LastOrDefault(); if (first == null) { return; } IEnumerable <ITextSnapshotLine> bufferLines = edit.Snapshot.Lines.Where(l => l.Start >= first.Span.Start && l.End <= last.Span.End); IEnumerable <string> lines = bufferLines.Select(b => b.GetText()); IOrderedEnumerable <string> properties = lines.OrderBy(l => l.IndexOf("csharp_") + l.IndexOf("dotnet_")) .ThenBy(p => p); var sb = new StringBuilder(); sb.AppendLine(section.Item.Text); foreach (string property in properties.Where(p => !string.IsNullOrWhiteSpace(p))) { sb.AppendLine(property); } edit.Replace(section.Span, sb.ToString().TrimEnd()); }
private async Task MakeChanges(string root, string fileName) { string text = Element.GetText(Element.InnerRange).Trim(); string reference = GetReference(Element, fileName, root); try { ProjectHelpers.DTE.UndoContext.Open(DisplayText); using (ITextEdit edit = TextBuffer.CreateEdit()) { edit.Replace(new Span(Element.Start, Element.Length), reference); edit.Apply(); } File.WriteAllText(fileName, text); ProjectHelpers.AddFileToActiveProject(fileName); ProjectHelpers.DTE.ItemOperations.OpenFile(fileName); await Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { ProjectHelpers.DTE.ExecuteCommand("Edit.FormatDocument"); }), DispatcherPriority.ApplicationIdle, null); } finally { ProjectHelpers.DTE.UndoContext.Close(); } }
/// Takes current text buffer and new text then builds list of changed /// regions and applies them to the buffer. This way we can avoid /// destruction of bookmarks and other markers. Complete /// buffer replacement deletes all markers which causes /// loss of bookmarks, breakpoints and other similar markers. public static void ApplyChange( ITextBuffer textBuffer, int position, int length, string newText, string transactionName, ISelectionTracker selectionTracker, int maxMilliseconds) { var snapshot = textBuffer.CurrentSnapshot; int oldLength = Math.Min(length, snapshot.Length - position); string oldText = snapshot.GetText(position, oldLength); var changes = TextChanges.BuildChangeList(oldText, newText, maxMilliseconds); if (changes != null && changes.Count > 0) { using (var selectionUndo = new SelectionUndo(selectionTracker, transactionName, automaticTracking: false)) { using (ITextEdit edit = textBuffer.CreateEdit()) { // Replace ranges in reverse so relative positions match for (int i = changes.Count - 1; i >= 0; i--) { TextChange tc = changes[i]; edit.Replace(tc.Position + position, tc.Length, tc.NewText); } edit.Apply(); } } } }
private bool TrimLines() { bool changed = false; using (ITextEdit edit = _document.TextBuffer.CreateEdit()) { foreach (ITextSnapshotLine line in _document.TextBuffer.CurrentSnapshot.Lines) { string originalText = line.GetText(); string newText = line.Extent.IsEmpty ? string.Empty : originalText.Trim(); if (originalText != newText) { edit.Replace(line.Start, line.Length, newText); } } if (edit.HasEffectiveChanges) { changed = true; edit.Apply(); } } return(changed); }
private void UpdateVendorValues(ParseItem item) { Declaration dec = item.FindType <Declaration>(); if (dec != null && Cache.Contains(dec) && !dec.IsVendorSpecific()) { // Find all vendor specifics that isn't the standard property. var matches = Cache.Where(d => d.IsValid && d != dec && d.Parent == dec.Parent && GetStandardName(d) == dec.PropertyName.Text && d.PropertyName.Text != dec.PropertyName.Text); // Undo sometimes messes with the positions, so we have to make this check before proceeding. if (!matches.Any() || dec.Text.Length < dec.Colon.AfterEnd - dec.Start || dec.Colon.AfterEnd < dec.Start) { return; } string text = dec.Text.Substring(dec.Colon.AfterEnd - dec.Start, dec.AfterEnd - dec.Colon.AfterEnd); using (ITextEdit edit = _buffer.CreateEdit()) { foreach (Declaration match in matches.Reverse()) { SnapshotSpan span = new SnapshotSpan(_buffer.CurrentSnapshot, match.Colon.AfterEnd, match.AfterEnd - match.Colon.AfterEnd); if (span.GetText() != text) { edit.Replace(span, text); } } edit.Apply(); } } }
public async override void Invoke(CancellationToken cancellationToken) { ImageCompressor compressor = new ImageCompressor(); bool isDataUri = Attribute.Value.StartsWith("data:image/", StringComparison.Ordinal); if (isDataUri) { string dataUri = await compressor.CompressDataUriAsync(Attribute.Value); if (dataUri.Length < Attribute.Value.Length) { using (WebEssentialsPackage.UndoContext(this.DisplayText)) using (ITextEdit edit = TextBuffer.CreateEdit()) { Span span = Span.FromBounds(Attribute.ValueRangeUnquoted.Start, Attribute.ValueRangeUnquoted.End); edit.Replace(span, dataUri); edit.Apply(); } } } else { var fileName = ImageQuickInfo.GetFullUrl(Attribute.Value, TextBuffer); if (string.IsNullOrEmpty(fileName) || !ImageCompressor.IsFileSupported(fileName) || !File.Exists(fileName)) { return; } await compressor.CompressFilesAsync(fileName); } }
private bool Format(SnapshotSpan span) { if (span.Snapshot.TextBuffer != this.textBuffer || span.IsEmpty || !this.CanFormatSpan(span)) { return(false); } SnapshotPoint startLinePoint = span.Start.GetContainingLine().Start; span = new SnapshotSpan(startLinePoint, span.End); SourceText sourceText = this.core.SourceTextCache.Get(this.textBuffer.CurrentSnapshot); Range range = new Range(span.Start.Position, span.Length); FormattingOptions formattingOptions = this.GetFormattingOptions(this.core.FormattingUserSettings); List <TextEditInfo> edits = this.core.FeatureContainer.Formatter.Format(sourceText, range, formattingOptions); using (ITextEdit textEdit = this.textBuffer.CreateEdit()) { foreach (TextEditInfo edit in edits) { textEdit.Replace(edit.Start, edit.Length, edit.ReplacingWith); } textEdit.Apply(); } return(true); }
/// <summary> /// Undo the text buffer change action. /// </summary> /// <exception cref="InvalidOperationException">Operation cannot be undone.</exception> public override void Undo() { // Validate that we can undo this change if (!CanUndo) { throw new InvalidOperationException(Strings.CannotUndo); } #if DEBUG // sanity check Debug.Assert(TextBuffer.CurrentSnapshot.Length == _bufferLengthAfterChange, "The buffer is in a different state than when this TextBufferUndoChangePrimitive was created!"); #endif // For undo-in-closed-files scenarios where we are done/undone on a buffer other // than the one we were originally created on. if (AttachedToNewBuffer) { AttachedToNewBuffer = false; _beforeVersion = null; _afterVersion = TextBuffer.CurrentSnapshot.Version.VersionNumber; } bool editCanceled = false; using (ITextEdit edit = TextBuffer.CreateEdit(EditOptions.None, _beforeVersion, typeof(TextBufferChangeUndoPrimitive))) { foreach (ITextChange textChange in _textChanges) { if (!edit.Replace(new Span(textChange.NewPosition, textChange.NewLength), textChange.OldText)) { // undo canceled by readonly region editCanceled = true; break; } } if (!editCanceled) { edit.Apply(); if (edit.Canceled) { editCanceled = true; } } } if (editCanceled) { throw new OperationCanceledException("Undo failed due to readonly regions or canceled edit."); } if (_beforeVersion == null) { _beforeVersion = TextBuffer.CurrentSnapshot.Version.VersionNumber; } _canUndo = false; }
public ITextSnapshot Replace(Span replaceSpan, string replaceWith) { using (ITextEdit textEdit = CreateEdit()) { textEdit.Replace(replaceSpan, replaceWith); return(textEdit.Apply()); } }
/// <summary> /// Undoes a replace operation. /// </summary> /// <param name="model">The model.</param> private void UndoReplace(DocumentModel doc, OpReplaceMessage model, ITextEdit edit) { //doc.BlockEvent = true; var span = new Span(model.Index, model.Content.Length); edit.Replace(span, model.OldContent); }
private int SwapItemWithNextSibling(ParseItem item, ITextEdit edit) { RuleSet next = item.NextSibling as RuleSet; if (next == null) return -1; ITextSnapshot snapshot = _textView.TextBuffer.CurrentSnapshot; string whitespace = snapshot.GetText(item.AfterEnd, next.Start - item.AfterEnd); string text = next.Text + whitespace + item.Text; edit.Replace(item.Start, next.AfterEnd - item.Start, text); edit.Apply(); return item.Start + next.Length + whitespace.Length; }
private void AdjustIndentationForSpan( Document document, ITextEdit edit, TextSpan visibleSpan, IFormattingRule baseIndentationRule, OptionSet options) { var root = document.GetSyntaxRootAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None); using (var rulePool = SharedPools.Default<List<IFormattingRule>>().GetPooledObject()) using (var spanPool = SharedPools.Default<List<TextSpan>>().GetPooledObject()) { var venusFormattingRules = rulePool.Object; var visibleSpans = spanPool.Object; venusFormattingRules.Add(baseIndentationRule); venusFormattingRules.Add(ContainedDocumentPreserveFormattingRule.Instance); var formattingRules = venusFormattingRules.Concat(Formatter.GetDefaultFormattingRules(document)); var workspace = document.Project.Solution.Workspace; var changes = Formatter.GetFormattedTextChanges( root, new TextSpan[] { CommonFormattingHelpers.GetFormattingSpan(root, visibleSpan) }, workspace, options, formattingRules, CancellationToken.None); visibleSpans.Add(visibleSpan); var newChanges = FilterTextChanges(document.GetTextAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None), visibleSpans, changes.ToReadOnlyCollection()).Where(t => visibleSpan.Contains(t.Span)); foreach (var change in newChanges) { edit.Replace(change.Span.ToSpan(), change.NewText); } } }
/// <summary> /// Enforce line endings to follow the rules defined in the EditorConfig file. /// </summary> /// <param name="snapshot">The snapshot of the document to enforce.</param> /// <param name="edit">The edit context of the document to enforce.</param> /// <param name="eol">The line ending to enforce.</param> internal void FixLineEndings(ITextSnapshot snapshot, ITextEdit edit, string eol) { if (eol == null) { return; } foreach (ITextSnapshotLine line in snapshot.Lines) { var lineBreak = line.GetLineBreakText(); if (!string.IsNullOrEmpty(lineBreak) && lineBreak != eol) edit.Replace(line.End.Position, line.LineBreakLength, eol); } }
bool IndentLine(ITextEdit ed, ITextSnapshotLine line, string lineString, VirtualSnapshotPoint vpos, bool onlyAddIndentSize, bool isOverwrite) { int virtIndex = vpos.Position - line.Start + vpos.VirtualSpaces; int startIndentIndex = GetFirstWhitespaceIndexForIndentReplace(lineString, virtIndex); int alignedVisualColumn = -1; if (isOverwrite && virtIndex < line.Length) { int visCol = ToVisualColumn(lineString, virtIndex); alignedVisualColumn = GetNextIndentedVisualColumn(visCol); while (ToVisualColumn(lineString, ++virtIndex) < alignedVisualColumn) /* Nothing */; } int endIndentIndex = Math.Min(line.Length, virtIndex); int startIndentVisualColumn = ToVisualColumn(lineString, startIndentIndex); int indentedEndIndentVisualColumn; if (alignedVisualColumn >= 0) indentedEndIndentVisualColumn = alignedVisualColumn; else { int endIndentVisualColumn = ToVisualColumn(lineString, virtIndex); indentedEndIndentVisualColumn = onlyAddIndentSize ? endIndentVisualColumn + Options.GetIndentSize() : GetNextIndentedVisualColumn(endIndentVisualColumn); } var indentString = GetWhitespaceForVirtualSpace(startIndentVisualColumn, indentedEndIndentVisualColumn - startIndentVisualColumn); int b = line.Start.Position; return ed.Replace(Span.FromBounds(b + startIndentIndex, b + endIndentIndex), indentString); }
public bool ApplyChanges(ITextEdit textEdit, FormatLinesResult result) { var lineEnding = DetectLineEnding(textEdit.Snapshot); var sb = new StringBuilder(); var indent = new string(' ', result.Indent); foreach (var line in result.Lines) { if (sb.Length > 0) sb.Append(lineEnding); sb.Append(indent); sb.Append(result.CommentType.TextPrefix); sb.Append(line); } var commentText = sb.ToString(); var oldSpan = result.SnapshotSpan.Span; var oldText = textEdit.Snapshot.GetText(oldSpan); if (oldText == commentText) return false; textEdit.Replace(oldSpan, commentText); return true; }
public TacticReplaceStatus ReplaceSingleTacticCall(ITextEdit tedit) { Contract.Requires(tedit != null); if (!MemberReady || _tacticCall==null) return TacticReplaceStatus.NoTactic; string expanded; var expandedStatus = ExpandSingleTacticCall(_tacticCall.Item1, out expanded); if (expandedStatus != TacticReplaceStatus.Success) return expandedStatus; tedit.Replace(_tacticCall.Item2, _tacticCall.Item3 - _tacticCall.Item2, expanded); return TacticReplaceStatus.Success; }
public void SetText(ITextSnapshotLine line, int startIndex, int length, string newText, ITextEdit edit) { var replaceSpan = new Span(line.Extent.Start.Position + startIndex, length); edit.Replace(replaceSpan, newText); }
/// <summary> /// Performs a replace in a document. /// </summary> /// <param name="model">The model.</param> private void Replace(DocumentModel doc, OpReplaceMessage model, ITextEdit edit) { //doc.BlockEvent = true; var start = model.Index; var length = model.OldContent.Length; if (start > edit.Snapshot.Length - length) { start = edit.Snapshot.Length - length; } if (model.TickStamp == 0) { length = edit.Snapshot.Length; } var span = new Span(start, length); edit.Replace(span, model.Content); }
private void ReplaceLines(ITextEdit edit, int startOldLine, int endOldLine, int startNewLine, int endNewLine) { int oldLineCount = endOldLine - startOldLine; int newLineCount = endNewLine - startNewLine; // replace one line at a time instead of all of the lines at once so that we preserve breakpoints int excessNewLineStart = startNewLine - startOldLine; for (int i = startOldLine; i < endOldLine && i < (endNewLine - startNewLine + startOldLine); i++) { edit.Replace( _snapshot.GetLineFromLineNumber(_startingReplacementLine + i).Extent, _newLines[startNewLine + i - startOldLine] ); excessNewLineStart = startNewLine + i - startOldLine + 1; } if (oldLineCount > newLineCount) { // we end up w/ less lines, we need to delete some text edit.Delete( Span.FromBounds( _snapshot.GetLineFromLineNumber(_startingReplacementLine + endOldLine - (oldLineCount - newLineCount)).Start.Position, _snapshot.GetLineFromLineNumber(_startingReplacementLine + endOldLine - 1).EndIncludingLineBreak.Position ) ); } else if (oldLineCount < newLineCount) { // we end up w/ more lines, we need to insert some text edit.Insert( _snapshot.GetLineFromLineNumber(_startingReplacementLine + endOldLine - 1).EndIncludingLineBreak, string.Join( _view.Options.GetNewLineCharacter(), _newLines, excessNewLineStart, endNewLine - excessNewLineStart ) + _view.Options.GetNewLineCharacter() ); } }
private void ReplaceLines(ITextEdit edit, int startOldLine, int endOldLine, int startNewLine, int endNewLine) { edit.Replace( Span.FromBounds( _snapshot.GetLineFromLineNumber(_startingReplacementLine + startOldLine).Start.Position, _snapshot.GetLineFromLineNumber(_startingReplacementLine + endOldLine - 1).End.Position ), string.Join( _view.Options.GetNewLineCharacter(), _newLines, startNewLine, endNewLine - startNewLine ) ); }