MacVim で日本語入力中に Shift+Space が効かない問題を修正する

問題

  • 私は日本語入力中でも Shift+Spaceで常に半角スペースを入力できるようにしている。
  • この機能はほぼすべてのアプリケーションで問題なく利用可能だが、唯一 MacVim のみで利用不可能であった。MacVim は私のメインエディタなので非常に困っていた。
  • MacVim-Kaoriya ではこの問題が修正されているが、更新が途絶えており可能であれば最新版の MacVim を使用したい。
  • macOS 標準の日本語入力ではなく Google 日本語入力に変更すればこの問題は解決するとする記事もあるが、私の環境では Google 日本語入力でも Shift+Space で半角スペース入力不可であった。

既存の報告

既存の報告もいくつかある。

MacVim-Kaoriya には下のパッチが取り込まれている。このパッチを取り込む形で最新版の MacVim をビルドすればよいと考えた。

commit 6b36374325cbcfe58172edfe95b6bbeff42b3bae
Author: Masayuki Yamaya <yamaya@cyberdom.co.jp>
Date:   Wed Oct 22 23:59:30 2014 +0900

    Fix dont input space with shift on yosemite

diff --git a/src/MacVim/MMTextViewHelper.m b/src/MacVim/MMTextViewHelper.m
index fdc7aaf..3da0c29 100644
--- a/src/MacVim/MMTextViewHelper.m
+++ b/src/MacVim/MMTextViewHelper.m
@@ -187,6 +187,11 @@ KeyboardInputSourcesEqual(TISInputSourceRef a, TISInputSourceRef b)
         // with Ctrl-6 or Ctrl-^ when IM is active.
         [self doKeyDown:@"\x1e"];
         string = nil;
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10)
+    } else if ((flags & NSShiftKeyMask) && [string isEqualToString:@" "]) {
+        // HACK! for Yosemite - Fix for Shift+Space inputing
+        // do nothing
+#endif
     } else {
         // HACK!  interpretKeyEvents: may call insertText: or
         // doCommandBySelector:, or it may swallow the key (most likely the

挿入ファイルと位置: https://github.com/macvim-dev/macvim/blob/35dc1a84c170d9945cd4cda69cafe60999f86824/src/MacVim/MMTextViewHelper.m#L176

ビルド

./configure

ビルドオプションは MacVim の Release 版をビルドしていると思われる Travis CI で指定されているものを利用した。 https://travis-ci.com/github/macvim-dev/macvim/jobs/372444524/config

$ ./configure LANGOPT="--enable-perlinterp=dynamic --enable-pythoninterp=dynamic --enable-python3interp=dynamic --enable-rubyinterp=dynamic --enable-luainterp=dynamic --with-lua-prefix=/usr/local" HAS_GETTEXT=1

2022-12-28 追記: ビルドは GitHub CI に移行したようだ。MacVim GitHub CI における MacVim Release 174 のビルド方法ワークフロー)を参考にビルドオプションを見直した。

configure 前に brew install lua などで lua などをインストールしておく。--enable-pythoninterp=dynamic はうまくいかなかったので除外した。arm64 の設定は ld: symbol(s) not found for architecture arm64 のエラーが出たため除外した。

$ ./configure --with-features=huge --enable-netbeans --with-tlib=ncurses --enable-cscope --enable-gui=macvim --enable-perlinterp=dynamic --enable-python3interp=dynamic --enable-rubyinterp=dynamic --enable-luainterp=dynamic --with-lua-prefix=/usr/local --with-macarchs=x86_64 --enable-fail-if-missing

make

Anaconda を使っている場合は make 前に conda deactivate しておく。 また Xcode をアップデートしてある場合は xcode-select --install しておく。

$ make -C src Vim
$ make

make 中にいくつかのエラーに遭遇したので対処した。

msgfmt: "ISO-8859-1" から "UTF-8" に変換できません. msgfmt は iconv() に依存しています.このバージョンは iconv() なしで作られています.

which gettext したところ Anaconda でインストールしたものが参照されていた。Deactivate して再度 make した。

$ conda deactivate

試行錯誤中に brew install gettext もしたが、おそらく conda deactivate だけでOKで、brew install gettext は不要だったと考える(∵ 公式のビルド説明書に Xcode Tools 以外には依存していないと書かれているので)。

tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

