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個だけあればランタイム等は必要ありません。
Posted at by



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
ハナクソ
どーん
Posted at by



2014/05/29


どうしても高速なWeb サーバが書きたくなったので joyent の libuvhttp-parser (nodejs が内部で使っているライブラリ)を使ってWeb サーバを書いてみた。
mattn/http-server - GitHub
https://github.com/mattn/http-server
I/O は全て非同期で行いブロッキングしない作りとしました。これで絶対速くなるとは言わないけど、少なくともスケールはするんじゃないかと思います。
Date ヘッダとか、65536 バイト以上の POST ペイロードとか色々省いてるのでツッコミビリディ高いですが、ひとまず GET でファイルのサーブが出来る状態にはしたのでベンチマークを取ってみました。

# nginx
$ ab -k -c 10 -n 10000 http://127.0.0.1/

# http-server
$ ab -k -c 10 -n 10000 http://127.0.0.1:7000/
Core i5/3GHz Ubuntu 14.04

5回程計測した平均で nginx が 25000req/sec、http-server が 24500req/sec でした。ほぼ互角までは来たのかなーと思います。
現状キャッシュなんかは考えてないので、純粋に非同期に拘っただけのコードになっています。

ちなみに mruby-uvmruby-http で書いたWebサーバはLinux で 9000req/sec、Windows(Core i5/3GHz)で 5000req/sec くらいしか出ませんでしたが、全てC言語で書いたこのサーバだと Linux 24500req/sec、Windows でも 15000req/sec は出ます。

研究材料として使って行こうと思います。
Posted at by