diff --git a/services/web/frontend/js/features/source-editor/components/command-tooltip/include-tooltip.tsx b/services/web/frontend/js/features/source-editor/components/command-tooltip/include-tooltip.tsx index 379f2cc100..87957a48ad 100644 --- a/services/web/frontend/js/features/source-editor/components/command-tooltip/include-tooltip.tsx +++ b/services/web/frontend/js/features/source-editor/components/command-tooltip/include-tooltip.tsx @@ -1,18 +1,12 @@ import { FC } from 'react' import { useTranslation } from 'react-i18next' -import { useCodeMirrorStateContext } from '../codemirror-editor' import { Button } from 'react-bootstrap' -import { resolveCommandNode } from '../../extensions/command-tooltip' -import { - FilePathArgument, - LiteralArgContent, -} from '../../lezer-latex/latex.terms.mjs' -import Icon from '../../../../shared/components/icon' -import { EditorState } from '@codemirror/state' +import Icon from '@/shared/components/icon' +import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file' export const IncludeTooltipContent: FC = () => { const { t } = useTranslation() - const state = useCodeMirrorStateContext() + const { openIncludedFile } = useIncludedFile('IncludeArgument') return (
@@ -20,17 +14,7 @@ export const IncludeTooltipContent: FC = () => { type="button" bsStyle="link" className="ol-cm-command-tooltip-link" - onClick={() => { - const name = readFileName(state) - if (name) { - window.dispatchEvent( - new CustomEvent('editor:open-file', { - detail: { name }, - }) - ) - // TODO: handle file not found - } - }} + onClick={openIncludedFile} > {t('open_file')} @@ -38,15 +22,3 @@ export const IncludeTooltipContent: FC = () => {
) } - -const readFileName = (state: EditorState) => { - const commandNode = resolveCommandNode(state) - const argumentNode = commandNode - ?.getChild('IncludeArgument') - ?.getChild(FilePathArgument) - ?.getChild(LiteralArgContent) - - if (argumentNode) { - return state.sliceDoc(argumentNode.from, argumentNode.to) - } -} diff --git a/services/web/frontend/js/features/source-editor/components/command-tooltip/input-tooltip.tsx b/services/web/frontend/js/features/source-editor/components/command-tooltip/input-tooltip.tsx index ad86cc7cb5..332e02a1ac 100644 --- a/services/web/frontend/js/features/source-editor/components/command-tooltip/input-tooltip.tsx +++ b/services/web/frontend/js/features/source-editor/components/command-tooltip/input-tooltip.tsx @@ -1,18 +1,12 @@ import { FC } from 'react' import { useTranslation } from 'react-i18next' -import { useCodeMirrorStateContext } from '../codemirror-editor' import { Button } from 'react-bootstrap' -import { resolveCommandNode } from '../../extensions/command-tooltip' -import { - FilePathArgument, - LiteralArgContent, -} from '../../lezer-latex/latex.terms.mjs' -import Icon from '../../../../shared/components/icon' -import { EditorState } from '@codemirror/state' +import Icon from '@/shared/components/icon' +import { useIncludedFile } from '@/features/source-editor/hooks/use-included-file' export const InputTooltipContent: FC = () => { const { t } = useTranslation() - const state = useCodeMirrorStateContext() + const { openIncludedFile } = useIncludedFile('InputArgument') return (
@@ -20,17 +14,7 @@ export const InputTooltipContent: FC = () => { type="button" bsStyle="link" className="ol-cm-command-tooltip-link" - onClick={() => { - const name = readFileName(state) - if (name) { - window.dispatchEvent( - new CustomEvent('editor:open-file', { - detail: { name }, - }) - ) - // TODO: handle file not found - } - }} + onClick={openIncludedFile} > {t('open_file')} @@ -38,15 +22,3 @@ export const InputTooltipContent: FC = () => {
) } - -const readFileName = (state: EditorState) => { - const commandNode = resolveCommandNode(state) - const argumentNode = commandNode - ?.getChild('InputArgument') - ?.getChild(FilePathArgument) - ?.getChild(LiteralArgContent) - - if (argumentNode) { - return state.sliceDoc(argumentNode.from, argumentNode.to) - } -} diff --git a/services/web/frontend/js/features/source-editor/hooks/use-included-file.ts b/services/web/frontend/js/features/source-editor/hooks/use-included-file.ts new file mode 100644 index 0000000000..a68bc20e82 --- /dev/null +++ b/services/web/frontend/js/features/source-editor/hooks/use-included-file.ts @@ -0,0 +1,47 @@ +import { useCodeMirrorStateContext } from '@/features/source-editor/components/codemirror-editor' +import { useFileTreePathContext } from '@/features/file-tree/contexts/file-tree-path' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' +import { useCallback } from 'react' +import { EditorState } from '@codemirror/state' +import { resolveCommandNode } from '@/features/source-editor/extensions/command-tooltip' +import { + FilePathArgument, + LiteralArgContent, +} from '@/features/source-editor/lezer-latex/latex.terms.mjs' + +export const useIncludedFile = (argumentType: string) => { + const state = useCodeMirrorStateContext() + const { findEntityByPath } = useFileTreePathContext() + const { openDocId } = useEditorManagerContext() + + const openIncludedFile = useCallback(() => { + const name = readIncludedPath(state, argumentType) + if (name) { + // TODO: find in relative path or root folder + for (const extension of ['.tex', '']) { + const result = findEntityByPath(`${name}${extension}`) + if (result) { + return openDocId(result.entity._id) + } + } + // TODO: handle file not found + } + }, [argumentType, findEntityByPath, openDocId, state]) + + return { openIncludedFile } +} + +const readIncludedPath = ( + state: EditorState, + argumentType: string | number +) => { + const commandNode = resolveCommandNode(state) + const argumentNode = commandNode + ?.getChild(argumentType) + ?.getChild(FilePathArgument) + ?.getChild(LiteralArgContent) + + if (argumentNode) { + return state.sliceDoc(argumentNode.from, argumentNode.to) + } +}