0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

CodeMirrorでオリジナルのエディタを作る

はじめに

福島高専アドベンドカレンダー11日目に飛び込みました@cyanです!
初めてのアドベントカレンダーの参加ですが、私自身、技術的に詳しく書けることは無いので以前利用したライブラリについて紹介したいと思います。

目標

CodeMirror というライブラリを使って、オリジナルのエディタを作っていきます。
エディタなんて「VSCodeで十分!」と思いませんか?
その通りで、さすがに強力な補完機能やアドオンを持っているVSCodeやAtomのようなものは作れないです :sweat:
なので、今回は表示用のコードビューアとして作っていきます。

↓こんな感じです↓
image.png

しかし、CodeMirrorはかなりのカスタマイズ性があり、やろうと思えばかなり本格的なエディタを作ることも可能です!

実際、

などでも使われています。

開発環境

  • ブラウザ(なんでも)
  • HTML , JavaScript

1. 前準備

CodeMirrorのライブラリをダウンロード

↓こちらからzipファイルをダウンロードし、解凍してください。
https://codemirror.net/codemirror.zip

今回は単純化のためzipファイルをダウンロードしますが、npmでもパッケージをインストールできます。

npm install codemirror

プロジェクト構成

  • 適当なプロジェクトフォルダを作成
  • index.htmlファイルを作成
  • 先ほどダウンロードしたCodeMirrorのライブラリから lib フォルダをプロジェクトフォルダにコピペ

↓こんな感じ↓
image.png

2. エディタを表示

それでは開発に入っていきましょう!
CodeMirrorはブラウザ上で動きます。なので基本はJavaScriptで処理を書いていきます。
まずは、index.html を以下のようにしましょう。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="lib/codemirror.css">
  <script src="lib/codemirror.js"></script>
</head>
<body>
  <script>
    var editor = CodeMirror(document.body, {
      value: 'console.log("Hello World")\n',
      lineNumbers: true,
    });
  </script>
</body>
</html>

では、 index.html をブラウザで開いてください。

どうでしょうか?
行番号が入ったエディタが表示されたら成功です!
image.png

説明

先に進む前に、先ほどのコードの説明を軽くします。

ライブラリのインポート

以下のコードで、最初にlib フォルダにあるCodeMirrorのファイルを指定します。

<link rel="stylesheet" href="lib/codemirror.css">
<script src="lib/codemirror.js"></script>

エディターの作成

スクリプトタグでエディタを作成します。 CodeMirror.fromTextArea メソッドの第一引数にエディターにさせるDOM(今回はbody)を指定し、第二引数に設定項目を記述します。

var editor = CodeMirror(document.body, {
  value: "console.log\n",
  lineNumbers: true,
});

今回の設定は lineNumbers で行番号の表示、valueでエディターの初期値を指定しています。

3. 装飾

エディタを表示させることはできましたが、このままじゃ味気ない感じになってしまうのでテーマを適用させていきたいと思います。

テーマファイルの取得

1からテーマを作成することも可能ですが、今回はすでに用意されているテーマを利用します。
CodeMirrorの解凍フォルダのthemeフォルダに各テーマのcssファイルがあると思います。
image.png

この中からお好きなテーマをプロジェクトフォルダのthemeフォルダに入れましょう。
説明ではmonokai.cssを入れます。
image.png

CodeMirrorの設定

では、エディタにテーマを適応させていきます。

先ほど入れたテーマファイルをインポートします。

<link rel="stylesheet" href="theme/monokai.css">

CodeMirrorの設定項目に theme を追加します。値は追加したテーマの名前です。

var editor = CodeMirror(document.body, {
  value: 'console.log("Hello World")\n',
  lineNumbers: true,
  theme: 'monokai'  // <- テーマの名前
});

全体コード

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="lib/codemirror.css">
  <link rel="stylesheet" href="theme/monokai.css">  <!-- ADD -->
  <script src="lib/codemirror.js"></script>
</head>
<body>
  <script>
    var editor = CodeMirror(document.body, {
      value: 'console.log("Hello World")\n',
      lineNumbers: true,
      theme: 'monokai'  // ADD
    });
  </script>
</body>
</html>

プレビュー

どうでしょうか?指定したテーマ色にエディタが変化したと思います。
image.png

4. 言語対応

