SDD(Sleep-Driven Development)

睡眠の重要性!!睡眠の重要性!!

MacでもRiderを使って快適にXamarinで開発しよう!!

これは

[学生さん・初心者さん大歓迎!]Xamarin Advent Calendar 2016 - Qiita

の7日目の記事です。

前日は

qiita.com

でした。
大学の講義でJavaやって2年目でServletその後Xamarinの流れとか完全に「自分かな?」と思いましたがこの話はまたいずれ。

今回はモバイルどころかIDEでほぼMac向けのお話ですがタイトルに(無理やり)Xamarinが入ったのでセーフ

祝!!Rider Public EAP Release!!

2016/11/22、RiderがPublic EAPになりました!!
長かった・・・

今回はそんなRiderの紹介です!

Riderとは

RiderはJetBrainsが絶賛開発中のクロスプラットフォームC# IDEです。詳しくは以下をお読み下さい。

Project Rider – 新しい C# IDE #jetbrainsrider | JetBrains ブログ

簡単に言うとJavaなどの開発環境でお馴染みのIntelliJ Platformで動作し、バックエンドではC#で書かれたReSharperが動作しています。

つまりは最強。

Riderの対応状況

最初にXamarinプロジェクトで使うに当たってのRiderの対応状況を見ていきたいと思います。現在のRiderの対応状況は以下のとおりです。

機能 対応状況 備考
プロジェクト読み込み UWPとかは無理(遠い未来対応するかも?)
ビルド 私はなぜかできるけどできない人もいる?
実行
デバッグ
コーディングスタイル 近いうちにきそう
XAML ハイライトが残念だけどReSharperと遜色ない補完
F# こんなに投票されてるのだから対応されないはずがない!
NuGet Xamarin Studioより高機能だけど若干怪しいところがある
ReSharperの機能
(補完やpostfixなど)
だいぶ対応したけど細かいところがまだ
IntelliJ Platformの機能
(Gitや各種プラグインなど)
普段使いには全く問題なく感じる

あくまで主観なので間違いがあったらコメントをぜひ。
コーディングスタイルは裏道がありそうですがそれは後述。

XamarinでRiderを使うにあたり、実行・デバッグはできません。なのでRider単体での開発は不可能です。
よってRiderでコーディング→Xamarin Studioでビルド・実行になります。

面倒くさいし切り替え忘れてXamarin Studioで編集してイライラする事もありますが、それでもRiderでコーディングすると圧倒的に書きやすいです。

始め方

そんな超有望なRiderをさっそくインストールしていきましょう!
インストール方法は2パターンあって www.jetbrains.com

からダウンロードしていつも通りインストールする方法とJetBrains Toolboxを使ってインストールする方法があります。Toolboxのダウンロードは以下からできます。

www.jetbrains.com

個人的には他のJetBrains製品を使っているならToolboxを利用したほうが楽だと思います。

初期設定

前回とほぼ変わりませんが初期設定について。

Riderを初めてインストールして起動するとおそらく以下の画面が表示されます。

f:id:crocus7724:20161127101303p:plain

前のバージョンから設定をインポートする?って聞かれますが初めてなのでデフォルトのままOK。
次はテーマを聞かれます。

f:id:crocus7724:20161127101441p:plain

個人的にダークテーマが好きなのでDarcula一択。
お次はエディターのカラーテーマです。左から独自、Visual Studio風(あくまで風)、IntelliJ風(というかそのまま)になります。お好きなものをどうぞ。

f:id:crocus7724:20161127104435p:plain

次にキーマップを選択できます。Visual Studio風とReSharperIntelliJ(macOS)から選択できます。

f:id:crocus7724:20161127104447p:plain

なおキーマップはあとで設定から下記も選べるようになります。

キーマップが選択し終わったらお次はDefault Pluginsです。私はいつも全部Enableのままにするのですが、もし「絶対使わねーよ!」という機能があれば無効にすれば起動が少し早くなるかも?

f:id:crocus7724:20161127104523p:plain

そして次におすすめっぽいPluginsがインストールできます。

f:id:crocus7724:20161127104513p:plain

