ScalaプログラミングはなんといってもEmacs+Ensimeですね!
先週サブノート目的でMacBook Air 11inchを入手したのですが、Emacs+Ensimeで満ち足りてしまって、まだEclipseは入れていない状況です。
Emacsのどこがよいかというと、まずテキストエディタとしての基本機能、シェルモードやディレクトリモードといったシェル機能が充実している点が挙げられますが、なんといってもelispで比較的簡単にカスタマイズができるのがよいですね。
カッコの捌き方
Scalaプログラミングをする時の生産性に影響があるのが「{」「}」の捌き方です。たとえば:
- abc {
といれると、自動的に括弧を開いてくれてカーソルを所定の位置に持って行ってくれると便利です。
- abc {
- ←カーソル
- }
もちろん、これぐらいの自動化はどのエディタにもついていると思いますが、問題なのは「abc { }」と打った時に自動的・強制的に上の形になってしまうと、逆に「abc { x => x + 1 }」と書きたかった時に手戻りが発生してしまいます。
このような問題があるため、キーの入力で自動的に上記のような整形をする機能(Emacsのscala-modeではscala-mode-feature-electric)は案外使いづらく、ボクもたいてい切ってしまいます。
- abc {
- ←カーソル
- }
にしたい時と
- abc { x => x + 1 }
にしたい時のどちらにも対応できる入力方法が欲しいところです。
カスタマイズ
この問題に対処するために、以下のelispの関数を作ってみました。
- (defun my-scala-newline(arg)
- (interactive "p")
- (cond ((scala-in-multi-line-comment-p)
- (scala-newline))
- ((char-equal ?\} (following-char))
- (let (killed)
- (newline-and-indent)
- (newline-and-indent)
- (forward-char)
- (setq killed (not (my-end-of-line-p)))
- (if killed (kill-line))
- (previous-line)
- (indent-for-tab-command)
- (if killed (yank))))
- (t
- (newline-and-indent))))
.emacsまたはinit.elへの設定は以下になります。
- (require 'scala-mode-feature-electric)
- (setq scala-mode-feature:electric-expand-delimiters-list '(?\{))
- (add-hook 'scala-mode-hook
- (function (lambda ()
- (scala-mode-feature-electric-mode)
- (define-key scala-mode-map "\r" 'my-scala-newline)
まずscala-mode-feature:electric-expand-delimiters-listで「{」のみを有効にするように設定しています。こうすることによって:
- abc {
と打つと自動的に以下のようになります。
- abc { }←カーソル
ここからの動きがポイントですが、先程のmy-scala-newline関数がReturnに設定されていると、この場所でReturnを押すことで、以下の形に整形されカーソルも所定の位置に移動します。
- abc {
- ←カーソル
- }
カーソルの位置が他の場所の場合、通常の改行キーの動作をするので、不必要な整形が行われません。「abc { x => x + 1 }」と書きたい時はそのまま入力をしていけばよいわけですね。
括弧を追加する場合の捌き方
my-scala-newline関数は、よく出てくるコーディングパターンをサポートするためにもう一工夫しています。
以下のように一行に書いていた文を:
- abc xyz
括弧を入れて複数行に分割したい時がよくあります。
- abc {
- xyz
- }
まず、最初の状態で「abc 」の場所で「{」を打つと以下のようになります。カーソルは「}」の上になります。
- abc { }xyz
ここでReturnを押下すると、「}」の後ろのxyzが自動的に括弧内に移動し、カーソルも所定の位置に移動します。
- abc {
- xyz←カーソル
- }
簡単なカスタマイズですが、なかなか効果抜群です。
0 件のコメント:
コメントを投稿