/// <summary> /// Selects the word around the current cursor position. /// </summary> /// <param name="controller">The controller.</param> public static void SelectWord(EditorViewController controller) { // Pull out information about the current context. IDisplayContext displayContext = controller.DisplayContext; LineBuffer buffer = displayContext.LineBuffer; TextPosition position = displayContext.Caret.Position; int lineIndex = position.LinePosition.GetLineIndex(buffer); string lineText = buffer.GetLineText(lineIndex); int characterIndex = position.GetCharacterIndex(buffer); // Find the boundaries for the current word. int startIndex = Math.Max( 0, displayContext.WordTokenizer.GetPreviousWordBoundary( lineText, characterIndex)); int endIndex = Math.Min( lineText.Length, displayContext.WordTokenizer.GetNextWordBoundary(lineText, characterIndex)); // Set the selection to the boundaries. displayContext.Caret.Selection = new TextRange( new TextPosition(position.LinePosition, startIndex), new TextPosition(position.LinePosition, endIndex)); }
/// <summary> /// Gets the wrapped line associated with this buffer position. /// </summary> /// <param name="bufferPosition">The buffer position.</param> /// <param name="displayContext">The display context.</param> /// <param name="layout">The layout.</param> /// <param name="wrappedLineIndex">Index of the wrapped line.</param> /// <returns></returns> public static LayoutLine GetWrappedLine( this TextPosition bufferPosition, IDisplayContext displayContext, out Layout layout, out int wrappedLineIndex) { // Get the layout and text associated with the line. LineBuffer lineBuffer = displayContext.LineBuffer; int lineIndex = bufferPosition.LinePosition.GetLineIndex(lineBuffer); string text = lineBuffer.GetLineText(lineIndex); layout = displayContext.Renderer.GetLineLayout( lineIndex, LineContexts.Unformatted); // Get the wrapped line associated with this character position. int characterIndex = bufferPosition.GetCharacterIndex(lineBuffer); int unicodeIndex = PangoUtility.TranslateStringToPangoIndex( text, characterIndex); int x; layout.IndexToLineX(unicodeIndex, false, out wrappedLineIndex, out x); // Return the resulting line. return(layout.Lines[wrappedLineIndex]); }
/// <summary> /// Gets the line X coordinates from either the state if we have one /// or calculate it from the buffer position's X coordinate. /// </summary> /// <param name="controller">The action context.</param> /// <param name="wrappedLine">The wrapped line.</param> /// <param name="position">The position.</param> /// <returns></returns> private static int GetLineX( EditorViewController controller, LayoutLine wrappedLine, TextPosition position) { int lineX; var state = controller.States.Get <VerticalMovementActionState>(); if (state == null) { // Calculate the line state from the caret position. The cursor // is always to the left of the character unless we're at the // end, and then it's considered trailing of the previous // character. LineBuffer lineBuffer = controller.DisplayContext.LineBuffer; int lineIndex = position.LinePosition.GetLineIndex(lineBuffer.LineCount); string lineText = lineBuffer.GetLineText(lineIndex); int characterIndex = position.CharacterPosition.GetCharacterIndex(lineText); bool trailing = false; if (characterIndex == lineText.Length && lineText.Length > 0) { characterIndex--; trailing = true; } // Because Pango works with UTF-8-based indexes, we need to // convert the C# character index into that index to properly // identify the character. characterIndex = NormalizeEmptyStrings(lineText, characterIndex); int unicodeIndex = PangoUtility.TranslateStringToPangoIndex( lineText, characterIndex); lineX = wrappedLine.IndexToX(unicodeIndex, trailing); // We need the line's style since it may have left passing // which will change our columns. LineBlockStyle style = controller.DisplayContext.Renderer.GetLineStyle( lineIndex, LineContexts.CurrentLine); var pixelPadding = (int)style.Padding.Left.GetValueOrDefault(0); lineX += Units.FromPixels(pixelPadding); // Save a new state into the states. state = new VerticalMovementActionState(lineX); controller.States.Add(state); } else { // Get the line coordinate from the state. lineX = state.LayoutLineX; } return(lineX); }
public static int GetCharacterIndex( this TextPosition textPosition, LineBuffer lineBuffer) { string lineText = lineBuffer.GetLineText(textPosition.LinePosition); int characterPosition = textPosition.CharacterPosition.GetCharacterIndex(lineText); return(characterPosition); }
public static void RightWord(EditorViewController controller) { // Pull out some useful variables. IDisplayContext displayContext = controller.DisplayContext; LineBuffer buffer = displayContext.LineBuffer; LineBuffer lineBuffer = displayContext.LineBuffer; // Pull out the line and chracter positions from where we're starting. TextPosition position = displayContext.Caret.Position; LinePosition linePosition = position.LinePosition; int lineIndex = linePosition.GetLineIndex(buffer); string lineText = buffer.GetLineText(lineIndex); CharacterPosition wordPosition = CharacterPosition.Word; CharacterPosition characterPosition = position.CharacterPosition; int characterIndex = characterPosition.GetCharacterIndex(lineText); // If we are at the beginning of the line, we need to move to the // previous line. if (characterIndex == lineText.Length) { // If we are at the last line, we don't do anything. if (lineIndex == lineBuffer.LineCount - 1) { return; } // Move to the end of the previous line. linePosition = new LinePosition(lineIndex + 1); characterPosition = CharacterPosition.Begin; } else { // Move to the previous left word. int rightCharacterIndex = wordPosition.GetCharacterIndex( lineText, characterPosition, WordSearchDirection.Right); characterPosition = new CharacterPosition(rightCharacterIndex); } // Cause the text editor to redraw itself. var caretPosition = new TextPosition(linePosition, characterPosition); displayContext.ScrollToCaret(caretPosition); }
public static void Copy(EditorViewController controller) { // If we don't have anything selected, we don't do anything. IDisplayContext displayContext = controller.DisplayContext; TextRange selection = displayContext.Caret.Selection; if (selection.IsEmpty) { return; } // Go through the selection and figure out if we have a single-line // copy. LineBuffer lineBuffer = displayContext.LineBuffer; int startLineIndex = selection.FirstLinePosition.GetLineIndex(lineBuffer); int endLineIndex = selection.LastLinePosition.GetLineIndex(lineBuffer); string firstLine = lineBuffer.GetLineText( selection.FirstLinePosition, LineContexts.Unformatted); if (endLineIndex == startLineIndex) { // Single-line copy is much easier since we just need a substring. int startCharacterIndex = selection.FirstTextPosition.GetCharacterIndex(lineBuffer); int endCharacterIndex = selection.FirstTextPosition.GetCharacterIndex(lineBuffer); string singleLineText = firstLine.Substring( startCharacterIndex, endCharacterIndex - startCharacterIndex); // Set the clipboard's text and return. displayContext.Clipboard.Text = singleLineText; return; } // For multiple line copies, we need to copy every line from the first // to the last. We already have the first, so just copy that. var buffer = new StringBuilder(); int firstLineIndex = selection.FirstTextPosition.CharacterPosition.GetCharacterIndex(firstLine); buffer.Append(firstLine.Substring(firstLineIndex)); buffer.Append("\n"); // Loop through the second to just shy of the last line, adding // each one as a full line. for (int lineIndex = startLineIndex + 1; lineIndex < endLineIndex; lineIndex++) { buffer.Append(lineBuffer.GetLineText(lineIndex, LineContexts.Unformatted)); buffer.Append("\n"); } // Add the last line, which is a substring, but we don't add a // newline to the end of this one. string lastLineText = lineBuffer.GetLineText( endLineIndex, LineContexts.Unformatted); int lastCharacterIndex = selection.EndCharacterPosition.GetCharacterIndex(lastLineText); buffer.Append(lastLineText.Substring(0, lastCharacterIndex)); // Set the clipboard value. displayContext.Clipboard.Text = buffer.ToString(); }