IdeaVimは私は使ったことないのでなんとも言えません。
ReSharper UnityではデバッグまでできるっぽいのでそのXamarin版マダーと常々思っていますがくる気配はまだありません。
Heap Allocations Viewerは前にも書きましたが、あると便利だと思います。ただnewとかまで表示するのは正直邪魔なので表示・非表示の設定ができればなーと思います。
最後のPython Community Editionは・・・なんでしょう?Pythonスクリプトが書けるらしいのですが果たしてC# IDEであるRiderで使う機会あるの?

欲しいと思ったPluginをインストールしたら最後に

f:id:crocus7724:20161127104059p:plain

で初期設定は終了です。
それではStart using Riderを押しましょう!

f:id:crocus7724:20161127104217p:plain

これで今日からあなたもRiderを使い始めることができます。お疲れ様でした!!

機能

本当は機能をいろいろ紹介していきたいのですが確実に長文駄文になるので泣く泣く諦めます。。。が、せっかく調べたので2点紹介致します。

Postfix

よくコーディングをしていると途中まで式を書いて「これ変数にしたいな」とか「これをリターンしたいな」と思うことがあるのですが、そのときに役立つのが「Postfix」です。変数名やクラス名のあとで.を入力して対象の文字を入力してTabを押すか補完で出てきたものを選択すると展開します。

現在Riderで使えるPostfixは以下のとおりです。

入力 展開後 備考
Foo.var var foo = new Foo();
Foo.new new Foo()
foo.return return foo; 戻り値と型が一致してるとき
foo.yield yield return foo;
foo.throw throw foo;
Foo.typeof typeof(Foo) クラス
foo.null if(foo==null) { }
foo.notnull if(foo!=null) {}
foo.switch switch(foo) {}
foo.not !foo bool型
foo.if if(foo) {} bool型
foo.else if(!foo) {} bool型
foo.while while(foo) {} bool型
foo.lock lock(foo) {} 参照型
foo.using using(foo) {} IDispose型
task.await await task Task型
list.for for (var i = 0; i < list.Count; i++) {} コレクションや配列など
list.forr for (var i = list.Count - 1; i >= 0; i--) コレクションや配列など
list.foreach foreach (var item in list){ } コレクションや配列など
foo.parse int.Parse(foo) string型
foo.tryparse int.TryParse(foo, ) string型
foo.arg Method(foo) *
foo.cast ((object)foo) *
foo.par (foo) *
foo.prop Foo = foo; *
プロパティを生成してくれる
foo.field _foo = foo; *
フィールドを生成してくれる
foo.sel foo *
fooが選択状態になる
foo.to target = foo; *
まずToString()が出てくるのでescで消してからTab

結構あります。幾つかは私も初めて知りました。個人的にfoo.nameofがほしいのですがnameofはC#でも特別扱いっぽいので難しいのかも。

基本的に型が一致してないと補完に出てきませんが、いくつか(たとえばifとか)は補完に出てこなくてもTabを押せば展開されます。
また、*がついているやつは補完には出てきません。たまに展開に失敗するのでおそらく正式対応していないと思います。

自作Live Templates

