mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-02 01:03:29 +01:00
* Move parallelizable to new file * Add UseSameRuneTypeForWords property * Add SelectWordOnlyOnDoubleClick property and ProcessDoubleClickSelection method * Change IsSameRuneType method to also handle equivalent rune types * Fix WordBackward and WordForward to support properly handle rune types * Fix unit test to deal properly with the new roles of rune types * Add new unit tests * Remove duplicated unit test * Add UseSameRuneTypeForWords and SelectWordOnlyOnDoubleClick handling into Editor scenario
This commit is contained in:
@@ -570,6 +570,19 @@ public class TextField : View, IDesignable
|
||||
/// </summary>
|
||||
public bool Used { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the word forward and word backward navigation should use the same or equivalent rune type.
|
||||
/// Default is <c>false</c> meaning using equivalent rune type.
|
||||
/// </summary>
|
||||
public bool UseSameRuneTypeForWords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the word navigation should select only the word itself without spaces around it or with the
|
||||
/// spaces at right.
|
||||
/// Default is <c>false</c> meaning that the spaces at right are included in the selection.
|
||||
/// </summary>
|
||||
public bool SelectWordOnlyOnDoubleClick { get; set; }
|
||||
|
||||
/// <summary>Clear the selected text.</summary>
|
||||
public void ClearAllSelection ()
|
||||
{
|
||||
@@ -754,7 +767,7 @@ public class TextField : View, IDesignable
|
||||
public virtual void KillWordBackwards ()
|
||||
{
|
||||
ClearAllSelection ();
|
||||
(int col, int row)? newPos = GetModel ().WordBackward (_cursorPosition, 0);
|
||||
(int col, int row)? newPos = GetModel ().WordBackward (_cursorPosition, 0, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos is null)
|
||||
{
|
||||
@@ -777,7 +790,7 @@ public class TextField : View, IDesignable
|
||||
public virtual void KillWordForwards ()
|
||||
{
|
||||
ClearAllSelection ();
|
||||
(int col, int row)? newPos = GetModel ().WordForward (_cursorPosition, 0);
|
||||
(int col, int row)? newPos = GetModel ().WordForward (_cursorPosition, 0, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos is null)
|
||||
{
|
||||
@@ -857,43 +870,15 @@ public class TextField : View, IDesignable
|
||||
{
|
||||
EnsureHasFocus ();
|
||||
int x = PositionCursor (ev);
|
||||
int sbw = x;
|
||||
(int startCol, int col, int row)? newPos = GetModel ().ProcessDoubleClickSelection (x, x, 0, UseSameRuneTypeForWords, SelectWordOnlyOnDoubleClick);
|
||||
|
||||
if (x == _text.Count
|
||||
|| (x > 0 && (char)_text [x - 1].Value != ' ')
|
||||
|| (x > 0 && (char)_text [x].Value == ' '))
|
||||
{
|
||||
(int col, int row)? newPosBw = GetModel ().WordBackward (x, 0);
|
||||
|
||||
if (newPosBw is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
sbw = newPosBw.Value.col;
|
||||
}
|
||||
|
||||
if (sbw != -1)
|
||||
{
|
||||
x = sbw;
|
||||
PositionCursor (x);
|
||||
}
|
||||
|
||||
(int col, int row)? newPosFw = GetModel ().WordForward (x, 0);
|
||||
|
||||
if (newPosFw is null)
|
||||
if (newPos is null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ClearAllSelection ();
|
||||
|
||||
if (newPosFw.Value.col != -1 && sbw != -1)
|
||||
{
|
||||
_cursorPosition = newPosFw.Value.col;
|
||||
}
|
||||
|
||||
PrepareSelection (sbw, newPosFw.Value.col - sbw);
|
||||
SelectedStart = newPos.Value.startCol;
|
||||
CursorPosition = newPos.Value.col;
|
||||
}
|
||||
else if (ev.Flags == MouseFlags.Button1TripleClicked)
|
||||
{
|
||||
@@ -1502,7 +1487,7 @@ public class TextField : View, IDesignable
|
||||
private void MoveWordLeft ()
|
||||
{
|
||||
ClearAllSelection ();
|
||||
(int col, int row)? newPos = GetModel ().WordBackward (_cursorPosition, 0);
|
||||
(int col, int row)? newPos = GetModel ().WordBackward (_cursorPosition, 0, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos is null)
|
||||
{
|
||||
@@ -1528,7 +1513,7 @@ public class TextField : View, IDesignable
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
(int col, int row)? newPos = GetModel ().WordBackward (x, 0);
|
||||
(int col, int row)? newPos = GetModel ().WordBackward (x, 0, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos is null)
|
||||
{
|
||||
@@ -1548,7 +1533,7 @@ public class TextField : View, IDesignable
|
||||
private void MoveWordRight ()
|
||||
{
|
||||
ClearAllSelection ();
|
||||
(int col, int row)? newPos = GetModel ().WordForward (_cursorPosition, 0);
|
||||
(int col, int row)? newPos = GetModel ().WordForward (_cursorPosition, 0, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos is null)
|
||||
{
|
||||
@@ -1568,7 +1553,7 @@ public class TextField : View, IDesignable
|
||||
if (_cursorPosition < _text.Count)
|
||||
{
|
||||
int x = _start > -1 && _start > _cursorPosition ? _start : _cursorPosition;
|
||||
(int col, int row)? newPos = GetModel ().WordForward (x, 0);
|
||||
(int col, int row)? newPos = GetModel ().WordForward (x, 0, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos is null)
|
||||
{
|
||||
|
||||
@@ -206,7 +206,7 @@ internal class TextModel
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
public (int col, int row)? WordBackward (int fromCol, int fromRow)
|
||||
public (int col, int row)? WordBackward (int fromCol, int fromRow, bool useSameRuneType)
|
||||
{
|
||||
if (fromRow == 0 && fromCol == 0)
|
||||
{
|
||||
@@ -245,7 +245,7 @@ internal class TextModel
|
||||
|
||||
RuneType runeType = GetRuneType (rune);
|
||||
|
||||
int lastValidCol = IsSameRuneType (rune, runeType) && (Rune.IsLetterOrDigit (rune) || Rune.IsPunctuation (rune) || Rune.IsSymbol (rune))
|
||||
int lastValidCol = IsSameRuneType (rune, runeType, useSameRuneType) && (Rune.IsLetterOrDigit (rune) || Rune.IsPunctuation (rune) || Rune.IsSymbol (rune))
|
||||
? col
|
||||
: -1;
|
||||
|
||||
@@ -253,21 +253,29 @@ internal class TextModel
|
||||
{
|
||||
if (Rune.IsWhiteSpace (nRune))
|
||||
{
|
||||
while (MovePrev (ref nCol, ref nRow, out nRune))
|
||||
while (MovePrev (ref nCol, ref nRow, out nRune, useSameRuneType))
|
||||
{
|
||||
lastValidCol = nCol;
|
||||
|
||||
if (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune))
|
||||
{
|
||||
lastValidCol = nCol;
|
||||
|
||||
if (runeType == RuneType.IsWhiteSpace || runeType == RuneType.IsUnknown)
|
||||
{
|
||||
runeType = GetRuneType (nRune);
|
||||
}
|
||||
|
||||
break;
|
||||
rune = nRune;
|
||||
runeType = GetRuneType (nRune);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastValidCol > -1)
|
||||
{
|
||||
nCol = lastValidCol;
|
||||
nRow = fromRow;
|
||||
}
|
||||
|
||||
if ((!Rune.IsWhiteSpace (nRune) && Rune.IsWhiteSpace (rune))
|
||||
|| (Rune.IsWhiteSpace (nRune) && !Rune.IsWhiteSpace (rune)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (nRow != fromRow && (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune)))
|
||||
{
|
||||
List<Cell> line = GetLine (nRow);
|
||||
@@ -276,38 +284,18 @@ internal class TextModel
|
||||
{
|
||||
nCol = lastValidCol + Math.Max (lastValidCol, line.Count);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (MovePrev (ref nCol, ref nRow, out nRune))
|
||||
{
|
||||
if (!Rune.IsLetterOrDigit (nRune) && !Rune.IsPunctuation (nRune) && !Rune.IsSymbol (nRune))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (nRow != fromRow)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
lastValidCol =
|
||||
(IsSameRuneType (nRune, runeType) && Rune.IsLetterOrDigit (nRune)) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune)
|
||||
? nCol
|
||||
: lastValidCol;
|
||||
}
|
||||
|
||||
if (lastValidCol > -1)
|
||||
{
|
||||
nCol = lastValidCol;
|
||||
nRow = fromRow;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!MovePrev (ref nCol, ref nRow, out nRune))
|
||||
if (!MovePrev (ref nCol, ref nRow, out nRune, useSameRuneType))
|
||||
{
|
||||
if (lastValidCol > -1)
|
||||
{
|
||||
nCol = lastValidCol;
|
||||
nRow = fromRow;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -321,7 +309,7 @@ internal class TextModel
|
||||
}
|
||||
|
||||
lastValidCol =
|
||||
(IsSameRuneType (nRune, runeType) && Rune.IsLetterOrDigit (nRune)) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune)
|
||||
(IsSameRuneType (nRune, runeType, useSameRuneType) && Rune.IsLetterOrDigit (nRune)) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune)
|
||||
? nCol
|
||||
: lastValidCol;
|
||||
|
||||
@@ -350,6 +338,15 @@ internal class TextModel
|
||||
return (col, row);
|
||||
}
|
||||
|
||||
if (fromCol == col && fromRow == row && row > 0)
|
||||
{
|
||||
row--;
|
||||
List<Cell> line = GetLine (row);
|
||||
col = line.Count;
|
||||
|
||||
return (col, row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -358,7 +355,7 @@ internal class TextModel
|
||||
}
|
||||
}
|
||||
|
||||
public (int col, int row)? WordForward (int fromCol, int fromRow)
|
||||
public (int col, int row)? WordForward (int fromCol, int fromRow, bool useSameRuneType)
|
||||
{
|
||||
if (fromRow == _lines.Count - 1 && fromCol == GetLine (_lines.Count - 1).Count)
|
||||
{
|
||||
@@ -370,10 +367,10 @@ internal class TextModel
|
||||
|
||||
try
|
||||
{
|
||||
Rune rune = RuneAt (col, row)!.Value.Rune;
|
||||
Rune rune = _lines [row].Count > 0 ? RuneAt (col, row)!.Value.Rune : default (Rune);
|
||||
RuneType runeType = GetRuneType (rune);
|
||||
|
||||
int lastValidCol = IsSameRuneType (rune, runeType) && (Rune.IsLetterOrDigit (rune) || Rune.IsPunctuation (rune) || Rune.IsSymbol (rune))
|
||||
int lastValidCol = IsSameRuneType (rune, runeType, useSameRuneType) && (Rune.IsLetterOrDigit (rune) || Rune.IsPunctuation (rune) || Rune.IsSymbol (rune))
|
||||
? col
|
||||
: -1;
|
||||
|
||||
@@ -381,16 +378,23 @@ internal class TextModel
|
||||
{
|
||||
if (Rune.IsWhiteSpace (nRune))
|
||||
{
|
||||
while (MoveNext (ref nCol, ref nRow, out nRune))
|
||||
while (MoveNext (ref nCol, ref nRow, out nRune, useSameRuneType))
|
||||
{
|
||||
lastValidCol = nCol;
|
||||
|
||||
if (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune))
|
||||
{
|
||||
lastValidCol = nCol;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
lastValidCol = nCol;
|
||||
|
||||
if (!Rune.IsWhiteSpace (nRune) && Rune.IsWhiteSpace (rune))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (nRow != fromRow && (Rune.IsLetterOrDigit (nRune) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune)))
|
||||
{
|
||||
if (lastValidCol > -1)
|
||||
@@ -401,24 +405,6 @@ internal class TextModel
|
||||
return;
|
||||
}
|
||||
|
||||
while (MoveNext (ref nCol, ref nRow, out nRune))
|
||||
{
|
||||
if (!Rune.IsLetterOrDigit (nRune) && !Rune.IsPunctuation (nRune) && !Rune.IsSymbol (nRune))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (nRow != fromRow)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
lastValidCol =
|
||||
(IsSameRuneType (nRune, runeType) && Rune.IsLetterOrDigit (nRune)) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune)
|
||||
? nCol
|
||||
: lastValidCol;
|
||||
}
|
||||
|
||||
if (lastValidCol > -1)
|
||||
{
|
||||
nCol = lastValidCol;
|
||||
@@ -427,12 +413,14 @@ internal class TextModel
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!MoveNext (ref nCol, ref nRow, out nRune))
|
||||
if (!MoveNext (ref nCol, ref nRow, out nRune, useSameRuneType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsSameRuneType (nRune, runeType) && !Rune.IsWhiteSpace (nRune))
|
||||
lastValidCol = nCol;
|
||||
|
||||
if (!IsSameRuneType (nRune, runeType, useSameRuneType) && !Rune.IsWhiteSpace (nRune))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -446,11 +434,6 @@ internal class TextModel
|
||||
return;
|
||||
}
|
||||
|
||||
lastValidCol =
|
||||
(IsSameRuneType (nRune, runeType) && Rune.IsLetterOrDigit (nRune)) || Rune.IsPunctuation (nRune) || Rune.IsSymbol (nRune)
|
||||
? nCol
|
||||
: lastValidCol;
|
||||
|
||||
if (fromRow != nRow)
|
||||
{
|
||||
nCol = 0;
|
||||
@@ -477,6 +460,64 @@ internal class TextModel
|
||||
}
|
||||
}
|
||||
|
||||
public (int startCol, int col, int row)? ProcessDoubleClickSelection (int fromStartCol, int fromCol, int fromRow, bool useSameRuneType, bool selectWordOnly)
|
||||
{
|
||||
List<Cell> line = GetLine (fromRow);
|
||||
|
||||
int startCol = fromStartCol;
|
||||
int col = fromCol;
|
||||
int row = fromRow;
|
||||
|
||||
(int col, int row)? newPos = WordForward (col, row, useSameRuneType);
|
||||
|
||||
if (newPos.HasValue)
|
||||
{
|
||||
col = row == newPos.Value.row ? newPos.Value.col : 0;
|
||||
}
|
||||
|
||||
if (startCol > 0
|
||||
&& StringExtensions.ToString (line.GetRange (startCol, col - startCol).Select (c => c.Rune).ToList ()).Trim () == ""
|
||||
&& (col - startCol > 1 || (col - startCol > 0 && line [startCol - 1].Rune == (Rune)' ')))
|
||||
{
|
||||
while (startCol > 0 && line [startCol - 1].Rune == (Rune)' ')
|
||||
{
|
||||
startCol--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newPos = WordBackward (col, row, useSameRuneType);
|
||||
|
||||
if (newPos is { })
|
||||
{
|
||||
startCol = row == newPos.Value.row ? newPos.Value.col : line.Count;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectWordOnly)
|
||||
{
|
||||
List<Rune> selRunes = line.GetRange (startCol, col - startCol).Select (c => c.Rune).ToList ();
|
||||
|
||||
if (StringExtensions.ToString (selRunes).Trim () != "")
|
||||
{
|
||||
for (int i = selRunes.Count - 1; i > -1; i--)
|
||||
{
|
||||
if (selRunes [i] == (Rune)' ')
|
||||
{
|
||||
col--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fromStartCol != startCol || fromCol != col || fromRow != row)
|
||||
{
|
||||
return (startCol, col, row);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static int CalculateLeftColumn (List<Cell> t, int start, int end, int width, int tabWidth = 0)
|
||||
{
|
||||
List<Rune> runes = new ();
|
||||
@@ -966,11 +1007,27 @@ internal class TextModel
|
||||
return RuneType.IsUnknown;
|
||||
}
|
||||
|
||||
private bool IsSameRuneType (Rune newRune, RuneType runeType)
|
||||
private bool IsSameRuneType (Rune newRune, RuneType runeType, bool useSameRuneType)
|
||||
{
|
||||
RuneType rt = GetRuneType (newRune);
|
||||
|
||||
return rt == runeType;
|
||||
if (useSameRuneType)
|
||||
{
|
||||
return rt == runeType;
|
||||
}
|
||||
|
||||
switch (runeType)
|
||||
{
|
||||
case RuneType.IsSymbol:
|
||||
case RuneType.IsPunctuation:
|
||||
return rt is RuneType.IsSymbol or RuneType.IsPunctuation;
|
||||
case RuneType.IsWhiteSpace:
|
||||
case RuneType.IsLetterOrDigit:
|
||||
case RuneType.IsUnknown:
|
||||
return rt == runeType;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException (nameof (runeType), runeType, null);
|
||||
}
|
||||
}
|
||||
|
||||
private bool MatchWholeWord (string source, string matchText, int index = 0)
|
||||
@@ -992,7 +1049,7 @@ internal class TextModel
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool MoveNext (ref int col, ref int row, out Rune rune)
|
||||
private bool MoveNext (ref int col, ref int row, out Rune rune, bool useSameRuneType)
|
||||
{
|
||||
List<Cell> line = GetLine (row);
|
||||
|
||||
@@ -1001,39 +1058,40 @@ internal class TextModel
|
||||
col++;
|
||||
rune = line [col].Rune;
|
||||
|
||||
if (col + 1 == line.Count && !Rune.IsLetterOrDigit (rune) && !Rune.IsWhiteSpace (line [col - 1].Rune))
|
||||
if (col + 1 == line.Count
|
||||
&& !Rune.IsLetterOrDigit (rune)
|
||||
&& !Rune.IsWhiteSpace (line [col - 1].Rune)
|
||||
&& IsSameRuneType (line [col - 1].Rune, GetRuneType (rune), useSameRuneType))
|
||||
{
|
||||
col++;
|
||||
}
|
||||
|
||||
if (!Rune.IsWhiteSpace (rune)
|
||||
&& (Rune.IsWhiteSpace (line [col - 1].Rune) || !IsSameRuneType (line [col - 1].Rune, GetRuneType (rune), useSameRuneType)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (col + 1 == line.Count)
|
||||
{
|
||||
col++;
|
||||
rune = default (Rune);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
while (row + 1 < Count)
|
||||
{
|
||||
col = 0;
|
||||
row++;
|
||||
line = GetLine (row);
|
||||
|
||||
if (line.Count > 0)
|
||||
{
|
||||
rune = line [0].Rune;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// End of line
|
||||
col = 0;
|
||||
row++;
|
||||
rune = default (Rune);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool MovePrev (ref int col, ref int row, out Rune rune)
|
||||
private bool MovePrev (ref int col, ref int row, out Rune rune, bool useSameRuneType)
|
||||
{
|
||||
List<Cell> line = GetLine (row);
|
||||
|
||||
@@ -1042,28 +1100,15 @@ internal class TextModel
|
||||
col--;
|
||||
rune = line [col].Rune;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (row == 0)
|
||||
{
|
||||
rune = default (Rune);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
while (row > 0)
|
||||
{
|
||||
row--;
|
||||
line = GetLine (row);
|
||||
col = line.Count - 1;
|
||||
|
||||
if (col >= 0)
|
||||
if ((!Rune.IsWhiteSpace (rune)
|
||||
&& !Rune.IsWhiteSpace (line [col + 1].Rune)
|
||||
&& !IsSameRuneType (line [col + 1].Rune, GetRuneType (rune), useSameRuneType))
|
||||
|| (Rune.IsWhiteSpace (rune) && !Rune.IsWhiteSpace (line [col + 1].Rune)))
|
||||
{
|
||||
rune = line [col].Rune;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
rune = default (Rune);
|
||||
|
||||
@@ -1015,6 +1015,19 @@ public class TextView : View, IDesignable
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the word forward and word backward navigation should use the same or equivalent rune type.
|
||||
/// Default is <c>false</c> meaning using equivalent rune type.
|
||||
/// </summary>
|
||||
public bool UseSameRuneTypeForWords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether the word navigation should select only the word itself without spaces around it or with the
|
||||
/// spaces at right.
|
||||
/// Default is <c>false</c> meaning that the spaces at right are included in the selection.
|
||||
/// </summary>
|
||||
public bool SelectWordOnlyOnDoubleClick { get; set; }
|
||||
|
||||
/// <summary>Allows clearing the <see cref="HistoryTextItemEventArgs"/> items updating the original text.</summary>
|
||||
public void ClearHistoryChanges () { _historyText?.Clear (_model.GetAllLines ()); }
|
||||
|
||||
@@ -1689,29 +1702,19 @@ public class TextView : View, IDesignable
|
||||
}
|
||||
|
||||
ProcessMouseClick (ev, out List<Cell> line);
|
||||
(int col, int row)? newPos;
|
||||
|
||||
if (CurrentColumn == line.Count
|
||||
|| (CurrentColumn > 0 && (line [CurrentColumn - 1].Rune.Value != ' ' || line [CurrentColumn].Rune.Value == ' ')))
|
||||
{
|
||||
newPos = _model.WordBackward (CurrentColumn, CurrentRow);
|
||||
|
||||
if (newPos.HasValue)
|
||||
{
|
||||
CurrentColumn = CurrentRow == newPos.Value.row ? newPos.Value.col : 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsSelecting)
|
||||
{
|
||||
StartSelecting ();
|
||||
}
|
||||
|
||||
newPos = _model.WordForward (CurrentColumn, CurrentRow);
|
||||
(int startCol, int col, int row)? newPos = _model.ProcessDoubleClickSelection (SelectionStartColumn, CurrentColumn, CurrentRow, UseSameRuneTypeForWords, SelectWordOnlyOnDoubleClick);
|
||||
|
||||
if (newPos is { } && newPos.HasValue)
|
||||
if (newPos.HasValue)
|
||||
{
|
||||
CurrentColumn = CurrentRow == newPos.Value.row ? newPos.Value.col : line.Count;
|
||||
SelectionStartColumn = newPos.Value.startCol;
|
||||
CurrentColumn = newPos.Value.col;
|
||||
CurrentRow = newPos.Value.row;
|
||||
}
|
||||
|
||||
PositionCursor ();
|
||||
@@ -3380,7 +3383,7 @@ public class TextView : View, IDesignable
|
||||
return;
|
||||
}
|
||||
|
||||
(int col, int row)? newPos = _model.WordBackward (CurrentColumn, CurrentRow);
|
||||
(int col, int row)? newPos = _model.WordBackward (CurrentColumn, CurrentRow, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos.HasValue && CurrentRow == newPos.Value.row)
|
||||
{
|
||||
@@ -3464,7 +3467,7 @@ public class TextView : View, IDesignable
|
||||
return;
|
||||
}
|
||||
|
||||
(int col, int row)? newPos = _model.WordForward (CurrentColumn, CurrentRow);
|
||||
(int col, int row)? newPos = _model.WordForward (CurrentColumn, CurrentRow, UseSameRuneTypeForWords);
|
||||
var restCount = 0;
|
||||
|
||||
if (newPos.HasValue && CurrentRow == newPos.Value.row)
|
||||
@@ -3754,7 +3757,7 @@ public class TextView : View, IDesignable
|
||||
|
||||
private void MoveWordBackward ()
|
||||
{
|
||||
(int col, int row)? newPos = _model.WordBackward (CurrentColumn, CurrentRow);
|
||||
(int col, int row)? newPos = _model.WordBackward (CurrentColumn, CurrentRow, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos.HasValue)
|
||||
{
|
||||
@@ -3767,7 +3770,7 @@ public class TextView : View, IDesignable
|
||||
|
||||
private void MoveWordForward ()
|
||||
{
|
||||
(int col, int row)? newPos = _model.WordForward (CurrentColumn, CurrentRow);
|
||||
(int col, int row)? newPos = _model.WordForward (CurrentColumn, CurrentRow, UseSameRuneTypeForWords);
|
||||
|
||||
if (newPos.HasValue)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user