もぐてっく

人は1つ歳を取る度、1ビットづつ大きくなれると信じてた。

Windows Subsystem for LinuxのUbuntuでuim-mozcを使う

Windows Subsystem for Linux(WSL)が正式版になって、晴れてWindowsでmikutterが普通に使えるようになりました。

moguno.hatenablog.jp

しかしながら、WSLではfctixやibusと言った最近のインプットメソッドが動作しません。
なので、ちょいと古めのuimAnthyの組み合わせで使っていたのですが、このAnthyの変換精度がどうも微妙。

できればmozcの様な今どきの変換エンジンを使いたいなと。

実は、Ubuntu(と言うかDebian)にはmozcをuimで使うためのパッケージuim-mozcが存在します。

でも、uim-mozcは14.10(Utopic)でいったん廃止され(バグでも見つかった?)17.04(Zesty)で復活してる感じなので、WSLのUbuntuである16.04(Xenial)にはそれが存在していないというのが現実です。

この日曜日にいろいろ試して、Zestyからuim-mozcを借りてくることに成功したので、手順を書いておこうと思います。

準備

では、bashを起動してください。
sudoの連続は面倒なのでsudo -sでrootなシェルを起動しておきます。

sudo -s

aptの設定ファイルの調整

お好きなviで2つのファイルを新規作成しましょう。

/etc/apt/sources.list.d/zesty.list

zestyのリポジトリを検索対象に加えます。

deb http://ja.archive.ubuntu.com/ubuntu zesty main universe

/etc/apt/preferences.d/zesty

名指しで指定した場合のみzestyのパッケージを採用する様に優先度を調整します。

Package: *
Pin: release n=xenial
Pin-Priority: 990

Package: *
Pin: release n=zesty
Pin-Priority: 90

いつものアレ

apt-getでパッケージのデータベースを更新しておきます。

apt-get update

uim-mozcのインストール

それでは、いよいよuim-mozcのインストールです。
zesty名指しがポイントです。

apt-get install -t zesty uim-mozc

後は、uimをIMに使うように指定したアプリケーション(mikutterとか)を起動すれば、変換エンジンがmozcに変わっています。
日本語入力をONした後、ps -aux | grep mozcしてmozc_serverが常駐してたらOKだと思います。

moguno   28926  0.0  0.2 810056 16952 ?        Sl   22:55   0:00 /usr/lib/mozc/mozc_server

WSLを使ってWindowsでmikutterを動かす。

愛機MacBook Air(Mid 2012)の調子が悪くなったので、メインマシンを買い置きしていたThinkpad X1 Carbon(2016)に変更しました。*1

画面が広い!重量も軽い!Windows10も結構使いやすくなってきてる!と概ね満足だったのですが、唯一の懸念事項がmikutter。
mikutterはバージョンアップを重ねるごとにWindowsで動かすのが難しくなってきてるんで、これからWindowsで暮らしていく上で、伴侶であるみくったーちゃんと添い遂げることは出来るのかしらと。

そういえば、最近流行りのWSLでmikutterの動作報告があったなぁ。試してみるかと設定してみました。

結論としてはすごくいい感じ。macOSX11版)と同等の使い勝手が得られました。

f:id:moguno:20171008151829p:plain:w400

WSLのインストール

ここはいろんなサイトで手順が公開されているので端折ります。

(1)コルタナたんに「更新」と伝え「更新プログラムのチェック」を起動する。
「開発者向け」にある「開発者モード」を有効にする

(2)コルタナたんに「コントロール」と伝え「コントロールパネル」を起動する。
「プログラムと機能」の「Windowsの機能の有効化または無効化」から
Windows Subsystem for Linux(Beta)」をインストールする。

(3)コルタナたんに「bash」と伝え「Bash on Windows on Windows」を起動する。
Ubuntuのインストールが始まる。)

コルタナたんは仕事のできる子。

(4)bashが起動したら、環境を最新化しておく。

sudo apt-get update
sudo apt-get dist-upgrade

mikutterのインストール

今回は手抜きでUbuntuリポジトリにいるmikutterを使います。腕に覚えがある人はgitで最新版を取ってきてインストールしてください。なんだかんだでUbuntuなので、ハマり要素はかなり少ないと思います。

