Refactor file naming logic

This commit is contained in:
tusharmagar 2026-02-24 19:03:22 +05:30
parent 53d48ab4f3
commit 9de0b4aea2

View file

@ -107,6 +107,10 @@ const clampNumber = (value: number, min: number, max: number) =>
Math.min(max, Math.max(min, value)) Math.min(max, Math.max(min, value))
const untitledBaseName = 'untitled' const untitledBaseName = 'untitled'
const untitledIndexedNamePattern = /^untitled-\d+$/
const isUntitledPlaceholderName = (name: string) =>
name === untitledBaseName || untitledIndexedNamePattern.test(name)
const getHeadingTitle = (markdown: string) => { const getHeadingTitle = (markdown: string) => {
const lines = markdown.split('\n') const lines = markdown.split('\n')
@ -848,46 +852,52 @@ function App() {
let renamedTo: string | null = null let renamedTo: string | null = null
try { try {
// Only rename the currently active file (avoids renaming/jumping while user switches rapidly) // Only rename the currently active file (avoids renaming/jumping while user switches rapidly)
if ( if (
wasActiveAtStart && wasActiveAtStart &&
selectedPathRef.current === pathAtStart && selectedPathRef.current === pathAtStart &&
!renameInProgressRef.current && !renameInProgressRef.current &&
pathAtStart.startsWith('knowledge/') pathAtStart.startsWith('knowledge/')
) { ) {
const headingTitle = getHeadingTitle(debouncedContent)
const desiredName = headingTitle ? sanitizeHeadingForFilename(headingTitle) : null
const currentBase = getBaseName(pathAtStart) const currentBase = getBaseName(pathAtStart)
if (desiredName && desiredName !== currentBase) { if (isUntitledPlaceholderName(currentBase)) {
const parentDir = pathAtStart.split('/').slice(0, -1).join('/') const headingTitle = getHeadingTitle(debouncedContent)
const targetPath = `${parentDir}/${desiredName}.md` const desiredName = headingTitle ? sanitizeHeadingForFilename(headingTitle) : null
if (targetPath !== pathAtStart) { if (desiredName && desiredName !== currentBase) {
const exists = await window.ipc.invoke('workspace:exists', { path: targetPath }) const parentDir = pathAtStart.split('/').slice(0, -1).join('/')
if (!exists.exists) { let targetPath = `${parentDir}/${desiredName}.md`
renameInProgressRef.current = true if (targetPath !== pathAtStart) {
await window.ipc.invoke('workspace:rename', { from: pathAtStart, to: targetPath }) let suffix = 1
pathToSave = targetPath while (true) {
renamedFrom = pathAtStart const exists = await window.ipc.invoke('workspace:exists', { path: targetPath })
renamedTo = targetPath if (!exists.exists) break
editorPathRef.current = targetPath targetPath = `${parentDir}/${desiredName}-${suffix}.md`
setFileTabs(prev => prev.map(tab => (tab.path === pathAtStart ? { ...tab, path: targetPath } : tab))) suffix += 1
initialContentByPathRef.current.delete(pathAtStart) }
const cachedContent = editorContentByPathRef.current.get(pathAtStart) renameInProgressRef.current = true
if (cachedContent !== undefined) { await window.ipc.invoke('workspace:rename', { from: pathAtStart, to: targetPath })
editorContentByPathRef.current.delete(pathAtStart) pathToSave = targetPath
editorContentByPathRef.current.set(targetPath, cachedContent) renamedFrom = pathAtStart
setEditorContentByPath((prev) => { renamedTo = targetPath
const oldContent = prev[pathAtStart] editorPathRef.current = targetPath
if (oldContent === undefined) return prev setFileTabs(prev => prev.map(tab => (tab.path === pathAtStart ? { ...tab, path: targetPath } : tab)))
const next = { ...prev } initialContentByPathRef.current.delete(pathAtStart)
delete next[pathAtStart] const cachedContent = editorContentByPathRef.current.get(pathAtStart)
next[targetPath] = oldContent if (cachedContent !== undefined) {
return next editorContentByPathRef.current.delete(pathAtStart)
}) editorContentByPathRef.current.set(targetPath, cachedContent)
} setEditorContentByPath((prev) => {
} const oldContent = prev[pathAtStart]
} if (oldContent === undefined) return prev
} const next = { ...prev }
} delete next[pathAtStart]
next[targetPath] = oldContent
return next
})
}
}
}
}
}
await window.ipc.invoke('workspace:writeFile', { await window.ipc.invoke('workspace:writeFile', {
path: pathToSave, path: pathToSave,
data: debouncedContent, data: debouncedContent,