[{"data":1,"prerenderedAt":334},["ShallowReactive",2],{"$fapXyY8XDq49k1hYCkif_2Ck3RvuuCWRqy7NfY3086Vw":3,"$fQpQTTQCD8rm1hGqFF8Kjw91eXGaugJ9kpBc7NgAndDw":91,"$fh_UbLxx2KWQQxMUSHEqfVo5z6MUe-Nb3I-RtaAiT56I":221},{"entry":4,"before":55},{"metadata":5,"sys":8,"fields":29},{"tags":6,"concepts":7},[],[],{"space":9,"id":14,"type":15,"createdAt":16,"updatedAt":17,"environment":18,"publishedVersion":22,"revision":23,"contentType":24,"locale":28},{"sys":10},{"type":11,"linkType":12,"id":13},"Link","Space","jmfsolylwbqz","43SeLsLF422R4RGvtCH2y6","Entry","2026-06-28T13:08:24.808Z","2026-06-28T14:24:46.134Z",{"sys":19},{"id":20,"type":11,"linkType":21},"master","Environment",51,3,{"sys":25},{"type":11,"linkType":26,"id":27},"ContentType","blogPost","ja-JP",{"title":30,"slug":31,"category":32,"body":51,"description":52,"legacy":53,"enableAd":54,"enableCommentField":54},"Dart/Flutterの非同期の仕組みについて思うところをつらつらと","flutter-async-architecture",{"metadata":33,"sys":36,"fields":48},{"tags":34,"concepts":35},[],[],{"space":37,"id":39,"type":15,"createdAt":40,"updatedAt":41,"environment":42,"publishedVersion":44,"revision":23,"contentType":45,"locale":28},{"sys":38},{"type":11,"linkType":12,"id":13},"4QnljevVGe4bI4JNVdk2Zc","2021-05-02T15:11:20.089Z","2021-11-16T05:32:02.763Z",{"sys":43},{"id":20,"type":11,"linkType":21},17,{"sys":46},{"type":11,"linkType":26,"id":47},"category",{"name":49,"slug":50},"どうでもいいこと","others","Flutterって、フレームワーク自体の設計にけっこう粗が目立つ。\n\nDartのlintルールに「[discarded_futures](https://dart.dev/tools/linter-rules/discarded_futures)」「[unawaited_futures](https://dart.dev/tools/linter-rules/unawaited_futures)」というものがある。これらは元々、Futureをawaitしなかったことによる意図しないバグを防ぐ目的のルールで、意図的に捨てていることを`unawaited`関数でラップして明示するか、大人しくawaitするかのどちらかに強制できる。\n\nしかし、Flutter側の設計に目を向けると、大半のユースケースでFutureが捨てられることを想定した関数、つまり少数のユースケースのためにFutureを戻り値に設定している関数が大量に存在する。そのため、このルールに従おうと思うと、画面遷移のための大量の関数呼び出しをunawaitedでラップする必要がある。バグを防ぐためのlintが、大量のコードノイズを発生させるという状態である。2025年頃に「[@awaitNotRequired](https://api.flutter.dev/flutter/meta/awaitNotRequired-constant.html)」アノテーションがmetaパッケージに追加され、これがついている関数はFutureを捨てても怒られなくなった。現在のFlutterプロジェクトでは、急ピッチで`Navigator.push`などの関数にこのアノテーションを付ける作業が行われているが、苦肉の策感は否めない。\n\n私が思うに、それぞれのユースケースで関数を分けるべきだったと思う。例えば、voidを返す`Navigator.push`、Futureを返す`Navigator.pushReturning`というように。そうすれば、静的解析に余計な負荷をかけずに済むし、awaitすべき関数とそうでない関数を簡単に区別できる。\n\nただこれは大規模API変更になるので、今更受け入れられるかは微妙なところ。シグネチャーも二重で定義が必要になり、ボイラープレートが増える。今までの慣習や記事が古くなる。結構影響はデカい。探してもメソッド分割に関する議論は全く見当たらなかったが、Issueを出すかはかなり悩むところ。すでに追加**されてしまった**@awaitNotRequiredとの兼ね合いも（分割の方針を取るとこのアノテーションの存在意義が行方不明に）。\n\nということを、私のプロジェクトにこの2つのlintルールを追加してみて思ったところ。lintの方向性は正しいのにその周辺がクソなので、このプロジェクトでは結局元に戻そうと思う。","",false,true,{"metadata":56,"sys":59,"fields":70},{"tags":57,"concepts":58},[],[],{"space":60,"id":62,"type":15,"createdAt":63,"updatedAt":64,"environment":65,"publishedVersion":67,"revision":23,"contentType":68,"locale":28},{"sys":61},{"type":11,"linkType":12,"id":13},"73BxP4cAKyGEaY0iSdAFJB","2026-06-05T01:09:11.677Z","2026-06-28T09:09:33.244Z",{"sys":66},{"id":20,"type":11,"linkType":21},19,{"sys":69},{"type":11,"linkType":26,"id":27},{"title":71,"slug":72,"category":73,"body":90,"description":52,"legacy":53,"enableAd":54,"enableCommentField":54},"IntelliJ IDEAをJujutsuのコンフリクト解決ツールとしてちゃんと使えるようにするプラグインを作ったよ","idea-mergex-plugin",{"metadata":74,"sys":77,"fields":87},{"tags":75,"concepts":76},[],[],{"space":78,"id":80,"type":15,"createdAt":81,"updatedAt":81,"environment":82,"publishedVersion":23,"revision":84,"contentType":85,"locale":28},{"sys":79},{"type":11,"linkType":12,"id":13},"5MKCmbhhcqboMXodYszCG6","2021-11-16T05:31:22.875Z",{"sys":83},{"id":20,"type":11,"linkType":21},1,{"sys":86},{"type":11,"linkType":26,"id":47},{"name":88,"slug":89},"役立ち情報","useful","本記事は以下の続編です。\n\n[Jujutsuのマージコンフリクト解決ツールとして IntelliJ IDEA を使用する方法（macOS）\n](/category/useful/jujutsu-merge-idea)\n\n上の記事で紹介した方法で、JujutsuのマージツールとしてIDEAを使用することができるようになりました。しかし、UIのボタンでマージ後のファイルが保存できない場合があったり、余計な警告ダイアログが出てきたりと、割と致命的な問題（端的に言えばバグ）が多いです。それらをなんとか解決しようとClaudeさんと話していたところ、**「プラグインで解決できるのでは・・・？」** と思い至り、Claude Codeを駆使して作ってみました。\n\n## IDE（2026.1.2現在）側の問題点\n\nまずは問題を整理します。\n\n- マージダイアログを開くたびに、プロジェクト外ファイル編集の確認ダイアログが表示される\n  ![Non-Project Files Protection dialog](https://static.zenn.studio/user-upload/c8768b8ffea6-20260529.png)\n  ↑これ\n- 書き込み処理のスレッドの関係で、例外が発生する\n    - どうやら、最近プラットフォーム側のスレッディングの方法が変更されたらしく、古い方法で処理を行うと例外が発生する場合があるようです。\n- `--wait`を位置引数と誤認識する\n    - プロセス終了まで待機させるために、Toolboxが生成するスクリプトに渡す`--wait`オプションは、macOSでは`open`コマンドに渡されます。しかし、そのスクリプトはそのオプションも含めてIDE側に伝搬しているようで、`merge`サブコマンドはそれをファイルパスと誤認識します。そのため、直接openコマンドを使用した場合には発生しません。\n\n## 作成したプラグイン\n\nというわけで、作って公開しました。\n\nhttps://plugins.jetbrains.com/plugin/32006-merge-cli-fixer\n\nこちらをインストールすると、`idea mergex`というサブコマンドが追加されます。Jujutsuでは`~/.config/jj/config.toml`に以下のように設定することで、マージツールとして機能します。\n\n```toml\n[ui]\nmerge-editor = \"idea\"\n\n[merge-tools.idea]\nprogram = \"idea\"\nmerge-args = [\"mergex\", \"--wait\", \"$left\", \"$right\", \"$base\", \"$output\"]\n```\n\nToolbox側の設定で、スクリプトの生成がONになっていることを確認してください。\n\nこの状態で、`jj resolve`を実行すると・・・\n\n![マージダイアログが表示されている](https://static.zenn.studio/user-upload/146e4c47bcdd-20260530.png)\n\nマージダイアログが表示されました🎉 解決してApplyすると・・・\n\n![ターミナルでコンフリクトが解決できた表示がある](https://static.zenn.studio/user-upload/10f3e320dd4c-20260530.png)\n\n正しく解決できたことが分かります。",{"sys":92,"total":94,"skip":95,"limit":96,"items":97,"includes":195},{"type":93},"Array",106,0,5,[98,113,132,157,176],{"fields":99,"sys":112},{"title":71,"slug":72,"category":100},{"metadata":101,"sys":104,"fields":111},{"tags":102,"concepts":103},[],[],{"space":105,"id":80,"type":15,"createdAt":81,"updatedAt":81,"environment":107,"publishedVersion":23,"revision":84,"contentType":109,"locale":28},{"sys":106},{"type":11,"linkType":12,"id":13},{"sys":108},{"id":20,"type":11,"linkType":21},{"sys":110},{"type":11,"linkType":26,"id":47},{"name":88,"slug":89},{"createdAt":63,"id":62,"type":15},{"fields":114,"sys":129},{"title":115,"slug":116,"category":117},"Jujutsuのマージコンフリクト解決ツールとして IntelliJ IDEA を使用する方法（macOS）","jujutsu-merge-idea",{"metadata":118,"sys":121,"fields":128},{"tags":119,"concepts":120},[],[],{"space":122,"id":80,"type":15,"createdAt":81,"updatedAt":81,"environment":124,"publishedVersion":23,"revision":84,"contentType":126,"locale":28},{"sys":123},{"type":11,"linkType":12,"id":13},{"sys":125},{"id":20,"type":11,"linkType":21},{"sys":127},{"type":11,"linkType":26,"id":47},{"name":88,"slug":89},{"createdAt":130,"id":131,"type":15},"2026-05-17T15:49:45.333Z","jBqOc4f2Q8xuAReMTNli2",{"fields":133,"sys":154},{"title":134,"slug":135,"category":136},"【Submon】最小iOSバージョンをiOS 16へ引き上げます","submon-min-ios-16",{"metadata":137,"sys":140,"fields":151},{"tags":138,"concepts":139},[],[],{"space":141,"id":143,"type":15,"createdAt":144,"updatedAt":145,"environment":146,"publishedVersion":96,"revision":148,"contentType":149,"locale":28},{"sys":142},{"type":11,"linkType":12,"id":13},"1AZ6Df2460uf9EaWHYRZi2","2022-04-25T12:44:16.773Z","2022-04-28T14:13:15.068Z",{"sys":147},{"id":20,"type":11,"linkType":21},2,{"sys":150},{"type":11,"linkType":26,"id":47},{"name":152,"slug":153},"Submonのお知らせ","submon-info",{"createdAt":155,"id":156,"type":15},"2026-05-06T04:47:12.868Z","44OAk3fEMxgnCY5QzxPiDr",{"fields":158,"sys":173},{"title":159,"slug":160,"category":161},"DartのSwitch式/文、when句、パターンマッチング周りのチートシート","dart-pattern-matching",{"metadata":162,"sys":165,"fields":172},{"tags":163,"concepts":164},[],[],{"space":166,"id":80,"type":15,"createdAt":81,"updatedAt":81,"environment":168,"publishedVersion":23,"revision":84,"contentType":170,"locale":28},{"sys":167},{"type":11,"linkType":12,"id":13},{"sys":169},{"id":20,"type":11,"linkType":21},{"sys":171},{"type":11,"linkType":26,"id":47},{"name":88,"slug":89},{"createdAt":174,"id":175,"type":15},"2026-01-15T15:27:29.616Z","5rj9AuEsebufNWtBTlTu6F",{"fields":177,"sys":192},{"title":178,"slug":179,"category":180},"【Dart/Flutter】とてもいい感じに末尾カンマを強制できるLintプラグインを作ったよ","better-require-trailing-commas",{"metadata":181,"sys":184,"fields":191},{"tags":182,"concepts":183},[],[],{"space":185,"id":80,"type":15,"createdAt":81,"updatedAt":81,"environment":187,"publishedVersion":23,"revision":84,"contentType":189,"locale":28},{"sys":186},{"type":11,"linkType":12,"id":13},{"sys":188},{"id":20,"type":11,"linkType":21},{"sys":190},{"type":11,"linkType":26,"id":47},{"name":88,"slug":89},{"createdAt":193,"id":194,"type":15},"2026-01-15T15:06:58.744Z","7DWX6Gej091IAM1nvGIaiw",{"Entry":196},[197,209],{"metadata":198,"sys":201,"fields":208},{"tags":199,"concepts":200},[],[],{"space":202,"id":143,"type":15,"createdAt":144,"updatedAt":145,"environment":204,"publishedVersion":96,"revision":148,"contentType":206,"locale":28},{"sys":203},{"type":11,"linkType":12,"id":13},{"sys":205},{"id":20,"type":11,"linkType":21},{"sys":207},{"type":11,"linkType":26,"id":47},{"name":152,"slug":153},{"metadata":210,"sys":213,"fields":220},{"tags":211,"concepts":212},[],[],{"space":214,"id":80,"type":15,"createdAt":81,"updatedAt":81,"environment":216,"publishedVersion":23,"revision":84,"contentType":218,"locale":28},{"sys":215},{"type":11,"linkType":12,"id":13},{"sys":217},{"id":20,"type":11,"linkType":21},{"sys":219},{"type":11,"linkType":26,"id":47},{"name":88,"slug":89},{"sys":222,"total":223,"skip":95,"limit":96,"items":224,"includes":320},{"type":93},13,[225,244,263,282,301],{"fields":226,"sys":241},{"title":227,"slug":228,"category":229},"【学マス】空と約束千奈の立ち回り（NIAマスター）メモ（随時更新）","tiny-brave-china-nia-master",{"metadata":230,"sys":233,"fields":240},{"tags":231,"concepts":232},[],[],{"space":234,"id":39,"type":15,"createdAt":40,"updatedAt":41,"environment":236,"publishedVersion":44,"revision":23,"contentType":238,"locale":28},{"sys":235},{"type":11,"linkType":12,"id":13},{"sys":237},{"id":20,"type":11,"linkType":21},{"sys":239},{"type":11,"linkType":26,"id":47},{"name":49,"slug":50},{"createdAt":242,"id":243,"type":15},"2025-11-29T12:56:25.421Z","2dGV5IqxRrE9or4veLCUa5",{"fields":245,"sys":260},{"title":246,"slug":247,"category":248},"【原神】旅の写真に閃きを・緑葉編で撮影した画像を載せる","genshin-inspiration",{"metadata":249,"sys":252,"fields":259},{"tags":250,"concepts":251},[],[],{"space":253,"id":39,"type":15,"createdAt":40,"updatedAt":41,"environment":255,"publishedVersion":44,"revision":23,"contentType":257,"locale":28},{"sys":254},{"type":11,"linkType":12,"id":13},{"sys":256},{"id":20,"type":11,"linkType":21},{"sys":258},{"type":11,"linkType":26,"id":47},{"name":49,"slug":50},{"createdAt":261,"id":262,"type":15},"2022-11-26T11:18:30.639Z","1mRoLW3GRyk6NIHGxTe8ZT",{"fields":264,"sys":279},{"title":265,"slug":266,"category":267},"【プログラミング言語】バラッッッッバラ。","diffffers",{"metadata":268,"sys":271,"fields":278},{"tags":269,"concepts":270},[],[],{"space":272,"id":39,"type":15,"createdAt":40,"updatedAt":41,"environment":274,"publishedVersion":44,"revision":23,"contentType":276,"locale":28},{"sys":273},{"type":11,"linkType":12,"id":13},{"sys":275},{"id":20,"type":11,"linkType":21},{"sys":277},{"type":11,"linkType":26,"id":47},{"name":49,"slug":50},{"createdAt":280,"id":281,"type":15},"2022-04-19T02:35:07.017Z","4GafLIYYZ4oVuMBu07blJN",{"fields":283,"sys":298},{"title":284,"slug":285,"category":286},"【原神】八重神子の仕様変更問題のすべて。実は今に始まったことではない！？","yaemiko-spec-change",{"metadata":287,"sys":290,"fields":297},{"tags":288,"concepts":289},[],[],{"space":291,"id":39,"type":15,"createdAt":40,"updatedAt":41,"environment":293,"publishedVersion":44,"revision":23,"contentType":295,"locale":28},{"sys":292},{"type":11,"linkType":12,"id":13},{"sys":294},{"id":20,"type":11,"linkType":21},{"sys":296},{"type":11,"linkType":26,"id":47},{"name":49,"slug":50},{"createdAt":299,"id":300,"type":15},"2022-04-03T11:07:21.604Z","7vJIJKGFRyJt1TuEOA4x4A",{"fields":302,"sys":317},{"title":303,"slug":304,"category":305},"Mac と Windows、どっちがどう良いの？バイアス抜きで解説。","mac-win-which-is-better",{"metadata":306,"sys":309,"fields":316},{"tags":307,"concepts":308},[],[],{"space":310,"id":39,"type":15,"createdAt":40,"updatedAt":41,"environment":312,"publishedVersion":44,"revision":23,"contentType":314,"locale":28},{"sys":311},{"type":11,"linkType":12,"id":13},{"sys":313},{"id":20,"type":11,"linkType":21},{"sys":315},{"type":11,"linkType":26,"id":47},{"name":49,"slug":50},{"createdAt":318,"id":319,"type":15},"2022-03-24T15:05:06.814Z","63TlT1uQUSMPwrHPR09w9h",{"Entry":321},[322],{"metadata":323,"sys":326,"fields":333},{"tags":324,"concepts":325},[],[],{"space":327,"id":39,"type":15,"createdAt":40,"updatedAt":41,"environment":329,"publishedVersion":44,"revision":23,"contentType":331,"locale":28},{"sys":328},{"type":11,"linkType":12,"id":13},{"sys":330},{"id":20,"type":11,"linkType":21},{"sys":332},{"type":11,"linkType":26,"id":47},{"name":49,"slug":50},1782656747356]