詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!

コード補完もできる Go の REPL「gore」を作った

Go

タイトルの通りです。Go は LL 的に使える、とはよく申しますが、そういう意識で使っていると REPL 的なことをしたいときに困りがちですよね。そこで作りました。gore。いい名前ですね。

motemen/gore · GitHub

以下のスクリーンキャストでだいたいの雰囲気をお察し下さい。

gore screencast

(スクリーンキャストは cho45/KeyCast を使って撮影しました)

特徴

gore の特徴は以下の通りです。

  • ラインエディタと履歴
  • 複数行入力
  • パッケージのインポート、補完つき
  • 式および文を実行可能
  • コード補完(nsf/gocode を利用)
  • プリティプリント(k0kubun/ppdavecgh/go-spew がおすすめ)
  • ドキュメントも引ける(godoc が必要)

以上のように、非常に便利なものになっております。むしろこの程度 REPL には当然あってほしい機能だとも言える。

インストール

利用には Go 本体が必要なため、バイナリの配布はしていません。

go get github.com/motemen/gore

完全な機能のために、以下のライブラリも別途 go get しておくことをお薦めします。

go get github.com/nsf/gocode # 入力補完に
go get github.com/k0kubun/pp # プリティプリントに
go get golang.org/x/tools/cmd/godoc # ドキュメントに

使い方・機能

gore で起動すると、プロンプトが表示されます。Go の式や文を入力してください。入力された内容が値を返す式や変数の代入となる文であった場合には、よしなに値が印字されます。

gore> n := 1
1
gore> n+1
2

入力がうまく解析できなかったときはプロンプトが ..... となり、続けて入力できます。EOF(^D)でキャンセルします。

gore> even := func(n int) bool {
..... return n % 2 == 0
..... }
func(int) bool {...}
gore> even(4)
true

Go のコードではない指示は、コロンで始まるコマンドで入力できます。:help ですべてのコマンドを一覧できますが、よく使うのはパッケージのインポートを行う :import でしょう。

gore> :import strings
gore> strings.TrimSpace(" foo ")
"foo"

また :write コマンドで、REPL セッションで生成されたコードをファイルに保存することができます。

コード補完

エディタで Go を書いている人は gocode をインストールしていることと思いますが、gore もこれを利用してコード補完を行います。スクリーンキャストにあるように、適当なところで Tab キーを押すことでコードの補完がいい感じになされます。

プリティプリント

ppspew がインポートできる環境であれば、これらを利用して値の表示をおこないます。なければ fmt.Printf("%#v", ...) にフォールバックします。

ドキュメントを引く

:doc コマンドでドキュメントを引けます。名前だけでなく型も見てるので、ある変数のメソッドからドキュメントを引くということもできます。godoc コマンドが必要。

gore> :import encoding/json
gore> :doc json.Decoder
(godoc encoding/json Decoder)
gore> d := json.NewDecoder(nil)
...
gore> :doc d.Decode
(godoc encoding/json Decode)

他の REPL 実装との比較

Go の REPL を作ろうという試みは人類共通のようで、すでにいくつかの実装が存在しています:

以下、これらにの機能について簡単に gore と比較をした表です。

実装 値の表示 インポート 文の入力 アンドゥ 行編集 複数行入力
gore
go-repl
rango
igo
play.golang.org

補足

  • 「値の表示」とは 1 + 1 などと入力したときにその値が表示できること。対応していない実装では "1 + 1 evaluated but not used" などのエラーが表示され、fmt.Println(1 + 1) などとしなければいけません。
  • コード補完、色付きプリティプリントに対応しているのは gore のみです。

注意点

  • REPL といいつつ実は裏ではそれまでの入力を順番に実行するソースコードを生成して go run しているだけなので、どこかの時点で評価に時間のかかるコードを入力すると、その後の入力の評価にも時間がかかるようになります。

以上