ReSharperのLive Templateはマクロが使えてものすごく便利です。ただ、現時点では自分でLive TemplateをRiderで作成できません。(Live Templateの項目はありますが、言語にC#がなくXamarin StudioのTemplateに毛が生えた程度)

これについて先日行われた?中の人へのQ&Aにてサポートされることは確定なのですが、回答の中で

Current workaround: create a template in Visual Studio + ReSharper, save it to solution-wide .dotSettings file, and Rider will pick it up.

とあります。
なるほど、.dotSettingsファイルがあればLive Template自体は動くらしいです。
私はVisual Studioには詳しくはないのですが、とりあえずVisual Studio + ReSharperで下記のようなLive Templateを作成しました。

f:id:crocus7724:20161206021451p:plain

あとはReSharperのTemplateウィンドウにあるExportボタンをクリックするとUser.DotSettingsファイルが吐き出されます。

それをMacに持ってきたら適当なソリューションと同じ階層にUser.DotSettingsファイルを置いて{ソリューション名}.sln.DotSettingsにリネームすれば・・・

f:id:crocus7724:20161206121450g:plain

展開できました!!(若干バグってるけど)
これでBindable Propertyが爆速で書けます!

なお.DotSettingsファイルの置き場所がわからなくて右往左往してましたが、mdfindで.DotSettingsを検索したところクローン後放置して久しいXamarin.Formsリポジトリに.DotSettingsファイルがあり、それを参考にしました。ありがとうございます。

ちなみに.csprojも.slnも.storyboardも手で編集する昨今、「GUIで編集できないなら手動で編集すればいいじゃない」なノリで.DotSettingsファイルを開いてみたら

<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/@KeyIndexDefined">True</s:Boolean>
    <s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Shortcut/@EntryValue">bindable</s:String>
    <s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Description/@EntryValue">Generate Bindable Property</s:String>
    <s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Text/@EntryValue">#region $name$ Bindable Property&#xD;
&#xD;
public static readonly BindableProperty $name$Property&#xD;
            = BindableProperty.Create(nameof($name$),typeof($type$),typeof($declearType$));&#xD;
&#xD;
public $type$ $name$&#xD;
{&#xD;
    get { return (($type$)GetValue($name$Property)); }&#xD;
    set { SetValue($name$Property, value); }&#xD;
}&#xD;
&#xD;
#endregion</s:String>
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Reformat/@EntryValue">True</s:Boolean>
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/ShortenQualifiedReferences/@EntryValue">True</s:Boolean>
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Applicability/=Live/@EntryIndexedValue">True</s:Boolean>
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Scope/=C3001E7C0DA78E4487072B7E050D86C5/@KeyIndexDefined">True</s:Boolean>
    <s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Scope/=C3001E7C0DA78E4487072B7E050D86C5/Type/@EntryValue">InCSharpFile</s:String>
    <s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Scope/=C3001E7C0DA78E4487072B7E050D86C5/CustomProperties/=minimumLanguageVersion/@EntryIndexedValue">2.0</s:String>
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=type/@KeyIndexDefined">True</s:Boolean>
    <s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=type/InitialRange/@EntryValue">1</s:Int64>
    <s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=type/Order/@EntryValue">0</s:Int64>
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=name/@KeyIndexDefined">True</s:Boolean>
    <s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=name/InitialRange/@EntryValue">2</s:Int64>
    <s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=name/Order/@EntryValue">1</s:Int64>
    <s:Boolean x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=declearType/@KeyIndexDefined">True</s:Boolean>
    <s:String x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=declearType/Expression/@EntryValue">typeName()</s:String>
    <s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=declearType/InitialRange/@EntryValue">-1</s:Int64>
    <s:Int64 x:Key="/Default/PatternsAndTemplates/LiveTemplates/Template/=02646611FBC11F46BCFB19BD6AE7495C/Field/=declearType/Order/@EntryValue">2</s:Int64></wpf:ResourceDictionary>

諦めました。

また、この.DotSettingsファイルはコーディング規則的なのを決められるみたいですが、こちらで簡単にやってみたところ変更できませんでした。ただ、私自身.DotSettingsを理解してないのでもうちょっと調べてみます。

→Xamarin.Formsリポジトリから.DotSettingsファイルをパクってきたところ、private修飾子をつけたら「いらねえよ」と言われるようになりましたなんでや!

f:id:crocus7724:20161206131042p:plain

Xamarin.Formsで開発するときは本家に合わせる意味でXamarin.Forms.sln.DotSettingsファイルをコピペしてもいいのではないでしょうか?

なお、Riderのyoutrackによると、RiderでのCodeStyle作成 のプロトタイプは既にできていて、次のEAPで利用できるようになるらしいです。(Live Templateは?)

次のEAPが待ち遠しいですね。

終わりに

以上、Riderの紹介でした。現在RiderはPublic EAPであり、正式リリースはまだまだ先です(2017年第2四半期になるらしい?)。また細かなところでバグいですが、現時点でもReSharperの恩恵を多大に受けることができます。ぜひ使ってみて下さい!!

なお学生の皆さんは今回出てきたReSharperIntelliJなどのJetBrains製品が在学期間中ずっと無料で使えます!
詳細は以下

www.jetbrains.com

人気の言語は一通り網羅しているので大学の講義などでプログラミングをやるときに使ってみてはいかがでしょうか?

明日の担当はmmmmmiya - Qiitaさんです。よろしくお願いします(((o(゚▽゚)o)))♡