mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-3476 feat: save text selection and cursor position for each tab (#1846)
Co-authored-by: EvgeniaBzzz <139753579+EvgeniaBzzz@users.noreply.github.com>
This commit is contained in:
co-authored by
EvgeniaBzzz
parent
27b0180107
commit
c7e6cf9d95
@@ -6,8 +6,10 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import type { EditorView } from '@codemirror/view';
|
||||
import type { SelectionRange } from '@codemirror/state';
|
||||
|
||||
export interface IEditorRef {
|
||||
container: HTMLDivElement | null;
|
||||
view: EditorView | null;
|
||||
selection: SelectionRange | null;
|
||||
}
|
||||
|
||||
@@ -33,11 +33,15 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
|
||||
const [view, setView] = useState<EditorView | null>(null);
|
||||
const [incomingView, setIncomingView] = useState<EditorView | null>(null);
|
||||
const callbackRef = useObjectRef({ onChange, onUpdate });
|
||||
const [selection, setSelection] = useState(view?.state.selection.main ?? null);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (container) {
|
||||
const updateListener = EditorView.updateListener.of((update: ViewUpdate) => {
|
||||
const remote = update.transactions.some(tr => tr.annotation(External));
|
||||
if (update.selectionSet) {
|
||||
setSelection(update.state.selection.main);
|
||||
}
|
||||
|
||||
if (update.docChanged && !remote) {
|
||||
const doc = update.state.doc;
|
||||
@@ -159,8 +163,9 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
|
||||
() => ({
|
||||
container,
|
||||
view,
|
||||
selection,
|
||||
}),
|
||||
[container, view],
|
||||
[container, view, selection],
|
||||
);
|
||||
|
||||
const context = useMemo<IReactCodemirrorContext>(
|
||||
|
||||
+23
-2
@@ -6,13 +6,13 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { MenuBarSmallItem, useExecutor, useS, useTranslate } from '@cloudbeaver/core-blocks';
|
||||
import { useService } from '@cloudbeaver/core-di';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { DATA_CONTEXT_NAV_NODE, getNodesFromContext, NavNodeManagerService } from '@cloudbeaver/core-navigation-tree';
|
||||
import { TabContainerPanelComponent, useDNDBox } from '@cloudbeaver/core-ui';
|
||||
import { TabContainerPanelComponent, useDNDBox, useTabLocalState } from '@cloudbeaver/core-ui';
|
||||
import { closeCompletion, IEditorRef, Prec, ReactCodemirrorPanel, useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';
|
||||
import type { ISqlEditorModeProps } from '@cloudbeaver/plugin-sql-editor';
|
||||
|
||||
@@ -25,15 +25,36 @@ import { useSqlDialectExtension } from '../useSqlDialectExtension';
|
||||
import style from './SQLCodeEditorPanel.m.css';
|
||||
import { useSQLCodeEditorPanel } from './useSQLCodeEditorPanel';
|
||||
|
||||
interface ILocalSQLCodeEditorPanelState {
|
||||
selection: { from: number; to: number };
|
||||
};
|
||||
export const SQLCodeEditorPanel: TabContainerPanelComponent<ISqlEditorModeProps> = observer(function SQLCodeEditorPanel({ data }) {
|
||||
const notificationService = useService(NotificationService);
|
||||
const navNodeManagerService = useService(NavNodeManagerService);
|
||||
const translate = useTranslate();
|
||||
const localState = useTabLocalState<ILocalSQLCodeEditorPanelState>(() => ({ selection: { from: 0, to: 0 } }));
|
||||
|
||||
const styles = useS(style);
|
||||
const [editorRef, setEditorRef] = useState<IEditorRef | null>(null);
|
||||
|
||||
const editor = useSQLCodeEditor(editorRef);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
editorRef?.view?.dispatch({
|
||||
selection: { anchor: localState.selection.from, head: localState.selection.to },
|
||||
scrollIntoView: true,
|
||||
});
|
||||
}, [editorRef?.view, localState]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!editorRef?.selection) {
|
||||
return;
|
||||
}
|
||||
|
||||
localState.selection = { ...editorRef?.selection };
|
||||
}, [editorRef?.selection]);
|
||||
|
||||
const panel = useSQLCodeEditorPanel(data, editor);
|
||||
const extensions = useCodemirrorExtensions(undefined, [ACTIVE_QUERY_EXTENSION, Prec.lowest(QUERY_STATUS_GUTTER_EXTENSION)]);
|
||||
const autocompletion = useSqlDialectAutocompletion(data);
|
||||
|
||||
Reference in New Issue
Block a user