sudo apt-get install mikutter

日本語フォントのインストール

こちらを参考にしてGoogle謹製のnotoフォントをインストールします。

ぽぬぽぬ: Bash on Ubuntu on Windows + XサーバでLXDEを起動

ついでに絵文字(ttf-ancient-fonts)も入れておきましょう。

sudo apt-get install noto-fonts-hinted noto-fonts-cjk ttf-ancient-fonts

日本語入力システムのインストール

ここではちょっと懐かしいuimanthyをインストールします。*2

あれやこれやZakki: bash on ubuntu on windows(WSL)でGUIを立ち上げて日本語入力までやる

sudo apt-get install uim uim-xim uim-anthy

ブラウザ起動シェルスクリプトの作成

mikutterには、アカウントの認証時やURLをクリックしたときに起動するWebブラウザが必要です。
WSL側にfirefoxとかをインストールしてもいいのですが、せっかくのWindowsなのでEdgeとかIEを使いたいなと。

WSLでは、Windows用のプログラムを拡張子.exeまで含めて指定すると、そのプログラムが起動できるので、それでサクッと解決・・・と思ったのですが、EdgeもIEも実は.exeファイルは存在せずシェルエクステンションみたいな概念に昇華されてしまっているので、この方法はとれません。

なので、コマンドプロンプト(cmd.exe)を経由して、Windowsの既定のブラウザを起動するようにします。

/opt/mikutter-wsl/bin/start

#!/bin/sh
cmd.exe /C start "$1"

実行権限を付けておきましょう。

chmod 755 /opt/mikutter-wsl/bin/start

Xサーバのインストール

Windows用のXサーバはけっこう豊富に存在しますが、ここではVcXsrvを選択しました。理由はたまたま目についたからです。
この子どうやら高速なことで有名みたいです。実際サクサク動きます。

VcXsrv Windows X Server download | SourceForge.net

VcXsrvの起動スクリプトの作成

VcXsrvには起動時に任意のコマンドを実行する機能があるので、mikutterをダイレクトに起動するようにします。
下記のXMLファイルを作成します。LocalProgramがキモの部分です。

mikutter.xlaunch

<?xml version="1.0" encoding="UTF-8"?>
<XLaunch WindowMode="MultiWindow"
ClientMode="StartProgram"
LocalClient="True"
Display="0"

LocalProgram="bash -c &quot;DISPLAY=:0 GTK_IM_MODULE=uim mikutter&quot; &gt; /dev/null 2&gt;&amp;1"

RemoteProgram="xterm"
RemotePassword=""
PrivateKey=""
RemoteHost=""
RemoteUser=""
XDMCPHost=""
XDMCPBroadcast="False"
XDMCPIndirect="False"
Clipboard="True"
ClipboardPrimary="True"
ExtraParams=""
Wgl="True"
DisableAC="False"
XDMCPTerminate="False"/>

実体参照が入ってて分かりにくいですが、デコードするとこんな感じになります。

bash -c "DISPLAY=:0 GTK_IM_MODULE_uim mikutter" > /dev/null 2>&1

標準出力、標準エラー出力を/dev/nullに捨てるのがポイントです。
そうしないとmikutterがコンソールにwarningとか出力するたびに、VcXsrvが「大丈夫?コマンド打つ?」ってダイアログを出してくるので。

起動してみる

さっき作ったmikutter.xlaunchをダブルクリックしてください。いつものmikutterが起動してくると思います。

f:id:moguno:20171008151850p:plain:w400

mikutterが起動したらさっき作ったブラウザを起動するシェルスクリプトを設定します。

(1)ウインドウ右下のネギレンチボタンを押す。
(2)「表示」の「URLを開く方法」に「/opt/mikutter-wsl/bin/start」と入力して下さい。

f:id:moguno:20171008151914p:plain:w400

これで完成です。Windowsでもレッツておくれ!

なお、日本語入力の切り替えはShift + スペースで行います。慣れましょう。

*1:使用頻度の低い公務用PCをスライドさせた感じっす。