紹介した機能のほかに、Go ではインポートしたパッケージが利用されていなかったり未使用の変数があったりするとエラーになる件の回避など、快適な REPL 体験のために細かく調整しています。どうぞご利用下さい。

いつも通りコードは GitHub 上にあります。不審な挙動があったら Issues よりお知らせください。

https://github.com/motemen/gore

Pocket の未読フィードを秘密の URL で公開するウェブサービスを作った

Pocket はあとで読むサービスで、とりあえずの URL を放り込むところとして使っているんだけど、これをほかのサービスとうまく連携しようとすると、IFTTT に対応していないところでは意外と面倒なときがある。今回は未読アイテムのフィードが欲しかった。

Pocket には RSS フィード形式で未読リストにアクセスできる機能がある(ヘルプ)のだけど、これは http://getpocket.com/users/username/feed/unread という URL に Basic 認証でアカウント名とパスワードを入力させるという形であったので、うーん……ちょっと使いたくない。認証を解除して全公開することも選べるが、自分がリストに何を入れているか知ってほしいわけでもない。こういう時はリセット可能な秘密の URL を作ってくれれば取り扱いしやすいだろ、というわけで作った。Pocket の API はシンプルでよい。

作ったのは Pocket Expose というウェブサービス。ログインすると自分用の URL が生成されます。プレーンテキスト(全件)、Atom フィード(最新 20 件)に対応。URL のリセットも情報の消去も簡単にできる。デザインは面倒なので Markdown 風です(笑)

ソースコードは GitHub に。

motemen/pocket-expose-web · GitHub

git-browse-remote で現在のブランチに対応するプルリクエストを一発で開く

マジで……というわけで、現在のブランチや作業ディレクトリなどをもとに いいかんじに GitHub (など)をブラウザで開いてくれる git-browse-remote にこれに対応する機能を追加したバージョン 0.2.0 をリリースしました。

インストール/アップグレード

RubyGems.org にアップロードされているので、

gem install git-browse-remote

でインストールできます。

使い方

git browse-remote --pr

とすると、現在のブランチから発しているプルリクエストのページ(/<user>/<repo>/pull/<branch>)をブラウザで開きます。プルリクエストが存在していればそのページ(/pull/<number>)に、存在していないときはプルリクエストの作成画面になるみたいです。何かにエイリアスしておくと便利ですね。

いまのところ GitHub (および GitHub Enterprise)専用の機能になるけど、Bitbucket にも同様の URL があったら対応できそう。

GitHub でイシューからイシューを作るときに便利な userscript

