あんパン

こしあん派

SKK-JISYO.jawikiをibus-skkで利用する

Linuxデスクトップをメインの端末にしてからこれまで2年ほどibus-skkを利用しており、辞書はSKK-JISYO.Lとユーザ辞書のみという状態で固有名詞に弱いことを不便に思っていた。都度ユーザ辞書に登録すれば良いが、それも面倒なのでWikipediaからSKK辞書を生成して利用できると便利そう。どうせ同じようなことを考えているひとはいるだろうと思って探したところ、tokuhiromさんが作られていた。しかもGitHub Actionsで定期的にビルドされているのである程度最新版のWikipediaに追従されている。最高です、ありがとうございます。

github.com

ということで、これをibus-skkで利用することにした。最初は $HOME/.config/ibus-skk/SKK-JISYO.jawiki に置いて辞書として登録したのだが、どうも使われていない様子。調べたところUTF-8の辞書を置くだけだとibus-skkが読んでくれていないようだった。

対処方法は以下の2つのいずれか。

  • Coding Cookie (;; -*- coding: utf-8 -*-) をファイルの先頭に挿入する
  • dconfで辞書のencodingを設定する

実際に両方とも試したところ、それぞれ辞書が使われるようになった。

辞書の取得と登録を自動化したいのでCoding Cookieを都度入れるのは面倒そう。生成時に含めるようにPull Requestを送るかどうかでいうと、いずれにせよ辞書の場所を設定したりその他の調整も自動化したいのでシェルスクリプトでdconfを叩いたら良いかという気持ちになりそのようにした。

$ dconf write /desktop/ibus/engine/skk/dictionaries "[..., 'file=/path/to/SKK-JISYO.jawiki,mode=readonly,type=file,encoding=UTF-8', ...]"

といった具合。作業前後に dconf read /desktop/ibus/engine/skk/dictionaries で様子を見ておくと良い。

内田真礼を一発で変換できて助かる。

GitHubにcurlで公開鍵を登録する2021

masawada.hatenablog.jp

ここでcurlで公開鍵を登録する方法を紹介していたのだけど、GitHub全域でこれまでのユーザ名・パスワード・OTPによるBASIC認証が使えなくなったようだった。以下のようなエラーが返る。

{
  "message": "Requires authentication",
  "documentation_url": "https://docs.github.com/rest/reference/users#create-a-public-ssh-key-for-the-authenticated-user"
}

ではどうすれば良いかというと、Personal Access Tokenを利用する。

docs.github.com

まず Personal Access Tokens から Generate new token を選択してPersonal Access Tokenを発行する。この際にpublic keysに関する権限をつけておく。

f:id:masawada:20210310111118p:plain

あとは以下で公開鍵を登録できるようになる。

curl -XPOST \
  -H 'Content-Type: application/json' \
  --basic -u '<user>:<personal_access_token>' \
  -d '{"title": "user@hostname", "key": "<public_key>"}' \
  'https://api.github.com/user/keys'

または以下のようにAuthorizationヘッダをつける形でも登録できるようだった。こちらの方がシンプルだと思う。

curl -XPOST \
  -H "Content-Type: application/json" \
  -H "Authorization: token <personal_access_token>" \
  -d '{"title": "user@hostname", "key": "<public_key>"}' \
  "https://api.github.com/user/keys"

登録した公開鍵はPersonal Access Tokenをrevokeすると削除される。あくまで一時的なものとして扱われるらしい。

一見 X-GitHub-OTP ヘッダをつけた方がセキュアなのではと思ったが、Personal Access Tokenを利用することで権限を絞って認可できるし一般的な認証方法に乗っかることができるから良いという話なんだろうか。個人的にはOSインストールの自動化のために利用しているのでPersonal Access Tokenをrevokeすると鍵が削除される仕様を若干不便に感じるけどその方がセキュアそうなので諦めるしかない。

gitでコミットする前のファイルを選択して編集する

