@@ -22,7 +22,7 @@ import * as nls from 'vs/nls';
2222import { ICommandService } from 'vs/platform/commands/common/commands' ;
2323import { ContextKeyExpr , IContextKeyService } from 'vs/platform/contextkey/common/contextkey' ;
2424import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation' ;
25- import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry' ;
25+ import { KeybindingWeight , KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry' ;
2626import { Context as SuggestContext , CompletionItem } from './suggest' ;
2727import { SuggestAlternatives } from './suggestAlternatives' ;
2828import { State , SuggestModel } from './suggestModel' ;
@@ -34,7 +34,7 @@ import { IdleValue } from 'vs/base/common/async';
3434import { isObject } from 'vs/base/common/types' ;
3535import { CommitCharacterController } from './suggestCommitCharacters' ;
3636import { IPosition } from 'vs/editor/common/core/position' ;
37- import { TrackedRangeStickiness , ITextModel } from 'vs/editor/common/model' ;
37+ import { TrackedRangeStickiness , ITextModel , IWordAtPosition } from 'vs/editor/common/model' ;
3838import { EditorOption } from 'vs/editor/common/config/editorOptions' ;
3939import * as platform from 'vs/base/common/platform' ;
4040
@@ -115,10 +115,10 @@ export class SuggestController implements IEditorContribution {
115115 const widget = this . _instantiationService . createInstance ( SuggestWidget , this . _editor ) ;
116116
117117 this . _toDispose . add ( widget ) ;
118- this . _toDispose . add ( widget . onDidSelect ( item => this . _insertSuggestion ( item , false , true , true ) , this ) ) ;
118+ this . _toDispose . add ( widget . onDidSelect ( item => this . _insertSuggestion ( item , false , true , true , false ) , this ) ) ;
119119
120120 // Wire up logic to accept a suggestion on certain characters
121- const commitCharacterController = new CommitCharacterController ( this . _editor , widget , item => this . _insertSuggestion ( item , false , true , false ) ) ;
121+ const commitCharacterController = new CommitCharacterController ( this . _editor , widget , item => this . _insertSuggestion ( item , false , true , false , false ) ) ;
122122 this . _toDispose . add ( commitCharacterController ) ;
123123 this . _toDispose . add ( this . _model . onDidSuggest ( e => {
124124 if ( e . completionModel . items . length === 0 ) {
@@ -223,7 +223,12 @@ export class SuggestController implements IEditorContribution {
223223 this . _lineSuffix . dispose ( ) ;
224224 }
225225
226- protected _insertSuggestion ( event : ISelectedSuggestion | undefined , keepAlternativeSuggestions : boolean , undoStopBefore : boolean , undoStopAfter : boolean ) : void {
226+ protected _insertSuggestion (
227+ event : ISelectedSuggestion | undefined ,
228+ keepAlternativeSuggestions : boolean ,
229+ undoStopBefore : boolean , undoStopAfter : boolean ,
230+ overwriteSuffix : boolean
231+ ) : void {
227232 if ( ! event || ! event . item ) {
228233 this . _alternatives . getValue ( ) . reset ( ) ;
229234 this . _model . cancel ( ) ;
@@ -237,8 +242,8 @@ export class SuggestController implements IEditorContribution {
237242 const model = this . _editor . getModel ( ) ;
238243 const modelVersionNow = model . getAlternativeVersionId ( ) ;
239244 const { completion : suggestion , position } = event . item ;
240- const editorColumn = this . _editor . getPosition ( ) . column ;
241- const columnDelta = editorColumn - position . column ;
245+ const editorPosition = this . _editor . getPosition ( ) ;
246+ const columnDelta = editorPosition . column - position . column ;
242247
243248 // pushing undo stops *before* additional text edits and
244249 // *after* the main edit
@@ -251,7 +256,7 @@ export class SuggestController implements IEditorContribution {
251256 }
252257
253258 // keep item in memory
254- this . _memoryService . memorize ( model , this . _editor . getPosition ( ) , event . item ) ;
259+ this . _memoryService . memorize ( model , editorPosition , event . item ) ;
255260
256261 let { insertText } = suggestion ;
257262 if ( ! ( suggestion . insertTextRules ! & CompletionItemInsertTextRule . InsertAsSnippet ) ) {
@@ -260,7 +265,12 @@ export class SuggestController implements IEditorContribution {
260265
261266 const overwriteBefore = position . column - suggestion . range . startColumn ;
262267 const overwriteAfter = suggestion . range . endColumn - position . column ;
263- const suffixDelta = this . _lineSuffix . value ? this . _lineSuffix . value . delta ( this . _editor . getPosition ( ) ) : 0 ;
268+
269+ let suffixDelta = this . _lineSuffix . value ? this . _lineSuffix . value . delta ( position ) : 0 ;
270+ let word : IWordAtPosition | null ;
271+ if ( overwriteAfter === 0 && overwriteSuffix && ( word = model . getWordAtPosition ( position ) ) ) {
272+ suffixDelta += word . endColumn - position . column ;
273+ }
264274
265275 SnippetController2 . get ( this . _editor ) . insert ( insertText , {
266276 overwriteBefore : overwriteBefore + columnDelta ,
@@ -300,7 +310,7 @@ export class SuggestController implements IEditorContribution {
300310 if ( modelVersionNow !== model . getAlternativeVersionId ( ) ) {
301311 model . undo ( ) ;
302312 }
303- this . _insertSuggestion ( next , false , false , false ) ;
313+ this . _insertSuggestion ( next , false , false , false , overwriteSuffix ) ;
304314 break ;
305315 }
306316 } ) ;
@@ -382,7 +392,7 @@ export class SuggestController implements IEditorContribution {
382392 return ;
383393 }
384394 this . _editor . pushUndoStop ( ) ;
385- this . _insertSuggestion ( { index, item, model : completionModel } , true , false , false ) ;
395+ this . _insertSuggestion ( { index, item, model : completionModel } , true , false , false , false ) ;
386396
387397 } , undefined , listener ) ;
388398 } ) ;
@@ -392,9 +402,9 @@ export class SuggestController implements IEditorContribution {
392402 this . _editor . focus ( ) ;
393403 }
394404
395- acceptSelectedSuggestion ( keepAlternativeSuggestions ? : boolean ) : void {
405+ acceptSelectedSuggestion ( keepAlternativeSuggestions : boolean , overwriteSuffix : boolean ) : void {
396406 const item = this . _widget . getValue ( ) . getFocusedItem ( ) ;
397- this . _insertSuggestion ( item , ! ! keepAlternativeSuggestions , true , true ) ;
407+ this . _insertSuggestion ( item , keepAlternativeSuggestions , true , true , overwriteSuffix ) ;
398408 }
399409
400410 acceptNextSuggestion ( ) {
@@ -489,18 +499,37 @@ const SuggestCommand = EditorCommand.bindToContribution<SuggestController>(Sugge
489499registerEditorCommand ( new SuggestCommand ( {
490500 id : 'acceptSelectedSuggestion' ,
491501 precondition : SuggestContext . Visible ,
492- handler : x => x . acceptSelectedSuggestion ( true ) ,
493502 kbOpts : {
494503 weight : weight ,
495504 kbExpr : EditorContextKeys . textInputFocus ,
496505 primary : KeyCode . Tab
506+ } ,
507+ handler ( x , args ) {
508+ let overwriteSuffix : boolean ;
509+ if ( typeof args !== 'object' ) {
510+ overwriteSuffix = false ;
511+ } else if ( typeof args . overwriteSuffix !== 'boolean' ) {
512+ overwriteSuffix = false ;
513+ } else {
514+ overwriteSuffix = args . overwriteSuffix ;
515+ }
516+ x . acceptSelectedSuggestion ( true , overwriteSuffix ) ;
497517 }
498518} ) ) ;
499519
520+ KeybindingsRegistry . registerKeybindingRule ( {
521+ id : 'acceptSelectedSuggestion' ,
522+ when : ContextKeyExpr . and ( SuggestContext . Visible , EditorContextKeys . textInputFocus ) ,
523+ primary : KeyMod . Shift | KeyCode . Tab ,
524+ secondary : [ KeyMod . Shift | KeyCode . Enter ] ,
525+ args : { overwriteSuffix : true } ,
526+ weight
527+ } ) ;
528+
500529registerEditorCommand ( new SuggestCommand ( {
501530 id : 'acceptSelectedSuggestionOnEnter' ,
502531 precondition : SuggestContext . Visible ,
503- handler : x => x . acceptSelectedSuggestion ( false ) ,
532+ handler : x => x . acceptSelectedSuggestion ( false , false ) ,
504533 kbOpts : {
505534 weight : weight ,
506535 kbExpr : ContextKeyExpr . and ( EditorContextKeys . textInputFocus , SuggestContext . AcceptSuggestionsOnEnter , SuggestContext . MakesTextEdit ) ,
0 commit comments