とくに GitHub を使って仕事をしていると、あるイシューからそのサブイシューを生成する機会がよくあって、そういう時はサブイシューから親イシューを(#765 のようにして)参照しておくと便利なのだけれど、イシューをまとめて整理しているときにはこの細かい作業が面倒。そこで userscript を書いた。

github-userscripts/refer-issue-when-creating at master · motemen/github-userscripts · GitHub

挙動は簡単で、GitHub 上のイシューや Pull Request のページ内にある「New Issue」ボタンをクリックしたとき、イシュー作成フォームの本文やタイトルに、もともとのイシューを参照するような内容がフィルインされるというもの。本文にはイシュー番号、タイトルには元のイシューの名前が入ります。このへんは人の好き好きだと思うので、各自カスタマイズするとよいと思う。また、ボタンのクリック時に選択していた内容がタイトルに付与されるというのもおまけでついてます。

以下のアニメーション GIF を見ればわかりやすい。

f:id:motemen:20150123135611g:plain

いつもどおり、利用するには chrome://extension に .user.js をドラッグ&ドロップすればよい(Chrome の場合)。どうぞご利用ください。

ウェブサイトの Windows 8.1 用ライブタイルを提供する

ライブタイルってのは Windows 8 のスタート画面に表示されてるタイルで、その内容がときどき更新されるものです。アプリをスタート画面にピン留めしておくと、アプリを起動することなしにニュースとか株価とかが表示できるって便利なやつです。Android で言うならウィジェットみたいな感じかな。

Windows ストアアプリでないとこれを提供することはできないと思っていたんだけど、実は Internet Explorer 11 の機能で、ウェブサイトをピン留めし、ライブタイルを表示できることを知ったのでやってみた。

IE11 での Web サイト用ライブ タイルの作成 (Windows) に詳しいドキュメントがある。やることは簡単で、

  1. ライブタイルに表示するための情報を提供する XML (と、それにアクセスするための URL)を用意する
  2. ウェブサイトからその XML をポイントするなど、(ライブ)タイルに関する情報を提供する

ウェブサイトがフィードを提供する場合と似たような感じなので、難しさはない。1. で指定できるタイルの種類は https://msdn.microsoft.com/ja-jp/library/ie/dn456348(v=vs.85).aspx にいろいろ書いてある。2. で URL やポーリング間隔を指定できる。これに関しては

  • meta タグをいくつか書く
  • JavaScript を書く
  • 設定リソースをポイントする

の 3 つの方法がある(https://msdn.microsoft.com/ja-jp/library/ie/bg183312(v=vs.85).aspx)。

実例

次の連休 という、次の連休まであと何日か知ることの出来るウェブアプリで試してみた。次の連休まであと何日か、ウェブサイトにアクセスせずに確認できれば便利なはずである。簡単そうな meta タグによる実装。

meta タグを書き、

<meta name="application-name" content="次の連休">
<meta name="msapplication-notification" content="frequency=60; polling-uri=http://japanese-long-weekends.herokuapp.com/ietile.xml">

XML を提供する: http://japanese-long-weekends.herokuapp.com/ietile.xml

あとは IE でウェブサイトにアクセスし、デスクトップにピン留めすると、

f:id:motemen:20150121135525p:plain

無事スタート画面に次の連休までの日数が表示される……

f:id:motemen:20150121134301p:plain

次の連休は 101 日後です(´;ω;`)ブワッ

格安 Windows タブレットのセットアップ

正月の気の緩みで Windows タブレットを買ってしまった。定価でも 2 万円台、Office のライセンスのないマーケットプレイス出品なら 1 万円台で最新の Windows とタブレットが手に入るのは異様に安い。毎日再起動してるけど、満足の日々を送っている。

所感

  • フル機能の Windows を楽しめるのでとてもよい。
  • Modern UI が結構使いやすい。
    • 画面端からのスワイプが便利。軽快である。
    • 特に Windows ストアアプリはスマートフォンやタブレット向けに全画面表示されるのだけど、画面を分割して表示させることもできる。
    • 画像は Pocket リーダーから URL を開いたら画面が分割されて Internet Explorer が起動したところ。アプリ内ブラウザなんていらんかったんや!という気分になる。
    • f:id:motemen:20150114130323p:plain

  • アプリ(Windows ストアアプリ)があまり充実してない気がする。少なくとも Kindle はない。
    • Twitter などメジャーどころでも評価の低いものが多いのも気になる。
  • Internet Explorer も Modern UI 使ってるけど普通に使えるのでほかのブラウザはインストールしていない。
  • ときどき反応がなくなるので再起動してる。

chocolately でパッケージ管理

Chocolatey Gallery

たぶん Windows 用の Homebrew 的なもの。だいたい Windows はアプリの管理ができなくて大変なことになるので、これを使いたい。メジャーかどうかは判断しかねる。

以下これを使ってインストールしたもの。

  • 7zip
  • autohotkey.portable
    • dropbox のインストールに必要だった。
  • avgantivirusfree
    • 同梱のマカフィーをアンインストールして、こちらを導入。
  • ConEmu
  • dropbox
  • git
  • golang
  • rktools.2003
  • vagrant
  • virtualbox
    • Windows で開発するぜ! と意気込んでいたけど、念のため入れといた。念のためな。

Windows ストアアプリをインストール

その他インストールしたもの

  • gVim は香り屋版がいいだろ、と思うのでこちらからダウンロード。
  • Kindle アプリがないので Kindle Cloud Reader をホーム画面にピン留め。タブレットで読みたいのはだいたい漫画なので、小説が読めないのはまあ我慢できるかな……。TAPL が読めないのにはまいった。

ゲーム

Windows 機ってことはゲームができるんですよ! 8 インチタブレットで普通にプレイできてしまうので感激。

  • 鬼哭街
    • 鬼哭街

      鬼哭街

    • これなんか特に、ただ読むだけなので横画面にして寝っ転がりながら遊べる(読める)。
  • 3Dカスタム少女
    • 低スペック PC でもわりと軽快に動作する救世主。20+ FPS くらいは出ます。

これからセットアップする人に注意! 初回セットアップ時、Microsoft アカウントと連携してはいけない

そして最後に、これが面倒な点。素直な性格なのでセットアップ時に Microsoft アカウントと連携してしまったが、その結果ホームディレクトリのパスに日本語が混じってしまい、以下のような弊害があった。

  • go test できない
    • 作業ディレクトリに日本語が混じってパッケージが発見できなくなる。TMP 環境変数を書き換えればなんとかなる。
    • C:\Users\����\AppData\Local\temp\go-build186010647\github.com\motemen\ghq\_t est\_testmain.go:12: can't find import: "github.com/motemen/ghq" みたいになる。
  • vagrant up できない
    • 文字コード関係のエラーが出るけど日本語が混じってるのがいけないらしい。
    • C:/HashiCorp/Vagrant/embedded/gems/gems/childprocess-0.5.5/lib/childprocess/windows/process_builder.rb:43:in ``join': incompatible character encodings: Windows-31J and UTF-8 (Encoding::CompatibilityError)

途中から変更できないらしいのでこれから再インストールします^^

まとめ

安価に Windows 環境を手に入れました。そして Windows 8.1 けっこう良い。楽しい!

PowerShell を使って .exe ファイルを Windows サービスとして登録する

Windows にはサービスという概念があって、UNIX でいうデーモン的なことはこれを使えば実現できる(MSDNWikipedia)。サービスにはその停止や再起動などの要求に答える責任があるので、それらに対応していないアプリケーションをそのままサービスとして登録することはできないのだけど、任意のアプリケーションのラッパーとなるサービスアプリケーションが Microsoft によって提供されているので、これを使えば実現できる。

前準備

サービスとして登録する PowerShell スクリプト

汎用化はできてなくて、決め打ち。

install-mackerel-agent-service.ps1

これを実行する(PowerShell コンソールを起動して、\Path\To\Script.ps1)と、管理者権限を求める UAC ダイアログが表示されたあと、管理者権限のコンソールが開き、自動で MackerelAgentService というサービスがインストールされる(起動はしない)。表示されたままのコンソールは閉じてもいいし、

sc.exe start MackerelAgentService

でサービスを起動することもできる。

ちなみにサービスの削除は sc.exe delete で可能。

f:id:motemen:20150111145459p:plain

Mackerel への PC の登録、メトリックの投稿ができました。

解説

  • PowerShell の New-Service コマンドレットを使って MackerelAgentService という名前で srvany.exe を登録する。
  • その後レジストリを操作して srvany.exe に渡すパラメータを登録する。このパラメータが、サービス化したいコマンドになってればいいらしい。
    • New-Item と Set-ItemProperty でレジストリを操作できる。これはファイルシステムに対しても同じように使える汎用的なコマンドレット。
  • Start-Process コマンドレットに -Verb RunAs を指定すると、指定したコマンドを管理者権限で実行できる。
  • powershell.exe は -Command "& {<command>}" を指定することで
  • { … } はスクリプトブロックと呼ばれる構文らしい。たぶん文字列化して渡してる気がするんだけど、この辺の正確な理解ができていない……。

参考

ちなみに NSSM - the Non-Sucking Service Manager ってのもあるらしい。