@@ -39,7 +39,8 @@ const enum WordType {
3939
4040export const enum WordNavigationType {
4141 WordStart = 0 ,
42- WordEnd = 1
42+ WordStartFast = 1 ,
43+ WordEnd = 2
4344}
4445
4546export class WordOperations {
@@ -161,9 +162,11 @@ export class WordOperations {
161162 public static moveWordLeft ( wordSeparators : WordCharacterClassifier , model : ICursorSimpleModel , position : Position , wordNavigationType : WordNavigationType ) : Position {
162163 let lineNumber = position . lineNumber ;
163164 let column = position . column ;
165+ let movedToPreviousLine = false ;
164166
165167 if ( column === 1 ) {
166168 if ( lineNumber > 1 ) {
169+ movedToPreviousLine = true ;
167170 lineNumber = lineNumber - 1 ;
168171 column = model . getLineMaxColumn ( lineNumber ) ;
169172 }
@@ -172,29 +175,41 @@ export class WordOperations {
172175 let prevWordOnLine = WordOperations . _findPreviousWordOnLine ( wordSeparators , model , new Position ( lineNumber , column ) ) ;
173176
174177 if ( wordNavigationType === WordNavigationType . WordStart ) {
175- if ( prevWordOnLine && prevWordOnLine . wordType === WordType . Separator ) {
176- if ( prevWordOnLine . end - prevWordOnLine . start === 1 && prevWordOnLine . nextCharClass === WordCharacterClass . Regular ) {
177- // Skip over a word made up of one single separator and followed by a regular character
178- prevWordOnLine = WordOperations . _findPreviousWordOnLine ( wordSeparators , model , new Position ( lineNumber , prevWordOnLine . start + 1 ) ) ;
178+
179+ if ( prevWordOnLine && ! movedToPreviousLine ) {
180+ // Special case for Visual Studio compatibility:
181+ // when starting in the trim whitespace at the end of a line,
182+ // go to the end of the last word
183+ const lastWhitespaceColumn = model . getLineLastNonWhitespaceColumn ( lineNumber ) ;
184+ if ( lastWhitespaceColumn < column ) {
185+ return new Position ( lineNumber , prevWordOnLine . end + 1 ) ;
179186 }
180187 }
181- if ( prevWordOnLine ) {
182- column = prevWordOnLine . start + 1 ;
183- } else {
184- column = 1 ;
185- }
186- } else {
187- if ( prevWordOnLine && column <= prevWordOnLine . end + 1 ) {
188+
189+ return new Position ( lineNumber , prevWordOnLine ? prevWordOnLine . start + 1 : 1 ) ;
190+ }
191+
192+ if ( wordNavigationType === WordNavigationType . WordStartFast ) {
193+ if (
194+ prevWordOnLine
195+ && prevWordOnLine . wordType === WordType . Separator
196+ && prevWordOnLine . end - prevWordOnLine . start === 1
197+ && prevWordOnLine . nextCharClass === WordCharacterClass . Regular
198+ ) {
199+ // Skip over a word made up of one single separator and followed by a regular character
188200 prevWordOnLine = WordOperations . _findPreviousWordOnLine ( wordSeparators , model , new Position ( lineNumber , prevWordOnLine . start + 1 ) ) ;
189201 }
190- if ( prevWordOnLine ) {
191- column = prevWordOnLine . end + 1 ;
192- } else {
193- column = 1 ;
194- }
202+
203+ return new Position ( lineNumber , prevWordOnLine ? prevWordOnLine . start + 1 : 1 ) ;
195204 }
196205
197- return new Position ( lineNumber , column ) ;
206+ // We are stopping at the ending of words
207+
208+ if ( prevWordOnLine && column <= prevWordOnLine . end + 1 ) {
209+ prevWordOnLine = WordOperations . _findPreviousWordOnLine ( wordSeparators , model , new Position ( lineNumber , prevWordOnLine . start + 1 ) ) ;
210+ }
211+
212+ return new Position ( lineNumber , prevWordOnLine ? prevWordOnLine . end + 1 : 1 ) ;
198213 }
199214
200215 public static moveWordRight ( wordSeparators : WordCharacterClassifier , model : ICursorSimpleModel , position : Position , wordNavigationType : WordNavigationType ) : Position {
0 commit comments