NP困難の問題のアルゴリズムを考える その2
の末尾に書いた通り、ortoolsを使おうとしている。 そのためには定式化が必要で、今見ている問題がどのタイプの問題かを判断する必要がある。
ここら辺で重大なことに気づいた。巡回サラリーマン問題などは点と点の間に距離があり、それが問題だった。しかし、今回の塗装の問題は塗る色の間に距離などない。白と黄色の距離と、白とくろの距離は同じである(なぜならエアブラシのカップの中に入れる色が何であれ、手間は変わらないからである)。
この問題、もしかしてNP困難ではないのでは?
問題を整理する
~
のN個の色を塗るとする。
また、
のような塗装順の制約がP個ある。
このとき、最小となるような塗装順を見つけたい。
これは、書き換えると次のような問題になる。
~
のN個の記号がある。
~
をそれぞれ1つ以上含んだ最短の記号列を求めよ。
ただし、
より後に必ず
を含む必要がある、といった制約LがP個ある。
こう考えるとNP困難ではない気がする。
多角的にこの問題を考えよう。
まず、[text: L_1] ~ [text: L_P]のどれにも含まれていない記号は考慮からすべて外せる。というのは、制約に含まれる記号を制約を満たすように順序付けしたあとは、制約に含まれていない記号はその列の任意の間に好きな順序でおけるからである。先頭にあまり全てをおいても良いし、末尾でも良い。ランダムでも数字順にソートでもいが、そのどれでも塗装回数に影響しない。
となると問題は以下のように書き換えられる。
~
のN個の記号がある。
~
をそれぞれ1つ以上含んだ最短の記号列を求めよ。
ただし、
より後に必ず
を含む必要がある、といった制約LがP個ある。また、
~
は制約
~
の中に必ず1度以上出てくる。
これを図として表現すると、NxNの行列(対角線はn/a)になる。
例えば
- のあとで
-
のあとで
-
のあとで
というルールは次の行列で表現できる。
| 先に通る点 \ 後に通る点 | |
|
|
|---|---|---|---|
| |
n/a | true | true |
| |
true | n/a | false |
| |
false | false | n/a |
この行列を持って最適化する。それが、この問題の解き方(の気がする・・・)。
もしかして、DPで行ける?
2022/08/11追記
重みがないから更に効率的なアルゴリズムがありそうと2,3日調査しながら頭をひねった結果、制約を一つずつ見ながらtreeを作っていくロジックを考えついた。

