public void Execute(bool up) { IWpfTextView textView = GetTextView(); ITextSnapshot snapshot = textView.TextSnapshot; if (snapshot != snapshot.TextBuffer.CurrentSnapshot) { return; } string sourceText = ""; int selectionLastLineNumber = 0; int selectionFirstLineNumber = 0; int selectionStartLineOffset = 0; int selectionLength = 0; int caretLineOffset = 0; bool noInitialSelection = false; bool caretAtTheEndOfSelection = true; int caretPos = textView.GetCaretPosition(); caretLineOffset = caretPos - textView.GetCaretLine().Start.Position; if (!textView.Selection.IsEmpty) { caretAtTheEndOfSelection = (textView.Selection.Start.Position != caretPos); if (textView.Selection.Start.Position < textView.Selection.End.Position) { selectionStartLineOffset = textView.Selection.Start.Position - textView.Selection.Start.Position.GetContainingLine().Start.Position; selectionLength = textView.Selection.End.Position - textView.Selection.Start.Position; } else { selectionStartLineOffset = textView.Selection.End.Position - textView.Selection.Start.Position.GetContainingLine().End.Position; selectionLength = textView.Selection.Start.Position - textView.Selection.End.Position; } selectionLastLineNumber = textView.Selection.End.Position.GetContainingLine().LineNumber; selectionFirstLineNumber = textView.Selection.Start.Position.GetContainingLine().LineNumber; var builder = new StringBuilder(); for (int i = selectionFirstLineNumber; i <= selectionLastLineNumber; i++) { builder.AppendLine(snapshot.GetLineFromLineNumber(i).GetText()); } sourceText = builder.ToString(); textView.Selection.Clear(); } else { noInitialSelection = true; selectionLength = selectionStartLineOffset = 0; selectionFirstLineNumber = selectionLastLineNumber = textView.GetCaretLine().End.GetContainingLine().LineNumber; sourceText = textView.Caret.ContainingTextViewLine.ExtentIncludingLineBreak.GetText(); } int insertionPosition; //int finalCaretPosition; using (ITextEdit edit = textView.TextBuffer.CreateEdit()) { int lineCount = selectionLastLineNumber - selectionFirstLineNumber + 1; try { for (int i = selectionLastLineNumber; i >= selectionFirstLineNumber; i--) { var line = edit.Snapshot.GetLineFromLineNumber(i); edit.Delete(new Span(line.Start.Position, line.LengthIncludingLineBreak)); } } catch { } if (up) { if (selectionFirstLineNumber == 0) { insertionPosition = 0; } else { insertionPosition = edit.Snapshot.GetLineFromLineNumber(selectionFirstLineNumber - 1).Start.Position; } } else { insertionPosition = edit.Snapshot.GetLineFromLineNumber(selectionFirstLineNumber + lineCount).ExtentIncludingLineBreak.End.Position; } edit.Insert(insertionPosition, sourceText); edit.Apply(); } int selectionStartUp = (noInitialSelection ? insertionPosition + caretLineOffset : insertionPosition + selectionStartLineOffset); int selectionStartDown = (noInitialSelection ? insertionPosition - sourceText.Length + caretLineOffset : (insertionPosition - sourceText.Length) + selectionStartLineOffset); int selectionStart = (up ? selectionStartUp : selectionStartDown); textView.SetSelection(selectionStart, selectionLength); if (caretAtTheEndOfSelection) { textView.MoveCaretTo(selectionStart + selectionLength); } else { textView.MoveCaretTo(selectionStart); } int caretLineNumber = textView.GetLineFromPosition(textView.GetCaretPosition()).LineNumber; if (up) { if ((caretLineNumber - textView.VisualSnapshot.Lines.First().LineNumber) < 5) { textView.ViewScroller.ScrollViewportVerticallyByLine(ScrollDirection.Up); } } else { if ((textView.VisualSnapshot.Lines.Last().LineNumber - caretLineNumber) < 5) { textView.ViewScroller.ScrollViewportVerticallyByLine(ScrollDirection.Down); } } if (textView.IsCaretClosToHorizontalEdge(up)) { textView.ViewScroller.ScrollViewportVerticallyByLines(up ? ScrollDirection.Up : ScrollDirection.Down, 1); } }
public void Execute() { IWpfTextView textView = txtMgr.GetTextView(); ITextSnapshot snapshot = textView.TextSnapshot; if (snapshot != snapshot.TextBuffer.CurrentSnapshot) { return; } Extensions.RefreshCommentForCurrentDocument(); if (!textView.Selection.IsEmpty) { int areaStart = textView.Selection.Start.Position.GetContainingLine().Start.Position; int areaEnd = textView.Selection.End.Position.GetContainingLine().End.Position; if (textView.Selection.Start > textView.Selection.End) { Extensions.Swap(ref areaStart, ref areaEnd); } string text = textView.TextBuffer.CurrentSnapshot.GetText(areaStart, areaEnd - areaStart); var textLines = text.Replace(Environment.NewLine, "\n").Split('\n') .Select(x => new { Text = x, IsCommented = x.TrimStart().StartsWith(Extensions.commentPreffix), TextStart = x.IndexOfNonWhitespace(), IsEmpty = (x == "") }); bool doComment = textLines.Any(x => !x.IsCommented && !x.IsEmpty); int indent = textLines.Where(x => !x.IsEmpty).Min(x => x.TextStart); string[] replacementLines = textLines.Select(x => { if (x.IsEmpty) { return(x.Text); } else { return(x.Text.CommentText(indent, doComment)); } }).ToArray(); string replacementText = string.Join(Environment.NewLine, replacementLines); using (ITextEdit edit = textView.TextBuffer.CreateEdit()) { edit.Replace(new Span(areaStart, areaEnd - areaStart), replacementText); edit.Apply(); } textView.Selection.Clear(); textView.SetSelection(areaStart, replacementText.Length); } else { int lineNum = textView.Caret.ContainingTextViewLine.End.GetContainingLine().LineNumber; var line = textView.GetLine(lineNum); int caretLineOffset = textView.GetCaretPosition() - textView.Caret.ContainingTextViewLine.Start.Position; using (ITextEdit edit = textView.TextBuffer.CreateEdit()) { string lineText = line.GetText(); bool doComment = !lineText.IsCommented(); int indent = lineText.IndexOfNonWhitespace(); if (caretLineOffset > indent) { if (doComment) { caretLineOffset += Extensions.commentPreffix.Length; } else { caretLineOffset -= Extensions.commentPreffix.Length; } } string text = line.GetTextIncludingLineBreak().CommentText(indent, doComment); edit.Replace(new Span(line.Start.Position, line.LengthIncludingLineBreak), text); edit.Apply(); } textView.MoveCaretTo(line.Start.Position + caretLineOffset); } }
public void Execute(bool commentOriginal = false) { IWpfTextView textView = txtMgr.GetTextView(); ITextSnapshot snapshot = textView.TextSnapshot; if (snapshot != snapshot.TextBuffer.CurrentSnapshot) { return; } Extensions.RefreshCommentForCurrentDocument(); if (!textView.Selection.IsEmpty) { var selectionStart = textView.Selection.Start; var selectionEnd = textView.Selection.End; if (textView.Selection.Start > textView.Selection.End) { Extensions.Swap(ref selectionStart, ref selectionEnd); } var selectionStartLine = selectionStart.Position.GetContainingLine(); var selectionEndLine = selectionEnd.Position.GetContainingLine(); var blockTextStart = selectionStartLine.Start.Position; string blockText = textView.TextBuffer.CurrentSnapshot.GetText(selectionStartLine.Start.Position, selectionEndLine.End.Position - selectionStartLine.Start.Position); string selectedText = textView.TextBuffer.CurrentSnapshot.GetText(selectionStart.Position, selectionEnd.Position - selectionStart.Position); var caretPositionWithinBlock = textView.GetCaretPosition() - selectionStartLine.Start.Position; var nonSelectedTextLeftOffset = selectionStart.Position - selectionStartLine.Start.Position; string textOffset = new string(' ', nonSelectedTextLeftOffset); string duplicatedText = textOffset + selectedText; string replacementText; if (commentOriginal) { var commentedText = blockText.Comment(); replacementText = commentedText + Environment.NewLine + duplicatedText; } else { replacementText = blockText + Environment.NewLine + duplicatedText; } using (ITextEdit edit = textView.TextBuffer.CreateEdit()) { edit.Replace(new Span(blockTextStart, blockText.Length), replacementText); edit.Apply(); } var firstDuplicatedTextLine = textView.GetLine(selectionEndLine.LineNumber + 1); int newSelectionStart = firstDuplicatedTextLine.Start.Position + nonSelectedTextLeftOffset; int newSelectionLength = Math.Min(selectedText.Length, textView.GetText().Length - newSelectionStart); textView.Selection.Clear(); textView.SetSelection(newSelectionStart, newSelectionLength); textView.MoveCaretTo(firstDuplicatedTextLine.Start.Position + caretPositionWithinBlock); } else { int selectionLastLineNumber = textView.Caret.ContainingTextViewLine.End.GetContainingLine().LineNumber; int caretLineOffset = textView.GetCaretPosition() - textView.Caret.ContainingTextViewLine.Start.Position; int areaStart = textView.Caret.ContainingTextViewLine.Start.Position; int areaEnd = textView.Caret.ContainingTextViewLine.End.Position; string text = textView.TextBuffer.CurrentSnapshot.GetText(areaStart, areaEnd - areaStart); string replacementText; if (commentOriginal) { replacementText = text.CommentText(text.IndexOfNonWhitespace(), true) + Environment.NewLine + text; } else { replacementText = text + Environment.NewLine + text; } using (ITextEdit edit = textView.TextBuffer.CreateEdit()) { edit.Replace(new Span(areaStart, text.Length), replacementText); edit.Apply(); } var line = textView.GetLine(selectionLastLineNumber + 1); textView.MoveCaretTo(line.Start.Position + caretLineOffset); return; } }