Command Line Tools を使用可能にしていなかったために起きたと思われる。 下のURLを参考に使用可能とした。 https://qiita.com/eytyet/items/59c5bad1c167d5addc68

Xcode を起動→Preferences→Locations→Command Line Tools のリストボックスから Xcode 10.x(現在のバージョンと同一の名称)を選択した。

ちなみにXcodeをアップデートした際は毎回 $ xcode-select --install すべきとのこと。

結果

Shift+Space で半角入力ができる MacVim をビルドすることができた。

2014年頃から存在する問題のようで、Pull Request を送ってもよさそうだが……。

追記

MacVim r179 をインストールしてみたらこの問題が修正されているように見える。しかしどのコミットで修正されたのかは不明。

オフラインの状態で iOS に APN プロファイル設定ファイルを適用する

格安 SIM の使用には APN プロファイルの適用が必要であるものがある。 この設定ファイルはウェブサイトからダウンロード可能となっていることが多いが、たとえば海外に行って海外の SIM を使用したのちに日本に帰ってきた場合、着陸から空港の Wi-Fi が使えるようになるまでの間は日本の SIM が使えないということになる。 特に成田空港ではタキシングに15分程度かかることがあるため、オフラインの状態で APN プロファイルの再設定をすることができるようにしておけば15分早く家族に無事を伝えることができて親孝行である。

ウェブを検索すると、設定ファイルをメールで自分自身に送っておく手法が複数ヒットするが(下に参考URLを掲載する)、メールアプリのキャッシュからいつ消えるかわからないので不安が残る。 https://iwatomo3.blogspot.com/2017/09/iphoneapnsim.html https://www.iphone-kakuyasu-sim.jp/news/no-wifi-iphone-apn/

Pythonista を使えば iOS 内で HTML サーバーを立ち上げることができるので、Safari を開いてそこから設定ファイルをダウンロード可能である。 下のスクリプトと同じディレクトリ内に、事前にダウンロードしておいた設定ファイル(拡張子 .mobileconfig)を配置しておく。実行すると localhost:8080 でディレクトリ内のファイル一覧が見られるので、設定ファイルをタップするといつもの設定適用画面になる。複数の SIM を使い分けている場合は複数の mobileconfig ファイルを置いておけば場合によって使い分けられるだろう。

Spotify API を利用して、ライブラリ内の曲の情報などを保存する

Spotify で曲を保存したりしていても、いつか解約したときにすべて消えてしまうような気がしてつらい。 せめてどんな曲を保存していたかの情報があれば、乗り換え先の音楽サービスで同じものを探すことができるかもしれない。 幸い Spotify は善良なサービスなので、API を公開している。これを利用すれば情報を取得できる。

事前に Spotify for Developers に登録してクライアントIDなどを取得する必要がある。 https://developer.spotify.com/dashboard/login

また、Python から Spotify の情報にアクセスするために、Spotipy というライブラリを利用する。 https://github.com/plamere/spotipy

import sys
import spotipy
import spotipy.util as util

scope = 'user-library-read user-follow-read playlist-read-collaborative playlist-read-private'
username = 'your_username'
token = util.prompt_for_user_token(username, scope, client_id='your_client_id',client_secret='your_client_secret',redirect_uri='http://localhost/')

if not token:
    print("Can't get token for", username)
    sys.exit()

sp = spotipy.Spotify(auth=token)
# Get all saved tracks:

# The result is paginated, so use spotipy.Spotify().next() to retrive all items.
results = sp.current_user_saved_tracks(limit=50)
tracks = results['items']
while results['next']:
    results = sp.next(results)
    tracks.extend(results['items'])

for item in tracks:
    track = item['track']
    print(track['name'] + ' - ' + track['artists'][0]['name'])

# Save: tracks
San Diego - South Park
Once Upon a Time - Toby Fox
Start Menu - Toby Fox
...
Ribcage - Kettel
Bootmens - Kettel
Alacasa (Rolando Simmons Remix) - Kettel
# Get all saved albums:

results = sp.current_user_saved_albums(limit=50)
albums = results['items']
while results['next']:
    results = sp.next(results)
    albums.extend(results['items'])

album_tracks = {}
for album in albums:
    album = album['album']
    print(album['name'] + ' - ' + album['artists'][0]['name'])
    results = sp.album_tracks(album['id'])
    this_album_tracks = results['items']
    while results['next']:
        results = sp.next(results)
        this_album_tracks.extend(results['items'])
    album_tracks[album['id']] = this_album_tracks
    for item in this_album_tracks:
        print(item['name'])