NP困難の問題のアルゴリズムを考える
エアブラシによる着色の順序は、同じパーツを2色以上で塗り分ける場合に制約がかかる。基本的に奥まったところを塗ってからそれ以外を塗る必要があるため。しかし、エアブラシで色を変える作業は結構手間なので、なるべく1つの色は一度にすべて塗りたい。これはアルゴリズムで最適化できる問題。
— 西田和史(k.bigwheel) 開発基盤EM @ Speee ⌨️🖊️ (@k_bigwheel) 2022年7月9日
から始まる問題の解き方を考える。
まずは問題としてのモデル化から入る。
モデル化
問題のモデル化のセオリーがわからないため、NP困難な問題の中で一番有名な巡回セールスマン問題との違いをまとめることから始める。
- 距離はない (あとでつけたい気もするが一旦なしで考える)
- 点Aより後に点Bを通る必要がある、という制約
- なるべくたどる点の数を少なくしたい
調べると、かなり近い(というかほぼまんま)の先行研究がいくつか見つかった。
- 巡回セールスマン問題 順序 制約 - Google 検索
- ある種の順序制約付きTSPと多項式オーダー解法について | 文献情報 | J-GLOBAL 科学技術総合リンクセンター (タイトルしか見てない)
特に 順序付き巡回セールスマン問題について - Qiita はやりたいことをほぼやっている。 ただ、モデルとして循環するような制約を除外しているようなので、循環を許容して点の通過回数2回以上を許容するような問題設定が必要になる。 たぶん、
- Sequential Ordering Problem
- TSP (Traveling Salesman Problem ) Order Constraint
などがクエリとして良さそう。
あと[難問]複雑な制約付きの巡回セールスマン問題(TSP)もしくはジョブショッ... - Yahoo!知恵袋の人が話題に出しているJSPの問題にも似ている。この人はセールスマンが複数いる場合の問題だけど、塗装の問題はセールスマンが1人のTSP+JSP複合問題と言えるかもしれない。
プリント基板の電気検査における数理計画法に基づくシステム最適化
そこで,カメラによるアライメント撮像を考慮 した最短検査経路を求める問題が,先行順序制約付き巡回セールスマン問題の中で も特に集荷配送巡回セールスマン問題として定式化が可能であることを示し,その 上で,小規模問題に対しては,数理計画ソルバーを用いて厳密解を求解可能である ことを示している。
お、これもかなり参考になりそう。そうか、順序制約はより一般的な用途だと集荷配送と近いのか。
先行順序付き合流可能運搬経路問題に対する局所探索法 (最適化手法の深化と広がり)
これもと期待問題にかなり近いが、verhicleが複数であるのがちょっと違う。 ここは1台でいい。
いくつかキーワードとそれらしい論文は出てきているが、これと言ったものがない。というより、こちらに理解の土壌がない気もする。
おそらく、僕が求めているものは
- The Precedence Constrained Traveling Salesman Problem
- 先行順序制約付き一般化巡回セールスマン問題
がほぼそれなんじゃないかと思う。 前者の論文をちゃんと読めばそれで問題は解決するかも。
もろもろ考えると論文読んで実装するのはつらそう。 googleのツールとか見るに組み合わせ問題として問題を得として、その概要を学び、solverの適用方法を調べて適当なsolover(library)を使うのが最短距離っぽいとわかった。
2022/08/08
移動中勉強していたが、
全体戦略は見えた。
— 西田和史(k.bigwheel) 開発基盤 / SRE ⌨️🖊️ (@k_bigwheel) 2022年8月7日
次は定式化だ。塗装順の問題は一般的なものではないから、自分で定式化を考える必要がある。 https://t.co/eM9dOSH8hl
という感じ。 vercelにpythonのAPIをデプロイできることもあり、google製のortoolsを使うつもりでいる。
update_tri_layer(_state)を使えばタイピングがより快適になる
わかりにくいupdate_tri_layer / update_tri_layer_state関数
update_tri_layer関数はいろんなキーマップで使用されている割にその意味がわかりにくい関数だと思う。
ちょっと調べれば、この関数がだいたいPlanckキーボード発祥で、LOWERレイヤー移動キー、RAISE移動キーを同時押ししたときにADJUSTレイヤーへ移動するためのものだということはわかる。
しかし、その詳細な使い方はかなりわかりにくい。 間違った説明や適切でない使い方が散見されることからも、よくわからずコピペしている人がかなりの割合いでいそうだ。 公式ドキュメントに専用の項目があり、それなりに説明されているものの暗黙的に前提としている知識が多く、qmkについての前提知識がない状態で読んでもほとんど理解できない。 本記事を書く上で非常に参考にさせていただいた未知の階層に挑戦Tri-Layers - Qiitaの記事ですら翻訳が役に立たず読み解けなかったと書かれている1。 例えば、応用の項目で
(なぜ上書きされない?一つ目のstateが二つ目の処理で上書きされて機能しないと思うのだが・・・)
と書かれているが、これはKeymap Overviewで書かれている用語・仕組みを理解すれば謎が解ける(端的に言うとqmkのレイヤーは複数のレイヤーが同時にONになりえて、もしそうなっている場合はレイヤー番号が一番大きなものだけが有効になるため)。
なぜupdate_tri_layerは必要なのか
update_tri_layerの最大の謎は、なぜこれが必要なのか、である。
どういう意味か。update_tri_layerは
LOWERレイヤー移動キー、RAISE移動キーを同時押ししたときにADJUSTレイヤーへ移動するためのもの
と上に書いたが、これを達成するだけなら実はupdate_tri_layerは不要だからだ。
実際、僕が今使っているtreadstone48はおろかすべてのキーマップでは使用していなかった。
というのも、画像のように MO キーをLOWERレイヤー、RAISEレイヤーそれぞれに配置するだけで十分やりたいことができるためだ(最下段のスペースの左とエンターの右のキーに注目してほしい)。

これはMOキーだけではなくLTキーでも同じだ。
では、なぜupdate_tri_layerを使うのだろう。
update_tri_layerの価値
結論から書くと、update_tri_layerを使えばレイヤー変更キー周りの体験を改善することができるからだ。
どういうことか説明する。

