Skip to content
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

fix: resolve editor when getting doc context #1793

Merged
merged 5 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 35 additions & 57 deletions lib/shared/src/chat/prompts/vscode-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,45 @@ import { truncateText } from '../../prompt/truncation'
import { answers, displayFileName } from './templates'
import { createSelectionDisplayText, createVSCodeTestSearchPattern, isValidTestFileName } from './utils'

// TODO bea move out of shared
/**
* Gets the currently active text editor instance from the list of visible editors.
* Returns undefined if there are no visible editors.
*
* Checks if selection is empty to handle case where webview panel is focused,
* since that will make activeTextEditor API return undefined.
*/
export function getActiveEditorFromVisibleEditors(): vscode.TextEditor | undefined {
const visibleTextEditors = vscode.window.visibleTextEditors
if (visibleTextEditors.length === 0) {
return undefined
}
// Because webview panel will return undefine so we cannot use
// vscode.window.activeTextEditor to get the current active editor
// when a user has moved to their webview panel for chat
// We will use the first visible editor that is not a
return visibleTextEditors.find(editor => !editor.selection.isEmpty)
}

/**
* Gets the currently active VS Code text document instance if one exists.
* @returns The active VS Code text document, or undefined if none.
*/
export function getCurrentVSCodeDoc(): vscode.TextDocument | undefined {
return getActiveEditorFromVisibleEditors()?.document
}

/**
* Gets the full text content of the currently active VS Code text document.
* @param range - Optional VS Code range to get only a subset of the document text.
* @returns The text content of the active document, or empty string if none.
*/
export function getCurrentVSCodeDocText(range?: vscode.Range): string {
return getCurrentVSCodeDoc()?.getText(range) || ''
}

/**
* Gets file path context.
*
* @param filePath - The path of the file to get context for.
*
* @returns Promise that resolves to context messages for the file.
* The context message contains the truncated file content and file name.
*/
Expand All @@ -50,9 +82,7 @@ export async function getFilePathContext(filePath: string): Promise<ContextMessa

/**
* Gets context messages for terminal output.
*
* @param terminalOutput - The output from the terminal to add to the context.
*
* @returns ContextMessage[] - The context messages containing the truncated
* terminal output.
*/
Expand All @@ -70,7 +100,6 @@ export function getTerminalOutputContext(terminalOutput: string): ContextMessage

/**
* Gets context messages for the current open file's directory.
*
* @param isUnitTestRequest - Whether this is a request for test files only.
* @returns A Promise resolving to ContextMessage[] containing file path context.
*/
Expand All @@ -87,11 +116,9 @@ export async function getCurrentDirContext(isUnitTestRequest: boolean): Promise<

/**
* Gets context messages for the given directory path.
*
* @param directoryPath - The path of the directory to get context for
* @param currentFileName - The name of the currently open file
* @param isUnitTestRequest - Whether this request is to get unit test files
*
* @returns Promise<ContextMessage[]> - A promise resolving to the context messages
* containing file information for the given directory.
*
Expand Down Expand Up @@ -126,10 +153,8 @@ export async function getEditorDirContext(

/**
* Gets context messages for test files related to the given file name.
*
* @param fileName - The name of the file to get test context for
* @param isUnitTestRequest - Whether the request is specifically for unit tests
*
* @returns Promise<ContextMessage[]> - A promise resolving to context messages
* containing information about test files related to the given file name.
*
Expand All @@ -154,9 +179,7 @@ export async function getEditorTestContext(fileName: string, isUnitTestRequest =

/**
* Gets the context for the test file related to the given file name.
*
* @param fileName - The name of the file to find the related test file for.
*
* @returns A Promise resolving to the ContextMessage[] containing the context
* for the found test file. If no related test file is found, returns context for
* other test files in the project.
Expand All @@ -182,10 +205,8 @@ export async function getCurrentTestFileContext(fileName: string, isUnitTest: bo

/**
* Gets context messages for test files related to the given file name.
*
* @param fileName - The name of the file to find related test files for.
* @param isUnitTest - Whether to only look for unit test files.
*
* @returns Promise resolving to ContextMessage[] containing the found test files.
*
* Searches for test files matching the fileName, excluding e2e and integration
Expand All @@ -205,10 +226,8 @@ async function getCodebaseTestFilesContext(fileName: string, isUnitTest: boolean

/**
* Gets context messages for the files in the given directory.
*
* @param dirUri - The URI of the directory to get files from.
* @param filesInDir - The array of file paths in the directory.
*
* @returns A Promise resolving to the ContextMessage[] containing the context.
*
* Loops through the files in the directory, gets the content of each file,
Expand Down Expand Up @@ -252,7 +271,6 @@ export async function getDirContextMessages(

/**
* Gets package.json context from the workspace.
*
* @param filePath - Optional file path to use instead of the active text editor's file.
* @returns A Promise resolving to ContextMessage[] containing package.json context.
* Returns empty array if package.json is not found.
Expand Down Expand Up @@ -292,7 +310,6 @@ export async function getPackageJsonContext(filePath?: string): Promise<ContextM

/**
* Generates context messages for each file in a given directory.
*
* @param dirUri - The URI representing the directory to be analyzed.
* @param filesInDir - An array of tuples containing the name and type of each file in the directory.
* @returns An array of context messages, one for each file in the directory.
Expand Down Expand Up @@ -354,7 +371,6 @@ export async function getCurrentDirFilteredContext(

/**
* Gets context messages for a list of file URIs.
*
* @param files - The array of file URIs to get context messages for.
* @returns A Promise resolving to an array of ContextMessage objects containing context from the files.
*/
Expand All @@ -369,7 +385,6 @@ export async function getContextMessageFromFiles(files: vscode.Uri[]): Promise<C

