CodeMirrorExtension
Summary
The CodeMirror extension adds fenced code blocks to your editor powered by CodeMirror 6. A code block contains a formatted snippets of source code.
This extension differs from the CodeExtension
, which provides code marks on inline text.
Also check a simpler code block implementation at CodeBlockExtension
.
Features
Keyboard support
Users can create a new code block by typing ```
(3 ticks and a space). Users can define the language of the code block by typing ```html
.
Usage
Installation
This extension is NOT installed for you when you install the main remirror
package but need to be installed separately:
npm install @remirror/extension-codemirror6
You will probably also want to install some basic CodeMirror packages:
npm install @codemirror/basic-setup @codemirror/language-data @codemirror/theme-one-dark
You can use the imports in the following way:
import { basicSetup } from '@codemirror/basic-setup';
import { languages } from '@codemirror/language-data';
import { oneDark } from '@codemirror/theme-one-dark';
import { CodeMirrorExtension } from '@remirror/extension-codemirror6';
const codeMirrorExtension = new CodeMirrorExtension({
languages: languages,
extensions: [basicSetup, oneDark],
});
Examples
Source code
import './styles.css';
import { languages } from '@codemirror/language-data';
import { oneDark } from '@codemirror/theme-one-dark';
import React from 'react';
import { ProsemirrorDevTools } from '@remirror/dev';
import { CodeMirrorExtension } from '@remirror/extension-codemirror6';
import { Remirror, ThemeProvider, useRemirror, useRemirrorContext } from '@remirror/react';
const extensions = () => [new CodeMirrorExtension({ languages, extensions: [oneDark] })];
const jsCode = `function sayHello {
console.log('Hello world, JavaScript!')
}`;
const mdCode = `Hello _world_, **Markdown**`;
const cssCode = `.hello-world-css {
color: red;
}`;
const jsonCode = `{
"hello-world": "JSON"
}`;
const content = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Press the button to insert a new CodeMirror block.',
},
],
},
{
type: 'codeMirror',
attrs: {
language: 'JavaScript',
},
content: [
{
type: 'text',
text: jsCode,
},
],
},
{
type: 'codeMirror',
attrs: {
language: 'markdown',
},
content: [
{
type: 'text',
text: mdCode,
},
],
},
{
type: 'codeMirror',
attrs: {
language: 'css',
},
content: [
{
type: 'text',
text: cssCode,
},
],
},
{
type: 'codeMirror',
attrs: {
language: 'JSON',
},
content: [
{
type: 'text',
text: jsonCode,
},
],
},
],
};
const CreateCodeMirrorButton = ({ language }: { language: string }) => {
const { commands } = useRemirrorContext<CodeMirrorExtension>({ autoUpdate: true });
const { createCodeMirror } = commands;
const enabled = createCodeMirror.enabled({ language });
return (
<button
onMouseDown={(event) => event.preventDefault()}
onClick={() => createCodeMirror({ language })}
disabled={!enabled}
>
Create a {language} block
</button>
);
};
const Basic = (): JSX.Element => {
const { manager, state } = useRemirror({ extensions, content });
return (
<ThemeProvider>
<Remirror manager={manager} initialContent={state} autoRender='end'>
<CreateCodeMirrorButton language='JavaScript' />
<CreateCodeMirrorButton language='Markdown' />
<ProsemirrorDevTools />
</Remirror>
</ThemeProvider>
);
};
export default Basic;
You can customize your CodeMirror editor by passing your custom extensions.
Source code
import { EditorView as CodeMirrorEditorView } from '@codemirror/view';
import React from 'react';
import { CodeMirrorExtension } from '@remirror/extension-codemirror6';
import { Remirror, ThemeProvider, useRemirror } from '@remirror/react';
const myTheme = CodeMirrorEditorView.theme(
{
'&': {
color: '#633501',
backgroundColor: '#f5f0ab',
borderRadius: '16px',
fontSize: '1.5em',
},
'&.cm-editor': {
outlineWidth: '3px',
outlineStyle: 'solid',
outlineColor: '#c2c0b1',
},
'&.cm-editor.cm-focused': {
outlineWidth: '3px',
outlineStyle: 'solid',
outlineColor: '#da8845',
},
'.cm-content': {
padding: '18px 16px',
caretColor: '#7e490d',
},
},
{ dark: false },
);
const extensions = () => [new CodeMirrorExtension({ extensions: [myTheme] })];
const content = `<pre><code>Custom CodeMirror color theme</code></pre>`;
const WithCustomExtension = (): JSX.Element => {
const { manager, state } = useRemirror({ extensions, content, stringHandler: 'html' });
return (
<ThemeProvider>
<Remirror manager={manager} initialContent={state} autoRender />
</ThemeProvider>
);
};
export default WithCustomExtension;