Skip to content

feat: add current file context automatically to chat #5670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 28, 2025
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"extensions/.continue-debug": true
// "sync/**": true
},
"editor.formatOnSave": true,
"eslint.workingDirectories": ["./core"],
"typescript.tsdk": "node_modules/typescript/lib",
"conventionalCommits.showNewVersionNotes": false,
Expand Down
5 changes: 5 additions & 0 deletions core/config/sharedConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const sharedConfigSchema = z
useChromiumForDocsCrawling: z.boolean(),
readResponseTTS: z.boolean(),
promptPath: z.string(),
useCurrentFileAsContext: z.boolean(),

// `ui` in `ContinueConfig`
showSessionTabs: z.boolean(),
Expand Down Expand Up @@ -166,6 +167,10 @@ export function modifyAnyConfigWithSharedConfig<
if (sharedConfig.readResponseTTS !== undefined) {
configCopy.experimental.readResponseTTS = sharedConfig.readResponseTTS;
}
if (sharedConfig.useCurrentFileAsContext !== undefined) {
configCopy.experimental.useCurrentFileAsContext =
sharedConfig.useCurrentFileAsContext;
}

return configCopy;
}
5 changes: 5 additions & 0 deletions core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1334,6 +1334,11 @@ export interface ExperimentalConfig {
*/
useChromiumForDocsCrawling?: boolean;
modelContextProtocolServers?: ExperimentalMCPOptions[];

/**
* If enabled, will add the current file as context.
*/
useCurrentFileAsContext?: boolean;
}

export interface AnalyticsConfig {
Expand Down
10 changes: 7 additions & 3 deletions extensions/vscode/src/VsCodeIde.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,10 @@ class VsCodeIde implements IDE {
const pathToLastModified: FileStatsMap = {};
await Promise.all(
files.map(async (file) => {
const stat = await this.ideUtils.stat(vscode.Uri.parse(file), false /* No need to catch ENOPRO exceptions */);
const stat = await this.ideUtils.stat(
vscode.Uri.parse(file),
false /* No need to catch ENOPRO exceptions */,
);
pathToLastModified[file] = {
lastModified: stat!.mtime,
size: stat!.size,
Expand Down Expand Up @@ -401,7 +404,8 @@ class VsCodeIde implements IDE {
const configs: ContinueRcJson[] = [];
for (const workspaceDir of workspaceDirs) {
const files = await this.ideUtils.readDirectory(workspaceDir);
if (files === null) {//Unlikely, but just in case...
if (files === null) {
//Unlikely, but just in case...
continue;
}
for (const [filename, type] of files) {
Expand Down Expand Up @@ -753,7 +757,7 @@ class VsCodeIde implements IDE {

async listDir(dir: string): Promise<[string, FileType][]> {
const entries = await this.ideUtils.readDirectory(vscode.Uri.parse(dir));
return entries === null? [] : entries as any;
return entries === null ? [] : (entries as any);
}

private getIdeSettingsSync(): IdeSettings {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { InputModifiers } from "core";
import { rifWithContentsToContextItem } from "core/commands/util";
import { MutableRefObject } from "react";
import { useWebviewListener } from "../../../hooks/useWebviewListener";
import { useAppSelector } from "../../../redux/hooks";
import { clearCodeToEdit } from "../../../redux/slices/editState";
import { setNewestToolbarPreviewForInput } from "../../../redux/slices/sessionSlice";
import { AppDispatch } from "../../../redux/store";
import { loadSession, saveCurrentSession } from "../../../redux/thunks/session";
import { CodeBlock, PromptBlock } from "./extensions";
import { insertCurrentFileContextMention } from "./utils/insertCurrentFileContextMention";

/**
* Hook for setting up main editor specific webview listeners
Expand All @@ -27,6 +29,14 @@ export function useMainEditorWebviewListeners({
inputId: string;
editorFocusedRef: MutableRefObject<boolean | undefined>;
}) {
const activeContextProviders = useAppSelector(
(state) => state.config.config.contextProviders,
);
const useCurrentFileAsContext = useAppSelector(
(state) => state.config.config.experimental?.useCurrentFileAsContext,
);
const isInEdit = useAppSelector((state) => state.session.isInEdit);

useWebviewListener(
"isContinueInputFocused",
async () => {
Expand Down Expand Up @@ -178,4 +188,14 @@ export function useMainEditorWebviewListeners({
},
[],
);

useWebviewListener(
"newSession",
async () => {
// do not insert current file context mention if we are in edit mode or if addFileContext is disabled
if (!editor || isInEdit || !useCurrentFileAsContext) return;
insertCurrentFileContextMention(editor, activeContextProviders);
},
[editor, activeContextProviders, isInEdit, useCurrentFileAsContext],
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Editor } from "@tiptap/core";
import { ContextProviderDescription } from "core";
import * as ContinueExtensions from "../extensions";

/**
* inserts the current file context as a removable mention in the editor area
*
* uses tiptap's `create` method to create a new node under the hood
*/
export function insertCurrentFileContextMention(
editor: Editor,
contextProviders: ContextProviderDescription[],
) {
const foundCurrentFileProvider = contextProviders.find(
(provider) => provider.title === "currentFile",
);

if (foundCurrentFileProvider) {
const node = editor.schema.nodes[ContinueExtensions.Mention.name].create({
name: foundCurrentFileProvider.displayTitle,
description: foundCurrentFileProvider.description,
id: foundCurrentFileProvider.title,
label: foundCurrentFileProvider.displayTitle,
renderInlineAs: foundCurrentFileProvider.renderInlineAs,
type: foundCurrentFileProvider.type,
itemType: "contextProvider",
});

editor
.chain()
.insertContent([node.toJSON(), { type: "text", text: " " }]) // add a space after the mention
.run();
}
}
16 changes: 14 additions & 2 deletions gui/src/pages/config/UserSettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ export function UserSettingsForm() {
const autoAcceptEditToolDiffs = config.ui?.autoAcceptEditToolDiffs ?? false;
const displayRawMarkdown = config.ui?.displayRawMarkdown ?? false;
const disableSessionTitles = config.disableSessionTitles ?? false;
const useCurrentFileAsContext =
config.experimental?.useCurrentFileAsContext ?? false;

const allowAnonymousTelemetry = config.allowAnonymousTelemetry ?? true;
const disableIndexing = config.disableIndexing ?? false;
Expand Down Expand Up @@ -336,7 +338,7 @@ export function UserSettingsForm() {
</form>
</div>

<div className="flex flex-col gap-2">
<div className="flex flex-col gap-x-2 gap-y-4">
<div
className="flex cursor-pointer items-center gap-2 text-left text-sm font-semibold"
onClick={() => setShowExperimental(!showExperimental)}
Expand All @@ -353,7 +355,7 @@ export function UserSettingsForm() {
showExperimental ? "max-h-40" : "max-h-0"
}`}
>
<div className="flex flex-col gap-1 pl-6">
<div className="flex flex-col gap-x-1 gap-y-4 pl-6">
<ToggleSwitch
isToggled={autoAcceptEditToolDiffs}
onToggle={() =>
Expand All @@ -374,6 +376,16 @@ export function UserSettingsForm() {
</>
}
/>

<ToggleSwitch
isToggled={useCurrentFileAsContext}
onToggle={() =>
handleUpdate({
useCurrentFileAsContext: !useCurrentFileAsContext,
})
}
text="Add Current File by Default"
/>
</div>
</div>
</div>
Expand Down
Loading