Skip to content

Commit 88c7342

Browse files
authored
Merge pull request #2878 from continuedev/nate/autocomplete-cleaning
Nate/autocomplete cleaning
2 parents 36f90f3 + a5f4380 commit 88c7342

File tree

13 files changed

+154
-89
lines changed

13 files changed

+154
-89
lines changed

core/autocomplete/context/root-path-context/RootPathContextService.ts

+29-30
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { LRUCache } from "lru-cache";
44
import Parser from "web-tree-sitter";
55

66
import { IDE } from "../../..";
7-
import { getQueryForFile, TSQueryType } from "../../../util/treeSitter";
7+
import { getQueryForFile } from "../../../util/treeSitter";
88
import { AstPath } from "../../util/ast";
99
import { ImportDefinitionsService } from "../ImportDefinitionsService";
1010
import { AutocompleteSnippet } from "../ranking";
@@ -27,6 +27,7 @@ export class RootPathContextService {
2727
"program",
2828
"function_declaration",
2929
"method_definition",
30+
"class_declaration",
3031
]);
3132

3233
/**
@@ -54,23 +55,12 @@ export class RootPathContextService {
5455
case "program":
5556
this.importDefinitionsService.get(filepath);
5657
break;
57-
case "function_declaration":
58+
default:
5859
query = await getQueryForFile(
5960
filepath,
60-
TSQueryType.FunctionDeclaration,
61+
`root-path-context-queries/${node.type}`,
6162
);
6263
break;
63-
case "method_definition":
64-
query = await getQueryForFile(filepath, TSQueryType.MethodDefinition);
65-
break;
66-
case "function_definition":
67-
query = await getQueryForFile(filepath, TSQueryType.FunctionDefinition);
68-
break;
69-
case "method_declaration":
70-
query = await getQueryForFile(filepath, TSQueryType.MethodDeclaration);
71-
break;
72-
default:
73-
break;
7464
}
7565

7666
if (!query) {
@@ -79,28 +69,37 @@ export class RootPathContextService {
7969

8070
await Promise.all(
8171
query.matches(node).map(async (match) => {
82-
const startPosition = match.captures[0].node.startPosition;
83-
const endPosition = match.captures[0].node.endPosition;
84-
const definitions = await this.ide.gotoDefinition({
85-
filepath,
86-
position: {
87-
line: endPosition.row,
88-
character: endPosition.column,
89-
},
90-
});
91-
const newSnippets = await Promise.all(
92-
definitions.map(async (def) => ({
93-
...def,
94-
contents: await this.ide.readRangeInFile(def.filepath, def.range),
95-
})),
96-
);
97-
snippets.push(...newSnippets);
72+
for (const item of match.captures) {
73+
const endPosition = item.node.endPosition;
74+
const newSnippets = await this.getSnippets(filepath, endPosition);
75+
snippets.push(...newSnippets);
76+
}
9877
}),
9978
);
10079

10180
return snippets;
10281
}
10382

83+
private async getSnippets(
84+
filepath: string,
85+
endPosition: Parser.Point,
86+
): Promise<AutocompleteSnippet[]> {
87+
const definitions = await this.ide.gotoDefinition({
88+
filepath,
89+
position: {
90+
line: endPosition.row,
91+
character: endPosition.column,
92+
},
93+
});
94+
const newSnippets = await Promise.all(
95+
definitions.map(async (def) => ({
96+
...def,
97+
contents: await this.ide.readRangeInFile(def.filepath, def.range),
98+
})),
99+
);
100+
return newSnippets;
101+
}
102+
104103
async getContextForPath(
105104
filepath: string,
106105
astPath: AstPath,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { testRootPathContext } from "./testUtils";
2+
3+
const TEST_CASES = [
4+
{
5+
description: "function",
6+
fileName: "file1.ts",
7+
range: {
8+
start: { line: 10, character: 2 },
9+
end: { line: 10, character: 24 },
10+
},
11+
positions: [
12+
{ row: 9, column: 34 }, // Person
13+
{ row: 9, column: 44 }, // Address
14+
],
15+
},
16+
{
17+
description: "class method",
18+
fileName: "file1.ts",
19+
range: {
20+
start: { line: 22, character: 4 },
21+
end: { line: 22, character: 30 },
22+
},
23+
positions: [
24+
{ row: 13, column: 29 }, // BaseClass
25+
{ row: 13, column: 55 }, // FirstInterface
26+
{ row: 13, column: 72 }, // SecondInterface
27+
{ row: 21, column: 33 }, // Person
28+
{ row: 21, column: 43 }, // Address
29+
],
30+
},
31+
];
32+
33+
describe("RootPathContextService", () => {
34+
describe("TypeScript should return expected snippets when editing inside a:", () => {
35+
test.each(TEST_CASES)(
36+
"should look for correct type definitions when editing inside a $description",
37+
async ({ fileName, range, positions }) => {
38+
await testRootPathContext("typescript", fileName, range, positions);
39+
},
40+
);
41+
});
42+
});

core/autocomplete/context/root-path-context/RootPathContextService.test.ts core/autocomplete/context/root-path-context/test/testUtils.ts

+27-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import { jest } from "@jest/globals";
12
import fs from "fs";
23
import path from "path";
34

4-
import { Range } from "../../..";
5-
import { testIde } from "../../../test/util/fixtures";
6-
import { getAst, getTreePathAtCursor } from "../../util/ast";
7-
import { ImportDefinitionsService } from "../ImportDefinitionsService";
8-
9-
import { RootPathContextService } from "./RootPathContextService";
5+
import Parser from "web-tree-sitter";
6+
import { Range } from "../../../..";
7+
import { testIde } from "../../../../test/util/fixtures";
8+
import { getAst, getTreePathAtCursor } from "../../../util/ast";
9+
import { ImportDefinitionsService } from "../../ImportDefinitionsService";
10+
import { RootPathContextService } from "../RootPathContextService";
1011

1112
function splitTextAtRange(fileContent: string, range: Range): [string, string] {
1213
const lines = fileContent.split("\n");
@@ -42,12 +43,21 @@ export async function testRootPathContext(
4243
folderName: string,
4344
relativeFilepath: string,
4445
rangeToFill: Range,
45-
expectedSnippets: string[],
46+
expectedDefinitionPositions: Parser.Point[],
4647
) {
48+
// Create a mocked instance of RootPathContextService
4749
const ide = testIde;
4850
const importDefinitionsService = new ImportDefinitionsService(ide);
4951
const service = new RootPathContextService(importDefinitionsService, ide);
5052

53+
const getSnippetsMock = jest
54+
// @ts-ignore
55+
.spyOn(service, "getSnippets")
56+
// @ts-ignore
57+
.mockImplementation(async (_filepath, _endPosition) => {
58+
return [];
59+
});
60+
5161
// Copy the folder to the test directory
5262
const folderPath = path.join(
5363
__dirname,
@@ -77,23 +87,17 @@ export async function testRootPathContext(
7787
}
7888

7989
const treePath = await getTreePathAtCursor(ast, prefix.length);
80-
const snippets = await service.getContextForPath(startPath, treePath);
90+
await service.getContextForPath(startPath, treePath);
8191

82-
expectedSnippets.forEach((expectedSnippet) => {
83-
const found = snippets.find((snippet) =>
84-
snippet.contents.includes(expectedSnippet),
85-
);
86-
expect(found).toBeDefined();
87-
});
88-
}
92+
expect(getSnippetsMock).toHaveBeenCalledTimes(
93+
expectedDefinitionPositions.length,
94+
);
8995

90-
describe("RootPathContextService", () => {
91-
it.skip("should be true", async () => {
92-
await testRootPathContext(
93-
"typescript",
94-
"file1.ts",
95-
{ start: { line: 3, character: 2 }, end: { line: 3, character: 24 } },
96-
["export interface Person", "export interface Address"],
96+
expectedDefinitionPositions.forEach((position, index) => {
97+
expect(getSnippetsMock).toHaveBeenNthCalledWith(
98+
index + 1,
99+
expect.any(String), // filepath argument
100+
position,
97101
);
98102
});
99-
});
103+
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
import { Address, Person } from "./types";
1+
import {
2+
Address,
3+
Person,
4+
BaseClass,
5+
FirstInterface,
6+
SecondInterface,
7+
// @ts-ignore
8+
} from "./types";
29

310
function getAddress(person: Person): Address {
411
return person.address;
512
}
613

7-
class Group {
14+
class Group extends BaseClass implements FirstInterface, SecondInterface {
815
people: Person[];
916

1017
constructor(people: Person[]) {
18+
super();
1119
this.people = people;
1220
}
21+
22+
getPersonAddress(person: Person): Address {
23+
return getAddress(person);
24+
}
1325
}

core/autocomplete/context/root-path-context/test/typescript/types.ts

-11
This file was deleted.

core/config/load.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import { execSync } from "child_process";
2+
import * as JSONC from "comment-json";
23
import * as fs from "fs";
34
import os from "os";
45
import path from "path";
56

6-
import * as JSONC from "comment-json";
77
import * as tar from "tar";
8-
98
import {
109
BrowserSerializedContinueConfig,
1110
Config,
@@ -72,7 +71,6 @@ import {
7271
} from "./promptFile.js";
7372
import { ConfigValidationError, validateConfig } from "./validation.js";
7473

75-
7674
export interface ConfigResult<T> {
7775
config: T | undefined;
7876
errors: ConfigValidationError[] | undefined;
@@ -138,6 +136,13 @@ function loadSerializedConfig(
138136
config.allowAnonymousTelemetry = true;
139137
}
140138

139+
if (config.ui?.getChatTitles === undefined) {
140+
config.ui = {
141+
...config.ui,
142+
getChatTitles: true,
143+
};
144+
}
145+
141146
if (ideSettings.remoteConfigServerUrl) {
142147
try {
143148
const remoteConfigJson = resolveSerializedConfig(

core/index.d.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,7 @@ export interface ContinueUIConfig {
944944
fontSize?: number;
945945
displayRawMarkdown?: boolean;
946946
showChatScrollbar?: boolean;
947+
getChatTitles?: boolean;
947948
}
948949

949950
interface ContextMenuConfig {
@@ -1006,11 +1007,6 @@ interface ExperimentalConfig {
10061007
*/
10071008
readResponseTTS?: boolean;
10081009

