@@ -56,5 +56,69 @@ public void MoveToLastLine(ConsoleKeyInfo? key = null, object arg = null)
56
56
57
57
_singleton . MoveCursor ( position ) ;
58
58
}
59
+
60
+ private void ViMoveToLine ( int lineOffset )
61
+ {
62
+ // When moving up or down in a buffer in VI mode
63
+ // the cursor wants to be positioned at a desired column number, which is:
64
+ // - either a specified column number, the 0-based offset from the start of the logical line.
65
+ // - or the end of the line
66
+ //
67
+ // Only one of those desired position is available at any given time.
68
+ //
69
+ // If the desired column number is specified, the cursor will be positioned at
70
+ // the specified offset in the target logical line, or at the end of the line as appropriate.
71
+ // The fact that a logical line is shorter than the desired column number *does not*
72
+ // change its value. If a subsequent move to another logical line is performed, the
73
+ // desired column number will take effect.
74
+ //
75
+ // If the desired column number is the end of the line, the cursor will be positioned at
76
+ // the end of the target logical line.
77
+
78
+ const int endOfLine = int . MaxValue ;
79
+
80
+ _moveToLineCommandCount += 1 ;
81
+
82
+ // if this is the first "move to line" command
83
+ // record the desired column number from the current position
84
+ // on the logical line
85
+
86
+ if ( _moveToLineCommandCount == 1 && _moveToLineDesiredColumn == - 1 )
87
+ {
88
+ var startOfLine = GetBeginningOfLinePos ( _current ) ;
89
+ _moveToLineDesiredColumn = _current - startOfLine ;
90
+ }
91
+
92
+ // Nothing needs to be done when:
93
+ // - actually not moving the line, or
94
+ // - moving the line down when it's at the end of the last logical line.
95
+ if ( lineOffset == 0 || ( lineOffset > 0 && _current == _buffer . Length ) )
96
+ {
97
+ return ;
98
+ }
99
+
100
+ int targetLineOffset ;
101
+
102
+ var currentLineIndex = _singleton . GetLogicalLineNumber ( ) - 1 ;
103
+
104
+ if ( lineOffset < 0 )
105
+ {
106
+ targetLineOffset = Math . Max ( 0 , currentLineIndex + lineOffset ) ;
107
+ }
108
+ else
109
+ {
110
+ var lastLineIndex = _singleton . GetLogicalLineCount ( ) - 1 ;
111
+ targetLineOffset = Math . Min ( lastLineIndex , currentLineIndex + lineOffset ) ;
112
+ }
113
+
114
+ var startOfTargetLinePos = GetBeginningOfNthLinePos ( targetLineOffset ) ;
115
+ var endOfTargetLinePos = GetEndOfLogicalLinePos ( startOfTargetLinePos ) ;
116
+
117
+ var newCurrent = _moveToLineDesiredColumn == endOfLine
118
+ ? endOfTargetLinePos
119
+ : Math . Min ( startOfTargetLinePos + _moveToLineDesiredColumn , endOfTargetLinePos ) ;
120
+
121
+ MoveCursor ( newCurrent ) ;
122
+ }
59
123
}
60
124
}
0 commit comments