EmacsでCloudFormationテンプレート(YAML)を編集する

2017.03.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

清水です。1年ほど前に以下のエントリでEmacsでCloudFormationテンプレート (JSON)を編集しやすくする方法をまとめてみました。

このエントリ執筆時はCloudFormationのテンプレートファイル記述方法はJSONのみでしたが、その後2016年9月のアップデートでYAML形式でもCloudFormationテンプレートファイルが記述できるようになりました。

今回はYAML形式のCloudFormationテンプレートファイル(つまりYAMLファイル)をEmacsで見やすく、編集しやすい環境を整える方法をまとめてみたいと思います。具体的にはシンタックスハイライト、リアルタイム文法チェック、そしてインデントハイライトの設定方法をまとめてみます。

emacs-yaml-007-0

emacsの環境

今回試した環境は以下になります。

編集用メジャーモード(yaml-mode)

調べてみたところ、GitHubでyaml-modeというものが公開されていました。

インストール方法としてはmake & make installする方法が記載されていましたが、GitHubから取得したコード(.elファイル)をload-pathが通っているところに配置するだけでも動作しました *1

yaml-mode.elをload-pathが通っているところに配置したら、設定のため以下を.emacsファイル *2に記載して、.yaml/.ymlファイルを開いたら自動でyaml-modeが適用するようにしておきます。

(require 'yaml-mode)
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))
(require 'yaml-mode)
(add-to-list 'auto-mode-alist '("\\.yaml\\'" . yaml-mode))

これでYAML形式のCloudFormationテンプレートファイルを開いてみます。例えばハッシュ形式のキーと値がそれぞれ色分けされ、だいぶ見やすくなりました。またインデントについても、[Tab]キーによりインデントの移動ができるようになっています。(例えばインデントスペースが2であり、4文字からインデントされている状態で[Tab]キーを押せば2文字からインデントされる状態に、もう一度[Tab]キーを押せば0文字からのインデントに移動します。もう一度[Tab]キーをを押せば4文字からのインデントに戻ります。)

emacs-yaml-002

他にもリージョンを選択してM-x comment-regionでコメント化、M-x uncomment-regionでコメントの解除が行えます。

flymake-yamlを使った文法チェック

続いて文法チェックです。Emacsではコードを書きながらリアルタイムに文法チェックをしてくれるflymakeというものがありますが、これをYAMLに対応させたflymake-yamlというものがありました。

こちらもGitHubから取得したコードをload-pathが通っているところに配置します。 あわせて、flymake-yamlではflymake-easyを必要とするので、こちらもGitHubから取得してload-pathが通っているところに配置します。

.emacsに以下を記載して、YAML形式のファイルを開いてみます。

(require 'flymake-yaml)
(add-hook 'yaml-mode-hook 'flymake-yaml-load)

例えば意図的にPropertiesの後のコロン(:)を削除してみると、以下のようにエラー箇所として強調表示して教えてくれました。

emacs-yaml-003

flycheckを使った文法チェック

先ほどのflymake-yamlのGitHubのページに興味深い一文がありました。 These days you might be better served by flycheck. https://github.com/yasuyk/flymake-yaml

リンクもあるので、こちらのflycheckもチェックしてみます。最近ではflymakeよりもこちらのflycheckの方がよく使われているそうです。

こちらもインストールしてみます。ホームページに書いてある手順にしたがって、.emacsに以下を記載してMELPA Stableリポジトリを追加します。

(require 'package)

(add-to-list 'package-archives
             '("MELPA Stable" . "https://stable.melpa.org/packages/") t)
(package-initialize)

そして、M-x package-install RET flycheckでflycheckをインストールします。

インストールできたら、以下を.emacsに記載してflycheckを有効化させます。

(add-hook 'after-init-hook #'global-flycheck-mode)

flycheckではたくさんの言語の文法チェックに対応していますが、それぞれの文法チェックを行うには各言語環境がインストールされていることが必要です。YAMLについてはjs-yamlを使うyaml-jsyamlと、Rubyの環境を使うyaml-rubyが使用できます。今回手元のMac環境にはRubyの環境がインストールされていましたので、特段設定はせずともflycheckが動作しました。

エラー箇所はこのように強調表示してくれます(こちらもPropertiesの後のコロン(:)を削除してみました)。またエラー内容についてエコーエリアに出力してくれます。

emacs-yaml-004

Highlighting indentationでインデントを見やすくする

YAMLはインデントが文法上重要な意味を持ちますので、インデントを強調表示して、階層構造を把握しながら編集できないかと思いました。イメージとしては以下のような感じです。

emacs-yaml-005

調べてみると、「Highlighting indentation for Emacs」というものがありました。

こちらもGitHubから取得したコードをload-pathが通っているところに配置します。設定ファイルに以下のように記載してyamlファイルを開き、M-x highlight-indentation-modeでインデントを強調表示することができます。またM-x highlight-indentation-current-column-modeで現在のインデントのみを強調表示することができます。両方の同時設定も可能ですね。

(require 'highlight-indentation)

YAMLでは標準的なインデントはスペース2個なので、以下のようにしてスペース2個毎に強調表示するようにすると良いでしょう。

(setq highlight-indentation-offset 2)

また個人的には使用しているテーマ(emacs-color-theme-solarized)とサンプルのカラーコードが上手くマッチしているので以下も設定しています。

(set-face-background 'highlight-indentation-face "#e3e3d3")
(set-face-background 'highlight-indentation-current-column-face "#c3b3b3")

以下のように設定すればyaml-mode使用時には自動でHighlight Indentation ModeもONになり、またスペース2個ごとにインデントの強調表示となります。(インデントについては言語によって変わるので、各モード毎に設定するのが良さそうですね。)

(add-hook 'yaml-mode-hook 'highlight-indentation-mode)
(add-hook 'yaml-mode-hook 'highlight-indentation-current-column-mode)
(add-hook 'yaml-mode-hook '(lambda() (setq highlight-indentation-offset 2)))

これらを設定したものが以下となります。インデントが強調表示され、わかりやすくなりました。

emacs-yaml-006

まとめ

ということで愛用しているEmacsでYAML形式のCloudFormationテンプレートファイルを閲覧・編集するために、シンタックスハイライト、リアルタイム文法チェック、インデントハイライトの設定を行ってみました。素の環境で編集することをやめて各設定をしたことで見やすく編集しやすい環境が整いました。引き続きYAML形式でもEmacsでバリバリCloudFormationを書いていきたいと思います。Happy Hacking with Emacs!

脚注

  1. makeすることでバイトコンパイルできるようです。
  2. 具体的には~/.emacs.d/init.elから読み込まれるファイル。環境に合わせて読み替えてください。