Remember Markdown TOC state while tabs are open (#6476)
* Keep markdown TOC open per document * Clean up Markdown visibility state for replaced previews
This commit is contained in:
parent
748bced2e6
commit
f8591d6991
|
|
@ -45,6 +45,8 @@ function EditorPanelInner({
|
|||
const openMarkdownPreview = useAppStore((s) => s.openMarkdownPreview)
|
||||
const markdownFrontmatterVisible = useAppStore((s) => s.markdownFrontmatterVisible)
|
||||
const setMarkdownFrontmatterVisible = useAppStore((s) => s.setMarkdownFrontmatterVisible)
|
||||
const markdownTableOfContentsVisible = useAppStore((s) => s.markdownTableOfContentsVisible)
|
||||
const setMarkdownTableOfContentsVisible = useAppStore((s) => s.setMarkdownTableOfContentsVisible)
|
||||
const closeFile = useAppStore((s) => s.closeFile)
|
||||
const clearUntitled = useAppStore((s) => s.clearUntitled)
|
||||
const editorDrafts = useAppStore((s) => s.editorDrafts)
|
||||
|
|
@ -75,7 +77,6 @@ function EditorPanelInner({
|
|||
},
|
||||
[clearCopiedPathToastResetTimer]
|
||||
)
|
||||
const [showMarkdownTableOfContents, setShowMarkdownTableOfContents] = useState(false)
|
||||
const [sideBySide, setSideBySide] = useState(settings?.diffDefaultView === 'side-by-side')
|
||||
const [prevDiffView, setPrevDiffView] = useState(settings?.diffDefaultView)
|
||||
|
||||
|
|
@ -310,14 +311,14 @@ function EditorPanelInner({
|
|||
)?.activeRuntimeEnvironmentId?.trim() ||
|
||||
(renameDialogFile ? getConnectionId(renameDialogFile.worktreeId) : null)
|
||||
)
|
||||
const markdownFrontmatterSourceFileId =
|
||||
const markdownDocumentStateFileId =
|
||||
activeFile.mode === 'markdown-preview'
|
||||
? (activeFile.markdownPreviewSourceFileId ?? activeFile.filePath)
|
||||
: activeFile.id
|
||||
let activeMarkdownContent: string | null = null
|
||||
if (activeFile.mode === 'markdown-preview') {
|
||||
activeMarkdownContent =
|
||||
editorDrafts[markdownFrontmatterSourceFileId] ?? fileContents[activeFile.id]?.content ?? null
|
||||
editorDrafts[markdownDocumentStateFileId] ?? fileContents[activeFile.id]?.content ?? null
|
||||
} else if (activeFile.mode === 'edit') {
|
||||
activeMarkdownContent =
|
||||
editorDrafts[activeFile.id] ?? fileContents[activeFile.id]?.content ?? null
|
||||
|
|
@ -329,7 +330,9 @@ function EditorPanelInner({
|
|||
extractFrontMatter(activeMarkdownContent)
|
||||
)
|
||||
const isMarkdownFrontmatterVisible =
|
||||
markdownFrontmatterVisible[markdownFrontmatterSourceFileId] ?? false
|
||||
markdownFrontmatterVisible[markdownDocumentStateFileId] ?? false
|
||||
const isMarkdownTableOfContentsVisible =
|
||||
markdownTableOfContentsVisible[markdownDocumentStateFileId] ?? false
|
||||
|
||||
return (
|
||||
<EditorPanelShell
|
||||
|
|
@ -338,7 +341,7 @@ function EditorPanelInner({
|
|||
activeViewStateId={activeViewStateId}
|
||||
model={model}
|
||||
copiedPathVisible={copiedPathToast?.fileId === activeFile.id}
|
||||
showMarkdownTableOfContents={showMarkdownTableOfContents}
|
||||
showMarkdownTableOfContents={isMarkdownTableOfContentsVisible}
|
||||
canShowMarkdownFrontmatterToggle={canShowMarkdownFrontmatterToggle}
|
||||
markdownFrontmatterVisible={isMarkdownFrontmatterVisible}
|
||||
sideBySide={sideBySide}
|
||||
|
|
@ -357,13 +360,15 @@ function EditorPanelInner({
|
|||
onOpenContainingFolder={handleOpenContainingFolder}
|
||||
onToggleSideBySide={() => setSideBySide((prev) => !prev)}
|
||||
onEditorToggleChange={handleEditorToggleChange}
|
||||
onToggleMarkdownTableOfContents={() => setShowMarkdownTableOfContents((shown) => !shown)}
|
||||
onToggleMarkdownFrontmatter={() =>
|
||||
setMarkdownFrontmatterVisible(
|
||||
markdownFrontmatterSourceFileId,
|
||||
!isMarkdownFrontmatterVisible
|
||||
onToggleMarkdownTableOfContents={() =>
|
||||
setMarkdownTableOfContentsVisible(
|
||||
markdownDocumentStateFileId,
|
||||
!isMarkdownTableOfContentsVisible
|
||||
)
|
||||
}
|
||||
onToggleMarkdownFrontmatter={() =>
|
||||
setMarkdownFrontmatterVisible(markdownDocumentStateFileId, !isMarkdownFrontmatterVisible)
|
||||
}
|
||||
onExportMarkdownToPdf={() =>
|
||||
void exportActiveMarkdownToPdf({ fileId: activeFile.id, root: panelRef.current })
|
||||
}
|
||||
|
|
@ -373,7 +378,9 @@ function EditorPanelInner({
|
|||
onSave={handleSave}
|
||||
onSaveForFile={handleSaveForFile}
|
||||
onReloadFileContent={reloadFileContent}
|
||||
onCloseMarkdownTableOfContents={() => setShowMarkdownTableOfContents(false)}
|
||||
onCloseMarkdownTableOfContents={() =>
|
||||
setMarkdownTableOfContentsVisible(markdownDocumentStateFileId, false)
|
||||
}
|
||||
onCloseRenameDialog={closeRenameDialog}
|
||||
onRenameConfirm={handleRenameConfirm}
|
||||
markdownAnnotationsEnabled={markdownAnnotationsEnabled}
|
||||
|
|
|
|||
|
|
@ -1459,6 +1459,64 @@ describe('createEditorSlice markdown view state', () => {
|
|||
})
|
||||
])
|
||||
})
|
||||
|
||||
it('drops markdown visibility for a preview replaced by a diff', () => {
|
||||
const store = createEditorStore()
|
||||
|
||||
store.getState().openFile(
|
||||
{
|
||||
filePath: '/repo/docs/README.md',
|
||||
relativePath: 'docs/README.md',
|
||||
worktreeId: 'wt-1',
|
||||
language: 'markdown',
|
||||
mode: 'edit'
|
||||
},
|
||||
{ preview: true }
|
||||
)
|
||||
store.getState().setMarkdownFrontmatterVisible('/repo/docs/README.md', true)
|
||||
store.getState().setMarkdownTableOfContentsVisible('/repo/docs/README.md', true)
|
||||
|
||||
store.getState().openDiff('wt-1', '/repo/docs/guide.md', 'docs/guide.md', 'markdown', false, {
|
||||
preview: true
|
||||
})
|
||||
|
||||
expect(store.getState().markdownFrontmatterVisible).toEqual({})
|
||||
expect(store.getState().markdownTableOfContentsVisible).toEqual({})
|
||||
})
|
||||
|
||||
it('keeps markdown visibility when another preview still references a replaced source', () => {
|
||||
const store = createEditorStore()
|
||||
|
||||
store.getState().openFile(
|
||||
{
|
||||
filePath: '/repo/docs/README.md',
|
||||
relativePath: 'docs/README.md',
|
||||
worktreeId: 'wt-1',
|
||||
language: 'markdown',
|
||||
mode: 'edit'
|
||||
},
|
||||
{ preview: true }
|
||||
)
|
||||
store.getState().openMarkdownPreview({
|
||||
filePath: '/repo/docs/README.md',
|
||||
relativePath: 'docs/README.md',
|
||||
worktreeId: 'wt-1',
|
||||
language: 'markdown'
|
||||
})
|
||||
store.getState().setMarkdownFrontmatterVisible('/repo/docs/README.md', true)
|
||||
store.getState().setMarkdownTableOfContentsVisible('/repo/docs/README.md', true)
|
||||
|
||||
store.getState().openDiff('wt-1', '/repo/docs/guide.md', 'docs/guide.md', 'markdown', false, {
|
||||
preview: true
|
||||
})
|
||||
|
||||
expect(store.getState().markdownFrontmatterVisible).toEqual({
|
||||
'/repo/docs/README.md': true
|
||||
})
|
||||
expect(store.getState().markdownTableOfContentsVisible).toEqual({
|
||||
'/repo/docs/README.md': true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('createEditorSlice editor view mode', () => {
|
||||
|
|
@ -1628,6 +1686,79 @@ describe('createEditorSlice markdown frontmatter visibility (#4468)', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('createEditorSlice markdown table of contents visibility', () => {
|
||||
it('stores visible=true as an explicit entry keyed by fileId', () => {
|
||||
const store = createEditorStore()
|
||||
|
||||
store.getState().setMarkdownTableOfContentsVisible('/repo/notes.md', true)
|
||||
|
||||
expect(store.getState().markdownTableOfContentsVisible).toEqual({ '/repo/notes.md': true })
|
||||
})
|
||||
|
||||
it('deletes the entry when visibility resets to hidden', () => {
|
||||
const store = createEditorStore()
|
||||
store.getState().setMarkdownTableOfContentsVisible('/repo/notes.md', true)
|
||||
|
||||
store.getState().setMarkdownTableOfContentsVisible('/repo/notes.md', false)
|
||||
|
||||
expect(store.getState().markdownTableOfContentsVisible).toEqual({})
|
||||
})
|
||||
|
||||
it('drops the visibility flag when replacing a preview tab', () => {
|
||||
const store = createEditorStore()
|
||||
store.getState().openFile(
|
||||
{
|
||||
filePath: '/repo/notes.md',
|
||||
relativePath: 'notes.md',
|
||||
worktreeId: 'wt-1',
|
||||
language: 'markdown',
|
||||
mode: 'edit'
|
||||
},
|
||||
{ preview: true }
|
||||
)
|
||||
store.getState().setMarkdownTableOfContentsVisible('/repo/notes.md', true)
|
||||
|
||||
store.getState().openFile(
|
||||
{
|
||||
filePath: '/repo/guide.md',
|
||||
relativePath: 'guide.md',
|
||||
worktreeId: 'wt-1',
|
||||
language: 'markdown',
|
||||
mode: 'edit'
|
||||
},
|
||||
{ preview: true }
|
||||
)
|
||||
|
||||
expect(store.getState().markdownTableOfContentsVisible).toEqual({})
|
||||
})
|
||||
|
||||
it('keeps the visibility flag while a preview tab still references the source file', () => {
|
||||
const store = createEditorStore()
|
||||
store.getState().openFile({
|
||||
filePath: '/repo/notes.md',
|
||||
relativePath: 'notes.md',
|
||||
worktreeId: 'wt-1',
|
||||
language: 'markdown',
|
||||
mode: 'edit'
|
||||
})
|
||||
store.getState().openMarkdownPreview({
|
||||
filePath: '/repo/notes.md',
|
||||
relativePath: 'notes.md',
|
||||
worktreeId: 'wt-1',
|
||||
language: 'markdown'
|
||||
})
|
||||
store.getState().setMarkdownTableOfContentsVisible('/repo/notes.md', true)
|
||||
|
||||
store.getState().closeFile('/repo/notes.md')
|
||||
|
||||
expect(store.getState().markdownTableOfContentsVisible).toEqual({ '/repo/notes.md': true })
|
||||
|
||||
store.getState().closeFile('markdown-preview::/repo/notes.md')
|
||||
|
||||
expect(store.getState().markdownTableOfContentsVisible).toEqual({})
|
||||
})
|
||||
})
|
||||
|
||||
describe('createEditorSlice openMarkdownPreview', () => {
|
||||
it('opens markdown preview as a separate read-only tab', () => {
|
||||
const store = createEditorStore()
|
||||
|
|
|
|||
|
|
@ -401,7 +401,12 @@ export type EditorSlice = {
|
|||
markdownFrontmatterVisible: Record<string, boolean>
|
||||
setMarkdownFrontmatterVisible: (fileId: string, visible: boolean) => void
|
||||
|
||||
// Markdown table of contents
|
||||
// Per-file opt-in to keep the markdown table of contents open. Default is
|
||||
// hidden; absent entry means hidden.
|
||||
markdownTableOfContentsVisible: Record<string, boolean>
|
||||
setMarkdownTableOfContentsVisible: (fileId: string, visible: boolean) => void
|
||||
|
||||
// Markdown table of contents panel sizing
|
||||
markdownTocPanelWidth: number
|
||||
setMarkdownTocPanelWidth: (width: number) => void
|
||||
|
||||
|
|
@ -792,35 +797,86 @@ function getReplaceablePreviewFileId(
|
|||
function removeEditorStateForReplacedPreview(
|
||||
state: Pick<
|
||||
EditorSlice,
|
||||
'editorDrafts' | 'editorCursorLine' | 'markdownViewMode' | 'editorViewMode'
|
||||
| 'editorDrafts'
|
||||
| 'editorCursorLine'
|
||||
| 'markdownViewMode'
|
||||
| 'editorViewMode'
|
||||
| 'markdownFrontmatterVisible'
|
||||
| 'markdownTableOfContentsVisible'
|
||||
| 'openFiles'
|
||||
>,
|
||||
replacedFileId: string,
|
||||
replacedFile: Pick<OpenFile, 'id' | 'markdownPreviewSourceFileId'>,
|
||||
nextFileId: string
|
||||
): Pick<EditorSlice, 'editorDrafts' | 'editorCursorLine' | 'markdownViewMode' | 'editorViewMode'> {
|
||||
if (replacedFileId === nextFileId) {
|
||||
): Pick<
|
||||
EditorSlice,
|
||||
| 'editorDrafts'
|
||||
| 'editorCursorLine'
|
||||
| 'markdownViewMode'
|
||||
| 'editorViewMode'
|
||||
| 'markdownFrontmatterVisible'
|
||||
| 'markdownTableOfContentsVisible'
|
||||
> {
|
||||
const visibilityKeys = [
|
||||
replacedFile.id,
|
||||
...(replacedFile.markdownPreviewSourceFileId ? [replacedFile.markdownPreviewSourceFileId] : [])
|
||||
].filter(
|
||||
(key) =>
|
||||
key !== nextFileId &&
|
||||
!state.openFiles.some(
|
||||
(file) =>
|
||||
file.id !== replacedFile.id &&
|
||||
(file.id === key || file.markdownPreviewSourceFileId === key)
|
||||
)
|
||||
)
|
||||
if (replacedFile.id === nextFileId) {
|
||||
return {
|
||||
editorDrafts: state.editorDrafts,
|
||||
editorCursorLine: state.editorCursorLine,
|
||||
markdownViewMode: state.markdownViewMode,
|
||||
editorViewMode: state.editorViewMode
|
||||
editorViewMode: state.editorViewMode,
|
||||
markdownFrontmatterVisible: state.markdownFrontmatterVisible,
|
||||
markdownTableOfContentsVisible: state.markdownTableOfContentsVisible
|
||||
}
|
||||
}
|
||||
return {
|
||||
editorDrafts: Object.fromEntries(
|
||||
Object.entries(state.editorDrafts).filter(([fileId]) => fileId !== replacedFileId)
|
||||
Object.entries(state.editorDrafts).filter(([fileId]) => fileId !== replacedFile.id)
|
||||
),
|
||||
editorCursorLine: Object.fromEntries(
|
||||
Object.entries(state.editorCursorLine).filter(([fileId]) => fileId !== replacedFileId)
|
||||
Object.entries(state.editorCursorLine).filter(([fileId]) => fileId !== replacedFile.id)
|
||||
),
|
||||
markdownViewMode: Object.fromEntries(
|
||||
Object.entries(state.markdownViewMode).filter(([fileId]) => fileId !== replacedFileId)
|
||||
Object.entries(state.markdownViewMode).filter(([fileId]) => fileId !== replacedFile.id)
|
||||
),
|
||||
editorViewMode: Object.fromEntries(
|
||||
Object.entries(state.editorViewMode).filter(([fileId]) => fileId !== replacedFileId)
|
||||
Object.entries(state.editorViewMode).filter(([fileId]) => fileId !== replacedFile.id)
|
||||
),
|
||||
markdownFrontmatterVisible: removeMarkdownVisibilityKeys(
|
||||
state.markdownFrontmatterVisible,
|
||||
visibilityKeys
|
||||
),
|
||||
markdownTableOfContentsVisible: removeMarkdownVisibilityKeys(
|
||||
state.markdownTableOfContentsVisible,
|
||||
visibilityKeys
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function removeMarkdownVisibilityKeys(
|
||||
visibility: Record<string, boolean>,
|
||||
keysToRemove: readonly string[]
|
||||
): Record<string, boolean> {
|
||||
let next: Record<string, boolean> | null = null
|
||||
for (const key of keysToRemove) {
|
||||
if (!(key in visibility)) {
|
||||
continue
|
||||
}
|
||||
next ??= { ...visibility }
|
||||
delete next[key]
|
||||
}
|
||||
return next ?? visibility
|
||||
}
|
||||
|
||||
function getGroupActiveTab(group: TabGroup, tabsById: Map<string, Tab>): Tab | null {
|
||||
return group.activeTabId ? (tabsById.get(group.activeTabId) ?? null) : null
|
||||
}
|
||||
|
|
@ -1331,7 +1387,27 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
return { markdownFrontmatterVisible: { ...s.markdownFrontmatterVisible, [fileId]: true } }
|
||||
}),
|
||||
|
||||
// Markdown table of contents
|
||||
// Markdown table of contents visibility
|
||||
markdownTableOfContentsVisible: {},
|
||||
setMarkdownTableOfContentsVisible: (fileId, visible) =>
|
||||
set((s) => {
|
||||
if (!visible) {
|
||||
if (!(fileId in s.markdownTableOfContentsVisible)) {
|
||||
return s
|
||||
}
|
||||
const next = { ...s.markdownTableOfContentsVisible }
|
||||
delete next[fileId]
|
||||
return { markdownTableOfContentsVisible: next }
|
||||
}
|
||||
return {
|
||||
markdownTableOfContentsVisible: {
|
||||
...s.markdownTableOfContentsVisible,
|
||||
[fileId]: true
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
// Markdown table of contents panel sizing
|
||||
markdownTocPanelWidth: 240,
|
||||
setMarkdownTocPanelWidth: (width) =>
|
||||
set((s) => ({
|
||||
|
|
@ -1645,13 +1721,12 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
([fileId]) => fileId !== replacedPreview.id
|
||||
)
|
||||
)
|
||||
const frontmatterVisibilityKeys = new Set([replacedPreview.id])
|
||||
const markdownVisibilityKeys = new Set([replacedPreview.id])
|
||||
if (replacedPreview.markdownPreviewSourceFileId) {
|
||||
frontmatterVisibilityKeys.add(replacedPreview.markdownPreviewSourceFileId)
|
||||
markdownVisibilityKeys.add(replacedPreview.markdownPreviewSourceFileId)
|
||||
}
|
||||
const frontmatterKeysToRemove = [...frontmatterVisibilityKeys].filter(
|
||||
const visibilityKeysToRemove = [...markdownVisibilityKeys].filter(
|
||||
(key) =>
|
||||
key in s.markdownFrontmatterVisible &&
|
||||
!s.openFiles.some(
|
||||
(file, index) =>
|
||||
index !== existingPreviewIdx &&
|
||||
|
|
@ -1659,12 +1734,15 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
)
|
||||
)
|
||||
const nextMarkdownFrontmatterVisible =
|
||||
replacedPreview.id === id || frontmatterKeysToRemove.length === 0
|
||||
replacedPreview.id === id || visibilityKeysToRemove.length === 0
|
||||
? s.markdownFrontmatterVisible
|
||||
: Object.fromEntries(
|
||||
Object.entries(s.markdownFrontmatterVisible).filter(
|
||||
([fileId]) => !frontmatterKeysToRemove.includes(fileId)
|
||||
)
|
||||
: removeMarkdownVisibilityKeys(s.markdownFrontmatterVisible, visibilityKeysToRemove)
|
||||
const nextMarkdownTableOfContentsVisible =
|
||||
replacedPreview.id === id || visibilityKeysToRemove.length === 0
|
||||
? s.markdownTableOfContentsVisible
|
||||
: removeMarkdownVisibilityKeys(
|
||||
s.markdownTableOfContentsVisible,
|
||||
visibilityKeysToRemove
|
||||
)
|
||||
// Why: editorCursorLine entries accumulate per file; clean up the
|
||||
// evicted preview's entry so it does not leak across tab replacements.
|
||||
|
|
@ -1721,6 +1799,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
markdownViewMode: nextMarkdownViewMode,
|
||||
editorViewMode: nextEditorViewMode,
|
||||
markdownFrontmatterVisible: nextMarkdownFrontmatterVisible,
|
||||
markdownTableOfContentsVisible: nextMarkdownTableOfContentsVisible,
|
||||
recentlyClosedEditorTabsByWorktree: nextRecentlyClosed,
|
||||
...previewTabBarUpdate,
|
||||
...activeResult
|
||||
|
|
@ -1962,25 +2041,22 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
delete newMarkdownViewMode[fileId]
|
||||
const newEditorViewMode = { ...s.editorViewMode }
|
||||
delete newEditorViewMode[fileId]
|
||||
const frontmatterVisibilityKeys = new Set([fileId])
|
||||
const markdownVisibilityKeys = new Set([fileId])
|
||||
if (closedFile?.markdownPreviewSourceFileId) {
|
||||
frontmatterVisibilityKeys.add(closedFile.markdownPreviewSourceFileId)
|
||||
markdownVisibilityKeys.add(closedFile.markdownPreviewSourceFileId)
|
||||
}
|
||||
const keysToRemove = [...frontmatterVisibilityKeys].filter(
|
||||
const visibilityKeysToRemove = [...markdownVisibilityKeys].filter(
|
||||
(key) =>
|
||||
key in s.markdownFrontmatterVisible &&
|
||||
!newFiles.some((file) => file.id === key || file.markdownPreviewSourceFileId === key)
|
||||
)
|
||||
const newMarkdownFrontmatterVisible =
|
||||
keysToRemove.length > 0
|
||||
? (() => {
|
||||
const next = { ...s.markdownFrontmatterVisible }
|
||||
for (const key of keysToRemove) {
|
||||
delete next[key]
|
||||
}
|
||||
return next
|
||||
})()
|
||||
visibilityKeysToRemove.length > 0
|
||||
? removeMarkdownVisibilityKeys(s.markdownFrontmatterVisible, visibilityKeysToRemove)
|
||||
: s.markdownFrontmatterVisible
|
||||
const newMarkdownTableOfContentsVisible =
|
||||
visibilityKeysToRemove.length > 0
|
||||
? removeMarkdownVisibilityKeys(s.markdownTableOfContentsVisible, visibilityKeysToRemove)
|
||||
: s.markdownTableOfContentsVisible
|
||||
// Why: editorCursorLine entries are keyed by fileId and accumulate on
|
||||
// every cursor move. Without cleanup they grow without bound across a
|
||||
// long session as files are opened and closed.
|
||||
|
|
@ -2112,6 +2188,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
markdownViewMode: newMarkdownViewMode,
|
||||
editorViewMode: newEditorViewMode,
|
||||
markdownFrontmatterVisible: newMarkdownFrontmatterVisible,
|
||||
markdownTableOfContentsVisible: newMarkdownTableOfContentsVisible,
|
||||
tabBarOrderByWorktree: nextTabBarOrderByWorktree,
|
||||
pendingEditorReveal: null,
|
||||
recentlyClosedEditorTabsByWorktree: nextRecentlyClosed
|
||||
|
|
@ -2208,6 +2285,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
markdownViewMode: {},
|
||||
editorViewMode: {},
|
||||
markdownFrontmatterVisible: {},
|
||||
markdownTableOfContentsVisible: {},
|
||||
pendingEditorReveal: null
|
||||
}
|
||||
}
|
||||
|
|
@ -2228,6 +2306,11 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
remainingFileIds.has(fileId)
|
||||
)
|
||||
)
|
||||
const newMarkdownTableOfContentsVisible = Object.fromEntries(
|
||||
Object.entries(s.markdownTableOfContentsVisible).filter(([fileId]) =>
|
||||
remainingFileIds.has(fileId)
|
||||
)
|
||||
)
|
||||
const newEditorCursorLine = Object.fromEntries(
|
||||
Object.entries(s.editorCursorLine).filter(([fileId]) => remainingFileIds.has(fileId))
|
||||
)
|
||||
|
|
@ -2295,6 +2378,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
markdownViewMode: newMarkdownViewMode,
|
||||
editorViewMode: newEditorViewMode,
|
||||
markdownFrontmatterVisible: newMarkdownFrontmatterVisible,
|
||||
markdownTableOfContentsVisible: newMarkdownTableOfContentsVisible,
|
||||
activeFileIdByWorktree: newActiveFileIdByWorktree,
|
||||
activeTabTypeByWorktree: newActiveTabTypeByWorktree,
|
||||
tabBarOrderByWorktree: nextTabBarOrderByWorktree,
|
||||
|
|
@ -2489,7 +2573,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
openFiles: s.openFiles.map((file, index) =>
|
||||
index === replaceablePreviewIndex ? newFile : file
|
||||
),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex].id, id),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex], id),
|
||||
activeFileId: id,
|
||||
activeTabType: 'editor',
|
||||
activeFileIdByWorktree: { ...s.activeFileIdByWorktree, [worktreeId]: id },
|
||||
|
|
@ -2580,7 +2664,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
openFiles: s.openFiles.map((file, index) =>
|
||||
index === replaceablePreviewIndex ? newFile : file
|
||||
),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex].id, id),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex], id),
|
||||
activeFileId: id,
|
||||
activeTabType: 'editor',
|
||||
activeFileIdByWorktree: { ...s.activeFileIdByWorktree, [worktreeId]: id },
|
||||
|
|
@ -2671,7 +2755,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
openFiles: s.openFiles.map((file, index) =>
|
||||
index === replaceablePreviewIndex ? newFile : file
|
||||
),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex].id, id),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex], id),
|
||||
activeFileId: id,
|
||||
activeTabType: 'editor',
|
||||
activeFileIdByWorktree: { ...s.activeFileIdByWorktree, [worktreeId]: id },
|
||||
|
|
@ -2872,7 +2956,7 @@ export const createEditorSlice: StateCreator<AppState, [], [], EditorSlice> = (s
|
|||
openFiles: s.openFiles.map((file, index) =>
|
||||
index === replaceablePreviewIndex ? newFile : file
|
||||
),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex].id, id),
|
||||
...removeEditorStateForReplacedPreview(s, s.openFiles[replaceablePreviewIndex], id),
|
||||
activeFileId: id,
|
||||
activeTabType: 'editor',
|
||||
activeFileIdByWorktree: { ...s.activeFileIdByWorktree, [worktreeId]: id },
|
||||
|
|
|
|||
Loading…
Reference in New Issue