*2:トレンディな日本語入力システムである(ibus|fcitx) + mozcは動きませんでした。Macでも定番のX用日本語入力システムはuimだったと思うので、そんなものなのでしょう。

ルータのボタンをワンプッシュ!Raspberry Pi Zero WのWifi接続を簡単に切り替える方法

第1回 全日本ラズパイゼロW争奪戦に運良く勝利して、Raspberry Pi Zero Wを手に入れました。

普段はPimoroniのScroll pHat HDを装着して、無線ルータ経由で為替とか明日の天気とかを取ってきてだらだら流しています。
結構実用的です。

f:id:moguno:20170830221018p:plain:w350

これをテザリングしたスマホに接続して飲み会でデモ(ドヤぁ!ええやろぉ!)をしたかったのですが、いちいちRaspberry Pi Zero Wにコンソールを繋いでWifi設定を変更するのが面倒でした。

なので、WPSを使ってWifi接続を簡単に切り替えられる仕組みを作ることにしました。

WPSって?

Wi-Fi Protected Setup - Wikipedia

ざっくり、ルータと端末の「WPSボタン」を押すことで、両者を設定なしで接続してくれる仕組みです。

しかしながら、Raspberry Pi Zero Wにはボタンみたいな入力デバイスは付いていないので、Raspbianの起動時に、WPSボタンを押したのと同等の状態になるようにしました。

後はお好きなルータのWPSボタンを押すことで、Raspberry Pi Zero WとのWifi接続が確立すると言う寸法です。

設定

これはRaspbianのwithout Desktop版用の設定です。

NICの設定

まずWifiアダプタwlan0を設定します。

/etc/network/interfaces
・・・
allow-hotplug wlan0
iface wlan0 inet dhcp
    wpa-conf /opt/wps/etc/wpa_supplicant/for_wps_button.conf
/opt/wps/etc/wpa_supplicant/for_wps_button.conf
ctrl_interface=/run/wpa_supplicant

普段はやたら面倒なwpa_supplicantの設定ですが、今回はWPSが全てやってくれるので超シンプルですね。

Raspberry Pi Zero W起動時に、WPSボタンを押した感じにするスクリプトを実行する

/etc/rc.local
・・・
/opt/wps/bin/wps_connect.sh &
・・・

スクリプトの中身はこんな感じです。
Raspberry Pi Zero WのLEDを操作して、WPS接続待ちであることが視覚的に分かるようにしました。

/opt/wps/bin/wps_connect.sh
#! /bin/sh

# LEDを100ms周期で点滅させる
echo timer > /sys/class/leds/led0/trigger
echo 100 > /sys/class/leds/led0/delay_off
echo 100 > /sys/class/leds/led0/delay_on

# WPSボタンを押す
/sbin/wpa_cli -i wlan0 wps_pbc

# 5秒周期でWifi接続が確立したかチェックする
while sleep 5;do
	STATUS=`/sbin/wpa_cli -i wlan0 status | grep wpa_state= | cut -d = -f 2`

	case $STATUS in
                # 接続失敗
		INACTIVE)
                        # もう一度WPSボタンを押す
			/sbin/wpa_cli -i wlan0 wps_pbc
			;;

                # 接続成功
		COMPLETED)
                        # LEDを点灯に戻して終了
                	echo "mmc0" > /sys/class/leds/led0/trigger
			exit 0
			;;
	esac
done

使い方

  • Raspberry Pi Zero WにUSB電源を接続してしばらく待つと、オンボードのLEDが短い周期で点滅し始めます。
  • すかさず、ルータのWPSボタン(各社呼び方がバラバラみたいです)を押したり、AndroidスマホWifiテザリング設定画面にある「WPSプッシュボタン」をタップしたりします。

f:id:moguno:20170830220945p:plain:w350
f:id:moguno:20170830220859p:plain:w350

  • 10〜20秒程度でWifi接続が確立し、オンボードLEDが点灯状態になります。

Vimでかっこいいコマンド補完を出す方法

Ubuntu17.04でvimを起動したら、なんか格好いい補完が出るじゃ無いですか。
これはメインマシン(macOS)にも制式採用せねばと、設定を調べました。

f:id:moguno:20170502214550p:plain

set wildmenu
set wildmode=full

