mirror of
https://github.com/pacnpal/Roo-Code.git
synced 2025-12-20 12:21:13 -05:00
Open read files in editor instead of code accordian
This commit is contained in:
@@ -1138,7 +1138,7 @@ export class ClaudeDev {
|
|||||||
const message = JSON.stringify({
|
const message = JSON.stringify({
|
||||||
tool: "readFile",
|
tool: "readFile",
|
||||||
path: this.getReadablePath(relPath),
|
path: this.getReadablePath(relPath),
|
||||||
content,
|
content: absolutePath,
|
||||||
} as ClaudeSayTool)
|
} as ClaudeSayTool)
|
||||||
if (this.alwaysAllowReadOnly) {
|
if (this.alwaysAllowReadOnly) {
|
||||||
await this.say("tool", message)
|
await this.say("tool", message)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import fs from "fs/promises"
|
|||||||
import { HistoryItem } from "../shared/HistoryItem"
|
import { HistoryItem } from "../shared/HistoryItem"
|
||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
import { getTheme } from "../utils/getTheme"
|
import { getTheme } from "../utils/getTheme"
|
||||||
import { openImage } from "../utils/open-image"
|
import { openFile, openImage } from "../utils/open-file"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
|
https://github.com/microsoft/vscode-webview-ui-toolkit-samples/blob/main/default/weather-webview/src/providers/WeatherViewProvider.ts
|
||||||
@@ -402,6 +402,9 @@ export class ClaudeDevProvider implements vscode.WebviewViewProvider {
|
|||||||
case "openImage":
|
case "openImage":
|
||||||
openImage(message.text!)
|
openImage(message.text!)
|
||||||
break
|
break
|
||||||
|
case "openFile":
|
||||||
|
openFile(message.text!)
|
||||||
|
break
|
||||||
// Add more switch case statements here as more webview message commands
|
// Add more switch case statements here as more webview message commands
|
||||||
// are created within the webview context (i.e. inside media/main.js)
|
// are created within the webview context (i.e. inside media/main.js)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export interface WebviewMessage {
|
|||||||
| "resetState"
|
| "resetState"
|
||||||
| "requestOllamaModels"
|
| "requestOllamaModels"
|
||||||
| "openImage"
|
| "openImage"
|
||||||
|
| "openFile"
|
||||||
text?: string
|
text?: string
|
||||||
askResponse?: ClaudeAskResponse
|
askResponse?: ClaudeAskResponse
|
||||||
apiConfiguration?: ApiConfiguration
|
apiConfiguration?: ApiConfiguration
|
||||||
|
|||||||
50
src/utils/open-file.ts
Normal file
50
src/utils/open-file.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import * as path from "path"
|
||||||
|
import * as os from "os"
|
||||||
|
import * as vscode from "vscode"
|
||||||
|
|
||||||
|
export async function openImage(dataUri: string) {
|
||||||
|
const matches = dataUri.match(/^data:image\/([a-zA-Z]+);base64,(.+)$/)
|
||||||
|
if (!matches) {
|
||||||
|
vscode.window.showErrorMessage("Invalid data URI format")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const [, format, base64Data] = matches
|
||||||
|
const imageBuffer = Buffer.from(base64Data, "base64")
|
||||||
|
const tempFilePath = path.join(os.tmpdir(), `temp_image_${Date.now()}.${format}`)
|
||||||
|
try {
|
||||||
|
await vscode.workspace.fs.writeFile(vscode.Uri.file(tempFilePath), imageBuffer)
|
||||||
|
await vscode.commands.executeCommand("vscode.open", vscode.Uri.file(tempFilePath))
|
||||||
|
} catch (error) {
|
||||||
|
vscode.window.showErrorMessage(`Error opening image: ${error}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openFile(absolutePath: string) {
|
||||||
|
try {
|
||||||
|
const uri = vscode.Uri.file(absolutePath)
|
||||||
|
|
||||||
|
// Check if the document is already open in a tab group that's not in the active editor's column. If it is, then close it (if not dirty) so that we don't duplicate tabs
|
||||||
|
try {
|
||||||
|
for (const group of vscode.window.tabGroups.all) {
|
||||||
|
const existingTab = group.tabs.find(
|
||||||
|
(tab) => tab.input instanceof vscode.TabInputText && tab.input.uri.fsPath === uri.fsPath
|
||||||
|
)
|
||||||
|
if (existingTab) {
|
||||||
|
const activeColumn = vscode.window.activeTextEditor?.viewColumn
|
||||||
|
const tabColumn = vscode.window.tabGroups.all.find((group) =>
|
||||||
|
group.tabs.includes(existingTab)
|
||||||
|
)?.viewColumn
|
||||||
|
if (activeColumn && activeColumn !== tabColumn && !existingTab.isDirty) {
|
||||||
|
await vscode.window.tabGroups.close(existingTab)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {} // not essential, sometimes tab operations fail
|
||||||
|
|
||||||
|
const document = await vscode.workspace.openTextDocument(uri)
|
||||||
|
await vscode.window.showTextDocument(document, { preview: false })
|
||||||
|
} catch (error) {
|
||||||
|
vscode.window.showErrorMessage(`Could not open file!`)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import * as path from "path"
|
|
||||||
import * as os from "os"
|
|
||||||
import * as vscode from "vscode"
|
|
||||||
|
|
||||||
export async function openImage(dataUri: string) {
|
|
||||||
const matches = dataUri.match(/^data:image\/([a-zA-Z]+);base64,(.+)$/)
|
|
||||||
if (!matches) {
|
|
||||||
vscode.window.showErrorMessage("Invalid data URI format")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const [, format, base64Data] = matches
|
|
||||||
const imageBuffer = Buffer.from(base64Data, "base64")
|
|
||||||
const tempFilePath = path.join(os.tmpdir(), `temp_image_${Date.now()}.${format}`)
|
|
||||||
try {
|
|
||||||
await vscode.workspace.fs.writeFile(vscode.Uri.file(tempFilePath), imageBuffer)
|
|
||||||
await vscode.commands.executeCommand("vscode.open", vscode.Uri.file(tempFilePath))
|
|
||||||
} catch (error) {
|
|
||||||
vscode.window.showErrorMessage(`Error opening image: ${error}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,10 @@ import React, { memo, useMemo } from "react"
|
|||||||
import ReactMarkdown from "react-markdown"
|
import ReactMarkdown from "react-markdown"
|
||||||
import { ClaudeMessage, ClaudeSayTool } from "../../../src/shared/ExtensionMessage"
|
import { ClaudeMessage, ClaudeSayTool } from "../../../src/shared/ExtensionMessage"
|
||||||
import { COMMAND_OUTPUT_STRING } from "../../../src/shared/combineCommandSequences"
|
import { COMMAND_OUTPUT_STRING } from "../../../src/shared/combineCommandSequences"
|
||||||
import CodeAccordian from "./CodeAccordian"
|
import CodeAccordian, { removeLeadingNonAlphanumeric } from "./CodeAccordian"
|
||||||
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "./CodeBlock"
|
import CodeBlock, { CODE_BLOCK_BG_COLOR } from "./CodeBlock"
|
||||||
import Thumbnails from "./Thumbnails"
|
import Thumbnails from "./Thumbnails"
|
||||||
|
import { vscode } from "../utils/vscode"
|
||||||
|
|
||||||
interface ChatRowProps {
|
interface ChatRowProps {
|
||||||
message: ClaudeMessage
|
message: ClaudeMessage
|
||||||
@@ -190,12 +191,54 @@ const ChatRowContent = ({ message, isExpanded, onToggleExpand, lastModifiedMessa
|
|||||||
{message.type === "ask" ? "Claude wants to read this file:" : "Claude read this file:"}
|
{message.type === "ask" ? "Claude wants to read this file:" : "Claude read this file:"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<CodeAccordian
|
{/* <CodeAccordian
|
||||||
code={tool.content!}
|
code={tool.content!}
|
||||||
path={tool.path!}
|
path={tool.path!}
|
||||||
isExpanded={isExpanded}
|
isExpanded={isExpanded}
|
||||||
onToggleExpand={onToggleExpand}
|
onToggleExpand={onToggleExpand}
|
||||||
/>
|
/> */}
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
borderRadius: 3,
|
||||||
|
backgroundColor: CODE_BLOCK_BG_COLOR,
|
||||||
|
overflow: "hidden",
|
||||||
|
border: "1px solid var(--vscode-editorGroup-border)",
|
||||||
|
}}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
color: "var(--vscode-descriptionForeground)",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
alignItems: "center",
|
||||||
|
padding: "6px 10px",
|
||||||
|
cursor: "pointer",
|
||||||
|
userSelect: "none",
|
||||||
|
WebkitUserSelect: "none",
|
||||||
|
MozUserSelect: "none",
|
||||||
|
msUserSelect: "none",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
vscode.postMessage({ type: "openFile", text: tool.content })
|
||||||
|
}}>
|
||||||
|
<div style={{ display: "flex", alignItems: "center" }}>
|
||||||
|
<span
|
||||||
|
style={{
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
marginRight: "8px",
|
||||||
|
fontSize: "11px",
|
||||||
|
direction: "rtl",
|
||||||
|
textAlign: "left",
|
||||||
|
}}>
|
||||||
|
{removeLeadingNonAlphanumeric(tool.path ?? "") + "\u200E"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
className={`codicon codicon-link-external`}
|
||||||
|
style={{ fontSize: 13, margin: "1.5px 0" }}></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
case "listFilesTopLevel":
|
case "listFilesTopLevel":
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ We need to remove leading non-alphanumeric characters from the path in order for
|
|||||||
[^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric.
|
[^a-zA-Z0-9]+: Matches one or more characters that are not alphanumeric.
|
||||||
The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character.
|
The replace method removes these matched characters, effectively trimming the string up to the first alphanumeric character.
|
||||||
*/
|
*/
|
||||||
const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "")
|
export const removeLeadingNonAlphanumeric = (path: string): string => path.replace(/^[^a-zA-Z0-9]+/, "")
|
||||||
|
|
||||||
const CodeAccordian = ({ code, diff, language, path, isFeedback, isExpanded, onToggleExpand }: CodeAccordianProps) => {
|
const CodeAccordian = ({ code, diff, language, path, isFeedback, isExpanded, onToggleExpand }: CodeAccordianProps) => {
|
||||||
const inferredLanguage = useMemo(
|
const inferredLanguage = useMemo(
|
||||||
|
|||||||
Reference in New Issue
Block a user