add diff viewer prefs and task session shortcut

This commit is contained in:
Shantur Rathore
2025-11-08 12:53:51 +00:00
parent f59c36f6f8
commit 81ab3a40ed
12 changed files with 595 additions and 46 deletions

50
src/lib/diff-utils.ts Normal file
View File

@@ -0,0 +1,50 @@
const HUNK_PATTERN = /(^|\n)@@/m
const FILE_MARKER_PATTERN = /(^|\n)(diff --git |--- |\+\+\+)/
const BEGIN_PATCH_PATTERN = /^\*\*\* (Begin|End) Patch/
const UPDATE_FILE_PATTERN = /^\*\*\* Update File: (.+)$/
function stripCodeFence(value: string): string {
const trimmed = value.trim()
if (!trimmed.startsWith("```")) return trimmed
const lines = trimmed.split("\n")
if (lines.length < 2) return ""
const lastLine = lines[lines.length - 1]
if (!lastLine.startsWith("```")) return trimmed
return lines.slice(1, -1).join("\n")
}
export function normalizeDiffText(raw: string): string {
if (!raw) return ""
const withoutFence = stripCodeFence(raw.replace(/\r\n/g, "\n"))
const lines = withoutFence.split("\n").map((line) => line.replace(/\s+$/u, ""))
let pendingFilePath: string | null = null
const cleanedLines: string[] = []
for (const line of lines) {
if (!line) continue
if (BEGIN_PATCH_PATTERN.test(line)) {
continue
}
const updateMatch = line.match(UPDATE_FILE_PATTERN)
if (updateMatch) {
pendingFilePath = updateMatch[1]?.trim() || null
continue
}
cleanedLines.push(line)
}
if (pendingFilePath && !FILE_MARKER_PATTERN.test(cleanedLines.join("\n"))) {
cleanedLines.unshift(`+++ b/${pendingFilePath}`)
cleanedLines.unshift(`--- a/${pendingFilePath}`)
}
return cleanedLines.join("\n").trim()
}
export function isRenderableDiffText(raw?: string | null): raw is string {
if (!raw) return false
const normalized = normalizeDiffText(raw)
if (!normalized) return false
return HUNK_PATTERN.test(normalized)
}

View File

@@ -7,6 +7,43 @@ let currentTheme: "light" | "dark" = "light"
let isInitialized = false
let highlightSuppressed = false
const extensionToLanguage: Record<string, string> = {
ts: "typescript",
tsx: "typescript",
js: "javascript",
jsx: "javascript",
py: "python",
sh: "bash",
bash: "bash",
json: "json",
html: "html",
css: "css",
md: "markdown",
yaml: "yaml",
yml: "yaml",
sql: "sql",
rs: "rust",
go: "go",
cpp: "cpp",
cc: "cpp",
cxx: "cpp",
hpp: "cpp",
h: "cpp",
c: "c",
java: "java",
cs: "csharp",
php: "php",
rb: "ruby",
swift: "swift",
kt: "kotlin",
}
export function getLanguageFromPath(path?: string | null): string | undefined {
if (!path) return undefined
const ext = path.split(".").pop()?.toLowerCase()
return ext ? extensionToLanguage[ext] : undefined
}
// Track loaded languages and queue for on-demand loading
const loadedLanguages = new Set<string>()
const queuedLanguages = new Set<string>()

View File

@@ -54,6 +54,7 @@ export class FileStorage {
environmentVariables: {},
modelRecents: [],
agentModelSelections: {},
diffViewMode: "split",
},
recentFolders: [],
opencodeBinaries: [],