feat: add table of contents shortcut
This commit is contained in:
@@ -1237,6 +1237,7 @@ function App() {
|
||||
|
||||
// Raw-toggle ref: Editor registers its handleToggleRaw here so the command palette can call it
|
||||
const rawToggleRef = useRef<() => void>(() => {})
|
||||
const tableOfContentsToggleRef = useRef<() => void>(() => {})
|
||||
// Diff-toggle ref: Editor registers its handleToggleDiff here so the command palette can call it
|
||||
const diffToggleRef = useRef<() => void>(() => {})
|
||||
const findInNoteRef = useRef<((options?: { replace?: boolean }) => void) | null>(null)
|
||||
@@ -1441,6 +1442,9 @@ function App() {
|
||||
() => canToggleRichEditor ? () => rawToggleRef.current() : undefined,
|
||||
[canToggleRichEditor],
|
||||
)
|
||||
const toggleTableOfContentsCommand = useCallback(() => {
|
||||
if (notes.activeTabPath) tableOfContentsToggleRef.current()
|
||||
}, [notes.activeTabPath])
|
||||
const findInNoteCommand = useCallback(() => {
|
||||
findInNoteRef.current?.({ replace: false })
|
||||
}, [])
|
||||
@@ -1558,6 +1562,7 @@ function App() {
|
||||
onToggleInspector: handleToggleInspector,
|
||||
onToggleDiff: toggleDiffCommand,
|
||||
onToggleRawEditor: toggleRawEditorCommand,
|
||||
onToggleTableOfContents: toggleTableOfContentsCommand,
|
||||
noteWidth: activeNoteWidth,
|
||||
defaultNoteWidth,
|
||||
onSetNoteWidth: handleSetActiveNoteWidth,
|
||||
@@ -1785,6 +1790,7 @@ function App() {
|
||||
noteWidth={activeNoteWidth}
|
||||
onToggleNoteWidth={handleToggleNoteWidth}
|
||||
rawToggleRef={rawToggleRef}
|
||||
tableOfContentsToggleRef={tableOfContentsToggleRef}
|
||||
findInNoteRef={findInNoteRef}
|
||||
diffToggleRef={diffToggleRef}
|
||||
canGoBack={canGoBack}
|
||||
|
||||
@@ -562,6 +562,15 @@ describe('BreadcrumbBar — table of contents toggle', () => {
|
||||
expect(screen.getByRole('button', { name: 'Close table of contents' })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows the table of contents shortcut in the button tooltip', async () => {
|
||||
render(<BreadcrumbBar entry={baseEntry} {...defaultProps} onToggleTableOfContents={vi.fn()} />)
|
||||
await expectTooltip(
|
||||
screen.getByRole('button', { name: 'Open table of contents' }),
|
||||
'Open table of contents',
|
||||
formatShortcutDisplay({ display: '⌘⇧T' }),
|
||||
)
|
||||
})
|
||||
|
||||
it('offers the table of contents action from the overflow menu', async () => {
|
||||
const onToggleTableOfContents = vi.fn()
|
||||
const restoreMeasurement = mockCollapsedBreadcrumbOverflow()
|
||||
|
||||
@@ -2,7 +2,7 @@ import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useStat
|
||||
import type { NoteWidthMode, VaultEntry } from '../types'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { translate, type AppLocale } from '../lib/i18n'
|
||||
import { formatShortcutDisplay } from '../hooks/appCommandCatalog'
|
||||
import { APP_COMMAND_IDS, formatShortcutDisplay, getAppCommandShortcutDisplay } from '../hooks/appCommandCatalog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { ActionTooltip, type ActionTooltipCopy } from '@/components/ui/action-tooltip'
|
||||
@@ -353,7 +353,10 @@ function TableOfContentsAction({
|
||||
|
||||
return (
|
||||
<IconActionButton
|
||||
copy={{ label: translate(locale, showTableOfContents ? 'editor.toolbar.closeTableOfContents' : 'editor.toolbar.openTableOfContents') }}
|
||||
copy={{
|
||||
label: translate(locale, showTableOfContents ? 'editor.toolbar.closeTableOfContents' : 'editor.toolbar.openTableOfContents'),
|
||||
shortcut: getAppCommandShortcutDisplay(APP_COMMAND_IDS.viewToggleTableOfContents),
|
||||
}}
|
||||
onClick={onToggleTableOfContents}
|
||||
className={cn(showTableOfContents ? 'text-foreground' : 'hover:text-foreground')}
|
||||
>
|
||||
|
||||
@@ -103,6 +103,8 @@ interface EditorProps {
|
||||
findInNoteRef?: React.MutableRefObject<((options?: { replace?: boolean }) => void) | null>
|
||||
/** Mutable ref that Editor registers its diff-mode toggle into, for command palette access. */
|
||||
diffToggleRef?: React.MutableRefObject<() => void>
|
||||
/** Mutable ref that Editor registers its table-of-contents toggle into, for app shortcuts and menus. */
|
||||
tableOfContentsToggleRef?: React.MutableRefObject<() => void>
|
||||
onFileCreated?: (relativePath: string) => void
|
||||
onFileModified?: (relativePath: string) => void
|
||||
onVaultChanged?: () => void
|
||||
@@ -601,6 +603,12 @@ export const Editor = memo(function Editor(props: EditorProps) {
|
||||
flushPendingRawContentRef: props.flushPendingRawContentRef,
|
||||
})
|
||||
const rightPanel = useRightPanelExclusion(props)
|
||||
const { tableOfContentsToggleRef } = props
|
||||
useEffect(() => {
|
||||
if (tableOfContentsToggleRef) {
|
||||
tableOfContentsToggleRef.current = rightPanel.handleToggleTableOfContents
|
||||
}
|
||||
}, [tableOfContentsToggleRef, rightPanel.handleToggleTableOfContents])
|
||||
|
||||
return (
|
||||
<EditorLayout
|
||||
|
||||
@@ -6,6 +6,9 @@ import { buildTableOfContents, buildTableOfContentsFromMarkdown } from './tableO
|
||||
|
||||
const entry = {
|
||||
title: 'The Compounding Software Factory',
|
||||
modifiedAt: 1700000000,
|
||||
createdAt: 1700000000,
|
||||
fileSize: 2048,
|
||||
} as VaultEntry
|
||||
|
||||
const blocks = [
|
||||
@@ -140,4 +143,20 @@ describe('TableOfContentsPanel', () => {
|
||||
fireEvent.click(screen.getByRole('button', { name: /What causes teams to degrade/ }))
|
||||
expect(setTextCursorPosition).toHaveBeenCalledWith('h2', 'start')
|
||||
})
|
||||
|
||||
it('shows note info at the bottom of the table of contents', () => {
|
||||
render(
|
||||
<TableOfContentsPanel
|
||||
editor={{ document: blocks, setTextCursorPosition: vi.fn() }}
|
||||
entry={entry}
|
||||
sourceContent="One two three"
|
||||
onClose={vi.fn()}
|
||||
/>,
|
||||
)
|
||||
|
||||
expect(screen.getByText('Info')).toBeInTheDocument()
|
||||
expect(screen.getByText('Words')).toBeInTheDocument()
|
||||
expect(screen.getByText('3')).toBeInTheDocument()
|
||||
expect(screen.getByText('2.0 KB')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
getFolderConnectorLeft,
|
||||
getFolderDepthIndent,
|
||||
} from './folder-tree/folderTreeLayout'
|
||||
import { NoteInfoPanel } from './inspector/NoteInfoPanel'
|
||||
|
||||
interface TableOfContentsEditor {
|
||||
document?: unknown[]
|
||||
@@ -283,6 +284,11 @@ export const TableOfContentsPanel = memo(function TableOfContentsPanel({
|
||||
onNavigate={navigateToItem}
|
||||
/>
|
||||
</div>
|
||||
{entry && (
|
||||
<div className="shrink-0 border-t border-border p-3">
|
||||
<NoteInfoPanel entry={entry} content={sourceContent ?? null} locale={locale} />
|
||||
</div>
|
||||
)}
|
||||
</aside>
|
||||
)
|
||||
})
|
||||
|
||||
@@ -45,6 +45,7 @@ type SimpleHandlerKey =
|
||||
| 'onToggleDiff'
|
||||
| 'onToggleInspector'
|
||||
| 'onToggleAIChat'
|
||||
| 'onToggleTableOfContents'
|
||||
| 'onCommandPalette'
|
||||
| 'onZoomIn'
|
||||
| 'onZoomOut'
|
||||
|
||||
@@ -48,6 +48,7 @@ function makeHandlers(): AppCommandHandlers {
|
||||
onToggleRawEditor: vi.fn(),
|
||||
onToggleDiff: vi.fn(),
|
||||
onToggleAIChat: vi.fn(),
|
||||
onToggleTableOfContents: vi.fn(),
|
||||
onPastePlainText: vi.fn(),
|
||||
onGoBack: vi.fn(),
|
||||
onGoForward: vi.fn(),
|
||||
@@ -134,6 +135,7 @@ describe('appCommandDispatcher', () => {
|
||||
expect(findShortcutCommandId('command-or-ctrl', 'o', 'KeyO')).toBe(APP_COMMAND_IDS.fileQuickOpen)
|
||||
expect(findShortcutCommandId('command-or-ctrl', '\\')).toBe(APP_COMMAND_IDS.editToggleRawEditor)
|
||||
expect(findShortcutCommandId('command-or-ctrl-shift', '¬', 'KeyL')).toBe(APP_COMMAND_IDS.viewToggleAiChat)
|
||||
expect(findShortcutCommandId('command-or-ctrl-shift', 'T', 'KeyT')).toBe(APP_COMMAND_IDS.viewToggleTableOfContents)
|
||||
expect(findShortcutCommandId('command-or-ctrl-shift', 'v', 'KeyV')).toBe(APP_COMMAND_IDS.editPastePlainText)
|
||||
})
|
||||
|
||||
@@ -196,6 +198,7 @@ describe('appCommandDispatcher', () => {
|
||||
expectShortcutEventCommand({ key: 'ArrowLeft', code: 'ArrowLeft', metaKey: true }, APP_COMMAND_IDS.viewGoBack)
|
||||
expectShortcutEventCommand({ key: 'ArrowRight', code: 'ArrowRight', metaKey: true }, APP_COMMAND_IDS.viewGoForward)
|
||||
expectShortcutEventCommand({ key: 'l', code: 'KeyL', ctrlKey: true, shiftKey: true }, APP_COMMAND_IDS.viewToggleAiChat)
|
||||
expectShortcutEventCommand({ key: 'T', code: 'KeyT', metaKey: true, shiftKey: true }, APP_COMMAND_IDS.viewToggleTableOfContents)
|
||||
expectShortcutEventCommand({ key: 'V', code: 'KeyV', metaKey: true, shiftKey: true }, APP_COMMAND_IDS.editPastePlainText)
|
||||
})
|
||||
|
||||
@@ -227,6 +230,12 @@ describe('appCommandDispatcher', () => {
|
||||
expect(handlers.onToggleAIChat).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('dispatches table of contents toggle through the shared command path', () => {
|
||||
const handlers = makeHandlers()
|
||||
expect(dispatchAppCommand(APP_COMMAND_IDS.viewToggleTableOfContents, handlers)).toBe(true)
|
||||
expect(handlers.onToggleTableOfContents).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('dispatches plain-text paste through the shared command path', () => {
|
||||
const handlers = makeHandlers()
|
||||
expect(dispatchAppCommand(APP_COMMAND_IDS.editPastePlainText, handlers)).toBe(true)
|
||||
|
||||
@@ -50,6 +50,7 @@ export interface AppCommandHandlers {
|
||||
onToggleRawEditor?: () => void
|
||||
onToggleDiff?: () => void
|
||||
onToggleAIChat?: () => void
|
||||
onToggleTableOfContents?: () => void
|
||||
onGoBack?: () => void
|
||||
onGoForward?: () => void
|
||||
onCheckForUpdates?: () => void
|
||||
@@ -87,6 +88,7 @@ type SimpleHandlerKey = keyof Pick<
|
||||
| 'onToggleDiff'
|
||||
| 'onToggleInspector'
|
||||
| 'onToggleAIChat'
|
||||
| 'onToggleTableOfContents'
|
||||
| 'onCommandPalette'
|
||||
| 'onZoomIn'
|
||||
| 'onZoomOut'
|
||||
@@ -131,6 +133,7 @@ const SIMPLE_HANDLER_EXECUTORS: readonly [SimpleHandlerKey, SimpleHandlerExecuto
|
||||
['onToggleDiff', (handlers) => handlers.onToggleDiff?.()],
|
||||
['onToggleInspector', (handlers) => handlers.onToggleInspector()],
|
||||
['onToggleAIChat', (handlers) => handlers.onToggleAIChat?.()],
|
||||
['onToggleTableOfContents', (handlers) => handlers.onToggleTableOfContents?.()],
|
||||
['onCommandPalette', (handlers) => handlers.onCommandPalette()],
|
||||
['onZoomIn', (handlers) => handlers.onZoomIn()],
|
||||
['onZoomOut', (handlers) => handlers.onZoomOut()],
|
||||
|
||||
@@ -28,6 +28,7 @@ export type KeyboardActions = Pick<
|
||||
| 'onGoBack'
|
||||
| 'onGoForward'
|
||||
| 'onToggleAIChat'
|
||||
| 'onToggleTableOfContents'
|
||||
| 'onToggleRawEditor'
|
||||
| 'onToggleInspector'
|
||||
| 'onToggleFavorite'
|
||||
|
||||
@@ -29,6 +29,7 @@ interface ViewCommandsConfig {
|
||||
onSetNoteWidth?: (mode: NoteWidthMode) => void
|
||||
onSetDefaultNoteWidth?: (mode: NoteWidthMode) => void
|
||||
onToggleAIChat?: () => void
|
||||
onToggleTableOfContents?: () => void
|
||||
zoomLevel: number
|
||||
onZoomIn: () => void
|
||||
onZoomOut: () => void
|
||||
@@ -92,12 +93,27 @@ function buildMoveSavedViewCommand(
|
||||
}
|
||||
}
|
||||
|
||||
function buildToggleTableOfContentsCommand(
|
||||
hasActiveNote: boolean,
|
||||
onToggleTableOfContents?: () => void,
|
||||
): CommandAction {
|
||||
return {
|
||||
id: 'toggle-table-of-contents',
|
||||
label: 'Toggle Table of Contents',
|
||||
group: 'View',
|
||||
shortcut: getAppCommandShortcutDisplay(APP_COMMAND_IDS.viewToggleTableOfContents),
|
||||
keywords: ['toc', 'outline', 'headings', 'contents', 'panel'],
|
||||
enabled: hasActiveNote && !!onToggleTableOfContents,
|
||||
execute: () => onToggleTableOfContents?.(),
|
||||
}
|
||||
}
|
||||
|
||||
export function buildViewCommands(config: ViewCommandsConfig): CommandAction[] {
|
||||
const {
|
||||
hasActiveNote, activeNoteModified,
|
||||
onSetViewMode, onToggleInspector, onToggleDiff, onToggleRawEditor,
|
||||
noteWidth = DEFAULT_NOTE_WIDTH_MODE, defaultNoteWidth = DEFAULT_NOTE_WIDTH_MODE,
|
||||
onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat,
|
||||
onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat, onToggleTableOfContents,
|
||||
zoomLevel, onZoomIn, onZoomOut, onZoomReset,
|
||||
onCustomizeNoteListColumns, canCustomizeNoteListColumns, noteListColumnsLabel,
|
||||
selectedViewName, onMoveSelectedViewUp, onMoveSelectedViewDown,
|
||||
@@ -116,6 +132,7 @@ export function buildViewCommands(config: ViewCommandsConfig): CommandAction[] {
|
||||
buildSetDefaultNoteWidthCommand('normal', defaultNoteWidth, onSetDefaultNoteWidth),
|
||||
buildSetDefaultNoteWidthCommand('wide', defaultNoteWidth, onSetDefaultNoteWidth),
|
||||
{ id: 'toggle-ai-panel', label: 'Toggle AI Panel', group: 'View', shortcut: getAppCommandShortcutDisplay(APP_COMMAND_IDS.viewToggleAiChat), keywords: ['ai', 'agent', 'chat', 'assistant', 'contextual'], enabled: true, execute: () => onToggleAIChat?.() },
|
||||
buildToggleTableOfContentsCommand(hasActiveNote, onToggleTableOfContents),
|
||||
{ id: 'new-ai-chat', label: 'New AI chat', group: 'View', keywords: ['ai', 'agent', 'chat', 'assistant', 'new', 'fresh', 'conversation', 'reset'], enabled: true, execute: requestNewAiChat },
|
||||
{ id: 'toggle-backlinks', label: 'Toggle Backlinks', group: 'View', keywords: ['backlinks', 'references', 'links', 'mentions', 'incoming'], enabled: hasActiveNote, execute: onToggleInspector },
|
||||
buildMoveSavedViewCommand('Up', selectedViewName, onMoveSelectedViewUp, canMoveSelectedViewUp),
|
||||
|
||||
@@ -75,6 +75,7 @@ interface AppCommandsConfig {
|
||||
onInitializeGit?: () => void
|
||||
onCreateType?: () => void
|
||||
onToggleAIChat?: () => void
|
||||
onToggleTableOfContents?: () => void
|
||||
onCheckForUpdates?: () => void
|
||||
onRemoveActiveVault?: () => void
|
||||
onRestoreGettingStarted?: () => void
|
||||
@@ -176,6 +177,7 @@ type CommandRegistryCoreActions = Pick<
|
||||
| 'onSetNoteWidth'
|
||||
| 'onSetDefaultNoteWidth'
|
||||
| 'onToggleAIChat'
|
||||
| 'onToggleTableOfContents'
|
||||
>
|
||||
type CommandRegistryVaultActions = Pick<
|
||||
CommandRegistryConfig,
|
||||
@@ -256,6 +258,7 @@ function createKeyboardActions(
|
||||
onGoBack: config.onGoBack,
|
||||
onGoForward: config.onGoForward,
|
||||
onToggleAIChat: config.onToggleAIChat,
|
||||
onToggleTableOfContents: config.onToggleTableOfContents,
|
||||
onToggleRawEditor: config.onToggleRawEditor,
|
||||
onToggleInspector: config.onToggleInspector,
|
||||
onToggleFavorite: config.onToggleFavorite,
|
||||
@@ -302,6 +305,7 @@ function createMenuEventActionHandlers(
|
||||
| 'onToggleRawEditor'
|
||||
| 'onToggleDiff'
|
||||
| 'onToggleAIChat'
|
||||
| 'onToggleTableOfContents'
|
||||
| 'onToggleOrganized'
|
||||
| 'onGoBack'
|
||||
| 'onGoForward'
|
||||
@@ -328,6 +332,7 @@ function createMenuEventActionHandlers(
|
||||
onToggleRawEditor: config.onToggleRawEditor,
|
||||
onToggleDiff: config.onToggleDiff,
|
||||
onToggleAIChat: config.onToggleAIChat,
|
||||
onToggleTableOfContents: config.onToggleTableOfContents,
|
||||
onToggleOrganized: config.onToggleOrganized,
|
||||
onGoBack: config.onGoBack,
|
||||
onGoForward: config.onGoForward,
|
||||
@@ -452,6 +457,7 @@ function createCommandRegistryCoreConfig(
|
||||
onSetNoteWidth: config.onSetNoteWidth,
|
||||
onSetDefaultNoteWidth: config.onSetDefaultNoteWidth,
|
||||
onToggleAIChat: config.onToggleAIChat,
|
||||
onToggleTableOfContents: config.onToggleTableOfContents,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ interface CommandRegistryConfig {
|
||||
onSetNoteWidth?: (mode: NoteWidthMode) => void
|
||||
onSetDefaultNoteWidth?: (mode: NoteWidthMode) => void
|
||||
onToggleAIChat?: () => void
|
||||
onToggleTableOfContents?: () => void
|
||||
activeNoteModified: boolean
|
||||
onCheckForUpdates?: () => void
|
||||
onZoomIn: () => void
|
||||
@@ -129,7 +130,7 @@ export function useCommandRegistry(config: CommandRegistryConfig): import('./com
|
||||
onQuickOpen, onCreateNote, onCreateNoteOfType, onSave, onPastePlainText, onOpenSettings, onOpenFeedback,
|
||||
onDeleteNote, onArchiveNote, onUnarchiveNote,
|
||||
onCommitPush, onPull, onResolveConflicts, onSetViewMode, onToggleInspector, onToggleDiff, onToggleRawEditor, onFindInNote, onReplaceInNote,
|
||||
noteWidth, defaultNoteWidth, onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat, onOpenVault, onCreateEmptyVault,
|
||||
noteWidth, defaultNoteWidth, onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat, onToggleTableOfContents, onOpenVault, onCreateEmptyVault,
|
||||
selectedViewName, onMoveSelectedViewUp, onMoveSelectedViewDown, canMoveSelectedViewUp, canMoveSelectedViewDown,
|
||||
activeNoteModified,
|
||||
onZoomIn, onZoomOut, onZoomReset, zoomLevel,
|
||||
@@ -224,12 +225,12 @@ export function useCommandRegistry(config: CommandRegistryConfig): import('./com
|
||||
|
||||
const viewCommands = useMemo(() => buildViewCommands({
|
||||
hasActiveNote, activeNoteModified, onSetViewMode, onToggleInspector,
|
||||
onToggleDiff, onToggleRawEditor, noteWidth, defaultNoteWidth, onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat, zoomLevel, onZoomIn, onZoomOut, onZoomReset,
|
||||
onToggleDiff, onToggleRawEditor, noteWidth, defaultNoteWidth, onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat, onToggleTableOfContents, zoomLevel, onZoomIn, onZoomOut, onZoomReset,
|
||||
onCustomizeNoteListColumns, canCustomizeNoteListColumns, noteListColumnsLabel,
|
||||
selectedViewName, onMoveSelectedViewUp, onMoveSelectedViewDown, canMoveSelectedViewUp, canMoveSelectedViewDown,
|
||||
}), [
|
||||
hasActiveNote, activeNoteModified, onSetViewMode, onToggleInspector,
|
||||
onToggleDiff, onToggleRawEditor, noteWidth, defaultNoteWidth, onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat,
|
||||
onToggleDiff, onToggleRawEditor, noteWidth, defaultNoteWidth, onSetNoteWidth, onSetDefaultNoteWidth, onToggleAIChat, onToggleTableOfContents,
|
||||
zoomLevel, onZoomIn, onZoomOut, onZoomReset,
|
||||
onCustomizeNoteListColumns, canCustomizeNoteListColumns, noteListColumnsLabel,
|
||||
selectedViewName, onMoveSelectedViewUp, onMoveSelectedViewDown, canMoveSelectedViewUp, canMoveSelectedViewDown,
|
||||
|
||||
@@ -182,6 +182,19 @@
|
||||
"requiresManualNativeAcceleratorQa": true
|
||||
}
|
||||
},
|
||||
"viewToggleTableOfContents": {
|
||||
"id": "view-toggle-table-of-contents",
|
||||
"route": { "kind": "handler", "handler": "onToggleTableOfContents" },
|
||||
"menuOwned": true,
|
||||
"shortcut": {
|
||||
"combo": "command-or-ctrl-shift",
|
||||
"key": "t",
|
||||
"code": "KeyT",
|
||||
"display": "⌘⇧T",
|
||||
"accelerator": "CmdOrCtrl+Shift+T",
|
||||
"requiresManualNativeAcceleratorQa": true
|
||||
}
|
||||
},
|
||||
"viewToggleBacklinks": {
|
||||
"id": "view-toggle-backlinks",
|
||||
"route": { "kind": "handler", "handler": "onToggleInspector" },
|
||||
@@ -474,6 +487,7 @@
|
||||
{ "kind": "command", "command": "noteOpenInNewWindow", "label": "Open in New Window" },
|
||||
{ "kind": "separator" },
|
||||
{ "kind": "command", "command": "editToggleRawEditor", "label": "Toggle Raw Editor" },
|
||||
{ "kind": "command", "command": "viewToggleTableOfContents", "label": "Toggle Table of Contents" },
|
||||
{ "kind": "command", "command": "viewToggleAiChat", "label": "Toggle AI Panel" },
|
||||
{ "kind": "command", "command": "viewToggleBacklinks", "label": "Toggle Backlinks" }
|
||||
]
|
||||
@@ -510,6 +524,7 @@
|
||||
{ "command": "noteDelete" },
|
||||
{ "command": "editToggleRawEditor" },
|
||||
{ "command": "editToggleDiff" },
|
||||
{ "command": "viewToggleTableOfContents" },
|
||||
{ "command": "viewToggleBacklinks" },
|
||||
{ "command": "noteOpenInNewWindow" }
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user