99using Microsoft . CodeAnalysis . Editor . Implementation . AutomaticCompletion ;
1010using Microsoft . CodeAnalysis . Editor . Shared . Extensions ;
1111using Microsoft . CodeAnalysis . Host . Mef ;
12+ using Microsoft . CodeAnalysis . Internal . Log ;
1213using Microsoft . CodeAnalysis . LanguageServices ;
1314using Microsoft . CodeAnalysis . Shared . Extensions ;
1415using Microsoft . CodeAnalysis . Text ;
1819using Microsoft . VisualStudio . Text ;
1920using Microsoft . VisualStudio . Text . Editor . Commanding . Commands ;
2021using Microsoft . VisualStudio . Utilities ;
21- using Roslyn . Utilities ;
2222using VSCommanding = Microsoft . VisualStudio . Commanding ;
2323
2424namespace Microsoft . CodeAnalysis . Editor . CSharp . CompleteStatement
@@ -173,22 +173,33 @@ private static void MoveCaretToFinalPositionInStatement(SyntaxNode statementNode
173173 return ;
174174 }
175175
176+ if ( TryGetCaretPositionToMove ( statementNode , caret , isInsideDelimiters , out var targetPosition ) )
177+ {
178+ Logger . Log ( FunctionId . CommandHandler_CompleteStatement , KeyValueLogMessage . Create ( LogType . UserAction , m =>
179+ {
180+ m [ nameof ( isInsideDelimiters ) ] = isInsideDelimiters ;
181+ m [ nameof ( statementNode ) ] = statementNode . Kind ( ) ;
182+ } ) ) ;
183+
184+ args . TextView . TryMoveCaretToAndEnsureVisible ( targetPosition ) ;
185+ }
186+ }
187+
188+ private static bool TryGetCaretPositionToMove ( SyntaxNode statementNode , SnapshotPoint caret , bool isInsideDelimiters , out SnapshotPoint targetPosition )
189+ {
190+ targetPosition = default ;
191+
176192 switch ( statementNode . Kind ( ) )
177193 {
178194 case SyntaxKind . DoStatement :
179195 // Move caret after the do statment's closing paren.
180- var doStatementCaret = args . SubjectBuffer . CurrentSnapshot . GetPoint ( ( ( DoStatementSyntax ) statementNode ) . CloseParenToken . Span . End ) ;
181- args . TextView . TryMoveCaretToAndEnsureVisible ( doStatementCaret ) ;
182- return ;
196+ targetPosition = caret . Snapshot . GetPoint ( ( ( DoStatementSyntax ) statementNode ) . CloseParenToken . Span . End ) ;
197+ return true ;
183198 case SyntaxKind . ForStatement :
184199 // `For` statements can have semicolon after initializer/declaration or after condition.
185200 // If caret is in initialer/declaration or condition, AND is inside other delimiters, complete statement
186201 // Otherwise, return without moving the caret.
187- if ( TryGetForStatementCaret ( caret , ( ForStatementSyntax ) statementNode , args , out var forStatementCaret ) && isInsideDelimiters )
188- {
189- args . TextView . TryMoveCaretToAndEnsureVisible ( forStatementCaret ) ;
190- }
191- return ;
202+ return isInsideDelimiters && TryGetForStatementCaret ( caret , ( ForStatementSyntax ) statementNode , out targetPosition ) ;
192203 case SyntaxKind . ExpressionStatement :
193204 case SyntaxKind . GotoCaseStatement :
194205 case SyntaxKind . LocalDeclarationStatement :
@@ -198,18 +209,15 @@ private static void MoveCaretToFinalPositionInStatement(SyntaxNode statementNode
198209 case SyntaxKind . DelegateDeclaration :
199210 // These statement types end in a semicolon.
200211 // if the original caret was inside any delimiters, `caret` will be after the outermost delimiter
201- if ( isInsideDelimiters )
202- {
203- args . TextView . TryMoveCaretToAndEnsureVisible ( args . SubjectBuffer . CurrentSnapshot . GetPoint ( caret ) ) ;
204- }
205- return ;
212+ targetPosition = caret ;
213+ return isInsideDelimiters ;
206214 default :
207215 // For all other statement types, don't complete statement. Return without moving the caret.
208- return ;
216+ return false ;
209217 }
210218 }
211219
212- private static bool TryGetForStatementCaret ( SnapshotPoint originalCaret , ForStatementSyntax forStatement , TypeCharCommandArgs args , out SnapshotPoint forStatementCaret )
220+ private static bool TryGetForStatementCaret ( SnapshotPoint originalCaret , ForStatementSyntax forStatement , out SnapshotPoint forStatementCaret )
213221 {
214222 if ( CaretIsInForStatementCondition ( originalCaret , forStatement ) )
215223 {
@@ -232,8 +240,7 @@ private static bool TryGetForStatementCaret(SnapshotPoint originalCaret, ForStat
232240 return ( forStatementCaret != default ) ;
233241
234242 // Locals
235- SnapshotPoint GetCaretAtPosition ( int position )
236- => args . SubjectBuffer . CurrentSnapshot . GetPoint ( position ) ;
243+ SnapshotPoint GetCaretAtPosition ( int position ) => originalCaret . Snapshot . GetPoint ( position ) ;
237244 }
238245
239246 private static bool CaretIsInForStatementCondition ( int caretPosition , ForStatementSyntax forStatementSyntax )
0 commit comments