画像のようなMOキーのみによって同時押しレイヤーを表現している場合、
| 順番 | 押したキーの位置 (Layer 0でのキー配置基準) |
押された/離されたと判定されたキー |
|---|---|---|
| 1 | 初期状態(何も押していない) | |
| 2 | MO(1) キーを押す |
Layer 0の MO(1) キー |
| 3 | MO(2) キーを押す |
Layer 1の MO(3) キー |
| 4 | MO(1) キーを離す |
Layer 3の MO(1) キー (Layer 0まで透過された結果) |
| 5 | N キーを押す |
Layer 3の Menu キー |
以上の順番で押すとLayer3の Menu キーが押された判定になる。
これは直感的には違和感がある。押しているのは MO(2) 位置のキーと N の位置のキーなので、Layer2の N 位置にある / が入力されてほしい。
なぜこんなことになるのかの詳細はコードを見てほしいが、簡単に言うと MO(1)キーを離したとしても押しっぱなしと判定されるのは Layer 1のMO(3) で、Layer 0の MO(2) が押されていると再度判定されるわけではないためである。
先程の手順にレイヤーの変化を書き加えるとこうなる。
| 順番 | 押したキーの位置 (Layer 0でのキー配置基準) |
押された/離されたと判定されたキー | それによるレイヤーのON/OFF変化 | 有効なレイヤー | 最上位レイヤー(=入力判定に使われるレイヤー) |
|---|---|---|---|---|---|
| 1 | 初期状態(何も押していない) | 0 (デフォルトレイヤー) | 0 | ||
| 2 | MO(1) キーを押す |
Layer 0の MO(1) キー |
Layer 1がON | 01 | 1 |
| 3 | MO(2) キーを押す |
Layer 1の MO(3) キー |
Layer 3がON | 013 | 3 |
| 4 | MO(1) キーを離す |
Layer 3の MO(1) キー (Layer 0まで透過された結果) |
Layer 1がOFF | 03 | 3 |
| 5 | N キーを押す |
Layer 3の Menu キー |
03 | 3 |
これに対してupdate_tri_layer (update_tri_layer_state)ベースのキーマップはこうなる。

見ての通り、Layer1と2にあった MO(3) がTransparent(透過)キーに変更されている。これにより、Layer 1の状態で MO(2) 位置のキーを押すと MO(2) 判定になる。以下に、update_tri_layerを使ったときの挙動を書く(太字の部分が使わなかった場合との差分)。
| 順番 | 押したキーの位置 (Layer 0でのキー配置基準) |
押された/離されたと判定されたキー | それによるレイヤーのON/OFF変化 | 有効なレイヤー | 最上位レイヤー(=入力判定に使われるレイヤー) |
|---|---|---|---|---|---|
| 1 | 初期状態(何も押していない) | 0 (デフォルトレイヤー) | 0 | ||
| 2 | MO(1) キーを押す |
Layer 0の MO(1) キー |
Layer 1がON | 01 | 1 |
| 3 | MO(2) キーを押す |
Layer 1の MO(2) キー (Layer 0まで透過された結果) |
Layer 2がON | 012 | 2 |
| update_tri_layer_stateがレイヤー1と2のONを検知してレイヤー3をONにする | Layer 3がON | 0123 | 3 | ||
| 4 | MO(1) キーを離す |
Layer 3の MO(1) キー (Layer 0まで透過された結果) |
Layer 1がOFF | 023 | 3 |
| update_tri_layer_stateがレイヤー1のOFFを検知してレイヤー3をONにする | Layer 3がOFF | 01 | 1 | ||
| 5 | N キーを押す |
Layer 1の Menu キー |
01 | 1 |
このように、言うなれば M(1) キーと M(2) キーの状態を独立して直交して扱えるため、より直感的な動作が可能になる。
果たしてこれはどの程度有効なのか
と思われるかもしれない。同時押しのレイヤー(いわゆるADJUSTレイヤー)は普段使わないものを配置しているため、上記のような状況は余り発生しないと思うだろう。しかし、実は上記のような状況はかなり簡単に発生する。

