• 作成:

WebStorm(IntelliJ IDEA)に負けないEmacsのweb開発環境

最近はElectronとReactでアプリを書いています.

web開発ならWebStormという風潮があるのでIntelliJ IDEAを使ってみたのですが3日でEmacsに戻ってきました.

周りはみんなIntelliJを使っていて. CTOの方針でVim, Emacs, Atom, VSCodeなどのテキストエディタを初心者に使わせるのはNGで. IDEを使わせるということになっているので. 少し肩身が狭いですが私はEmacsを使い続けています.

というわけで現代的(2018年)なEmacsでのweb開発環境とかについて軽くメモします. このメモは後々の私のためになります. 設定を整理したり, 後でどうしてこういう設定したのか見返せるので.

なお私のEmacsの設定ファイルは全て以下のリポジトリにアップロードされています.

ncaq/.emacs.d: Emacsの設定ディレクトリ

editorconfig

これを使えばIntelliJ派の人たちともコーディング設定を共有できます. 共存可. 設定不要.

nodejs-repl

NodeのREPLも手に馴染んだキーバインディングで使いたいですよね. これを使えばNodeのREPLがEmacsで動きます. ちょっと動作が怪しいのはご愛嬌.

web-mode

web-mode.el - html template editing for emacs

数多のweb言語に対応している変態メジャーモード.

JSXを書くにあたってjs2-modeやrjsx-modeなども試しましたがweb-modeが一番良いという結論に至りました.

私も簡単な高速化パッチをpull requestしたりしました.

下のように設定すると良いと思います.

(custom-set-variables
 '(web-mode-enable-auto-quoting nil)
 '(web-mode-enable-current-column-highlight t)
 '(web-mode-enable-current-element-highlight t)
 '(web-mode-markup-indent-offset 2)
 )

(put 'web-mode-markup-indent-offset 'safe-local-variable 'integerp)

(add-to-list 'auto-mode-alist '("\\.[agj]sp\\'"  . web-mode))
(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'"  . web-mode))
(add-to-list 'auto-mode-alist '("\\.djhtml\\'"   . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb\\'"      . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'"    . web-mode))
(add-to-list 'auto-mode-alist '("\\.js\\'"       . web-mode))
(add-to-list 'auto-mode-alist '("\\.jsx\\'"      . web-mode))
(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.php\\'"      . web-mode))
(add-to-list 'auto-mode-alist '("\\.phtml\\'"    . web-mode))
(add-to-list 'auto-mode-alist '("\\.tpl\\'"      . web-mode))
(add-to-list 'auto-mode-alist '("\\.tsx\\'"      . web-mode))

(with-eval-after-load 'web-mode (sp-local-pair '(web-mode) "<" ">" :actions :rem))

JSXを編集してる時はクオート自動入力は切ったほうが良いです. 属性設定する時にキレることになります. '(web-mode-enable-auto-quoting nil)がそれです.

flycheck

普通にESLintに対応しているのでyarn global add eslint-cliでもしてパスを通しておけばリアルタイムでエラーチェックが可能です.

web-modeと連携してHTMLとJavaScriptとJSXに対応可です.

prettier-js

コードフォーマッターがprettier/prettier: Prettier is an opinionated code formatter.というコマンドラインツールに独立して使える良い時代になりました.

モードを有効にしておけば保存時に自動フォーマットがかかります. IntelliJのデフォルトはコミット時にフォーマットなのでこちらの方が楽.

web-modeとflycheckとprettier-jsを協調させる

以下のコードでweb-modeの開いたファイルに対応した機能を有効にします.

(flycheck-add-mode 'html-tidy 'web-mode)
(flycheck-add-mode 'javascript-eslint 'web-mode)

(add-hook
 'web-mode-hook
 '(lambda ()
    (cond
     ((string= web-mode-content-type "html")
      (when (executable-find "tidy") (flycheck-select-checker 'html-tidy)))
     ((or (string= web-mode-content-type "javascript") (string= web-mode-content-type "jsx"))
      (when (executable-find "eslint") (flycheck-select-checker 'javascript-eslint))
      (prettier-js-mode)))))

IntelliJのEmacsに対するメリット

オムニ補完が強い

Emacsではauto-completeを使っているのですがスマート補完とか全く設定してないのでオムニ補完はゼロです. 設定しなくてもメソッド補完などが強いのは良いですね.

GitのdiffがGUI上で見やすい

コミット時のGitのdiffがGUIで見やすく表示されるのは良いです. 横に並ぶとわかりやすいし挟まった場所もわかりやすい.

あまり設定をしなくて良い

一々設定しなくても現代的な設定がされているのは大きなメリットです.

ただ私はキーボードの設定をたくさんする必要がありましたが…

IntelliJのEmacsに対するデメリット

非オムニ補完が弱い

私はEmacsのauto-completeに

(setq-default ac-sources '(ac-source-filename
                           ac-source-words-in-all-buffer
                           ))

と書いています. このac-source-words-in-all-bufferは全てのバッファから適当に単語を取ってくるものです.

auto-completeはEmacsの全てのバッファで使えるのでgitのcommit書く時でも使えて嬉しい.

フリーズすると復旧できない

IntelliJは機能がたくさんあるせいか手元のEmacsと比べてよくフリーズするのですが, Emacsの場合フリーズしてもC-gを押し続ければ戻れるのに対してIntelliJは復旧する手段がありません. kill -9するしか無いです.

UIがキーボードで操作できない

EmacsはCUIで動くだけあって殆どの操作がキーボードのみで可能です. マウスを使わざるを得ないのはお絵描きモードみたいなお遊びのみです.

IntelliJも一応キーボードで操作できますが十字キーを使うことを強要されます. キーバインディングしてホームポジションで移動したい. しかしUI部分は変更できないようですね.

Magitの方が操作が速い

IntelliJはVCSの操作が一々かったるいです.

MagitならM-g s S y c cでコミット画面に入れるのにIntelliJでは作業を何度もマウスクリックを要求されます.

settings-repositoryが動かない

複数のデバイスで設定を同期するsettings-repository機能がバグってるのか環境が悪いのか全く動きませんでした.

変換欄が別のウィンドウに表示される

デュアルディスプレイを使っているのですが上のディスプレイに表示しても下のディスプレイに変換欄が出てくるため日本語入力体験が最悪.

プラグインを書きにくい

JavaよりEmacs Lispの方が私に合う. しかしKotlinでも書けるようなのでそれは痛み分けかも…