diff --git a/extensions/copilot/package.json b/extensions/copilot/package.json index 76e5801e04d..aa739ed71de 100644 --- a/extensions/copilot/package.json +++ b/extensions/copilot/package.json @@ -2426,19 +2426,14 @@ "markdownDescription": "%github.copilot.nextEditSuggestions.enabled%", "scope": "language-overridable" }, - "github.copilot.nextEditSuggestions.nextCursorPrediction.enabled": { - "type": "string", - "enum": [ - "off", - "onlyWithEdit", - "jump" - ], - "default": "off", + "github.copilot.nextEditSuggestions.extendedRange": { + "type": "boolean", + "default": false, "tags": [ "nextEditSuggestions", "onExp" ], - "markdownDescription": "%github.copilot.nextEditSuggestions.nextCursorPrediction.enabled%" + "markdownDescription": "%github.copilot.nextEditSuggestions.extendedRange%" }, "github.copilot.nextEditSuggestions.fixes": { "type": "boolean", diff --git a/extensions/copilot/package.nls.json b/extensions/copilot/package.nls.json index 163d50a4bf7..02f59c31481 100644 --- a/extensions/copilot/package.nls.json +++ b/extensions/copilot/package.nls.json @@ -91,7 +91,7 @@ "github.copilot.config.edits.enabled": "Whether to enable the Copilot Edits feature.", "github.copilot.config.codesearch.enabled": "Whether to enable agentic codesearch when using `#codebase`.", "github.copilot.nextEditSuggestions.enabled": "Whether to enable next edit suggestions (NES).\n\nNES can propose a next edit based on your recent changes. [Learn more](https://aka.ms/vscode-nes) about next edit suggestions.", - "github.copilot.nextEditSuggestions.nextCursorPrediction.enabled": "Controls when next cursor line prediction is enabled for next edit suggestions (NES).\n\n- `off`: Disable next cursor line prediction.\n- `onlyWithEdit` (recommended): Enable next cursor line prediction only when an edit is proposed.\n- `jump`: Always enable next cursor line prediction, even if no edit is proposed.", + "github.copilot.nextEditSuggestions.extendedRange": "Whether to allow next edit suggestions (NES) to modify code farther away from the cursor position.", "github.copilot.nextEditSuggestions.fixes": "Whether to offer fixes for diagnostics via next edit suggestions (NES).", "github.copilot.nextEditSuggestions.allowWhitespaceOnlyChanges": "Whether to allow whitespace-only changes be proposed by next edit suggestions (NES).", "github.copilot.chat.copilotDebugCommand.enabled": "Whether the `copilot-debug` command is enabled in the terminal.", diff --git a/extensions/copilot/src/extension/configuration/vscode-node/configurationMigration.ts b/extensions/copilot/src/extension/configuration/vscode-node/configurationMigration.ts index 13c2ca0c582..c9756cbdb2a 100644 --- a/extensions/copilot/src/extension/configuration/vscode-node/configurationMigration.ts +++ b/extensions/copilot/src/extension/configuration/vscode-node/configurationMigration.ts @@ -162,17 +162,19 @@ ConfigurationMigrationRegistry.registerConfigurationMigrations([{ } }]); +const oldCursorJumpKey = 'github.copilot.chat.advanced.inlineEdits.nextCursorPrediction.enabled'; +const newCursorJumpKey = 'github.copilot.nextEditSuggestions.extendedRange'; ConfigurationMigrationRegistry.registerConfigurationMigrations([{ - key: 'github.copilot.chat.advanced.inlineEdits.nextCursorPrediction.enabled', - migrateFn: async (value: NextCursorLinePrediction | /* the rest is for backward compat: */ 'labelOnlyWithEdit' | boolean | undefined) => { - if (typeof value === 'boolean') { - value = value ? NextCursorLinePrediction.OnlyWithEdit : NextCursorLinePrediction.Off; - } else if (value === 'labelOnlyWithEdit') { - value = NextCursorLinePrediction.OnlyWithEdit; + key: oldCursorJumpKey, + migrateFn: async (value: boolean | /* the rest is for backward compat: */ NextCursorLinePrediction | 'labelOnlyWithEdit' | boolean | undefined) => { + if (typeof value === 'string') { // for backward compatibility -- one of 'onlyWithEdit' | 'jump' | 'labelOnlyWithEdit' + value = true; + } else if (value === undefined) { + value = false; } return [ - ['github.copilot.nextEditSuggestions.nextCursorPrediction.enabled', { value }], - ['github.copilot.chat.advanced.inlineEdits.nextCursorPrediction.enabled', { value: undefined }] + [newCursorJumpKey, { value }], + [oldCursorJumpKey, { value: undefined }] ]; } }]); diff --git a/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts b/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts index 0049411fd2c..2a6a67b1b43 100644 --- a/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts +++ b/extensions/copilot/src/extension/xtab/node/xtabNextCursorPredictor.ts @@ -43,13 +43,21 @@ export class XtabNextCursorPredictor { return undefined; } - const originalNextCursorLinePrediction = this.configService.getExperimentBasedConfig(ConfigKey.InlineEditsNextCursorPredictionEnabled, this.expService); + // the cast is for backward compatibility with older experiments + const originalNextCursorLinePrediction = this.configService.getExperimentBasedConfig(ConfigKey.InlineEditsNextCursorPredictionEnabled, this.expService) as (NextCursorLinePrediction | boolean | undefined); switch (originalNextCursorLinePrediction) { + case true: + return NextCursorLinePrediction.OnlyWithEdit; + + case false: + case undefined: + return undefined; + + // for backward compatibility case NextCursorLinePrediction.OnlyWithEdit: case NextCursorLinePrediction.Jump: - case NextCursorLinePrediction.Off: - return originalNextCursorLinePrediction; + return NextCursorLinePrediction.OnlyWithEdit; default: assertNever(originalNextCursorLinePrediction); diff --git a/extensions/copilot/src/extension/xtab/node/xtabProvider.ts b/extensions/copilot/src/extension/xtab/node/xtabProvider.ts index a687a7ecce9..4eaecebc33f 100644 --- a/extensions/copilot/src/extension/xtab/node/xtabProvider.ts +++ b/extensions/copilot/src/extension/xtab/node/xtabProvider.ts @@ -827,7 +827,7 @@ export class XtabProvider implements IStatelessNextEditProvider { } const nextCursorLinePrediction = this.nextCursorPredictor.determineEnablement(); - if (nextCursorLinePrediction !== undefined && retryState === RetryState.NotRetrying && nextCursorLinePrediction !== NextCursorLinePrediction.Off) { + if (nextCursorLinePrediction !== undefined && retryState === RetryState.NotRetrying) { const nextCursorLineR = await this.nextCursorPredictor.predictNextCursorPosition(promptPieces, tracer); if (cancellationToken.isCancellationRequested) { pushEdit(Result.error(new NoNextEditReason.NoSuggestions(request.documentBeforeEdits, editWindow))); diff --git a/extensions/copilot/src/extension/xtab/test/node/xtabNextCursorPredictor.spec.ts b/extensions/copilot/src/extension/xtab/test/node/xtabNextCursorPredictor.spec.ts index 0949f10846c..a7976db562b 100644 --- a/extensions/copilot/src/extension/xtab/test/node/xtabNextCursorPredictor.spec.ts +++ b/extensions/copilot/src/extension/xtab/test/node/xtabNextCursorPredictor.spec.ts @@ -100,7 +100,7 @@ describe('XtabNextCursorPredictor', () => { // Enable the next cursor prediction feature const configService = accessor.get(IConfigurationService); - configService.setConfig(ConfigKey.InlineEditsNextCursorPredictionEnabled, NextCursorLinePrediction.OnlyWithEdit); + configService.setConfig(ConfigKey.InlineEditsNextCursorPredictionEnabled, true); configService.setConfig(ConfigKey.TeamInternal.InlineEditsNextCursorPredictionModelName, 'test-model'); }); diff --git a/extensions/copilot/src/platform/configuration/common/configurationService.ts b/extensions/copilot/src/platform/configuration/common/configurationService.ts index 2938b21a0b3..bf354be4754 100644 --- a/extensions/copilot/src/platform/configuration/common/configurationService.ts +++ b/extensions/copilot/src/platform/configuration/common/configurationService.ts @@ -14,7 +14,6 @@ import * as types from '../../../util/vs/base/common/types'; import { ICopilotTokenStore } from '../../authentication/common/copilotTokenStore'; import { isPreRelease, packageJson } from '../../env/common/packagejson'; import { JointCompletionsProviderStrategy, JointCompletionsProviderTriggerChangeStrategy } from '../../inlineEdits/common/dataTypes/jointCompletionsProviderOptions'; -import { NextCursorLinePrediction } from '../../inlineEdits/common/dataTypes/nextCursorLinePrediction'; import * as xtabPromptOptions from '../../inlineEdits/common/dataTypes/xtabPromptOptions'; import { LANGUAGE_CONTEXT_ENABLED_LANGUAGES, LanguageContextLanguages } from '../../inlineEdits/common/dataTypes/xtabPromptOptions'; import { ResponseProcessor } from '../../inlineEdits/common/responseProcessor'; @@ -872,7 +871,8 @@ export namespace ConfigKey { export const InlineEditsEnabled = defineSetting('nextEditSuggestions.enabled', ConfigType.ExperimentBased, false); export const InlineEditsEnableDiagnosticsProvider = defineSetting('nextEditSuggestions.fixes', ConfigType.ExperimentBased, true); export const InlineEditsAllowWhitespaceOnlyChanges = defineSetting('nextEditSuggestions.allowWhitespaceOnlyChanges', ConfigType.ExperimentBased, true); - export const InlineEditsNextCursorPredictionEnabled = defineSetting('nextEditSuggestions.nextCursorPrediction.enabled', ConfigType.ExperimentBased, NextCursorLinePrediction.Off); + /** Because of migration the value returned may be `boolean | "onlyWithEdit" | "jump" | undefined` */ + export const InlineEditsNextCursorPredictionEnabled = defineSetting('nextEditSuggestions.extendedRange', ConfigType.ExperimentBased, false, undefined, { oldKey: 'chat.advanced.inlineEdits.nextCursorPrediction.enabled' }); export const NewWorkspaceCreationAgentEnabled = defineSetting('chat.newWorkspaceCreation.enabled', ConfigType.Simple, true); export const NewWorkspaceUseContext7 = defineSetting('chat.newWorkspace.useContext7', ConfigType.Simple, false); export const SummarizeAgentConversationHistory = defineSetting('chat.summarizeAgentConversationHistory.enabled', ConfigType.Simple, true); diff --git a/extensions/copilot/src/platform/inlineEdits/common/dataTypes/nextCursorLinePrediction.ts b/extensions/copilot/src/platform/inlineEdits/common/dataTypes/nextCursorLinePrediction.ts index f099fb4cac4..a5f8fa2e832 100644 --- a/extensions/copilot/src/platform/inlineEdits/common/dataTypes/nextCursorLinePrediction.ts +++ b/extensions/copilot/src/platform/inlineEdits/common/dataTypes/nextCursorLinePrediction.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ export enum NextCursorLinePrediction { - Off = 'off', Jump = 'jump', OnlyWithEdit = 'onlyWithEdit', }