UFCSでも補完を効かせてDを書きたい

TL;DR

  • VSCodeD言語を書きたいときにはD Programming Language (code-d)パッケージを入れるとDCDのお力で補完が効いてうれしくなれる
  • でもUFCSには対応してないのでかなしい
  • 先人のお力を借りてDCDをいじったらUFCSで書いたときにも補完が効くようになってうれしくなった
  • 一応ソースはここに置いたが、先人曰く未完成なので使用は自己責任でお願いしたい

本編

昨日、急にD言語が書きたくなる発作に見舞われました。発作後すぐにD言語を鼻から吸引したおかげで今は容態が落ち着いています。一安心です。

まるで危ないクスリをやっているかのようですが、実際D言語は麻薬です。UFCSが気持ちよくて仕方がありません。念のために説明すると、UFCS(Uniform Function Call Syntax)というのはD言語の最高にハイになれる機能のひとつで、f(a, b, c, ...)a.f(b, c, ...)みたいに書ける糖衣構文を提供してくれるものです。例えば……

writeln(join(map!(to!string)(reverse([1, 2, 3])), "-"));  // ---> "3-2-1"

……こんなおどろおどろしいコードも……

[1, 2, 3].reverse.map!(to!string).join("-").writeln;  // ---> "3-2-1"

……こんな簡単に書けてしまいます*1 。気持ちがいい。

さて、話を本題に移しましょう。人間なら誰しもバリバリ補完が効く環境で快適コーディング生活を送りたいはずです。そこでVSCode拡張機能タブから「dlang」で検索すると、D Programming Language (code-d)というパッケージが見つかります。検索結果のうちではもっともDLされているので、多分大人気パッケージです。

marketplace.visualstudio.com

code-dはDCDというコード補完支援ツールとその他便利な諸々をまとめて、セットアップから実際に動かすところまでをお世話してくれます。 dubさえインストールされているなら、あとはcode-dをインストールするだけでOKです。

……OKです。確かにOKなのですが、実はcode-dはUFCSで書こうとすると補完が効きません。なぜならDCDは現状UFCSをサポートしていないからです。でもUFCS書きたい……すごく書きたい……あ、発作が……

ご覧の通り、ことによると発作にも繋がりかねない重大な問題です。したがってissueが立っています

github.com

こちらのissueを追っていくと、一番下にUFCSサポートを仮実装したよ~という方がいらっしゃいます。曰くまだ完成はしていないのでプルリクは見送るとのことですが、試しに彼のコードをビルドしてみると既に割としっかり動きます。というわけで最新版DCDに彼のコードを勝手にマージしたものを勝手に作りました。

github.com

使い方

上記リポジトリを適当にcloneし、v0.9.13_ufcsブランチをチェックアウトします。その後プロジェクトディレクトリのルートで

> dub build -c=server -b=release --force
> dub build -c=client -b=release --force

を実行してdcd-server.exedcd-client.exeを生成してください。 生成したexeを適当な場所に置いて、VSCodeの設定からd.dcdServerPathd.dcdClientPathにパスを設定すれば導入完了です。

こんな感じで動作します。

f:id:penpenpng:20181114210224p:plain

ただし、上記のコードを"hoge".writeln;と書こうとすると(文法上は正しいですが)補完が効かないので注意です。一度変数に入れてあげる必要があります。

ちなみに

実はVisual Dならこんな面倒なことなしに最初っからUFCSで補完が効きます。

rainers.github.io

でも何故か構成マネージャをいじれないのでunittestとかしようとするとわざわざ別窓にコンソールが必要になったり、シンタックスハイライトがしょぼかったりで、僕はVSCodeの方がいいかなと思いました。でも補完はとても強力ですし導入も楽なので、選択肢としては普通にアリだと思います。

*1:この例はちょっとやりすぎで、普通はwriteln([1,2,3].reverse.…って書くと思います。