1009-
/**
1010-
* Prompt the user's LLM for a title given the current chat content
1011-
*/
1012-
getChatTitles?: boolean;
1013-
10141010
/**
10151011
* If set to true, we will attempt to pull down and install an instance of Chromium
10161012
* that is compatible with the current version of Puppeteer.

core/util/chatDescriber.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { stripImages } from "../llm/images";
33

44
import { removeQuotesAndEscapes } from ".";
55

6-
import type { IMessenger } from "./messenger";
76
import type { FromCoreProtocol, ToCoreProtocol } from "../protocol";
7+
import type { IMessenger } from "./messenger";
88

99
/**
1010
* Removes code blocks from a message.
@@ -42,7 +42,7 @@ export class ChatDescriber {
4242
return;
4343
}
4444

45-
completionOptions.maxTokens = 24;
45+
completionOptions.maxTokens = 6;
4646

4747
// Prompt the user's current LLM for the title
4848
const titleResponse = await model.chat(

core/util/treeSitter.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ export enum TSQueryType {
140140

141141
export async function getQueryForFile(
142142
filepath: string,
143-
queryType: TSQueryType,
143+
queryPath: string,
144144
): Promise<Parser.Query | undefined> {
145145
const language = await getLanguageForFile(filepath);
146146
if (!language) {
@@ -154,7 +154,7 @@ export async function getQueryForFile(
154154
...(process.env.NODE_ENV === "test"
155155
? ["extensions", "vscode", "tree-sitter"]
156156
: ["tree-sitter"]),
157-
queryType,
157+
queryPath,
158158
`${fullLangName}.scm`,
159159
);
160160
if (!fs.existsSync(sourcePath)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(
2+
(class_declaration
3+
(class_heritage
4+
(extends_clause
5+
(identifier) @base-class
6+
)
7+
)
8+
)
9+
)
10+
11+
(
12+
(class_declaration
13+
(class_heritage
14+
(implements_clause
15+
(type_identifier) @interface
16+
)
17+
)
18+
)
19+
)

extensions/vscode/tree-sitter/root-path-context-queries/function_declaration/typescript.scm

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
(function_declaration
33
(formal_parameters
44
(_
5-
(type_annotation) @type
5+
(type_annotation) @param_type
66
)
77
)
8+
(type_annotation) @return_type
89
)
910
)

extensions/vscode/tree-sitter/root-path-context-queries/method_definition/typescript.scm

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
(method_definition
33
(formal_parameters
44
(_
5-
(type_annotation) @type
5+
(type_annotation) @param_type
66
)
77
)
8+
(type_annotation) @return_type
89
)
9-
)
10+
)

0 commit comments

Comments
 (0)