diff options
| author | adamelmore <[email protected]> | 2026-01-26 09:29:03 -0600 |
|---|---|---|
| committer | adamelmore <[email protected]> | 2026-01-26 09:33:42 -0600 |
| commit | 7c34319b1952cd972f47cfd09542e057c5744852 (patch) | |
| tree | c209b6dbab5d0725f726a24decfd869451194ecc /packages/app/src | |
| parent | cd4676171b03048e6894160c5f11199392e33e53 (diff) | |
| download | opencode-7c34319b1952cd972f47cfd09542e057c5744852.tar.gz opencode-7c34319b1952cd972f47cfd09542e057c5744852.zip | |
fix(app): query selector with non-latin chars
Diffstat (limited to 'packages/app/src')
| -rw-r--r-- | packages/app/src/context/file.tsx | 58 | ||||
| -rw-r--r-- | packages/app/src/pages/session.tsx | 2 |
2 files changed, 58 insertions, 2 deletions
diff --git a/packages/app/src/context/file.tsx b/packages/app/src/context/file.tsx index 20fc980f6..afde451ff 100644 --- a/packages/app/src/context/file.tsx +++ b/packages/app/src/context/file.tsx @@ -57,6 +57,62 @@ function stripQueryAndHash(input: string) { return input } +function unquoteGitPath(input: string) { + if (!input.startsWith('"')) return input + if (!input.endsWith('"')) return input + const body = input.slice(1, -1) + const bytes: number[] = [] + + for (let i = 0; i < body.length; i++) { + const char = body[i]! + if (char !== "\\") { + bytes.push(char.charCodeAt(0)) + continue + } + + const next = body[i + 1] + if (!next) { + bytes.push("\\".charCodeAt(0)) + continue + } + + if (next >= "0" && next <= "7") { + const chunk = body.slice(i + 1, i + 4) + const match = chunk.match(/^[0-7]{1,3}/) + if (!match) { + bytes.push(next.charCodeAt(0)) + i++ + continue + } + bytes.push(parseInt(match[0], 8)) + i += match[0].length + continue + } + + const escaped = + next === "n" + ? "\n" + : next === "r" + ? "\r" + : next === "t" + ? "\t" + : next === "b" + ? "\b" + : next === "f" + ? "\f" + : next === "v" + ? "\v" + : next === "\\" || next === '"' + ? next + : undefined + + bytes.push((escaped ?? next).charCodeAt(0)) + i++ + } + + return new TextDecoder().decode(new Uint8Array(bytes)) +} + export function selectionFromLines(range: SelectedLineRange): FileSelection { const startLine = Math.min(range.start, range.end) const endLine = Math.max(range.start, range.end) @@ -197,7 +253,7 @@ export const { use: useFile, provider: FileProvider } = createSimpleContext({ const root = directory() const prefix = root.endsWith("/") ? root : root + "/" - let path = stripQueryAndHash(stripFileProtocol(input)) + let path = unquoteGitPath(stripQueryAndHash(stripFileProtocol(input))) if (path.startsWith(prefix)) { path = path.slice(prefix.length) diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index bc89b2a48..5e5cba69c 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -1016,7 +1016,7 @@ export default function Page() { const activeTab = createMemo(() => { const active = tabs().active() - if (active) return active + if (active) return normalizeTab(active) if (hasReview()) return "review" const first = openedTabs()[0] |