# Save: albums, album_tracks
UNDERTALE Soundtrack - Toby Fox
Once Upon a Time
Start Menu
...
Ribcage
Bootmens
Alacasa (Rolando Simmons Remix)
# Get all followed artists:

results = sp.current_user_followed_artists(limit=50)['artists']
artists = results['items']
while results['next']:
    results = sp.next(results)
    artists.extend(results['items'])

for item in artists:
    artist = item
    print(artist['name'])

# Save: artists
Kettel
Domotic
Casey Abrams
...
Aphex Twin
Juana Molina
I Am Robot And Proud
# Get all playlists:

results = sp.current_user_playlists(limit=50)
playlists = results['items']
while results['next']:
    results = sp.next(results)
    playlists.extend(results['items'])

playlist_tracks = {}
for playlist in playlists:
    print(playlist['name'])
    results = sp.user_playlist_tracks(user=sp.me()['id'], playlist_id=playlist['id'])  # playlist の中身を表示
    this_playlist_tracks = results['items']
    while results['next']:
        results = sp.next(results)
        this_playlist_tracks.extend(results['items'])
    playlist_tracks[playlist['id']] = this_playlist_tracks
    for item in this_playlist_tracks:
        print(item['track']['name'])

# Save: playlists, playlist_tracks
Jazz Favorite
Del Sasser
IDM
...
Words (feat. Bri Tolani) [kr1sh Remix]
Angery
Without Your Love (feat. Ralph Larenzo)
data = {'tracks': tracks, 'albums': albums, 'album_tracks': album_tracks, 'artists': artists, 'playlists': playlists, 'playlist_tracks': playlist_tracks}

import pickle
with open('spotify_data.pickle', mode='wb') as f:
    pickle.dump(data, f)

家事の自動化に必要な投資額とオススメ機種紹介

最近 Twitter で「食洗機買え」「ルンバ買え」の声をよく目にする。たしかにこれらの自動化家電は家事の負担を軽減させ、QoL の向上に寄与する。しかしそれらの声に対して「でもお高いんでしょう」「いろいろあってどれがいいかわからない」と尋ねる声も目にする。そこで、金額やオススメ機種の情報を探しているかた向けに、実際に食洗機・ルンバ・ドラム型洗濯乾燥機を導入してみた自分がそれぞれのオススメを紹介しようと思う。結論から書くと、すべて購入すると工事費をあわせて約 22 万円弱かかるが、それでも購入して損はない。

ロボット掃除機

ロボット掃除機は、1回の掃除で床を完璧に綺麗にするものではない。むしろ毎日動かして綺麗を維持するためのものである。ゆえに、1回の掃除力は高くなくてよく、金額としては安いものでも十分にその役割を果たしてくれる。

そうは言っても、他社製の安いものより Roomba はやはり安定なので、Roomba の最安品がおすすめである。

Roomba 641(2018-07-24 現在、約32000円)

カーペットを使用しない・床に物を置かないなど、生活をロボット掃除機に適したものに変更する必要はある。

食器洗い乾燥機 追記あり

ビルトインでない家庭用食洗機は Panasonic しか製造していないので、選択肢は少ない。 その少ない選択肢の中で、毎日使用する・昼食は外で取る前提を置けば、1-2人で生活するならばプチ食洗で間に合う。 乾燥機能は必須なので、必ず乾燥機能つきのものを選択する必要がある(洗濯機能のみのものは、洗濯完了後に食洗機の蓋を開ける必要があるが、それは自動化としては不十分である。選択完了後に蓋を開けられるような人は家事を自動化しようとは思い立たないはずである)。特殊な洗浄機能は不要である。以上の条件を満たすのは下の1機種のみである。

NP-TCM4(2018-07-24 現在、約40000円)

食洗機購入に際しての注意点としては工事費が別途かかることが挙げられる。本体以外に分岐水栓パーツ代(約1万円強;蛇口の形式によって異なる)+分岐水栓工事代(約1万円弱;業者によって異なる)が別途必要で、本体と合わせて計6万円程度の出費となる。

また、食器についても、この食洗機に入り、かつ食洗機対応の食器を選んで購入・使用する必要がある。

加えて、調理器具(フライパン等)も、T-fal の取っ手が取れるタイプのうち、食洗機対応で、この食洗機に入るものを使用すれば手洗いの手間が省ける。