/**
* Get context messages for the currently open editor tabs.
*
* @param skipDirectory - Optional directory path to skip. Tabs with URIs in this directory will be skipped.
* @returns Promise<ContextMessage[]> - Promise resolving to the array of context messages for the open tabs.
*/
Expand Down Expand Up @@ -539,7 +554,6 @@ export async function getCurrentFileImportsContext(): Promise<ContextMessage[]>
/** HELPERS */
/**
* Checks if a file URI is part of the current workspace.
*
* @param fileToCheck - The file URI to check
* @returns True if the file URI belongs to a workspace folder, false otherwise
*/
Expand All @@ -549,7 +563,6 @@ export function isInWorkspace(fileToCheck: URI): boolean {

/**
* Gets files from a directory, optionally filtering for test files only.
*
* @param dirUri - The URI of the directory to get files from.
* @param testFilesOnly - Whether to only return file names with test in it.
* @returns A Promise resolving to an array of [fileName, fileType] tuples.
Expand Down Expand Up @@ -582,11 +595,9 @@ export const getFilesFromDir = async (

/**
* Finds VS Code workspace files matching a global pattern.
*
* @param globalPattern - The global file search pattern to match.
* @param excludePattern - An optional exclude pattern to filter results.
* @param maxResults - The maximum number of results to return.
*
* @returns A Promise resolving to an array of URI objects for the matching files, up to maxResults.
*/
export async function findVSCodeFiles(globalPattern: string, excludePattern?: string, maxResults = 3): Promise<URI[]> {
Expand All @@ -611,9 +622,7 @@ export async function findVSCodeFiles(globalPattern: string, excludePattern?: st

/**
* Decodes the text contents of a VS Code file URI.
*
* @param fileUri - The VS Code URI of the file to decode.
*
* @returns A Promise resolving to the decoded text contents of the file.
*/
export async function decodeVSCodeTextDoc(fileUri: URI): Promise<string> {
Expand All @@ -628,44 +637,15 @@ export async function decodeVSCodeTextDoc(fileUri: URI): Promise<string> {

/**
* Creates a relative file path using the VS Code workspace APIs.
*
* @param filePath - The absolute file path to convert to a relative path.
* @returns The relative path string for the given file path.
*/
export function createVSCodeRelativePath(filePath: string | URI): string {
return vscode.workspace.asRelativePath(filePath)
}

/**
* Gets the currently active VS Code text document instance if one exists.
*
* @returns The active VS Code text document, or undefined if none.
*/
export function getCurrentVSCodeDoc(): vscode.TextDocument | undefined {
const doc = vscode.window.activeTextEditor?.document
if (!doc) {
return undefined
}
return doc
}

/**
* Gets the full text content of the currently active VS Code text document.
*
* @param range - Optional VS Code range to get only a subset of the document text.
* @returns The text content of the active document, or empty string if none.
*/
export function getCurrentVSCodeDocText(range?: vscode.Range): string {
const doc = vscode.window.activeTextEditor?.document
if (!doc) {
return ''
}
return doc?.getText(range) || ''
}

/**
* Gets the text content of a VS Code text document specified by URI.
*
* @param uri - The URI of the text document to get content for.
* @param range - Optional VS Code range to get only a subset of the document text.
* @returns A Promise resolving to the text content of the specified document.
Expand All @@ -684,7 +664,6 @@ export async function getCurrentVSCodeDocTextByURI(uri: URI, range?: vscode.Rang

/**
* Gets folding ranges for the given URI.
*
* @param uri - The URI of the document to get folding ranges for.
* @param type - Optional type of folding ranges to get. Can be 'imports', 'comment' or 'all'. Default 'all'.
* @param getLastItem - Optional boolean whether to only return the last range of the given type. Default false.
Expand Down Expand Up @@ -752,7 +731,6 @@ export function getHumanDisplayTextWithFileName(

/**
* Creates a human readable display text with a link to the VS Code editor.
*
* @param input - The original human input text.
* @param docUri - The URI of the referenced text document.
* @param selection - The selection in the text document.
Expand Down
4 changes: 4 additions & 0 deletions lib/shared/src/telemetry-v2/TelemetryRecorderProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ class ConfigurationMetadataProcessor implements TelemetryProcessor {
{
key: 'guardrails',
value: this.config.experimentalGuardrails ? 1 : 0,
},
{
key: 'newChatUI',
value: this.config.experimentalChatPanel ? 1 : 0,
}
)
}
Expand Down
2 changes: 2 additions & 0 deletions vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Starting from `0.2.0`, Cody is using `major.EVEN_NUMBER.patch` for release versi
### Fixed

- Edit: Fixed an issue where Cody would regularly include unrelated XML tags in the generated output. [pull/1789](https://github.com/sourcegraph/cody/pull/1789)
- - Chat: Fixed an issue that caused Cody to be unable to locate active editors when running commands from the new chat panel. [pull/1793](https://github.com/sourcegraph/cody/pull/1793)
- Chat: Replaced uses of deprecated getWorkspaceRootPath that caused Cody to be unable to determine the current workspace in the chat panel. [pull/1793](https://github.com/sourcegraph/cody/pull/1793)

### Changed

Expand Down
3 changes: 2 additions & 1 deletion vscode/src/chat/ContextProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export class ContextProvider implements vscode.Disposable {
// these are ephemeral
return
}
const workspaceRoot = this.editor.getWorkspaceRootPath()
const workspaceRoot = this.editor.getWorkspaceRootUri()?.fsPath
if (!workspaceRoot || workspaceRoot === '' || workspaceRoot === this.currentWorkspaceRoot) {
return
}
Expand Down Expand Up @@ -308,6 +308,7 @@ async function getCodebaseContext(
return null
}
const remoteUrl = repositoryRemoteUrl(workspaceRoot)
console.log(config.codebase)
// Get codebase from config or fallback to getting repository name from git clone URL
const codebase = config.codebase || (remoteUrl ? convertGitCloneURLToCodebaseName(remoteUrl) : null)
if (!codebase) {
Expand Down
5 changes: 4 additions & 1 deletion vscode/src/editor/vscode-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ export class VSCodeEditor implements Editor<InlineController, FixupController, C
return getActiveEditor()?.document.fileName ?? ''
}

/** @deprecated Use {@link VSCodeEditor.getWorkspaceRootUri} instead. */
/**
* @deprecated Use {@link VSCodeEditor.getWorkspaceRootUri} instead
/** NOTE DO NOT UES - this does not work with chat webview panel
*/
public getWorkspaceRootPath(): string | null {
const uri = this.getWorkspaceRootUri()
return uri?.scheme === 'file' ? uri.fsPath : null
Expand Down
2 changes: 1 addition & 1 deletion vscode/src/local-context/filename-context-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class FilenameContextFetcher {
public async getContext(query: string, numResults: number): Promise<ContextResult[]> {
const time0 = performance.now()

const rootPath = this.editor.getWorkspaceRootPath()
const rootPath = this.editor.getWorkspaceRootUri()?.fsPath
if (!rootPath) {
return []
}
Expand Down
4 changes: 2 additions & 2 deletions vscode/src/local-context/local-keyword-context-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export class LocalKeywordContextFetcher implements KeywordContextFetcher {
*/
public async getContext(query: string, numResults: number): Promise<ContextResult[]> {
const startTime = performance.now()
const rootPath = this.editor.getWorkspaceRootPath()
const rootPath = this.editor.getWorkspaceRootUri()?.fsPath
if (!rootPath) {
return []
}
Expand Down Expand Up @@ -210,7 +210,7 @@ export class LocalKeywordContextFetcher implements KeywordContextFetcher {

// Return context results for the Codebase Context Search recipe
public async getSearchContext(query: string, numResults: number): Promise<ContextResult[]> {
const rootPath = this.editor.getWorkspaceRootPath()
const rootPath = this.editor.getWorkspaceRootUri()?.fsPath
if (!rootPath) {
return []
}
Expand Down