Closed UvDream closed 2 years ago
@UvDream Example: https://codesandbox.io/embed/react-codemirror-example-codemirror-6-forked-6dymyn?fontsize=14&hidenavigation=1&theme=dark
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { javascript } from "@codemirror/lang-javascript";
import { ViewPlugin } from "@codemirror/view";
import { code } from "./code";
export default function App() {
const scroll = ViewPlugin.fromClass(
class {
constructor(view) {
view.scrollDOM.addEventListener("scroll", () => {
console.log("sss122");
});
}
}
);
const onChange = React.useCallback((value, viewUpdate) => {
console.log("value:", value);
}, []);
return (
<div>
<CodeMirror
value={code}
height="200px"
theme="dark"
extensions={[scroll, javascript({ jsx: true })]}
onChange={onChange}
/>
</div>
);
}
非常感谢,那么我设置滚动高度也可以通过这个设置吗
<CodeMirror
value="console.log('hello world!');"
+ height="200px"
extensions={[javascript({ jsx: true })]}
onChange={onChange}
/>
@UvDream
我的意思是滚动到指定高度,因为我需要做一个同步滚动功能
@UvDream view.scrollDOM 这是个内置的 dom 节点,你可以正对它进行操控。
@jaywcjlove 好的,那么我在光标处插入文字是不是也可以操作这个dom来实现
@UvDream 这个你需要看 codemirror 官方文档,插入文字不使用 dom 实现。
@UvDream 这个你需要看 codemirror 官方文档,插入文字不使用 dom 实现。
CodeMirror.instance.replaceSelection("插入文字"),这个CodeMirror就是这个组件?还是组件向外暴露了另外的对象吗
@UvDream react-codemirror 是基于 codemirror 封装的。
import CodeMirror from '@uiw/react-codemirror';
import { events } from '@uiw/codemirror-extensions-events';
function App() {
const [scrollTop, setScrollTop] = useState(0);
const eventExt = events.scroll({
scroll: (evn) => {
setScrollTop(evn.target.scrollTop);
},
});
const eventExt2 = events.content({
focus: (evn) => {
console.log('focus');
},
blur: (evn) => {
console.log('blur');
},
});
return <CodeMirror value="console.log('hello world!');" height="200px" extensions={[eventExt, eventExt2]} />;
}
export default App;
@UvDream react-codemirror 是基于 codemirror 封装的。
还是和这个相关的问题请教下,在1.0的时候获取
这个对象是这样的
<CodeMirror
...
ref={this.getInstance}
/>
.....
getInstance=(instance)=>{
console.log(instance.editor)
}
v4新版本有啥方法可以获取吗,感谢
@UvDream 一样的获取,但是获取的内容是 CM 6 的对象。 v1~v3 是基于 CM 5 搞的, CM6 变化非常大。
一样的获取,但是获取的内容是 CM 6 的对象。 v1~v3 是基于 CM 5 搞的, CM6 变化非常大。
@jaywcjlove 不知道为啥获取差异性还挺大
v1版本
getInstance = (instance) => {
if (instance) {
console.log( instance);
}
};
@UvDream CM6 重构的版本
@UvDream CM6 重构的版本
好的,我去看看v6版本咋在光标处插入文字
import React from "react";
import CodeMirror from "@uiw/react-codemirror";
import { javascript } from "@codemirror/lang-javascript";
export default function App() {
const onChange = React.useCallback((value, viewUpdate) => {
console.log("value:", value);
}, []);
return (
<div>
<CodeMirror
value="console.log('hello world!');"
height="200px"
theme="dark"
ref={(instance) => {
console.log(instance);
}}
extensions={[javascript({ jsx: true })]}
onChange={onChange}
/>
</div>
);
}
import React from "react"; import CodeMirror from "@uiw/react-codemirror"; import { javascript } from "@codemirror/lang-javascript"; export default function App() { const onChange = React.useCallback((value, viewUpdate) => { console.log("value:", value); }, []); return ( <div> <CodeMirror value="console.log('hello world!');" height="200px" theme="dark" ref={(instance) => { console.log(instance); }} extensions={[javascript({ jsx: true })]} onChange={onChange} /> </div> ); }
是的,我也是这样的,但是我看api是instance.state.replaceSelection(),
[replaceSelection](https://codemirror.net/docs/ref/#state.EditorState.replaceSelection)([text](https://codemirror.net/docs/ref/#state.EditorState.replaceSelection^text): [string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) | [Text](https://codemirror.net/docs/ref/#state.Text)) → [TransactionSpec](https://codemirror.net/docs/ref/#state.TransactionSpec)
Create a [transaction spec](https://codemirror.net/docs/ref/#state.TransactionSpec) that replaces every selection range with the given content.
但是我没插入成功,可以帮忙试试在光标处插入文本吗,感谢
import CodeMirror from "@uiw/react-codemirror";
import { useRef, useCallback, useState } from "react";
import { javascript } from "@codemirror/lang-javascript";
const code = `console.log('hello world!');
`;
export default function App() {
const $ref = useRef();
const [text, setText] = useState(code);
const handleClick = () => {
const state = $ref.current.view.viewState.state;
const range = state.selection.ranges[0];
console.log(">>>>1>", state.selection.ranges[0]);
$ref.current.view.dispatch({
changes: { from: range.from, to: range.to, insert: "test" }
});
};
const onChange = useCallback((value, viewUpdate) => {
setText(value);
}, []);
return (
<div>
<button onClick={handleClick}>Click Me!</button>
<CodeMirror
ref={$ref}
value={text}
height="200px"
extensions={[javascript({ jsx: true })]}
onChange={onChange}
/>
</div>
);
}
import CodeMirror from "@uiw/react-codemirror"; import { useRef, useCallback, useState } from "react"; import { javascript } from "@codemirror/lang-javascript"; const code = `console.log('hello world!'); `; export default function App() { const $ref = useRef(); const [text, setText] = useState(code); const handleClick = () => { const state = $ref.current.view.viewState.state; const range = state.selection.ranges[0]; console.log(">>>>1>", state.selection.ranges[0]); $ref.current.view.dispatch({ changes: { from: range.from, to: range.to, insert: "test" } }); }; const onChange = useCallback((value, viewUpdate) => { setText(value); }, []); return ( <div> <button onClick={handleClick}>Click Me!</button> <CodeMirror ref={$ref} value={text} height="200px" extensions={[javascript({ jsx: true })]} onChange={onChange} /> </div> ); }
感谢,那文档实在太不易读了
@jaywcjlove 大佬,我又来问问题了,codemirror6的文档实在太难找了,示例都少,还是那个光标插入的时候如何将光标放入插入文本中间,markdown中加粗光标,以前我是这样写的
editor.replaceSelection(`**${selection}**`);
正常这种你应该在 官方论坛中提问 https://discuss.codemirror.net , 刚好有人提供了方法,你自己看看去吧。
@UvDream https://github.com/uiwjs/react-codemirror/issues/243#issuecomment-1003873169
使用下面方法移动光标位置:
EditorSelection.cursor(5)
const { from, to } = ranges[0] || {};
const txt = view.state.sliceDoc(from, to);
view.dispatch(view.state.replaceSelection(`**${txt}**`));
const { from, to } = ranges[0] || {}; const txt = view.state.sliceDoc(from, to); view.dispatch(view.state.replaceSelection(`**${txt}**`));
谢谢,我去论坛找到了方法
@UvDream 是下面方法吗?
view.dispatch(
view.state.changeByRange((range) => ({
changes: [
{ from: range.from, insert: "**" },
{ from: range.to, insert: "**" }
],
range: EditorSelection.range(range.from + 2, range.to + 2)
}))
);
@UvDream 是下面方法吗?
view.dispatch( view.state.changeByRange((range) => ({ changes: [ { from: range.from, insert: "**" }, { from: range.to, insert: "**" } ], range: EditorSelection.range(range.from + 2, range.to + 2) })) );
export const insert = (editor, text, selection) => {
const state = editor.current.view.viewState.state;
const range = state.selection.ranges[0];
editor.current.view.dispatch({
changes: {
from: range.from,
to: range.to,
insert: `${text}`
},
selection: {anchor: range.from + selection}
})
}
这个,但是有个bug,我还没找到原因,例如输入# ,第一次输入就是正确一个#,再次触发就输入两个##了,依次累计,触发条件和编辑器不在一个组件里面就会这样,如果和编辑器在一个组件不会,论坛没人鸟我,哈哈哈
Does the v4 version not get the editor scroll height event?