この、treadstone48で 1- というキーを入力するシーンを考える。
この場合、
- Layer 1で
Qの位置を押して1を入力 - Layer 2で
Sの位置を押して-を入力
となる。 このとき、理想的な打鍵順序は以下になる。
| 順番 | 押した/離したキーの位置 (Layer 0でのキー配置基準) |
押されたと判定されたキー |
|---|---|---|
| 1 | MO(1) キーを押す |
Layer 0の MO(1) キー |
| 2 | Q キーを押す |
Layer 1の 1 キー |
| 3 | Q キーを離す |
|
| 4 | MO(1) キーを離す |
|
| 5 | MO(2) キーを押す |
Layer 0の MO(2) キー |
| 6 | S キーを押す |
Layer 1の - キー |
| 7 | S キーを離す |
|
| 8 | MO(2) キーを離す |
しかし、人間はそれほど正確に動けないため、このように複雑な同時押しや順序が絡んだシークエンスは容易にミスをする。特に早く打鍵しようとするとレイヤーが切り替わるタイミングは順序が前後しやすい。上記の4と5の順番が入れ替わってしまうと、一瞬レイヤー3が有効になる。これは上の方で説明した、レイヤー3へ移動した後に片方離した状態である。
| 順番 | 押した/離したキーの位置 (Layer 0でのキー配置基準) |
押されたと判定されたキー |
|---|---|---|
| 1 | MO(1) キーを押す |
Layer 0の MO(1) キー |
| 2 | Q キーを押す |
Layer 1の 1 キー |
| 3 | Q キーを離す |
|
| 4 | MO(2) キーを押す |
Layer 1の MO(3) キー |
| 5 | MO(1) キーを離す |
|
| 6 | S キーを押す |
update_tri_layerを使っていない場合: Layer 3の RGB Mode + キーupdate_tri_layerを使っている 場合: Layer 1の - キー |
| 7 | S キーを離す |
|
| 8 | MO(2) キーを離す |
実際、早く打鍵しようとすればするほどこの現象は発生してしまうため、快適かつ高速な打鍵を達成するためには update_tri_layerはとても有効ということになる。
まとめ
udpate_tri_layer(_state) の動作について詳しく見ていき、その有用性について説明した。 ただ、実際のところなくてとても不便かと言うと打鍵速度がそれほど早くなかったり、レイヤー1と2の間をコロコロ切り替わるようなことがなければそれほど困らないとも言える。 更に言うと、このupdate_tri_layerを使うには自分でファームウェアを書き換える必要があり、remapなどでは実現が難しそうに見える(未調査)。
自分が何を優先するかによって、利用するかどうかを選択しよう、というのが最終的な結論になる。
-
この記事には感謝したい。update_tri_layerをかなり詳細に調査されており、それが僕自身のudpate_tri_layer理解につながった↩
sensibleキーマップv1→v2(com4table)のアップデート内容
| sensible v1 | com4table(sensible v2) |
|---|---|
|
|
しばらくsensibleを使っているうちにキーマップを少し変更したので、その変更内容と理由をまとめておく。
上記のキーマップは違うキーボードのものなので比較しづらいが、概要を掴むには十分なのでそのまま比較する。
親指キーに日本語入力関連キーを直接配置
一定以上のタイピング速度では LT_2 などの条件付き分岐キーマップではどうしても暴発を避けられなかった。
そのため、親指キーには直接日本語入力関連のキーを配置した。
それによって行き場を失うAltキー、Winキーは右手外側へ移すことにした。
親指キーの並び順を修正
親指部分はMOキーとSpace / Enterの位置を逆にした。これは親指の3種(日本語入力, space / enter, レイヤー)の中でSpaceとEnterキーが最も使用頻度が高いこと、かつ、使用頻度の高いキーの左右にキーを配置したほうがホームポジションを見失わず快適だったことが理由。仮にtreadstone48のように親指キーの真ん中のキーが圧倒的に押しやすいとしても、その2つ隣の日本語入力キーは比較的頻繁に押すことになる。なので、多少無理な手の並びだとしても、3つ並んでいるうちの真ん中のキーをホームポジションとしたほうが特に日本語が入力しやすい。
追記
treadstone48のような親指のホームポジションが明らかに3つのキーのうちの端っこの場合、思っていた以上に違和感があった。このことからわかったのは、どうやら親指を2キー分動かす不安定さよりSpace / Enterがホームポジションにないことのほうが打鍵上違和感がある、ということ。
Layer 1とLayer 2を大幅整理
書き出すと概ね以下。
- Home / End / Page Up / Page DownをLayer2へ移動させて矢印キーと合わせた
- Home / Endなどの移動に合わせて記号入力キーを左手側へ移動 & + などShiftなしでも入力できた系キーを削除、それらはすべてShift + ベースキーへ
- キーの順序は105キーボードでの実際の並びがベース
,./などはlayer 0と重複するが、nomu30のようにその部分のキーがないものを一貫した形でサポートするためこの形に
メモ
KC_TRANSを乱用すると混乱の元になるかと思い、modifierキーの上以外は極力KC_TRANSを使わないように一度はしたが、ある程度以上の速さでタイピングしているとMOキーを押しているときにEnterやSpaceを押してスカることが頻発した。なので、基本的にKC_TRANSは使うままにしている。
最近自作キーボードのキーマップについて考えていること
一時期キーマップのことばかり考えていた時期がある。
ただ、完全に煮詰まってしまってそれが自作キーボードからちょっと離れる理由の一つになってしまった。
最近、またキーマップを考えたいと思い始めたのだけど、
のように如何に自動キー入力や配置変更で楽を使用かと考えていた1年以上前から少し考え方が変わった。
背景は、mimic keymapなどで思った以上にトラブルが多かったことから。 うまく使えば便利ではあるのだけど、Ctrl+Shif+なにかなど、組み合わせのときに何かと問題を引き起こしがちだった。また、複雑なキー配置も忘れやすく問題が起こったときに即座に解決できないことも多かった。 決め手となったのは会社で使っているMacを英字に変えたことで、これで日本語キーボードと英字キーボードの間を行ったり来たりせずに良くなった(すべて英字キーボードに統一できるようになった)。 こうなると切り替えが必要なのはPC / Macのキー配置間ぐらいになる。
次のcon4t4ble v2は、やるとしても長時間放置したときのIME無効化(auto_disable_ime)ぐらいでよさそうだ(記号押したときの自動ME無効化(disable_ime)や記号入力の配列を擬似的に書き換える機能(mimic_keymap)もいらない)。
qmk_firmwareにswap alt/gui ボタンがあるので、これでmacとpc用を切り替えられるならいっそIMEの自動無効化も切ってもいいかもしれない。 そこまでやれば、あとはカスタムしたい要素は
#define PERMISSIVE_HOLD #define RETRO_TAPPING
ぐらいになる(http://oookaworks.seesaa.net/article/465349890.html)。
一通りキーボード側でいろいろ入力を工夫できないか試してみて思ったのは、ファームウェアだけで行うことには限界がある、ということだった。 mimic_keymapも自動IME OFFも言ってしまえばIME側でうまく制御できればもっとよくできる話だった。ハードウェア(ファームウェア)側でやることには、OSが切り替わったりPCを複数つないでもそれぞれで設定が不要という利点はあるものの、OS側の状態がどうやっても取得できないためいつ部不器用にならざるを得ず、それがmimic_keymapやdisable_imeで自動的にIMEをOFFにするところで問題を発生させがちだった。むしろ、その複雑さからくる問題がポータビリティや可用性を下げてしまい、本末転倒なことになりがちだった。
幸い、会社と自宅のキーボードを英字配列に統一できたため、これからはOS側の設定を英字に統一して見ようと思う。その上でmacとlinuxの設定差は吸収する必要があるが、それは英字/日本語よりだいぶ小さな差分で済む。 もし、IME領域含めてまで開発する動機ができたらまたソフトウェアによる入力改善のテーマへ挑んでみようと思う。
マンションの換気ダクトと塗装ブースのホースを直結できる部品を3Dプリンタで作った
省エネ記事。
最初のアイデアはAmazon | 排気ホース・集合ダクト【補強 タミヤ塗装ブース・ツインファンの2本のホースを連結して1本に (タミヤホース) | ペインティングスタンド・ブース 通販から。
しかし、そのためにはCADでモデルを作らないといけない。 Fusion 360を使うかFreeCADを使うか、つまりwindowsをやむなく使うかlinuxでも使えるソフトウェアを使うか3日悩んで、ユーザビリティに劣るとしても長期的には価値が高いと判断したFreeCADを使うことにした。 ちなみにこの判断はあとで大正解だったと感じた。確かにわかりやすくはなかったがyoutubeなどに解説動画も多くあり、やりたいことができないことはなかった。これでwindowsの呪縛から逃れられるなら多少の不便は許容できる。




































というわけで早速試しに設置してみたのだがとてもよかった。 かかった費用はフィラメント1KG未満で前半は安物を使っていたのでおそらく2,000円もかかっていない。 今回はできたものにも大満足だが、なによりFreeCADで工業デザインのためのCADを学べたのが本当に良かった。僕はもともとロボットコンテストで興味を持って高専に入ったのだけど結局学科は当時急速に伸びていた情報工学科を選んだ。そんなわけで昔から機械科の友達がCADを使っているのを少し羨ましいと思っていた。だから昔からの念願が一つかなった感じ。
なぜ今10年使ったzshをやめてfish shell / nushell / xonsh / elvishへ移行しようとしているか
zshをかれこれ10年ぐらい使っている。
最初のきっかけは忘れたけども、本格的に使うようになったのは2007年ぐらいに書かれた「漢のzsh」という伝説的な紹介記事によるもので僕の .zshrc には未だに 漢のzsh 4thから引用 みたいな設定がたくさんある。
そんなzsh、僕は会社でmac自宅でlinuxを使うようになってもhomeshickというツールを使って設定を同期していたのだけど近頃調子が悪い。自宅のlinuxの方は問題ないのだけど会社のmacでshellの立ち上げに5秒ぐらいかかるようになってしまった。 tmuxを使っているのでshellを立ち上げ中に元のペインへ戻って作業をしているのだけど考えてみると結構作業効率を落としている。なにか目的があって別のシェルを立ち上げているので、一時的にでも別のことをせざるを得ないということは思考が中断されている。人間の脳のコンテキストスイッチはかなり効率が悪いのでこれは良くない。
調べてみたらzsh+anyenvが不味そうなことがわかったのでそこを直そうかとも思ったんだけど、そもそもその問題を解決しても起動に1.5秒ぐらいかかる。 なんでこんな時間がかかるんだとzshのプラグインマネージャーを比較し始めたあたりでもう嫌になってきた。
そうだ、fishをためそう。
fish shell
fish shellは新時代のshellとして数年前から話題になっていた。 ただ、移行に踏み切らなかった理由はいくつかあって、一つにposix標準じゃないこと、もう一つはportabilityの観点だった。
fish shellの懸念
posix標準のshellというのはだいたいsh互換のシェルという意味で、ifやwhileなどの構文がshと同じようにかけるshellだ。 fish shellはこのif for whileのような構文がshと違うことがネックだった。というのは僕のようなインフラ寄りのエンジニアにとってシェルスクリプトは日常書くので2種類の構文を使うと混同して混乱してしまう恐れがある。
もう一つのportabilityというのはログイン先のサーバなどでfishが使えないことで、数年前はまだfish shellは新しめのshellという印象だったのでログインした先のredhatやcentosで使えるかが不安だった。当時は日常的に数十台のサーバへログインして作業しており、サーバによってはその中でツールをインストールして実行していたので手元のPCと出先のサーバでshellが違うことはこれまた認知負荷を余計に高める要因だった。
しかし、状況が変化した。
サーバレスの時代
オンプレからAWS初期の時代はインスタンスに直接sshしての作業は日常茶飯事だったが、Lambda, ECS, EKSへ移行していくに連れcompute nodeへログインすることはおろか踏み台サーバを使用することすらまれになってきた。 そして今の会社ではついに全面EKS / lambda移行を行い、踏み台サーバすらない状態になっている。 こうなると懸念だったポータビリティの観点はほとんどどうでもよくなる。 また、posix標準についても5年前は不慣れだったposix標準構文に十分慣れたことで混同する恐れがほとんどなくなったために問題はクリアされた。
zshからの移行先
こうして、fish shellを避ける理由がなくなったのでzshrcからfishへの設定移行をしているのだが、bigwheel/fish-castleかなり移行を進めた段階でこれはこれで気になる点がいくつか出てきた。一つは設定のポータビリティで、サーバーへはログインしなくなったものの会社と自宅PCで同じ設定は使いたいのだがfish shellはuniversal variablesという変数周りのポータビリティがそもそも設計思想になく各PCでuniversal variablesは固有の思想になっているため同期に難がある。
またC++で書いているのも気になって、令和ならgolangかrust使っているほうが将来性があるのではという気になってきた。 そこで上がった選択肢が以下
- xonsh
- nushell
- elvish
特にnushellはすでに一定の信頼を得ている気がするので、これが良さそうであればfish shellを飛び越してこれにするのもありだと思っている。
追記
fish, nushell, elvishと試した結果、結局fishを使うことにした。 nushellはHistory (ctrl + r) with fzf · Issue #1616 · nushell/nushellにある通りhistoryに対して高度な検索を行えないのが痛い。 elvishは最初ctrl-aのようなショートカットキーが使えなくて、しばらく調べてreadline-binding: Readline-like Key Bindings - Elvish Shellで有効化できることはわかったのだけど、fishの哲学のout of the boxで使用できるというものが以下に価値があるかわかった & elvishは全編こんな感じで対処しないといけない匂いを感じたので結局fishに戻ってきた。

