CodeMirror 6 を触ってみよう

APIが充実しててカスタマイズしやすいCodeMirrorというWysiwygエディタの開発中のバージョン6が、スマホでもいい感じに動くことを目指してるし、共同編集の機能を実装しやすそうな気がしたのでちょっと試してみました！

[出来上がるもの](https://codesandbox.io/s/codemirror6-test-tx5ys?fontsize=14&hidenavigation=1&theme=dark)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10609/942c45de-1361-65f1-822d-32fd3f8f7d40.png)

（エディタのとこを3回くらいクリックすると編集できるよ！）

## Hello World!

✍️ まずはエディタを設置する。CodeMirror6はコアには最低限の機能だけを備えていて、必要な昨日はExtensionを追加することで実現する。
✍️ そのため、ソースコードが小さくなるし（今は全部が一つのリポジトリに入ってるから小さくはない？)、必要な処理だけするから速い

このままだと文字が書けるだけ。

```typescript
import { EditorView } from "@codemirror/next/view";
import { EditorState } from "@codemirror/next/state";

let myView = new EditorView({
  state: EditorState.create({
    doc: "hello world!",
    extensions: []
  })
});

document.body.appendChild(myView.dom);
```

## 履歴機能を追加

✍️ 拡張機能を追加する時はこう書く
✍️ 履歴機能とキーマップのExtensionを追加
✍️ 実装方法を学ぶ時は[デモ](https://github.com/codemirror/codemirror.next/blob/master/demo/demo.ts)を見るのがわかりやすい
✍️ baseKeymapは日本語の変換時の挙動がちょっとおかしい

これで、元に戻す・やり直すができるようになった。

```typescript
import {
  history,
  redo,
  redoSelection,
  undo,
  undoSelection
} from "@codemirror/next/history";
import { keymap } from "@codemirror/next/keymap";
import { baseKeymap } from "@codemirror/next/commands";
import { EditorView } from "@codemirror/next/view";
import { EditorState } from "@codemirror/next/state";

let myView = new EditorView({
  state: EditorState.create({
    doc: "hello world!",
    extensions: [
      history(),
      keymap({
        "Mod-z": undo,
        "Mod-Shift-z": redo,
        "Mod-u": view => undoSelection(view) || true,
        "Mod-Shift-u": redoSelection,
        "Ctrl-y": undefined
      }),
      keymap(baseKeymap),
    ]
  })
});

document.body.appendChild(myView.dom);
```

## 行番号を設置

✍️ 簡単（gutterのlineNumbersを追加するだけ）

行番号を設置したら見た目が変わって嬉しい。

```typescript
import {
  history,
  redo,
  redoSelection,
  undo,
  undoSelection
} from "@codemirror/next/history";
import { keymap } from "@codemirror/next/keymap";
import { baseKeymap } from "@codemirror/next/commands";
import { lineNumbers} from '@codemirror/next/gutter'
import { EditorView } from "@codemirror/next/view";
import { EditorState } from "@codemirror/next/state";

let myView = new EditorView({
  state: EditorState.create({
    doc: "hello world!",
    extensions: [
      history(),
      keymap({
        "Mod-z": undo,
        "Mod-Shift-z": redo,
        "Mod-u": view => undoSelection(view) || true,
        "Mod-Shift-u": redoSelection,
        "Ctrl-y": undefined
      }),
      keymap(baseKeymap),
      lineNumbers()
    ]
  })
});

document.body.appendChild(myView.dom);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10609/b301169a-257c-622c-00f3-0b2542cf3ea7.png)



## シンタックスハイライトを追加

✍️ jsとhtmlとcssは初めから用意されてる
✍️ typescriptを使うとモジュールを見つけやすい

シンタックスハイライトが入るとエディタ感が増して良いよね。

```typescript

import {
  history,
  redo,
  redoSelection,
  undo,
  undoSelection
} from "@codemirror/next/history";
import { html } from "@codemirror/next/lang-html";
import { defaultHighlighter } from "@codemirror/next/highlight";
import { keymap } from "@codemirror/next/keymap";
import { baseKeymap } from "@codemirror/next/commands";
import { lineNumbers } from "@codemirror/next/gutter";
import { EditorView } from "@codemirror/next/view";
import { EditorState } from "@codemirror/next/state";

let myView = new EditorView({
  state: EditorState.create({
    doc: "hello world!",
    extensions: [
      history(),
      keymap({
        "Mod-z": undo,
        "Mod-Shift-z": redo,
        "Mod-u": view => undoSelection(view) || true,
        "Mod-Shift-u": redoSelection,
        "Ctrl-y": undefined
      }),
      keymap(baseKeymap),
      lineNumbers(),
      html(),
      defaultHighlighter
    ]
  })
});

document.body.appendChild(myView.dom);
```

終わり