repoで作業していて変更を加えたファイルを開き直してさらに追記したいケースは少なくない。historyから絞り込んで選択するよりは、差分が発生したファイルのリストから絞り込む方が見通しが良いのではないか、ということで普段は差分が発生したファイルから絞り込んでいる。以下のようなファイルを git-edit-changed という名前で $PATH のいずれかのディレクトリの中に置いて実行権限をつけておくと git edit-changed コマンドとして呼び出せる。

#!/bin/bash

filepath=$({\
  git ls-files $(git rev-parse --show-toplevel) --exclude-standard --others --full-name; \
  git diff --name-only HEAD; \
} | sort -u | peco)
if [ ${#filepath} -ne 0 ]; then
  cd $(git rev-parse --show-toplevel) && ${EDITOR} ${filepath}
fi

git ls-files $(git rev-parse --show-top-level) --exclude-standard --others --full-name では、untrackedなファイルをrepo rootからのパスとして出力している。 --others はgit管理されていないファイル群を出力するためのオプション。これを指定するだけでは .gitignore 等でignoreしているファイル群も含まれてしまうため、これらのファイルを無視するのが --exclude-standard--full-name を指定することで自分がどのディレクトリにいてもrepo rootからの相対パスとして出力できる。

git diff --name-only HEAD では、HEADからの差分を出力している。git diff --name-only 単体では、indexと現在の差分が出力されてしまうので、 HEAD をつけることで最新コミットからの差分を出力する。untrackedなファイルはindexに追加すると上記のコマンドでは出力されなくなり、こちらのコマンドで出力されるようになる。

これらの出力を {} でひとつにまとめてパイプで sort -u | peco に渡して絞り込んでから $filepath に代入している。といった具合でHEADとの差分一覧(コミットする前のファイル一覧)を取得できる。

どうぞご利用ください。

git管理下のファイルのみをtree表示する

treeはみなさんご存知便利なコマンドで、cwd以下のファイルをツリー表示するもの。だいたいの環境にはデフォルトで入っていないので、 brew などで入れる必要がある。

$ tree
.
├── hello.txt
├── test
│   └── hoge.txt
└── world.txt

1 directory, 3 files

大抵のソフトウェアのプロジェクトでは node_modules のような依存ライブラリ群をプロジェクトのディレクトリに内包しているのが常で、gitで管理している場合は .gitignore で無視することがほとんどだと思う。このような環境下でtreeを使うとこれらのファイルが一気に出力されてノイズとなることがしばしば。初めて参加するプロジェクトのコードを読む際はどこから読むかあたりをつけるのにtreeコマンドが便利そうだが、正直このままでは使いづらい。

treeには --fromfile オプションがあり、パスのリストをファイルから読み取ってツリー表示することができる。更に --fromfile=. とすると、標準入力からパスのリストを受け取ることができる。git ls-files | tree --fromfile=. とすることで、git管理しているファイルのみ、つまり依存などが無視されて純粋にプロジェクトそのもののファイルリストのみがツリー表示されるようになる。例えば以下は以前書いたbt2usbhidのプロジェクトルートでの出力。.gitignore で指定されている bin/bt2usbhid はファイルとしては存在するが、ツリー表示には出力されていないことが分かる。

$ ls bin
bt2usbhid  init_bt2usbhid
$ git ls-files | tree --fromfile=.
.
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── bin
│   └── init_bt2usbhid
├── config
│   ├── 99-bluetooth.rules.example
│   ├── bt2usbhid_keyboard.service
│   ├── bt2usbhid_mouse.service
│   └── init_bt2usbhid.service
└── src
    ├── keyboard.c
    ├── keyboard.h
    ├── main.c
    ├── mouse.c
    └── mouse.h

3 directories, 14 files

github.com

以下のシェルスクリプトを $PATH のいずれかのディレクトリの中に git-tree という名前で実行権限をつけて入れておくと、 git tree サブコマンドでこれを呼び出すことができる。

#!/bin/bash

set -e

if ! type tree > /dev/null 2>&1; then
  echo 'command not found: tree'
  exit 1;
fi

git ls-files | tree --fromfile=. "$@"

インターネットで探したところ、これと同等の機能をGoやPythonで実装したツールが出てきたが、tree自体に実現する機能があるのでtreeを使う方が柔軟性があって良い。treeにはまだ面白いオプションがいくつかある。例えば -J オプションでツリーをJSONに変換することができる。上記のスクリプトはそのままオプションを受け取れるようにしているので、以下のようにJSONを出力することができる。

$ git tree -J
[{"type":"directory","name": ".","contents":[
    {"type":"file","name":".gitignore"},
    {"type":"file","name":"LICENSE"},
    {"type":"file","name":"Makefile"},
    {"type":"file","name":"README.md"},
    {"type":"directory","name":"bin","contents":[
      {"type":"file","name":"init_bt2usbhid"}
    ]},
    {"type":"directory","name":"config","contents":[
      {"type":"file","name":"99-bluetooth.rules.example"},
      {"type":"file","name":"bt2usbhid_keyboard.service"},
      {"type":"file","name":"bt2usbhid_mouse.service"},
      {"type":"file","name":"init_bt2usbhid.service"}
    ]},
    {"type":"directory","name":"src","contents":[
      {"type":"file","name":"keyboard.c"},
      {"type":"file","name":"keyboard.h"},
      {"type":"file","name":"main.c"},
      {"type":"file","name":"mouse.c"},
      {"type":"file","name":"mouse.h"}
    ]}
  ]},
  {"type":"report","directories":3,"files":14}
]

これでファイルリストをプログラムやjqなどのコマンドに食わせやすくなる。同様に -X オプションでXMLを出力することもできるし、 -H . とすればHTMLを出力することもできる。もっともこれらが役立つ場面があるかというと滅多になさそうではあるが、覚えておくと役に立つことがあるかもしれない。


追記(2021-02-24): 指摘いただいて、 git-tree のスクリプトの $@"$@" に変更しました。引数にスペースが含まれている場合に分割されてしまうためです

自作ラップトップ: ThinkPad X270を組み立てる

本業を含めて作業環境をLinuxに移行してからmacOSで開発するのが億劫になってしまい、ここ半年はDeskMiniで組んだ自作機に入れたArch Linuxで個人の開発をしていた。しかしそろそろ寒いし布団の中で開発したいなーと思い、サブPCとしてラップトップを見繕うことにした。条件は以下の通り。

  • 新品
    • 天板とかキーボードがテカってるPCを使いたくないので
  • メモリは16GB以上
    • 最近の人権は64GBと聞くけどサブなのでこれくらい
  • CPUはi5くらい
    • i3は避けたいかな〜くらいのつもり。あんまり強いこだわりでない
  • 13インチ以下のサイズでFull HD以上の解像度
    • できれば12インチ台が良い
    • デカいラップトップがあんまり好きじゃない。4Kとかまでは不要
  • USキーボード
    • 別にJISキーでも開発できるだろうけど自宅のPCは全部USキーで統一してるので
  • できればRJ45ポートがある
    • ネットワーク回り触る人、RJ45ポートがないPCつらくないですか? わざわざアダプタ持ち歩くの?
    • 最近のPC、薄型を目指しすぎていてだいたい省略されていて困ることが多い
  • できればUSB-Cで充電できる
    • 変な充電器を増やしたくない
    • 家中にUSB-C 30W or 60Wの充電ケーブルが生えているからこれを使いたい
  • できればバッテリを換装できる
    • バッテリが弱まってたら換装できると便利なので

これだけ条件をつけるとだいたい絞られてきて、手頃なのはXPSかThinkPadあたりかなーというところ。どちらかというとXPSに傾いていた。が。メモリを16GBにしてSSDを512GBにすると13.5万程度とまあまあ高い。いや高いわけではなくて普通の値段なのは分かっているんだけど、サブにしてはやっぱり高い気がする。しかし他に選択肢もなぁと思っていたところ、突然中古のThinkPadを買ってきて外装部品変えたらいいじゃんという気持ちになった。本業で使っているのもT480なのでスムーズに生活に溶けこむであろう。世の中にはThinkPadを自分で組み立てる人間がいると聞いたことがあるし、自分もそちら側の人間になってみたい。

早速調べて実行に移すことにした。以下のような手順で進めることにした。

  • 組み立てるThinkPadのモデルを選ぶ
  • ヤフオクでThinkPadの中古を買う
  • ThinkPadの構成部品を調べつつ本体を解体して必要なパーツをリストする
  • パーツを注文する
  • 全てのパーツが届いたら組み立てる

ところで自作PCってなんで自作なんだろうか。解せないところはありつつも一般にはPCパーツを買ってきて組み上げる行いを自作PCと呼んでいるはずなのでこの記事でもそれに従った。

組み立てるThinkPadのモデルを選ぶ

13インチ以下が良いので、おのずとXシリーズに絞られる。Xシリーズの中でも比較的最近の機種を見て回ることにした。

  • X250
    • 中古価格がこなれていて安い
    • メモリがDDR3なのでもはや売られておらず、16GBのものはめっちゃ高い
    • 一応変換アダプタを噛ませればUSB-Cで充電できる
  • X260
    • X250よりちょっと高い
    • DDR4になっているのでメモリの入手性が向上した
    • 一応変換アダプタを噛ませればUSB-Cで充電できる
  • X270
    • X260よりちょっと高いけどだいたい同じくらい
    • USB-Cポートを搭載していて一応ここから充電できる
  • X280
    • 中古でも高い
    • メモリを換装できない
  • X390
    • 高い、新品で買ったほうがマシ
    • 13インチ
    • バッテリを換装できない
    • RJ45ポートがない
    • WLANアダプタとかがオンボードになってて突然Wi-Fi6にしたくなってもできない、LTEモジュールも搭載できない
      • もともと条件として考えてなかったのでどうでもいいけど
    • 正直これが発表されたときにXシリーズで良いと思っていたところが全てなくなって愕然とした

という感じでリストしたところ、どうみてもX270だよねーということで落ち着いた。一瞬X250と迷ったものの、やはり16GBのメモリの入手性が悪いのがひっかかった。USB-Cポートを備えているのも良くて、X260を組むならX270の方が明らかに良い。

ヤフオクでThinkPadの中古を買う

そうと決まれば本体を買うぞということでいろいろ見て回った。最初はBe-Stockかなーと思っていたが、どうせ外装全部換装するのだからボコボコになった中古でもかまわんということでヤフオクで安そうなX270を競り落とすことにした。i5モデルの相場はだいたい3万弱くらいで、運が良いと送料込みで2.5万くらいで買える。入札したところ他のユーザと微妙に競ることになったけど、無事2.5万くらいで入手することができた。

ThinkPadの構成部品を調べつつ本体を解体して必要なパーツをリストする

ではどの部品を買ったらよいのか。ThinkPadは保守マニュアルが充実しているのでこれを見ればどのような部品で構成されているのかが分かる。

また、以前のものがどうかは分からないが、サポートサイトでThinkPadのシリアルナンバーを入力すると当該製品に使われている部品を表示してくれる。型番も表示してくれるので便利。

届いたThinkPadのシリアルナンバーをこれに入力しつつ、解体して必要なパーツをリストする。

f:id:masawada:20210202043721j:plain
ベゼルを外したところ

最初は換装する必要がないと思っていたWi-Fiアンテナやカメラは天板に接着されているので新たに購入する必要があることが分かった。その他にも、指紋リーダーとトラックパッドと本体を繋ぐフレキ(ひとつのFPCで両方に繋がっている)とCMOSバッテリがキーボードベゼルに接着されていることも分かった。

最終的に、以下のパーツを購入することにした。

  • キーボードベゼル: 01HW957
  • 指紋センサー: SC50F54334
  • トラックパッド用FPC: SM10M38706
  • ベースカバーアセンブリー: 01HY501
  • コイン型CMOSバッテリ: AliExpressになかったのでAmazonで適当に検索して探した
  • ファン: 01HY452
  • トラックパッド: SM10K87872
  • キーボード: 01EP062
  • LCDベゼル: 01HW947
  • カメラモジュール: 00HN376
  • カメラケーブル: 01AW448
  • ワイヤレスLAN/WANアンテナ: 01HW955
  • LCD背面カバー: 01HW944
  • LCDパネル: LP125WF2-SPB2
  • LCDヒンジ: 00HN990
  • X270ステッカー: 適当に検索すると出てくる(LCDベゼルの右下にあるモデル名の部分)
  • カメラカバー: 適当に検索すると出てくる(LCDベゼル側に貼るやつ)

…ほぼ全部になってしまった。

なお購入した本体についていたLCDはFWXGAだったが、交換部品はFull HDのものにした。FWXGAのものはeDPコネクタが中央からズレていて横に寄っており、同じく横にズレたパネルを買わないとケーブルの長さが足りなくなってしまう。純正品のFull HDパネルは中央にあるようなので、元々Full HDだった場合は上記のパネルを買ってはいけない。

パーツを注文する

リストしたパーツを順に購入していく。基本はAliExpressで購入する。後述するがAliExpress Standard Shippingで注文することを強くオススメしたい。あと、必ずNew and Originalと書いてあるものを選ぶこと。これが書いていない場合は中古だったり互換品だったりする。もっともOriginalと書いてあるものが本当に純正品なのかはかなり疑わしいところではある。

AliにないものはAmazonなどで探すと出てくる場合がある。CMOSバッテリはAliで見当たらなかったのでAmazonで注文した。

その他、上記にないものとして512GBのSSDと16GBのDDR4 S.O.DIMMメモリを購入した。ファンを交換するのでCPUグリスも必要だが、手持ちのものがあったので買わなかった。あとはもともとCPUとファンの間に塗布されていて固着しているであろうグリスを拭くために無水アルコールがあると良い。こちらも手持ちのものがわずかに残っていたので買わなかった。

全てのパーツが届いたら組み立てる

パーツが届いたら組み立てる。注文から到着までだいたい2-3週間くらいで、全て公称の14-21days以内で届いた。今回の発送はすべてyanwenに引き継がれて台湾経由で日本に入り、そこからは日本郵政に引き継がれる。YPで終わるトラッキングコードが払出されている場合はyanwenのサイトでトラッキングできて、ここに日本に入ってきてからのコード(LXで始まってTWで終わる?)も表示される。毎日のようにパーツが届く時期があって、ディアゴスティーニのようなワクワク感があった。

分解する際はBIOSからバッテリを無効化して、一番最初にバッテリのコネクタを抜いておくこと。一度解体しているのでハマりどころも分かっていてここからはサクサク進む。といっても組み上げるまで2時間くらいかかったが。

f:id:masawada:20210202043724j:plain
パーツたち(一部)

ネジなどの細かいパーツは紛失しないようにジッパーがついた小さいビニール袋に入れてどこのパーツかを油性ペンで描いておくと良い。同一のパーツを固定するネジであっても場所によってネジの種類が違うことがあるので注意して分類しておく必要がある。

f:id:masawada:20210202043730j:plain
Wi-Fiアンテナを配線しようとしているところ

組み上げたらあとは電源を投入してBIOSの時刻を合わせて、OSをインストールすれば良い。Secure Bootのキーをリセットしておかないとインストーラを立ち上げられないことがあるので注意。OSインストール後にハマったことについては以前記事にしていた。

masawada.hatenablog.jp

発生したトラブル

とまあここまで順調に組み上げたように書いてきたけど、様々なトラブルにぶちあたったのでいくつか紹介したい。細かい話題だと、注文したWi-Fiアンテナの在庫が尽きていて「別のモデルのアンテナを改造して送るが良いか?」と連絡が来たりした(その後発注してくれて正しい製品が届いた)。

ディスプレイがうまく閉まらない

組み上げたは良いがディスプレイがうまく閉まらない。どうも天板が微妙に歪曲しているからなのかキーボード付近が盛り上がっているからなのか干渉してうまく閉まらない。これに関してはどうしようもないのでひとまず無視することにした。Aliで売られているパーツ、実は正規品ではありつつも検品かなんかで弾かれたやつが流れてるんじゃないかという気がする。どれも微妙に噛み合わせが悪い。

あんまりよくないのは分かっていつつも最近はディスプレイを閉じた状態で上に重たいものを載せて矯正している。少しマシになったかもしれない??

パーツが届かない

これまで運が良かったからなのかAliExpressで買ったものはだいたい届いていたのだけど、今回初めて届かないパーツがあった。正確には一部のパーツが含まれていなかった。すぐさま紛争を開始(Open Dispute)してお金を取り戻した。含まれていなかったパーツは別のショップで購入した。

AliExpress Standard Shippingを利用している場合、パーツがないなどで紛争を開始するとAliExpressが紛争の相手となってくれる。今回は届いたパーツの写真を撮って上げることで確認として含まれていない分を返金してくれた。結構ザルなので本当にこれでいいのか…と思うものの、まあいろいろやりとりするコストよりかは安くつくのであろう。自分はある程度利用履歴があるからさっと認めてくれたのかもしれない。よくわからん。

AliExpress Standard Shipping以外の発送方法を利用した場合は紛争の相手がショップになるようで、AliExpressは仲介をしてくれるだけの存在になる。この場合返事を待ったり相手がゴネたりと対応が面倒になるケースがあるという情報をインターネットでみかけたので特に理由がなければAliExpress Standard Shippingが良いと思う。

ディスプレイのバックライトが死ぬ

本当につらい出来事だったのだけど、ディスプレイのバックライトがつかなくなった。最初はケーブルの接触不良と思っていたが、iPhoneのフラッシュを常時点灯にして画面に近づけたところ表示が見えたのでバックライトが死んだと判断した。

いろいろ調べたところ、どうも分解する際にBIOSでバッテリを無効化するのを忘れてディスプレイを取り外ししたせいでロジックボード側のヒューズ飛んでバックライトがつかなくなったようだった。そう、ロジックボードなのでつまり本体の買い直しになる。直せるひとはヒューズを交換したら直せるのかもしれないが、そこまで労力をかける気持ちがなかったので本体を買い直した。2.5万の追加出費は痛い。

おわりに

かかった金額を合計したところ以下のようになった。

  • 本体2台分: 54,480円
  • SSD: 6,182円
  • メモリ: 5,770円
  • その他のパーツ: 40,445円
  • 合計: 106,877円

うーん微妙な結果! やはり本体を2台分購入することになったのが痛手だった。これがなければ8万円以下で収まっていたのだが。とはいえ故障してもパーツを買ってきたら自分の手で直せることが分かったし、新品のPCを買うよりは安かったしなにより最初に考えていた自分の要望は全て満たすことができた。16GBのメモリにしたので32GBへの拡張性も残されている。

実は去年の12月くらいから動き始めて年末には組み上げていたのだけれど、年始からこれまで1ヶ月ちょっと、ほぼ毎日のように組み上げたThinkPadで何かしらの作業をしていて満足度がかなり高い。ニッチな趣味であることは自覚しつつも、時間とお金に余裕がある人・単にラップトップPCを買うことに満足できない人には是非オススメしたいと思う。