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)
+ }
+}