Humanity

Edit the world by your favorite way

3.5 特殊なコマンドラインを作る

Windowsだったら、ckw + nyaos使いましょう。
正直コマンドプロンプトでどうにかできる人を尊敬すらしてます。

あと一応言うと、ckwは端末、nyaosはシェル。
Linuxで言えば、GNOME Terminalは端末、zshはシェル。


まずせめて^R、これはbashzshでも同じキーバインドとしてありますが、
過去実行したコマンドを検索して実行できます。
これのおかげでaliasとか「地道な」技に頼るよりも、
検索性を考えて、ちょっとだけ長いコマンドでも、
そのまま打ってあとですぐに使い回せるようにしたほうがお得です。
これdankogaiさんも同じこと言ってて、多分それに影響を受けたんだと思います。


追記: これは勘違いで、今のnyaosでもできることでした。
すみませんid:zetamattaさん!
いつもnyaos使わせてもらってますありがとうございます!


あと、nyaosのちょっとした不満点として、
^Rで検索した後にその履歴を編集できないことです。
引数を一部だけ変えて実行したい場合はけっこうあるので、
ぜひとも可能になってほしいです。

なので、ブログでリクエスト要求はlazyすぎると感じながらも、
id:zetamattaさん、nyaosにこういう機能がほしいのですがどうですか?


さて、Linuxコマンドライン環境だったら選択肢はいろいろあります。
とりあえず端末から。

日本語をうまく扱うために、GNOME Terminalが一番だと感じました。
あとGNOMEインストールすればついてくるし。

ただ、デフォルトではEast Asian Width Class Ambiguous な文字
(ユーロ、登録商標記号、著作権記号、ギリシャ文字キリル文字など)
の扱いに難があります。
具体的に言うと「□」などの幅がずれます。(1バイト分しか幅をとらせてくれない)

と言ってもこれらの文字は幅がAmbiguousなので、
環境によって幅が違ったりするらしく
「難がある」というのは身勝手すぎる気がしますが。

なお、Vimでは'ambiwidth'オプションでどう表示するかを変えられます。
詳しくは :help 'ambiwidth' で。


GNOME Terminalでこれを回避するには
「システム→設定→既定のプログラム→システム→コマンド」
の入力欄に

VTE_CJK_WIDTH=1 gnome-terminal --disable-factory

のようにします。

これはShougoさん経由で知ったネタで、
第18回 あえてターミナルを使う(1):ターミナルに関する設定:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社
で知りました。


次にシェルですが、zsh一択です。
というのも、id:hchbawさんのauto-fu.zshが強力すぎるためです。
これはパスなどを自動補完してくれます。

これはzshの補完関数の挙動が悪いのですが、
たまに自動補完してほしくない部分を自動補完されて
入力中のコマンドラインが壊されてしまうといった状況にたまたま陥ります。

なので、始めから言っておくと、Ctrl-Cでauto-fu.zshの自動補完を無効にできます。
なので慣れると「なんか危っかしいな...」と思う状況がだいたいわかってくるので、
そういった場所ではCtrl-Cを押します。

なんだかめんどくさそうと感じるかもしれませんが、
こういったケースはほとんどないです。
あと悪いのはそういう補完関数を書いた奴です。
Vimと同じで、慣れれば便利、です。


最後にauto-fu.zshの設定を貼っておきます。

if [ -f "$HOME/.zsh/auto-fu.zsh/auto-fu.zsh" -a "$MY_CURRENT_ENV" != "cygwin" ]; then
    unsetopt sh_word_split
    zstyle ':completion:*' completer _oldlist _complete _expand _match _prefix _approximate _list _history

    AUTO_FU_NOCP=1 source $HOME/.zsh/auto-fu.zsh/auto-fu.zsh

    # enable.
    zle-line-init () {
        auto-fu-init
    }
    zle -N zle-line-init


    # http://d.hatena.ne.jp/tarao/20100823/1282543408
    #
    # delete unambiguous prefix when accepting line
    function afu+delete-unambiguous-prefix () {
        afu-clearing-maybe
        local buf; buf="$BUFFER"
        local bufc; bufc="$buffer_cur"
        [[ -z "$cursor_new" ]] && cursor_new=-1
        [[ "$buf[$cursor_new]" == ' ' ]] && return
        [[ "$buf[$cursor_new]" == '/' ]] && return
        ((afu_in_p == 1)) && [[ "$buf" != "$bufc" ]] && {
            # there are more than one completion candidates
            zle afu+complete-word
            [[ "$buf" == "$BUFFER" ]] && {
                # the completion suffix was an unambiguous prefix
                afu_in_p=0; buf="$bufc"
            }
            BUFFER="$buf"
            buffer_cur="$bufc"
        }
    }
    zle -N afu+delete-unambiguous-prefix
    function afu-ad-delete-unambiguous-prefix () {
        local afufun="$1"
        local code; code=$functions[$afufun]
        eval "function $afufun () { zle afu+delete-unambiguous-prefix; $code }"
    }
    afu-ad-delete-unambiguous-prefix afu+accept-line
    afu-ad-delete-unambiguous-prefix afu+accept-line-and-down-history
    afu-ad-delete-unambiguous-prefix afu+accept-and-hold
fi

このように ~/.zsh/auto-fu.zsh に保存して、
存在してたら有効にするようにしています。

ちなみに$MY_CURRENT_ENVは次のようになってて、環境を特定するために使っています。

MY_CURRENT_ENV="$(perl -e 'print $^O')"

自分の環境

Windows: ckw + nyaos
Linux: GNOME Terminal + zsh + auto-fu.zsh