2014/06/17


peco に custom-matcher という仕組みを入れて頂きました。
User CustomMatcher by mattn - Pull Request #65 - lestrrat/peco - GitHub
https://github.com/lestrrat/peco/pull/65
~/.config/peco/config.json に以下の様に CustomMatcher を追加します。
{
    "CustomMatcher": {
        "C/Migemo": [
            "c:/dev/peco-cmigemo/peco-cmigemo.exe",
            "$QUERY"
        ]
    }
}
例は Windows ですが、unix でも動きます。配列部分は実行するコマンド引数になり、$QUERY がクエリになります。
CustomMatcher は自作する事が出来ます。標準入力から行を読み込み、引数をパターンとして絞りこんだ結果を標準出力に吐き出せばOKです。いわゆる自前 grep ですね。
以下のリポジトリに cmigemo を使った CustomMatcher を置きました。
mattn/peco-cmigemo - GitHub
https://github.com/mattn/peco-cmigemo
これをビルドした実行モジュール peco-cmigemo と cmigemo が使う辞書(UTF-8である必要があります)は同じ位置に dict/migemo-dict という形で置く必要があります。
peco-cmigemo
欲しかった機能の殆どが peco に入ってきたし、かなり便利になった。

2014/06/12


Windows ユーザのごく一部には、コマンドプロンプトが無いと生きられない民族がいます。そしてその民族の一部には cygwin や msys bash 等といった、サードパーティなシェル(powershell?何それ聞こえなーい)を使いたがらない種族もいます。
私もその種族なのですが、今日はそういった世界中のWindowsエンジニアの中でも数パーセントしかいないであろう人達にとって便利なTipsを紹介したいと思います。(オマケでbash連携もあるよ)
lestrrat/peco - GitHub
https://github.com/lestrrat/peco
peco
以前、私も同じようなツールとして gof というのを作りましたが、peco はこれをもっと簡素に、もっとカスタマイザブルにした物になります。
一見、UNIX でしか動作しなさそうに見えますが、gof ど同様に Windows でも動作します。マルチバイト文字列も扱えます(ただし標準入力は utf-8 にする必要があるので必要な方は iconv コマンドや nkf コマンドをパイプに加えて下さい)。
peco の動作は非常にシンプルで、標準入力から与えられた行を UI で選択し、選んだ行を標準出力に書き込みます。キーのカスタマイズも出来ますので、詳しく知りたい方は上記リンクを参照下さい。

で、Windows でこの peco をどう使うかですが、今回 pcd というコマンドを作ってみました。
@echo off

if "%1" equ "add" (
  if "%2" neq "" (
    echo %2 >> "%USERPROFILE%\.peco-cd"
    goto end
  )
  goto usage
)
if "%1" equ "edit" (
  goto edit
)
if "%1" neq "" (
  goto usage
)
goto query

:usage
echo %0 [add PATH ^| edit]
goto end

:edit
if "%EDITOR%" neq "" (
  "%EDITOR%" "%USERPROFILE%\.peco-cd"
  goto end
)
notepad "%USERPROFILE%\.peco-cd"
goto end

:query
rem NOTE:
rem
rem If you have a problem caused by character-set, modify below part like:
rem   'type ^"%USERPROFILE%\.peco-cd^" ^| iconv -f char -t utf-8 ^| peco'
rem
for /f %%i in ('type ^"%USERPROFILE%\.peco-cd^" ^| peco') do (
  cd %%i
  break
)

:end
良く使うフォルダに簡単に移動できるコマンドです。まず良く移動するフォルダを登録します。
C:\>pcd add c:\vagrant
C:\>pcd add c:\users\mattn\vimfiles
めんどくさい人は
C:\>pcd edit
とするとエディタが起動し、そこで編集出来ます。そして
C:\>pcd
とすると
pcd
peco が起動しますのでそこで移動したいフォルダを絞り込み、ENTER で確定するとそのフォルダに移動できます。
面倒な手順が省略できて便利かと思います。

またこれを応用すると golang を使った開発も便利に出来ます。
ghqを使ったローカルリポジトリの統一的・効率的な管理について - delirious thoughts
http://blog.kentarok.org/entry/2014/06/03/135300
上記の記事では UNIX シェルコマンドが紹介されていますが、これを Windows のバッチファイルで書くと以下になります。
peco-ghq.bat
@echo off

for /f %%i in ('ghq list -p ^| peco') do (
  cd %%i
  break
)
これで、「peco のソースを確認したい」と思ったら何時でも何処でも「peco-ghq」を実行するだけで
peco-ghq
peco のフォルダへ移動する事が出来ます。

番外編

基本的に perco や peco は zsh と連携して使用される事が多いですが bash でも問題なく使えます。例えば以下を $HOME/.bashrc に追加しておけば <C-x><C-g> で ghq による github リポジトリ作業フォルダへの移動が、<C-x><C-r> でコマンド履歴の選択が行える様になります。
select-ghq() {
  DIR=$(ghq list -p | peco)
  [ -n "$DIR" ] && cd $DIR
}
select-history() {
  CMD=$(history | sed 's/^\s[0-9]\+\s*//' | peco)
  [ -n "$CMD" ] && cd $CMD
}
bind '"\C-x\C-g":"select-ghq\n"'
bind '"\C-x\C-r":"select-history\n"'
なお、peco は golang で開発されており、exe ファイル1個だけあればランタイム等は必要ありません。

2014/06/03


元ネタ
「:」を引数の名前と型の間に入れられるようしたりにする魔改造 - moriyoshiの日記

とある言語が func halfOpenRangeLength(start: Int, end: Int) -> Int { return end - start } println (halfOpe...

http://moriyoshi.hatenablog.com/entry/2014/06/03/114845
Go のソースを落としてきて
diff -r fde405c62fca src/cmd/gc/lex.c
--- a/src/cmd/gc/lex.c  Tue Jun 03 11:44:17 2014 +0900
+++ b/src/cmd/gc/lex.c  Tue Jun 03 12:49:01 2014 +0900
@@ -1308,6 +1308,11 @@
        if(c >= Runeself) {
            ungetc(c);
            rune = getr();
+           if (rune == 0x261c) {
+               c = LCOMM;
+               goto lx;
+           }
+
            // 0xb7 · is used for internal names
            if(!isalpharune(rune) && !isdigitrune(rune) && (importpkg == nil || rune != 0xb7))
                yyerror("invalid identifier character U+%04x", rune);
を当てて
$ (cd src/cmd/gc && rm y.tab.h && make)
とする。
package main

import (
    "fmt"
)

func main() {
    鼻 := make(chan string)
    go func() {
        鼻 ☜ "ハナクソ"
    }()

    fmt.Println(☜鼻)
}
$ go run test.go
ハナクソ
どーん