Skip to content

Commit 7215958

Browse files
authored
add commands to navigate between hunks (microsoft#205293)
microsoft#203349
1 parent 80b556e commit 7215958

File tree

5 files changed

+84
-1
lines changed

5 files changed

+84
-1
lines changed

src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider {
331331
this.editor.changeViewZones(accessor => {
332332
accessor.layoutZone(this._viewZone!.id);
333333
});
334+
this._positionMarkerId.set([{
335+
range: Range.isIRange(rangeOrPos) ? rangeOrPos : Range.fromPositions(rangeOrPos),
336+
options: ModelDecorationOptions.EMPTY
337+
}]);
338+
334339
}
335340
}
336341

src/vs/workbench/contrib/inlineChat/browser/inlineChat.contribution.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ registerAction2(InlineChatActions.DiscardAction);
4242
registerAction2(InlineChatActions.DiscardToClipboardAction);
4343
registerAction2(InlineChatActions.DiscardUndoToNewFileAction);
4444
registerAction2(InlineChatActions.CancelSessionAction);
45+
registerAction2(InlineChatActions.MoveToNextHunk);
46+
registerAction2(InlineChatActions.MoveToPreviousHunk);
4547

4648
registerAction2(InlineChatActions.ArrowOutUpAction);
4749
registerAction2(InlineChatActions.ArrowOutDownAction);

src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,46 @@ export class ConfigureInlineChatAction extends AbstractInlineChatAction {
640640
}
641641
}
642642

643+
export class MoveToNextHunk extends AbstractInlineChatAction {
644+
645+
constructor() {
646+
super({
647+
id: 'inlineChat.moveToNextHunk',
648+
title: localize2('moveToNextHunk', 'Move to Next Change'),
649+
precondition: CTX_INLINE_CHAT_VISIBLE,
650+
f1: true,
651+
keybinding: {
652+
weight: KeybindingWeight.WorkbenchContrib,
653+
primary: KeyCode.F7
654+
}
655+
});
656+
}
657+
658+
override runInlineChatCommand(accessor: ServicesAccessor, ctrl: InlineChatController, editor: ICodeEditor, ...args: any[]): void {
659+
ctrl.moveHunk(true);
660+
}
661+
}
662+
663+
export class MoveToPreviousHunk extends AbstractInlineChatAction {
664+
665+
constructor() {
666+
super({
667+
id: 'inlineChat.moveToPreviousHunk',
668+
title: localize2('moveToPreviousHunk', 'Move to Previous Change'),
669+
f1: true,
670+
precondition: CTX_INLINE_CHAT_VISIBLE,
671+
keybinding: {
672+
weight: KeybindingWeight.WorkbenchContrib,
673+
primary: KeyMod.Shift | KeyCode.F7
674+
}
675+
});
676+
}
677+
678+
override runInlineChatCommand(accessor: ServicesAccessor, ctrl: InlineChatController, editor: ICodeEditor, ...args: any[]): void {
679+
ctrl.moveHunk(false);
680+
}
681+
}
682+
643683
export class CopyRecordings extends AbstractInlineChatAction {
644684

645685
constructor() {

src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,11 @@ export class InlineChatController implements IEditorContribution {
10571057
return this._zone.value.widget.hasFocus();
10581058
}
10591059

1060+
moveHunk(next: boolean) {
1061+
this.focus();
1062+
this._strategy?.move?.(next);
1063+
}
1064+
10601065
populateHistory(up: boolean) {
10611066
const len = InlineChatController._promptHistory.length;
10621067
if (len === 0) {

src/vs/workbench/contrib/inlineChat/browser/inlineChatStrategies.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ export abstract class EditModeStrategy {
123123

124124
abstract renderChanges(response: ReplyResponse): Promise<Position | undefined>;
125125

126+
move?(next: boolean): void;
127+
126128
abstract hasFocus(): boolean;
127129

128130
getWholeRangeDecoration(): IModelDeltaDecoration[] {
@@ -401,6 +403,7 @@ type HunkDisplayData = {
401403
discardHunk: () => void;
402404
toggleDiff?: () => any;
403405
remove(): void;
406+
move: (next: boolean) => void;
404407
};
405408

406409

@@ -429,7 +432,6 @@ export class LiveStrategy extends EditModeStrategy {
429432

430433
private readonly _progressiveEditingDecorations: IEditorDecorationsCollection;
431434

432-
433435
override acceptHunk: () => Promise<void> = () => super.acceptHunk();
434436
override discardHunk: () => Promise<void> = () => super.discardHunk();
435437

@@ -617,6 +619,33 @@ export class LiveStrategy extends EditModeStrategy {
617619
});
618620
};
619621

622+
const move = (next: boolean) => {
623+
assertType(widgetData);
624+
625+
const candidates: Position[] = [];
626+
for (const item of this._session.hunkData.getInfo()) {
627+
if (item.getState() === HunkState.Pending) {
628+
candidates.push(item.getRangesN()[0].getStartPosition().delta(-1));
629+
}
630+
}
631+
if (candidates.length < 2) {
632+
return;
633+
}
634+
for (let i = 0; i < candidates.length; i++) {
635+
if (candidates[i].equals(widgetData.position)) {
636+
let newPos: Position;
637+
if (next) {
638+
newPos = candidates[(i + 1) % candidates.length];
639+
} else {
640+
newPos = candidates[(i + candidates.length - 1) % candidates.length];
641+
}
642+
this._zone.updatePositionAndHeight(newPos);
643+
renderHunks();
644+
break;
645+
}
646+
}
647+
};
648+
620649
const zoneLineNumber = this._zone.position!.lineNumber;
621650
const myDistance = zoneLineNumber <= hunkRanges[0].startLineNumber
622651
? hunkRanges[0].startLineNumber - zoneLineNumber
@@ -632,6 +661,7 @@ export class LiveStrategy extends EditModeStrategy {
632661
discardHunk,
633662
toggleDiff: !hunkData.isInsertion() ? toggleDiff : undefined,
634663
remove,
664+
move
635665
};
636666

637667
this._hunkDisplayData.set(hunkData, data);
@@ -674,6 +704,7 @@ export class LiveStrategy extends EditModeStrategy {
674704
this.toggleDiff = widgetData.toggleDiff;
675705
this.acceptHunk = async () => widgetData!.acceptHunk();
676706
this.discardHunk = async () => widgetData!.discardHunk();
707+
this.move = next => widgetData!.move(next);
677708

678709
} else if (this._hunkDisplayData.size > 0) {
679710
// everything accepted or rejected

0 commit comments

Comments
 (0)