textbringer APIメモ

カーソルを動かす

Buffer::goto_line(行)
Buffer::goto_char(列)

goto_char()に1行の文字数以上の値を渡しても、次の行には行かない。

モードラインをナウくする

Face.define(:mode_line, foreground: "blue", background: "#FFFF00", bold: true, reverse: false)

f:id:moguno:20170411233334p:plain

foreground、backgroundにはこの他にCurses::COLOR_BLUEとかColorオブジェクトのインスタンスも渡せるっぽい。

textbringerで時計マクロを書いてみた

textbringerで非同期な処理はどう書けばいいかな?と思って、試しに時計を作ることに。

非同期処理はスレッドを勝手に立てればいいとして、気になるのはオレオレスレッドとUIスレッドとの通信手段です。

GUIツールキットはシングルスレッドを前提に設計されているものも多く、別スレッドから無理に操作をすると、誤動作したりバカよけの例外が発生したりします。
そのため、別のスレッドからUIスレッドに指令を出す「スレッド間通信」が必要になるわけです。

textbringerでは、任意のブロックをUIスレッドで実行してくれるController::next_tick()と言うメソッドが用意されていました。バッチリですね。
(mikutterで言うDelayerですね。)

と、言うわけでこんなコードを書いてみました。
ミニバッファを更新(UI操作)する部分を、next_tick()でUIスレッドにお願いしています。

Thread.new {
  loop {
    sleep(0.5)

    Controller.current.next_tick {
      message("#{Time.now}")
    }
  }
}

下の画像の通り、ミニバッファが時を刻み始めました。
非同期処理なのでキーボード入力など他の操作を阻害することもありません。いい感じです。

f:id:moguno:20170411015126p:plain

おまけ

next_tick()はわかったけど、お前の1tickってなんぼやねん?
=>実測してみましたが、1msっぽいです。

日本発のRuby製テキストエディタ!その名もtextbringer!のマクロを書いてみる

shugo.net

日本発のRubyテキストエディタtextbringer。

Emacsライクな操作性とRubyによる(度の過ぎた)拡張性が今後の大発展を予感させますね。

ちょっと遊んでみたので情報を残しておこうと思います。

GitHubからtextbringerをインストールして起動するまで

gemコマンドでインストールするのが最短ルートですが、ゆくゆくは本体をゴリゴリ触ってみたいのでGithubから持ってきます。

git https://github.com/shugo/textbringer
cd textbringer
bundle install --path vendor/bundle
bundle exec exe/textbringer

マクロを書く

~/.textbringer.rbってファイルが起動時に実行されるので、それにRubyコードを書いて行きます。

vi ~/.textbringer.rb 

注:当方vim

APIを探っていく

マニュアル類はなさげなので、ソースコード(lib/textbringer)を読み解いていきます。

バッファに文字列を挿入する

Buffer.current.insert("test")

最下段(ミニバッファ)に文字列を表示する

Utils::message("moguno")

f:id:moguno:20170408180732p:plain

コマンドを定義する

define_command(:test) {
  insert("test")
}

と書くと、

M-x test

で、バッファに"test"って文字列が挿入されます。
(M-xはEmacs語で「ESCキーを押して離してxキーを押す」ってことらしいです。)

このコマンドの書式。mikutterのcommand DSLに似てますね・・・あっ!

mikutterプラグインを動かしてみる

mikutter。知る人ぞ知るTwitterクライアントですね。

mikutter

プラグインRubyでお手軽に作れるので、なんか変なプラグインがゴロゴロしてるのが特徴です。

と言うことで、mikutterプラグインが使っているPlugin、Message、User、Serviceあたりのクラスをでっち上げて、mikutterのコピペ投稿プラグインを動かしてみました。
思ったよりもあっさり完動。

f:id:moguno:20170409012927p:plain

テキストエディタでヨドバシプラグインを動かす理由はこれから見出すとして、ルール無用でなんでもできちゃうところが、Ruby製プロダクトの魅力ですね。

まとめ

Emacsライクな動きがvim派にはキツイですが、「環境」と呼んで差し支えない大きな拡張性が魅力的です。
今後も触って行きたいと思います。