@@ -40,7 +40,7 @@ import { StashedSession } from './inlineChatSession';
4040import { IModelDeltaDecoration , ITextModel , IValidEditOperation } from 'vs/editor/common/model' ;
4141import { InlineChatContentWidget } from 'vs/workbench/contrib/inlineChat/browser/inlineChatContentWidget' ;
4242import { MessageController } from 'vs/editor/contrib/message/browser/messageController' ;
43- import { ChatModel , IChatRequestModel , IChatTextEditGroup , IChatTextEditGroupState , IResponse } from 'vs/workbench/contrib/chat/common/chatModel' ;
43+ import { ChatModel , ChatRequestRemovalReason , IChatRequestModel , IChatTextEditGroup , IChatTextEditGroupState , IResponse } from 'vs/workbench/contrib/chat/common/chatModel' ;
4444import { InlineChatError } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSessionServiceImpl' ;
4545import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures' ;
4646import { ChatInputPart } from 'vs/workbench/contrib/chat/browser/chatInputPart' ;
@@ -445,10 +445,16 @@ export class InlineChatController implements IEditorContribution {
445445 const exchange = this . _session ! . exchanges . find ( candidate => candidate . prompt . request . id === e . requestId ) ;
446446 if ( exchange && this . _editor . hasModel ( ) ) {
447447 // undo till this point
448- const model = this . _editor . getModel ( ) ;
449- const targetAltVersion = exchange . prompt . modelAltVersionId ;
450- while ( targetAltVersion < model . getAlternativeVersionId ( ) && model . canUndo ( ) ) {
451- await model . undo ( ) ;
448+ this . _session ! . hunkData . ignoreTextModelNChanges = true ;
449+ try {
450+
451+ const model = this . _editor . getModel ( ) ;
452+ const targetAltVersion = exchange . prompt . modelAltVersionId ;
453+ while ( targetAltVersion < model . getAlternativeVersionId ( ) && model . canUndo ( ) ) {
454+ await model . undo ( ) ;
455+ }
456+ } finally {
457+ this . _session ! . hunkData . ignoreTextModelNChanges = false ;
452458 }
453459 }
454460 }
@@ -641,7 +647,7 @@ export class InlineChatController implements IEditorContribution {
641647 const progressiveEditsClock = StopWatch . create ( ) ;
642648 const progressiveEditsQueue = new Queue ( ) ;
643649
644- let next : State . SHOW_RESPONSE | State . CANCEL | State . PAUSE | State . ACCEPT | State . WAIT_FOR_INPUT = State . SHOW_RESPONSE ;
650+ let next : State . SHOW_RESPONSE | State . SHOW_REQUEST | State . CANCEL | State . PAUSE | State . ACCEPT | State . WAIT_FOR_INPUT = State . SHOW_RESPONSE ;
645651 store . add ( Event . once ( this . _messages . event ) ( message => {
646652 this . _log ( 'state=_makeRequest) message received' , message ) ;
647653 this . _chatService . cancelCurrentRequestForSession ( chatModel . sessionId ) ;
@@ -658,7 +664,11 @@ export class InlineChatController implements IEditorContribution {
658664 if ( e . kind === 'removeRequest' && e . requestId === request . id ) {
659665 progressiveEditsCts . cancel ( ) ;
660666 responsePromise . complete ( ) ;
661- next = State . CANCEL ;
667+ if ( e . reason === ChatRequestRemovalReason . Resend ) {
668+ next = State . SHOW_REQUEST ;
669+ } else {
670+ next = State . CANCEL ;
671+ }
662672 }
663673 } ) ) ;
664674
@@ -678,61 +688,59 @@ export class InlineChatController implements IEditorContribution {
678688 let localEditGroup : IChatTextEditGroup | undefined ;
679689
680690 // apply edits
681- store . add ( response . onDidChange ( ( ) => {
682-
683- if ( response . isCanceled ) {
684- progressiveEditsCts . cancel ( ) ;
685- responsePromise . complete ( ) ;
686- return ;
687- }
688-
689- if ( response . isComplete ) {
690- responsePromise . complete ( ) ;
691- return ;
692- }
691+ const handleResponse = ( ) => {
693692
694693 if ( ! localEditGroup ) {
695- localEditGroup = < IChatTextEditGroup > response . response . value . find ( part => part . kind === 'textEditGroup' && isEqual ( part . uri , this . _session ?. textModelN . uri ) ) ;
694+ localEditGroup = < IChatTextEditGroup | undefined > response . response . value . find ( part => part . kind === 'textEditGroup' && isEqual ( part . uri , this . _session ?. textModelN . uri ) ) ;
696695 }
697696
698- if ( ! localEditGroup ) {
699- return ;
700- }
697+ if ( localEditGroup ) {
701698
702- localEditGroup . state ??= editState ;
699+ localEditGroup . state ??= editState ;
703700
704- const edits = localEditGroup . edits ;
705- const newEdits = edits . slice ( lastLength ) ;
706- if ( newEdits . length === 0 ) {
707- return ; // NO change
708- }
709- lastLength = edits . length ;
710- progressiveEditsAvgDuration . update ( progressiveEditsClock . elapsed ( ) ) ;
711- progressiveEditsClock . reset ( ) ;
701+ const edits = localEditGroup . edits ;
702+ const newEdits = edits . slice ( lastLength ) ;
703+ if ( newEdits . length > 0 ) {
704+ // NEW changes
705+ lastLength = edits . length ;
706+ progressiveEditsAvgDuration . update ( progressiveEditsClock . elapsed ( ) ) ;
707+ progressiveEditsClock . reset ( ) ;
712708
713- progressiveEditsQueue . queue ( async ( ) => {
709+ progressiveEditsQueue . queue ( async ( ) => {
714710
715- const startThen = this . _session ! . wholeRange . value . getStartPosition ( ) ;
711+ const startThen = this . _session ! . wholeRange . value . getStartPosition ( ) ;
716712
717- // making changes goes into a queue because otherwise the async-progress time will
718- // influence the time it takes to receive the changes and progressive typing will
719- // become infinitely fast
720- for ( const edits of newEdits ) {
721- await this . _makeChanges ( edits , {
722- duration : progressiveEditsAvgDuration . value ,
723- token : progressiveEditsCts . token
724- } , isFirstChange ) ;
713+ // making changes goes into a queue because otherwise the async-progress time will
714+ // influence the time it takes to receive the changes and progressive typing will
715+ // become infinitely fast
716+ for ( const edits of newEdits ) {
717+ await this . _makeChanges ( edits , {
718+ duration : progressiveEditsAvgDuration . value ,
719+ token : progressiveEditsCts . token
720+ } , isFirstChange ) ;
725721
726- isFirstChange = false ;
727- }
722+ isFirstChange = false ;
723+ }
728724
729- // reshow the widget if the start position changed or shows at the wrong position
730- const startNow = this . _session ! . wholeRange . value . getStartPosition ( ) ;
731- if ( ! startNow . equals ( startThen ) || ! this . _ui . value . zone . position ?. equals ( startNow ) ) {
732- this . _showWidget ( false , startNow . delta ( - 1 ) ) ;
725+ // reshow the widget if the start position changed or shows at the wrong position
726+ const startNow = this . _session ! . wholeRange . value . getStartPosition ( ) ;
727+ if ( ! startNow . equals ( startThen ) || ! this . _ui . value . zone . position ?. equals ( startNow ) ) {
728+ this . _showWidget ( false , startNow . delta ( - 1 ) ) ;
729+ }
730+ } ) ;
733731 }
734- } ) ;
735- } ) ) ;
732+ }
733+
734+ if ( response . isCanceled ) {
735+ progressiveEditsCts . cancel ( ) ;
736+ responsePromise . complete ( ) ;
737+
738+ } else if ( response . isComplete ) {
739+ responsePromise . complete ( ) ;
740+ }
741+ } ;
742+ store . add ( response . onDidChange ( handleResponse ) ) ;
743+ handleResponse ( ) ;
736744
737745 // (1) we must wait for the request to finish
738746 // (2) we must wait for all edits that came in via progress to complete
0 commit comments