2019-03-15 追記

2018年9月、水道工事の不要な食洗機が発売された。SKジャパン の SDW-J5L である。

2019年3月現在の価格が約40000円弱と、NP-TCM4と同等かそれ以下の価格であるのに加え、洗浄水の供給がタンク式なので水道工事が不要であるという大きな利点がある。 この利点によって、入居・退去時の水道工事代を削減することができるのに加え、設置自由度が上がるため一人暮らしの狭い台所でも設置場所を見つけることができる(排水はバケツなどを別途購入してそこへすればよい)。

価格・工事不要・設置自由度の点から、前述の NP-TCM4 よりおすすめできる品である。

ドラム型洗濯乾燥機

各社各機種存在するが、基本的な機能はどれも同じである。要は自動で洗濯から乾燥までやってくれればよいので、最安のもので問題ない。

たとえば、BD-SG100BL などで十分用をなすだろう(2018-07-24 現在、約120000円)

これについても食洗機と同様に、ノーアイロンシャツなど、乾燥後に放置してもシワにならない衣服を選ぶ必要はある。

まとめ

上記3機種で、計22万円弱。ロボット掃除機をより低価格なものに抑えれば20万円以内も夢ではない。それでもなかなか高額だが、これらによって家事の時間的・肉体的・精神的負担が激減する。初任給が出たら買って損はないと考える。

グラフィックボードの交換

最近 PUBG というゲームをやっているのだが、グラフィックを最低設定にしても、室内に入ると重くなる・急に振り向くことができない などの問題が生じていてなかなかドン勝を食べることができていなかった。勝てないのは自分の腕のせいではなくグラボのせいにするという PC ゲーマーの旧習に則り、私もグラボのせいにすることにして2011年ごろに購入したグラボを交換することにした。

まずは AMD のドライバを削除する。コントロールパネル の プログラムの変更・削除 から AMD Catalyst Control Center をアンインストール。 また、AMDドライバを完全に削除するユーティリティ を配布している。通常のアンインストールが失敗したら使用せよと書かれているので、コントロールパネルからのアンインストール終了後に1回実行しておこう。

続いて、完全に PC の電源を落として(裏面の電源スイッチまで切る)からグラフィックボードを差し替える。

電源を入れ、新しいドライバを GeForce のサイト からダウンロードしてくる。インストールの際に、標準でインストールしようとしたら失敗した。カスタムから、クリーンインストールする にチェックを入れてインストールしたら正常にインストールされた。

とてもスムーズに交換することができた。ファンが2枚から1枚になったので静音にもなり、足音がよく聞こえるようになった。 PUBG はグラフィック 中 設定で快適に動くようになった。高 でもわりと快適だがところどころひっかかりを感じる。 ちょっとまえに購入して、これまたグラフィック最低設定で遊んでいた Watch_Dogs 2 も高めのグラフィック設定でプレイできるようになったのでサンフランシスコの霧を味わいに行ってこようと思う。

Raspberry Pi 2 を AirPlay サーバーにする

Sharepoint Sync をインストール

本家 の General Build Instructions を参考に必要なライブラリをインストール。 libsoxr は負荷が高いようなので使用しないことにする。

$ sudo apt-get install build-essential git
$ sudo apt-get install autoconf automake libtool libdaemon-dev libasound2-dev libpopt-dev libconfig-dev
$ sudo apt-get install avahi-daemon libavahi-client-dev
$ sudo apt-get install libssl-dev
$ sudo apt-get install libpolarssl-dev

続いて Sharepoint Sync 本体のインストールに移る。

$ git clone https://github.com/mikebrady/shairport-sync.git
$ cd shairport-sync
$ autoreconf -i -f

systemd が走っているシステムなのか System V なのかを次のコマンドで判断。出力に systemd を含むものがあれば前者。

$ ps aux | grep systemd | grep -v grep

コンパイルオプションを指定して make してユーザーを作って make install する。公式の手順に従っているだけ。

$ ./configure --sysconfdir=/etc --with-alsa --with-avahi --with-ssl=openssl --with-metadata --with-systemd
$ make
$ getent group shairport-sync &>/dev/null || sudo groupadd -r shairport-sync >/dev/null
$ getent passwd shairport-sync &> /dev/null || sudo useradd -r -M -g shairport-sync -s /usr/bin/nologin -G audio shairport-sync >/dev/null
$ sudo make install
$ sudo systemctl enable shairport-sync

