mirror of
https://github.com/silvanocerza/github-gitless-sync.git
synced 2026-07-22 05:41:36 +00:00
Go with react-codemirror lib
This commit is contained in:
parent
d1b980f031
commit
6ff48b9517
5 changed files with 132 additions and 64 deletions
|
|
@ -27,6 +27,7 @@
|
|||
"@codemirror/lang-markdown": "^6.3.2",
|
||||
"@codemirror/state": "^6.5.2",
|
||||
"@codemirror/view": "^6.36.2",
|
||||
"@uiw/react-codemirror": "^4.23.8",
|
||||
"codemirror": "^6.0.1",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ importers:
|
|||
'@codemirror/view':
|
||||
specifier: ^6.36.2
|
||||
version: 6.36.2
|
||||
'@uiw/react-codemirror':
|
||||
specifier: ^4.23.8
|
||||
version: 4.23.8(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.9)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.2)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
codemirror:
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
|
|
@ -68,6 +71,10 @@ packages:
|
|||
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/runtime@7.26.9':
|
||||
resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@codemirror/autocomplete@6.18.6':
|
||||
resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==}
|
||||
|
||||
|
|
@ -98,6 +105,9 @@ packages:
|
|||
'@codemirror/state@6.5.2':
|
||||
resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==}
|
||||
|
||||
'@codemirror/theme-one-dark@6.1.2':
|
||||
resolution: {integrity: sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==}
|
||||
|
||||
'@codemirror/view@6.36.2':
|
||||
resolution: {integrity: sha512-DZ6ONbs8qdJK0fdN7AB82CgI6tYXf4HWk1wSVa0+9bhVznCuuvhQtX8bFBoy3dv8rZSQqUd8GvhVAcielcidrA==}
|
||||
|
||||
|
|
@ -420,6 +430,28 @@ packages:
|
|||
resolution: {integrity: sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@uiw/codemirror-extensions-basic-setup@4.23.8':
|
||||
resolution: {integrity: sha512-XJR/8AEVcE7ufy1BhW2nCN9qSVDYEdCtYLfvhaMwl6Q3qcaYYCGE2K5QbFCy7LsdP/3uZKvc1OskuqatoOPdhQ==}
|
||||
peerDependencies:
|
||||
'@codemirror/autocomplete': '>=6.0.0'
|
||||
'@codemirror/commands': '>=6.0.0'
|
||||
'@codemirror/language': '>=6.0.0'
|
||||
'@codemirror/lint': '>=6.0.0'
|
||||
'@codemirror/search': '>=6.0.0'
|
||||
'@codemirror/state': '>=6.0.0'
|
||||
'@codemirror/view': '>=6.0.0'
|
||||
|
||||
'@uiw/react-codemirror@4.23.8':
|
||||
resolution: {integrity: sha512-/NA5Pj4MmXkLSlmlUm4yfEmRLntrNq5TkQKBSINn7TukXQ4fc+C6Bk0U60Qa4rkvCSgwzZdQ2exyP0t0+2GtqA==}
|
||||
peerDependencies:
|
||||
'@babel/runtime': '>=7.11.0'
|
||||
'@codemirror/state': '>=6.0.0'
|
||||
'@codemirror/theme-one-dark': '>=6.0.0'
|
||||
'@codemirror/view': '>=6.0.0'
|
||||
codemirror: '>=6.0.0'
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
|
||||
acorn-jsx@5.3.2:
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
peerDependencies:
|
||||
|
|
@ -755,6 +787,9 @@ packages:
|
|||
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
regenerator-runtime@0.14.1:
|
||||
resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
|
||||
|
||||
resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
|
@ -861,6 +896,10 @@ snapshots:
|
|||
'@babel/helper-validator-identifier@7.25.9':
|
||||
optional: true
|
||||
|
||||
'@babel/runtime@7.26.9':
|
||||
dependencies:
|
||||
regenerator-runtime: 0.14.1
|
||||
|
||||
'@codemirror/autocomplete@6.18.6':
|
||||
dependencies:
|
||||
'@codemirror/language': 6.10.8
|
||||
|
|
@ -940,6 +979,13 @@ snapshots:
|
|||
dependencies:
|
||||
'@marijn/find-cluster-break': 1.0.2
|
||||
|
||||
'@codemirror/theme-one-dark@6.1.2':
|
||||
dependencies:
|
||||
'@codemirror/language': 6.10.8
|
||||
'@codemirror/state': 6.5.2
|
||||
'@codemirror/view': 6.36.2
|
||||
'@lezer/highlight': 1.2.1
|
||||
|
||||
'@codemirror/view@6.36.2':
|
||||
dependencies:
|
||||
'@codemirror/state': 6.5.2
|
||||
|
|
@ -1237,6 +1283,33 @@ snapshots:
|
|||
'@typescript-eslint/types': 8.19.0
|
||||
eslint-visitor-keys: 4.2.0
|
||||
|
||||
'@uiw/codemirror-extensions-basic-setup@4.23.8(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.9)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)':
|
||||
dependencies:
|
||||
'@codemirror/autocomplete': 6.18.6
|
||||
'@codemirror/commands': 6.8.0
|
||||
'@codemirror/language': 6.10.8
|
||||
'@codemirror/lint': 6.8.4
|
||||
'@codemirror/search': 6.5.9
|
||||
'@codemirror/state': 6.5.2
|
||||
'@codemirror/view': 6.36.2
|
||||
|
||||
'@uiw/react-codemirror@4.23.8(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.9)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.2)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.9
|
||||
'@codemirror/commands': 6.8.0
|
||||
'@codemirror/state': 6.5.2
|
||||
'@codemirror/theme-one-dark': 6.1.2
|
||||
'@codemirror/view': 6.36.2
|
||||
'@uiw/codemirror-extensions-basic-setup': 4.23.8(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.9)(@codemirror/state@6.5.2)(@codemirror/view@6.36.2)
|
||||
codemirror: 6.0.1
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
transitivePeerDependencies:
|
||||
- '@codemirror/autocomplete'
|
||||
- '@codemirror/language'
|
||||
- '@codemirror/lint'
|
||||
- '@codemirror/search'
|
||||
|
||||
acorn-jsx@5.3.2(acorn@8.14.0):
|
||||
dependencies:
|
||||
acorn: 8.14.0
|
||||
|
|
@ -1591,6 +1664,8 @@ snapshots:
|
|||
|
||||
react@19.0.0: {}
|
||||
|
||||
regenerator-runtime@0.14.1: {}
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
reusify@1.0.4: {}
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ const DiffView: React.FC<DiffViewProps> = ({
|
|||
<div>
|
||||
<EditorPane
|
||||
content={oldText}
|
||||
highlightPlugin={createDiffHighlightPlugin({
|
||||
highlightPluginSpec={{
|
||||
diff: diffs,
|
||||
isOriginal: true,
|
||||
})}
|
||||
}}
|
||||
onEditorUpdate={handleEditorReady}
|
||||
onContentChange={onOldTextChange}
|
||||
/>
|
||||
|
|
@ -79,10 +79,10 @@ const DiffView: React.FC<DiffViewProps> = ({
|
|||
<div>
|
||||
<EditorPane
|
||||
content={newText}
|
||||
highlightPlugin={createDiffHighlightPlugin({
|
||||
highlightPluginSpec={{
|
||||
diff: diffs,
|
||||
isOriginal: false,
|
||||
})}
|
||||
}}
|
||||
onContentChange={onNewTextChange}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from "@codemirror/view";
|
||||
import { DiffChunk } from "./diff";
|
||||
|
||||
interface DiffHighlightPluginSpec {
|
||||
export interface DiffHighlightPluginSpec {
|
||||
diff: DiffChunk[];
|
||||
isOriginal: boolean;
|
||||
}
|
||||
|
|
@ -21,12 +21,6 @@ export function createDiffHighlightPlugin(spec: DiffHighlightPluginSpec) {
|
|||
this.decorations = this.buildDecorations(view);
|
||||
}
|
||||
|
||||
update(update: ViewUpdate) {
|
||||
if (update.docChanged) {
|
||||
this.decorations = this.buildDecorations(update.view);
|
||||
}
|
||||
}
|
||||
|
||||
buildDecorations(view: EditorView): DecorationSet {
|
||||
const decorations = [];
|
||||
const doc = view.state.doc;
|
||||
|
|
|
|||
|
|
@ -1,71 +1,69 @@
|
|||
import { markdown } from "@codemirror/lang-markdown";
|
||||
import { EditorState, StateEffect } from "@codemirror/state";
|
||||
import { EditorView, ViewPlugin } from "@codemirror/view";
|
||||
import { EditorView, ViewUpdate } from "@codemirror/view";
|
||||
import * as React from "react";
|
||||
import {
|
||||
DiffHighlightPluginSpec,
|
||||
createDiffHighlightPlugin,
|
||||
} from "./diff-highlight-plugin";
|
||||
import CodeMirror from "@uiw/react-codemirror";
|
||||
|
||||
interface EditorPaneProps {
|
||||
content: string;
|
||||
highlightPlugin: ViewPlugin<any>;
|
||||
highlightPluginSpec: DiffHighlightPluginSpec;
|
||||
onEditorUpdate?: (editor: EditorView) => void;
|
||||
onContentChange: (content: string) => void;
|
||||
}
|
||||
|
||||
const EditorPane: React.FC<EditorPaneProps> = ({
|
||||
content,
|
||||
highlightPlugin,
|
||||
highlightPluginSpec,
|
||||
onEditorUpdate,
|
||||
onContentChange,
|
||||
}) => {
|
||||
const editorRef = React.useRef<HTMLDivElement>(null);
|
||||
const extensions = [
|
||||
// basicSetup minus line numbers
|
||||
// EditorView.lineWrapping,
|
||||
EditorView.editable.of(true),
|
||||
createDiffHighlightPlugin(highlightPluginSpec),
|
||||
EditorView.theme({
|
||||
"&": {
|
||||
backgroundColor: "var(--background-primary)",
|
||||
color: "var(--text-normal)",
|
||||
},
|
||||
".cm-content": {
|
||||
padding: 0,
|
||||
caretColor: "var(--caret-color)",
|
||||
fontSize: "var(--font-text-size)",
|
||||
fontFamily: "var(--font-text)",
|
||||
},
|
||||
"&.cm-focused .cm-selectionBackground, .cm-selectionBackground": {
|
||||
background: "var(--text-selection)",
|
||||
},
|
||||
"&.cm-focused": {
|
||||
outline: 0,
|
||||
},
|
||||
"&.cm-focused .cm-cursor": {
|
||||
borderLeftColor: "var(--text-normal)",
|
||||
},
|
||||
}),
|
||||
markdown(),
|
||||
];
|
||||
|
||||
React.useEffect(() => {
|
||||
if (editorRef.current) {
|
||||
const editorState = EditorState.create({
|
||||
doc: content,
|
||||
extensions: [
|
||||
// basicSetup minus line numbers
|
||||
// EditorView.lineWrapping,
|
||||
EditorView.editable.of(true),
|
||||
highlightPlugin,
|
||||
EditorView.theme({
|
||||
"&": {
|
||||
backgroundColor: "var(--background-primary)",
|
||||
color: "var(--text-normal)",
|
||||
},
|
||||
".cm-content": {
|
||||
padding: 0,
|
||||
},
|
||||
"&.cm-focused .cm-selectionBackground, .cm-selectionBackground": {
|
||||
background: "var(--text-selection)",
|
||||
},
|
||||
"&.cm-focused .cm-cursor": {
|
||||
borderLeftColor: "var(--text-normal)",
|
||||
},
|
||||
}),
|
||||
markdown(),
|
||||
EditorView.updateListener.of((update) => {
|
||||
if (update.docChanged) {
|
||||
onContentChange(update.state.doc.toString());
|
||||
}
|
||||
// We want to know when it updates in case the line height changes
|
||||
onEditorUpdate?.(update.view);
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const editor = new EditorView({
|
||||
parent: editorRef.current,
|
||||
state: editorState,
|
||||
});
|
||||
|
||||
return () => {
|
||||
// Cleanup
|
||||
editor.destroy();
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
|
||||
return <div ref={editorRef} />;
|
||||
return (
|
||||
<CodeMirror
|
||||
value={content}
|
||||
theme={"none"}
|
||||
basicSetup={false}
|
||||
extensions={extensions}
|
||||
onUpdate={(viewUpdate: ViewUpdate) => {
|
||||
if (viewUpdate.docChanged) {
|
||||
onContentChange(viewUpdate.state.doc.toString());
|
||||
}
|
||||
// We want to know when it updates in case the line height changes
|
||||
onEditorUpdate?.(viewUpdate.view);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditorPane;
|
||||
|
|
|
|||
Loading…
Reference in a new issue