Skip to content
This repository was archived by the owner on May 20, 2026. It is now read-only.

Commit cec74dc

Browse files
authored
Merge pull request #4449 from microsoft/ulugbekna/interior-catshark
revert last 3 PRs
2 parents b4c41f0 + 411f967 commit cec74dc

8 files changed

Lines changed: 24 additions & 483 deletions

File tree

src/extension/inlineEdits/common/editRebase.ts

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@ import { ILinesDiffComputerOptions } from '../../../util/vs/editor/common/diff/l
1515
const TROUBLESHOOT_EDIT_CONSISTENCY = false;
1616

1717
export interface NesRebaseConfigs {
18-
/**
19-
* When enabled, if the user's typed text can be aligned as a subsequence of the
20-
* suggestion's insert text, the rebase absorbs it instead of failing.
21-
* For example, "()" aligns with "(n: number): number" because "(" and ")"
22-
* appear in that order; "(n: )" aligns similarly. Text like "abc" that cannot
23-
* be matched as a subsequence is not absorbed.
24-
*/
25-
readonly absorbSubsequenceTyping?: boolean;
2618
}
2719

2820
export class EditDataWithIndex implements IEditData<EditDataWithIndex> {
@@ -239,21 +231,7 @@ function tryRebaseEdits<T extends IEditData<T>>(content: string, ours: Annotated
239231
export const maxAgreementOffset = 10; // If the user's typing is more than this into the suggestion we consider it a miss.
240232
export const maxImperfectAgreementLength = 5; // If the user's typing is longer than this and the suggestion is not a perfect match we consider it a miss.
241233

242-
/** Returns true if every character of `typed` appears in `suggestion` in order (subsequence match). */
243-
function isSubsequenceOf(typed: string, suggestion: string): boolean {
244-
let si = 0;
245-
for (let ti = 0; ti < typed.length; ti++) {
246-
const idx = suggestion.indexOf(typed[ti], si);
247-
if (idx === -1) {
248-
return false;
249-
}
250-
si = idx + 1;
251-
}
252-
return true;
253-
}
254-
255234
function agreementIndexOf<T extends IEditData<T>>(content: string, ourE: AnnotatedStringReplacement<T>, baseE: StringReplacement, previousBaseE: StringReplacement | undefined, ourNewTextOffset: number, resolution: 'strict' | 'lenient', nesConfigs: NesRebaseConfigs) {
256-
const originalBaseNewText = baseE.newText;
257235
const minStart = previousBaseE ? previousBaseE.replaceRange.endExclusive : ourE.replaceRange.start;
258236
if (minStart < baseE.replaceRange.start) {
259237
baseE = new StringReplacement(
@@ -262,20 +240,13 @@ function agreementIndexOf<T extends IEditData<T>>(content: string, ourE: Annotat
262240
);
263241
}
264242
const j = ourE.newText.indexOf(baseE.newText, ourNewTextOffset);
265-
const strictRejected = j !== -1 && resolution === 'strict' && (
266-
j > maxAgreementOffset ||
267-
(j > 0 && baseE.newText.length > maxImperfectAgreementLength)
268-
);
269-
if (j !== -1 && !strictRejected) {
270-
return j + baseE.newText.length;
243+
if (resolution === 'strict' && j > maxAgreementOffset) {
244+
return -1;
271245
}
272-
// User typed text not found in suggestion (or rejected by strict limits) — absorb if it aligns as a subsequence.
273-
// Guard: only attempt for short typed text to avoid expensive matching on long pastes
274-
// and to stay consistent with the existing strict safeguards.
275-
if (nesConfigs.absorbSubsequenceTyping && originalBaseNewText.length <= maxImperfectAgreementLength && isSubsequenceOf(originalBaseNewText, ourE.newText.substring(ourNewTextOffset))) {
276-
return ourNewTextOffset;
246+
if (resolution === 'strict' && j > 0 && baseE.newText.length > maxImperfectAgreementLength) {
247+
return -1;
277248
}
278-
return -1;
249+
return j !== -1 ? j + baseE.newText.length : -1;
279250
}
280251

281252
function computeDiff(original: string, modified: string, offset: number, editData: EditDataWithIndex, options: ILinesDiffComputerOptions): AnnotatedStringReplacement<EditDataWithIndex>[] | undefined {

src/extension/inlineEdits/node/nextEditCache.ts

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { mapObservableArrayCached } from '../../../util/vs/base/common/observabl
1515
import { AnnotatedStringReplacement, StringEdit, StringReplacement } from '../../../util/vs/editor/common/core/edits/stringEdit';
1616
import { OffsetRange } from '../../../util/vs/editor/common/core/ranges/offsetRange';
1717
import { StringText } from '../../../util/vs/editor/common/core/text/abstractText';
18-
import { checkEditConsistency, EditDataWithIndex, NesRebaseConfigs, tryRebase } from '../common/editRebase';
18+
import { checkEditConsistency, EditDataWithIndex, tryRebase } from '../common/editRebase';
1919
import { NextEditFetchRequest } from './nextEditProvider';
2020

2121
export interface CachedEditOpts {
@@ -62,8 +62,8 @@ export class NextEditCache extends Disposable {
6262
constructor(
6363
public readonly workspace: ObservableWorkspace,
6464
private readonly _logService: ILogService,
65-
private readonly _configService: IConfigurationService,
66-
private readonly _expService: IExperimentationService,
65+
configService: IConfigurationService,
66+
expService: IExperimentationService,
6767
) {
6868
super();
6969

@@ -81,7 +81,7 @@ export class NextEditCache extends Disposable {
8181
}
8282
// if editor-change triggering is allowed,
8383
// it means an edit in file A can result in a cached edit for file B to be less relevant than with the edits in file A included
84-
if (this._configService.getExperimentBasedConfig(ConfigKey.Advanced.InlineEditsTriggerOnEditorChangeAfterSeconds, this._expService) !== undefined) {
84+
if (configService.getExperimentBasedConfig(ConfigKey.Advanced.InlineEditsTriggerOnEditorChangeAfterSeconds, expService) !== undefined) {
8585
for (const [k, v] of this._sharedCache.entries()) {
8686
if (v.docId !== doc.id) {
8787
this._sharedCache.deleteKey(k);
@@ -112,26 +112,20 @@ export class NextEditCache extends Disposable {
112112
docCache.setNoNextEdit(documentContents, editWindow, source);
113113
}
114114

115-
private _getNesRebaseConfigs(): NesRebaseConfigs {
116-
return {
117-
absorbSubsequenceTyping: this._configService.getExperimentBasedConfig(ConfigKey.TeamInternal.InlineEditsAbsorbSubsequenceTyping, this._expService),
118-
};
119-
}
120-
121115
public lookupNextEdit(docId: DocumentId, currentDocumentContents: StringText, currentSelection: readonly OffsetRange[]): CachedOrRebasedEdit | undefined {
122116
const docCache = this._documentCaches.get(docId);
123117
if (!docCache) {
124118
return undefined;
125119
}
126-
return docCache.lookupNextEdit(currentDocumentContents, currentSelection, this._getNesRebaseConfigs());
120+
return docCache.lookupNextEdit(currentDocumentContents, currentSelection);
127121
}
128122

129123
public tryRebaseCacheEntry(cachedEdit: CachedEdit, currentDocumentContents: StringText, currentSelection: readonly OffsetRange[]): CachedOrRebasedEdit | undefined {
130124
const docCache = this._documentCaches.get(cachedEdit.docId);
131125
if (!docCache) {
132126
return undefined;
133127
}
134-
return docCache.tryRebaseCacheEntry(cachedEdit, currentDocumentContents, currentSelection, this._getNesRebaseConfigs());
128+
return docCache.tryRebaseCacheEntry(cachedEdit, currentDocumentContents, currentSelection);
135129
}
136130

137131
public rejectedNextEdit(requestId: string): void {
@@ -234,7 +228,7 @@ class DocumentEditCache {
234228
}
235229
}
236230

237-
public lookupNextEdit(currentDocumentContents: StringText, currentSelection: readonly OffsetRange[], nesRebaseConfigs: NesRebaseConfigs): CachedOrRebasedEdit | undefined {
231+
public lookupNextEdit(currentDocumentContents: StringText, currentSelection: readonly OffsetRange[]): CachedOrRebasedEdit | undefined {
238232
// TODO@chrmarti: Update entries i > 1 with user edits and edit window and start tracking.
239233
const key = this._getKey(currentDocumentContents.value);
240234
const cachedEdit = this._sharedCache.get(key);
@@ -252,15 +246,15 @@ class DocumentEditCache {
252246
return cachedEdit;
253247
}
254248
for (const cachedEdit of this._trackedCachedEdits) {
255-
const rebased = this.tryRebaseCacheEntry(cachedEdit, currentDocumentContents, currentSelection, nesRebaseConfigs);
249+
const rebased = this.tryRebaseCacheEntry(cachedEdit, currentDocumentContents, currentSelection);
256250
if (rebased) {
257251
return rebased;
258252
}
259253
}
260254
return undefined;
261255
}
262256

263-
public tryRebaseCacheEntry(cachedEdit: CachedEdit, currentDocumentContents: StringText, currentSelection: readonly OffsetRange[], nesRebaseConfigs: NesRebaseConfigs): CachedEdit | undefined {
257+
public tryRebaseCacheEntry(cachedEdit: CachedEdit, currentDocumentContents: StringText, currentSelection: readonly OffsetRange[]): CachedEdit | undefined {
264258
const logger = this._logger.createSubLogger('tryRebaseCacheEntry');
265259
if (cachedEdit.userEditSince && !cachedEdit.rebaseFailed) {
266260
const originalEdits = cachedEdit.edits || (cachedEdit.edit ? [cachedEdit.edit] : []);
@@ -273,7 +267,7 @@ class DocumentEditCache {
273267
: [cachedEdit.editWindow];
274268

275269
for (const window of windowsToTry) {
276-
const res = tryRebase(cachedEdit.documentBeforeEdit.value, window, originalEdits, cachedEdit.detailedEdits, cachedEdit.userEditSince, currentDocumentContents.value, currentSelection, 'strict', logger, nesRebaseConfigs);
270+
const res = tryRebase(cachedEdit.documentBeforeEdit.value, window, originalEdits, cachedEdit.detailedEdits, cachedEdit.userEditSince, currentDocumentContents.value, currentSelection, 'strict', logger);
277271
if (res === 'rebaseFailed') {
278272
cachedEdit.rebaseFailed = true;
279273
return undefined;

0 commit comments

Comments
 (0)