名前の設定を変更する。

$ sudo vi /etc/shairport-sync.conf

general = {
  name = "AirPi";

}

あとは $ sudo reboot すれば使えるようになるはず。同じネットワークにある iOS 機器 もしくは iTunes から、さきほど設定した名前のデバイスが検出できていることを確認する。

USB オーディオ機器を接続

オーディオの音質を上げるため、USB サウンドデバイスを接続した。手順は ここ を参考にした。デバイスとしては、家にあった UA-4FX を利用した。

まずは何も接続していない状態でサウンドデバイスを確認。

$ cat /proc/asound/modules
0 snd_bcm2835

USB に UA-4FX を接続して、再度確認。

$ cat /proc/asound/modules
0 snd_bcm2835
1 snd_usb_audio

この機器番号 (1) をデフォルトとして使うように alsa のコンフィグを変更し、再起動。

$ sudo vi /usr/share/alsa/alsa.conf
...
defaults.ctl.card 1
defaults.pcm.card 1
...
$ sudo reboot

小型軽量有線USBマウスのケーブルを着脱可能に改造する

動機

ノートパソコンにはトラックパッドが付いているが、長時間のカーソル操作のしやすさではマウスに軍配が上がる。 無線マウスは電池を内蔵しているので重いうえに、使っていないとすぐに省電力モードとなり、動かし始めの最初の数百ミリ秒ではあるが移動に遅れが発生してストレスが溜まるため、小型軽量の有線マウス を常時持ち歩いている。

ところが、このマウスはケーブルが細いため、カバンの中に入れておくと頻繁に断線する。Amazon で購入記録を調べたところ、前回の購入日が 2016-10-30 であり、この記事を書いている 2017-01-21 の数日前に断線したのだから、実質今回は3ヶ月持たなかったことになる。もちろんメーカー保証期間内であるため家電量販店などに持っていけば交換してくれるのだが、交換までに数日・数週間かかるので現実的ではない(再購入のほうが総合的なコストは低いように感じてしまう)。

この状況があまりにもストレスフルだったため、断線したケーブルを取り去って着脱可能となるように改造した。もちろん保証範囲外となるので、試される方は自己責任でお願いします。

端子の選定

Android 端末・カメラ などの充電端子として使われている USB Micro B メス コネクタをマウスにつければ、常時持ち歩いている USB ケーブルを用いてマウスを使用することが可能となる。 ただし、通常の Micro B メス コネクタは表面実装用であるため、手で配線をするのは困難である。よって秋月電子で販売されている ブレッドボード用マイクロBメスUSBコネクタDIP化キット を利用する。

マウスの解体

裏面にある QC と書かれたシールを破るとネジが現れる。このネジを外すとマウス本体のケースを上下に分離できる。

コネクタ取り付け位置の選定

今回はちょうど前方にコネクタを取り付けることができそうなスペースがあった。

Mouse Base Front

周囲のプラスチックを切り落とし、コネクタの基盤も不要な部分は切り落としてその部位に嵌まるように加工する。

Cut USB Connector and Mouse Base

USB Connector Inserted

ケーブルの接続部分は太くなっていることが多いため、周囲をちょっと大きめに切り落としてケーブルとの干渉を防ぐ(このあたりは、いったん作ってみて、ケーブルと干渉した場合に微調整するという方針でよいだろう)。 クリック操作に支障が出ないように注意する。

Mouse After Remodeling Front View

ケーブルの取り外し・再結線

ハンダ吸い取り線を用いて USB ケーブルが基盤に接続されていた部位を切り離し、コネクタの基盤に再配線する。

Mouse Substrate Before Remodeling

New Cables Inserted

USB は通常 4 線なのだが、USB Micro B は 5 線であり、そのうちの 4 番目の線は拡張用なので、導線は 1, 2, 3, 5 番のピンに接続することに注意。

Cables Connected to USB Connector

ケースへの収納

ケースを閉じて、ケーブルを接続し、通常のマウスのように使えたら完成である。 コネクタがきちんとマウス自体に固定されるように、グルーガンや接着材などを使用してもよいかもしれない(ズボラなのである程度ガタガタでも私は許容してしまっている)。

Substrate Inserted

結句

荒療治ではあるが、けっこう簡単にできる加工なので(所要時間2時間弱)オススメである。