aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Editing/CaretNavigationCommandHandler.cs
blob: d1b812b66227aaa1e13bc857d37a1e03189b664d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/* Generated by the protocol buffer compiler.  DO NOT EDIT! */
/* Generated from: KillProcessRequest.proto */

/* Do not generate deprecated warnings for self */
#ifndef PROTOBUF_C__NO_DEPRECATED
#define PROTOBUF_C__NO_DEPRECATED
#endif

#include "KillProcessRequest.pb-c.h"
void   kill_process_request__init
                     (KillProcessRequest         *message)
{
  static const KillProcessRequest init_value = KILL_PROCESS_REQUEST__INIT;
  *message = init_value;
}
size_t kill_process_request__get_packed_size
                     (const KillProcessRequest *message)
{
  assert(message->base.descriptor == &kill_process_request__descriptor);
  return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
}
size_t kill_process_request__pack
                     (const KillProcessRequest *message,
                      uint8_t       *out)
{
  assert(message->base.descriptor == &kill_process_request__descriptor);
  return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
}
size_t kill_process_request__pack_to_buffer
                     (const KillProcessRequest
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.TextFormatting;
using Tango.Scripting.Editors.Document;
using Tango.Scripting.Editors.Rendering;
using Tango.Scripting.Editors.Utils;

namespace Tango.Scripting.Editors.Editing
{
	static class CaretNavigationCommandHandler
	{
		/// <summary>
		/// Creates a new <see cref="TextAreaInputHandler"/> for the text area.
		/// </summary>
		public static TextAreaInputHandler Create(TextArea textArea)
		{
			TextAreaInputHandler handler = new TextAreaInputHandler(textArea);
			handler.CommandBindings.AddRange(CommandBindings);
			handler.InputBindings.AddRange(InputBindings);
			return handler;
		}
		
		static readonly List<CommandBinding>
="o">>(); static readonly List<InputBinding> InputBindings = new List<InputBinding>(); static void AddBinding(ICommand command, ModifierKeys modifiers, Key key, ExecutedRoutedEventHandler handler) { CommandBindings.Add(new CommandBinding(command, handler)); InputBindings.Add(TextAreaDefaultInputHandler.CreateFrozenKeyBinding(command, modifiers, key)); } static CaretNavigationCommandHandler() { const ModifierKeys None = ModifierKeys.None; const ModifierKeys Ctrl = ModifierKeys.Control; const ModifierKeys Shift = ModifierKeys.Shift; const ModifierKeys Alt = ModifierKeys.Alt; AddBinding(EditingCommands.MoveLeftByCharacter, None, Key.Left, OnMoveCaret(CaretMovementType.CharLeft)); AddBinding(EditingCommands.SelectLeftByCharacter, Shift, Key.Left, OnMoveCaretExtendSelection(CaretMovementType.CharLeft)); AddBinding(RectangleSelection.BoxSelectLeftByCharacter, Alt | Shift, Key.Left, OnMoveCaretBoxSelection(CaretMovementType.CharLeft)); AddBinding(EditingCommands.MoveRightByCharacter, None, Key.Right, OnMoveCaret(CaretMovementType.CharRight)); AddBinding(EditingCommands.SelectRightByCharacter, Shift, Key.Right, OnMoveCaretExtendSelection(CaretMovementType.CharRight)); AddBinding(RectangleSelection.BoxSelectRightByCharacter, Alt | Shift, Key.Right, OnMoveCaretBoxSelection(CaretMovementType.CharRight)); AddBinding(EditingCommands.MoveLeftByWord, Ctrl, Key.Left, OnMoveCaret(CaretMovementType.WordLeft)); AddBinding(EditingCommands.SelectLeftByWord, Ctrl | Shift, Key.Left, OnMoveCaretExtendSelection(CaretMovementType.WordLeft)); AddBinding(RectangleSelection.BoxSelectLeftByWord, Ctrl | Alt | Shift, Key.Left, OnMoveCaretBoxSelection(CaretMovementType.WordLeft)); AddBinding(EditingCommands.MoveRightByWord, Ctrl, Key.Right, OnMoveCaret(CaretMovementType.WordRight)); AddBinding(EditingCommands.SelectRightByWord, Ctrl | Shift, Key.Right, OnMoveCaretExtendSelection(CaretMovementType.WordRight)); AddBinding(RectangleSelection.BoxSelectRightByWord, Ctrl | Alt | Shift, Key.Right, OnMoveCaretBoxSelection(CaretMovementType.WordRight)); AddBinding(EditingCommands.MoveUpByLine, None, Key.Up, OnMoveCaret(CaretMovementType.LineUp)); AddBinding(EditingCommands.SelectUpByLine, Shift, Key.Up, OnMoveCaretExtendSelection(CaretMovementType.LineUp)); AddBinding(RectangleSelection.BoxSelectUpByLine, Alt | Shift, Key.Up, OnMoveCaretBoxSelection(CaretMovementType.LineUp)); AddBinding(EditingCommands.MoveDownByLine, None, Key.Down, OnMoveCaret(CaretMovementType.LineDown)); AddBinding(EditingCommands.SelectDownByLine, Shift, Key.Down, OnMoveCaretExtendSelection(CaretMovementType.LineDown)); AddBinding(RectangleSelection.BoxSelectDownByLine, Alt | Shift, Key.Down, OnMoveCaretBoxSelection(CaretMovementType.LineDown)); AddBinding(EditingCommands.MoveDownByPage, None, Key.PageDown, OnMoveCaret(CaretMovementType.PageDown)); AddBinding(EditingCommands.SelectDownByPage, Shift, Key.PageDown, OnMoveCaretExtendSelection(CaretMovementType.PageDown)); AddBinding(EditingCommands.MoveUpByPage, None, Key.PageUp, OnMoveCaret(CaretMovementType.PageUp)); AddBinding(EditingCommands.SelectUpByPage, Shift, Key.PageUp, OnMoveCaretExtendSelection(CaretMovementType.PageUp)); AddBinding(EditingCommands.MoveToLineStart, None, Key.Home, OnMoveCaret(CaretMovementType.LineStart)); AddBinding(EditingCommands.SelectToLineStart, Shift, Key.Home, OnMoveCaretExtendSelection(CaretMovementType.LineStart)); AddBinding(RectangleSelection.BoxSelectToLineStart, Alt | Shift, Key.Home, OnMoveCaretBoxSelection(CaretMovementType.LineStart)); AddBinding(EditingCommands.MoveToLineEnd, None, Key.End, OnMoveCaret(CaretMovementType.LineEnd)); AddBinding(EditingCommands.SelectToLineEnd, Shift, Key.End, OnMoveCaretExtendSelection(CaretMovementType.LineEnd)); AddBinding(RectangleSelection.BoxSelectToLineEnd, Alt | Shift, Key.End, OnMoveCaretBoxSelection(CaretMovementType.LineEnd)); AddBinding(EditingCommands.MoveToDocumentStart, Ctrl, Key.Home, OnMoveCaret(CaretMovementType.DocumentStart)); AddBinding(EditingCommands.SelectToDocumentStart, Ctrl | Shift, Key.Home, OnMoveCaretExtendSelection(CaretMovementType.DocumentStart)); AddBinding(EditingCommands.MoveToDocumentEnd, Ctrl, Key.End, OnMoveCaret(CaretMovementType.DocumentEnd)); AddBinding(EditingCommands.SelectToDocumentEnd, Ctrl | Shift, Key.End, OnMoveCaretExtendSelection(CaretMovementType.DocumentEnd)); CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, OnSelectAll)); TextAreaDefaultInputHandler.WorkaroundWPFMemoryLeak(InputBindings); } static void OnSelectAll(object target, ExecutedRoutedEventArgs args) { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { args.Handled = true; textArea.Caret.Offset = textArea.Document.TextLength; textArea.Selection = SimpleSelection.Create(textArea, 0, textArea.Document.TextLength); } } static TextArea GetTextArea(object target) { return target as TextArea; } enum CaretMovementType { CharLeft, CharRight, WordLeft, WordRight, LineUp, LineDown, PageUp, PageDown, LineStart, LineEnd, DocumentStart, DocumentEnd } static ExecutedRoutedEventHandler OnMoveCaret(CaretMovementType direction) { return (target, args) => { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { args.Handled = true; textArea.ClearSelection(); MoveCaret(textArea, direction); textArea.Caret.BringCaretToView(); } }; } static ExecutedRoutedEventHandler OnMoveCaretExtendSelection(CaretMovementType direction) { return (target, args) => { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { args.Handled = true; TextViewPosition oldPosition = textArea.Caret.Position; MoveCaret(textArea, direction); textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position); if (!textArea.Document.IsInUpdate) // if we're inside a larger update (e.g. called by EditingCommandHandler.OnDelete()), avoid calculating the caret rectangle now textArea.Caret.BringCaretToView(); } }; } static ExecutedRoutedEventHandler OnMoveCaretBoxSelection(CaretMovementType direction) { return (target, args) => { TextArea textArea = GetTextArea(target); if (textArea != null && textArea.Document != null) { args.Handled = true; // First, convert the selection into a rectangle selection // (this is required so that virtual space gets enabled for the caret movement) if (textArea.Options.EnableRectangularSelection && !(textArea.Selection is RectangleSelection)) { if (textArea.Selection.IsEmpty) { textArea.Selection = new RectangleSelection(textArea, textArea.Caret.Position, textArea.Caret.Position); } else { // Convert normal selection to rectangle selection textArea.Selection = new RectangleSelection(textArea, textArea.Selection.StartPosition, textArea.Caret.Position); } } // Now move the caret and extend the selection TextViewPosition oldPosition = textArea.Caret.Position; MoveCaret(textArea, direction); textArea.Selection = textArea.Selection.StartSelectionOrSetEndpoint(oldPosition, textArea.Caret.Position); textArea.Caret.BringCaretToView(); } }; } #region Caret movement static void MoveCaret(TextArea textArea, CaretMovementType direction) { DocumentLine caretLine = textArea.Document.GetLineByNumber(textArea.Caret.Line); VisualLine visualLine = textArea.TextView.GetOrConstructVisualLine(caretLine); TextViewPosition caretPosition = textArea.Caret.Position; TextLine textLine = visualLine.GetTextLine(caretPosition.VisualColumn); switch (direction) { case CaretMovementType.CharLeft: MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.Normal); break; case CaretMovementType.CharRight: MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.Normal); break; case CaretMovementType.WordLeft: MoveCaretLeft(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart); break; case CaretMovementType.WordRight: MoveCaretRight(textArea, caretPosition, visualLine, CaretPositioningMode.WordStart); break; case CaretMovementType.LineUp: case CaretMovementType.LineDown: case CaretMovementType.PageUp: case CaretMovementType.PageDown: MoveCaretUpDown(textArea, direction, visualLine, textLine, caretPosition.VisualColumn); break; case CaretMovementType.DocumentStart: SetCaretPosition(textArea, 0, 0); break; case CaretMovementType.DocumentEnd: SetCaretPosition(textArea, -1, textArea.Document.TextLength); break; case CaretMovementType.LineStart: MoveCaretToStartOfLine(textArea, visualLine); break; case CaretMovementType.LineEnd: MoveCaretToEndOfLine(textArea, visualLine); break; default: throw new NotSupportedException(direction.ToString()); } } #endregion #region Home/End static void MoveCaretToStartOfLine(TextArea textArea, VisualLine visualLine) { int newVC = visualLine.GetNextCaretPosition(-1, LogicalDirection.Forward, CaretPositioningMode.WordStart, textArea.Selection.EnableVirtualSpace); if (newVC < 0) throw ThrowUtil.NoValidCaretPosition(); // when the caret is already at the start of the text, jump to start before whitespace if (newVC == textArea.Caret.VisualColumn) newVC = 0; int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC); SetCaretPosition(textArea, newVC, offset); } static void MoveCaretToEndOfLine(TextArea textArea, VisualLine visualLine) { int newVC = visualLine.VisualLength; int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC); SetCaretPosition(textArea, newVC, offset); } #endregion #region By-character / By-word movement static void MoveCaretRight(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode) { int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace); if (pos >= 0) { SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset); } else { // move to start of next line DocumentLine nextDocumentLine = visualLine.LastDocumentLine.NextLine; if (nextDocumentLine != null) { VisualLine nextLine = textArea.TextView.GetOrConstructVisualLine(nextDocumentLine); pos = nextLine.GetNextCaretPosition(-1, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace); if (pos < 0) throw ThrowUtil.NoValidCaretPosition(); SetCaretPosition(textArea, pos, nextLine.GetRelativeOffset(pos) + nextLine.FirstDocumentLine.Offset); } else { // at end of document Debug.Assert(visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength == textArea.Document.TextLength); SetCaretPosition(textArea, -1, textArea.Document.TextLength); } } } static void MoveCaretLeft(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode) { int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace); if (pos >= 0) { SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset); } else { // move to end of previous line DocumentLine previousDocumentLine = visualLine.FirstDocumentLine.PreviousLine; if (previousDocumentLine != null) { VisualLine previousLine = textArea.TextView.GetOrConstructVisualLine(previousDocumentLine); pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace); if (pos < 0) throw ThrowUtil.NoValidCaretPosition(); SetCaretPosition(textArea, pos, previousLine.GetRelativeOffset(pos) + previousLine.FirstDocumentLine.Offset); } else { // at start of document Debug.Assert(visualLine.FirstDocumentLine.Offset == 0); SetCaretPosition(textArea, 0, 0); } } } #endregion #region Line+Page up/down static void MoveCaretUpDown(TextArea textArea, CaretMovementType direction, VisualLine visualLine, TextLine textLine, int caretVisualColumn) { // moving up/down happens using the desired visual X position double xPos = textArea.Caret.DesiredXPos; if (double.IsNaN(xPos)) xPos = visualLine.GetTextLineVisualXPosition(textLine, caretVisualColumn); // now find the TextLine+VisualLine where the caret will end up in VisualLine targetVisualLine = visualLine; TextLine targetLine; int textLineIndex = visualLine.TextLines.IndexOf(textLine); switch (direction) { case CaretMovementType.LineUp: { // Move up: move to the previous TextLine in the same visual line // or move to the last TextLine of the previous visual line int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1; if (textLineIndex > 0) { targetLine = visualLine.TextLines[textLineIndex - 1]; } else if (prevLineNumber >= 1) { DocumentLine prevLine = textArea.Document.GetLineByNumber(prevLineNumber); targetVisualLine = textArea.TextView.GetOrConstructVisualLine(prevLine); targetLine = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1]; } else { targetLine = null; } break; } case CaretMovementType.LineDown: { // Move down: move to the next TextLine in the same visual line // or move to the first TextLine of the next visual line int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1; if (textLineIndex < visualLine.TextLines.Count - 1) { targetLine = visualLine.TextLines[textLineIndex + 1]; } else if (nextLineNumber <= textArea.Document.LineCount) { DocumentLine nextLine = textArea.Document.GetLineByNumber(nextLineNumber); targetVisualLine = textArea.TextView.GetOrConstructVisualLine(nextLine); targetLine = targetVisualLine.TextLines[0]; } else { targetLine = null; } break; } case CaretMovementType.PageUp: case CaretMovementType.PageDown: { // Page up/down: find the target line using its visual position double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle); if (direction == CaretMovementType.PageUp) yPos -= textArea.TextView.RenderSize.Height; else yPos += textArea.TextView.RenderSize.Height; DocumentLine newLine = textArea.TextView.GetDocumentLineByVisualTop(yPos); targetVisualLine = textArea.TextView.GetOrConstructVisualLine(newLine); targetLine = targetVisualLine.GetTextLineByVisualYPosition(yPos); break; } default: throw new NotSupportedException(direction.ToString()); } if (targetLine != null) { double yPos = targetVisualLine.GetTextLineVisualYPosition(targetLine, VisualYPosition.LineMiddle); int newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), textArea.Selection.EnableVirtualSpace); SetCaretPosition(textArea, targetVisualLine, targetLine, newVisualColumn, false); textArea.Caret.DesiredXPos = xPos; } } #endregion #region SetCaretPosition static void SetCaretPosition(TextArea textArea, VisualLine targetVisualLine, TextLine targetLine, int newVisualColumn, bool allowWrapToNextLine) { int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine); if (!allowWrapToNextLine && newVisualColumn >= targetLineStartCol + targetLine.Length) { if (newVisualColumn <= targetVisualLine.VisualLength) newVisualColumn = targetLineStartCol + targetLine.Length - 1; } int newOffset = targetVisualLine.GetRelativeOffset(newVisualColumn) + targetVisualLine.FirstDocumentLine.Offset; SetCaretPosition(textArea, newVisualColumn, newOffset); } static void SetCaretPosition(TextArea textArea, int newVisualColumn, int newOffset) { textArea.Caret.Position = new TextViewPosition(textArea.Document.GetLocation(newOffset), newVisualColumn); textArea.Caret.DesiredXPos = double.NaN; } #endregion } }