Skip to content

Commit 7c34319

Browse files
committed
fix(app): query selector with non-latin chars
1 parent cd46761 commit 7c34319

5 files changed

Lines changed: 135 additions & 8 deletions

File tree

packages/app/src/context/file.tsx

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,62 @@ function stripQueryAndHash(input: string) {
5757
return input
5858
}
5959

60+
function unquoteGitPath(input: string) {
61+
if (!input.startsWith('"')) return input
62+
if (!input.endsWith('"')) return input
63+
const body = input.slice(1, -1)
64+
const bytes: number[] = []
65+
66+
for (let i = 0; i < body.length; i++) {
67+
const char = body[i]!
68+
if (char !== "\\") {
69+
bytes.push(char.charCodeAt(0))
70+
continue
71+
}
72+
73+
const next = body[i + 1]
74+
if (!next) {
75+
bytes.push("\\".charCodeAt(0))
76+
continue
77+
}
78+
79+
if (next >= "0" && next <= "7") {
80+
const chunk = body.slice(i + 1, i + 4)
81+
const match = chunk.match(/^[0-7]{1,3}/)
82+
if (!match) {
83+
bytes.push(next.charCodeAt(0))
84+
i++
85+
continue
86+
}
87+
bytes.push(parseInt(match[0], 8))
88+
i += match[0].length
89+
continue
90+
}
91+
92+
const escaped =
93+
next === "n"
94+
? "\n"
95+
: next === "r"
96+
? "\r"
97+
: next === "t"
98+
? "\t"
99+
: next === "b"
100+
? "\b"
101+
: next === "f"
102+
? "\f"
103+
: next === "v"
104+
? "\v"
105+
: next === "\\" || next === '"'
106+
? next
107+
: undefined
108+
109+
bytes.push((escaped ?? next).charCodeAt(0))
110+
i++
111+
}
112+
113+
return new TextDecoder().decode(new Uint8Array(bytes))
114+
}
115+
60116
export function selectionFromLines(range: SelectedLineRange): FileSelection {
61117
const startLine = Math.min(range.start, range.end)
62118
const endLine = Math.max(range.start, range.end)
@@ -197,7 +253,7 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({
197253
const root = directory()
198254
const prefix = root.endsWith("/") ? root : root + "/"
199255

200-
let path = stripQueryAndHash(stripFileProtocol(input))
256+
let path = unquoteGitPath(stripQueryAndHash(stripFileProtocol(input)))
201257

202258
if (path.startsWith(prefix)) {
203259
path = path.slice(prefix.length)

packages/app/src/pages/session.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ export default function Page() {
10161016

10171017
const activeTab = createMemo(() => {
10181018
const active = tabs().active()
1019-
if (active) return active
1019+
if (active) return normalizeTab(active)
10201020
if (hasReview()) return "review"
10211021

10221022
const first = openedTabs()[0]

packages/opencode/src/file/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,11 @@ export namespace File {
206206
const project = Instance.project
207207
if (project.vcs !== "git") return []
208208

209-
const diffOutput = await $`git diff --numstat HEAD`.cwd(Instance.directory).quiet().nothrow().text()
209+
const diffOutput = await $`git -c core.quotepath=false diff --numstat HEAD`
210+
.cwd(Instance.directory)
211+
.quiet()
212+
.nothrow()
213+
.text()
210214

211215
const changedFiles: Info[] = []
212216

@@ -223,7 +227,7 @@ export namespace File {
223227
}
224228
}
225229

226-
const untrackedOutput = await $`git ls-files --others --exclude-standard`
230+
const untrackedOutput = await $`git -c core.quotepath=false ls-files --others --exclude-standard`
227231
.cwd(Instance.directory)
228232
.quiet()
229233
.nothrow()
@@ -248,7 +252,7 @@ export namespace File {
248252
}
249253

250254
// Get deleted files
251-
const deletedOutput = await $`git diff --name-only --diff-filter=D HEAD`
255+
const deletedOutput = await $`git -c core.quotepath=false diff --name-only --diff-filter=D HEAD`
252256
.cwd(Instance.directory)
253257
.quiet()
254258
.nothrow()

packages/opencode/src/session/summary.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,62 @@ import { Agent } from "@/agent/agent"
2020
export namespace SessionSummary {
2121
const log = Log.create({ service: "session.summary" })
2222

23+
function unquoteGitPath(input: string) {
24+
if (!input.startsWith('"')) return input
25+
if (!input.endsWith('"')) return input
26+
const body = input.slice(1, -1)
27+
const bytes: number[] = []
28+
29+
for (let i = 0; i < body.length; i++) {
30+
const char = body[i]!
31+
if (char !== "\\") {
32+
bytes.push(char.charCodeAt(0))
33+
continue
34+
}
35+
36+
const next = body[i + 1]
37+
if (!next) {
38+
bytes.push("\\".charCodeAt(0))
39+
continue
40+
}
41+
42+
if (next >= "0" && next <= "7") {
43+
const chunk = body.slice(i + 1, i + 4)
44+
const match = chunk.match(/^[0-7]{1,3}/)
45+
if (!match) {
46+
bytes.push(next.charCodeAt(0))
47+
i++
48+
continue
49+
}
50+
bytes.push(parseInt(match[0], 8))
51+
i += match[0].length
52+
continue
53+
}
54+
55+
const escaped =
56+
next === "n"
57+
? "\n"
58+
: next === "r"
59+
? "\r"
60+
: next === "t"
61+
? "\t"
62+
: next === "b"
63+
? "\b"
64+
: next === "f"
65+
? "\f"
66+
: next === "v"
67+
? "\v"
68+
: next === "\\" || next === '"'
69+
? next
70+
: undefined
71+
72+
bytes.push((escaped ?? next).charCodeAt(0))
73+
i++
74+
}
75+
76+
return Buffer.from(bytes).toString()
77+
}
78+
2379
export const summarize = fn(
2480
z.object({
2581
sessionID: z.string(),
@@ -116,7 +172,18 @@ export namespace SessionSummary {
116172
messageID: Identifier.schema("message").optional(),
117173
}),
118174
async (input) => {
119-
return Storage.read<Snapshot.FileDiff[]>(["session_diff", input.sessionID]).catch(() => [])
175+
const diffs = await Storage.read<Snapshot.FileDiff[]>(["session_diff", input.sessionID]).catch(() => [])
176+
const next = diffs.map((item) => {
177+
const file = unquoteGitPath(item.file)
178+
if (file === item.file) return item
179+
return {
180+
...item,
181+
file,
182+
}
183+
})
184+
const changed = next.some((item, i) => item.file !== diffs[i]?.file)
185+
if (changed) Storage.write(["session_diff", input.sessionID], next).catch(() => {})
186+
return next
120187
},
121188
)
122189

packages/opencode/src/snapshot/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export namespace Snapshot {
163163
const git = gitdir()
164164
await $`git --git-dir ${git} --work-tree ${Instance.worktree} add .`.quiet().cwd(Instance.directory).nothrow()
165165
const result =
166-
await $`git -c core.autocrlf=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff ${hash} -- .`
166+
await $`git -c core.autocrlf=false -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff ${hash} -- .`
167167
.quiet()
168168
.cwd(Instance.worktree)
169169
.nothrow()
@@ -196,7 +196,7 @@ export namespace Snapshot {
196196
export async function diffFull(from: string, to: string): Promise<FileDiff[]> {
197197
const git = gitdir()
198198
const result: FileDiff[] = []
199-
for await (const line of $`git -c core.autocrlf=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff --no-renames --numstat ${from} ${to} -- .`
199+
for await (const line of $`git -c core.autocrlf=false -c core.quotepath=false --git-dir ${git} --work-tree ${Instance.worktree} diff --no-ext-diff --no-renames --numstat ${from} ${to} -- .`
200200
.quiet()
201201
.cwd(Instance.directory)
202202
.nothrow()

0 commit comments

Comments
 (0)