Skip to main content

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.

info

This extension differs from the CodeExtension, which provides code marks on inline text.

info

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;

API