エディタの装飾はできましたが文字がまだ単色の状態です。これを解決するには、設定でどの言語仕様で装飾するかを指定する必要があります。
今回はエディタを javascript の仕様にします。

設定ファイルの取得

CodeMirrorの解凍フォルダのmodeフォルダに各言語ごとの設定ファイルがあります。ここから自分が使いたい言語を持っていきます。
image.png

今回はjavascriptの記述にするため、 javascriptフォルダを取得します。プロジェクトフォルダのmodeフォルダに持ってきます。
image.png

持ってきたフォルダの中身にはいくつかファイルが入ってますが使うのは 言語名.js というファイルです。
今回の場合だと、 javascript.js ですね。
image.png

CodeMirrorの設定

テーマを適用した時と同じように設定していきます。
まず、先ほど持ってきた設定ファイルをインポートしましょう。

<script src="mode/javascript/javascript.js"></script>

CodeMirrorの設定項目に mode を追加します。値には言語名を入れます。

var editor = CodeMirror(document.body, {
  value: 'console.log("Hello World")\n',
  lineNumbers: true,
  theme: 'monokai',
  mode: 'javascript'  // 言語名
});

全体コード

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="lib/codemirror.css">
  <link rel="stylesheet" href="theme/monokai.css">
  <script src="lib/codemirror.js"></script>
  <script src="mode/javascript/javascript.js"></script>  <!-- ADD -->
</head>
<body>
  <script>
    var editor = CodeMirror(document.body, {
      value: 'console.log("Hello World")\n',
      lineNumbers: true,
      theme: 'monokai',
      mode: 'javascript'  // ADD
    });
  </script>
</body>
</html>

プレビュー

かなりエディタっぽくなってきたのではないでしょうか?
言語仕様に沿って、単語ごとに装飾が入ると思います。

自分でコードを記述して試してみてください!
image.png

テーマをカスタマイズ

では最後にテーマを自分好みにカスタマイズしてみましょう!
テーマはCSSで定義されており、各単語の色や背景を自由に変えることができます。

テーマ作成

今回は文字列の色を変えていきます。
新しくindex.cssというファイルをプロジェクトフォルダに作成し、以下のコードを入れてください。

index.css
.cm-s-custom span.cm-string {
  color: #489748;
}

細かい説明が省きますが、CSSのクラス名は .cm-s-{テーマ名} と定義する必要があり、セレクタでどの要素を対象にするかを決めます。上記のコードは span.cm-string で文字列("")の色を変えています。

テーマの適用

それでは、自分で作成したテーマを適応させていきます。index.html の head タグに新しく index.css を追加しましょう。

<link rel="stylesheet" href="index.css">

あとは CodeMirror に適応させます。 theme 属性に追加したいテーマ名を記述します。
テーマ名はindex.cssで記述した custom ですね。

var editor = CodeMirror(document.body, {
  value: 'console.log("Hello World")\n',
  lineNumbers: true,
  theme: 'monokai custom',
  mode: 'javascript'
});

全体コード

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="lib/codemirror.css">
  <link rel="stylesheet" href="theme/monokai.css">
  <link rel="stylesheet" href="index.css">
  <script src="lib/codemirror.js"></script>
  <script src="mode/javascript/javascript.js"></script>
</head>
<body>
  <script>
    var editor = CodeMirror(document.body, {
      value: 'console.log("Hello World")\n',
      lineNumbers: true,
      theme: 'monokai custom',
      mode: 'javascript'
    });
  </script>
</body>
</html>

プレビュー

文字列の色が変われば成功です。
image.png

カスタマイズは他にもできることがたくさんあるので是非試して欲しいです!
(GIF画像を入れることだってできます)
ezgif-5-7400f3b7869f.gif

最後に

CodeMirrorを使えば、少し知識でかなり良いエディタが作れるのではないかと思います。
自分のサイトなどでコードを見せたいときに利用してみてはいかがでしょうか?

宣伝

CodeMirrorを使ってWebアプリを作ってみたので良かったら使ってみてください。
画面共有時やプレゼン中にコードを他人に見せるときに、簡単に説明したい部分を強調できるツールです。
完成度はかなり低いので「こんな機能があったらな〜」という意見があれば是非お願いします!

↓こちらから↓

Github

今回使ったコード
https://github.com/cyan-0fbcf9/codemirror-sample

参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?