csh-no-function

ひょんなことで、Glide Noteさんの Akira Maeda さんが書かれた、

Jumping to the Finder Location in Terminal

という記事を目にしました。
紹介されている Brett Terpstra さんの元の記事も読んでみて、こりゃあ便利だってんで、スクリプトを読んでみると、私の可愛いshellたちのうち、「sh系」と「ksh系」は全てそのままでいけますねぇ。
ならば、「fish」「rc」「csh/tcsh」たちにも何とかしてあげたい、というのが親心というものです。

まずは「fish」から。

function cdf
    set -l target (osascript -e 'tell application "Finder" to if (count of Finder windows) > 0 then get POSIX path of (target of front Finder window as text)')
    if test -d "$target"
        cd "$target"; pwd
    else
        echo 'No Finder window found' >&2
    end
end

function f
    open -a Finder ./
end

こんな感じでしょうか。やっぱり「fish」は書きやすいですね。
続いて「rc」。

fn cdf {
    target=``(){osascript -e 'tell application "Finder" to if (count of Finder windows) > 0 then get POSIX path of (target of front Finder window as text)' | tr -d \n}
    if (!~ $#target 0) {
        builtin cd $target; pwd
    }else{
        echo 'No Finder window found' >[1=2]
    }
    target=()
}

fn f {
    open -a Finder ./
}

# 空白を含むディレクトリに対応
fn prompt {
    cwd=``(){pwd | sed -e s@^$home@~@ | tr -d \n}
    prompt=$LOGNAME'@'$hostname'['$cwd'] '
    autojump -a $PWD >[2=1] >/dev/null
}

「rc」の場合、少しだけ問題があります。
変数をリストとして扱うので、エスケープできないこんなケースの場合、空白を含むフォルダをうまく捌くためには、少々細工が必要でした。
「“(){ ・・・ }」という構文でデフォルトのIFSを一時的に無効にし(デフォルトでは空白/タブ/改行)、最後に「tr -d \n」で改行文字を削除しています。
気付けば「prompt」関数にも問題があったので修正しました。

ところで・・・

それよりも何よりも、最大の困ったちゃんが「csh/tcsh」なのです。
この子たちには関数自体が無いので、aliasで組むしか無いのですが、このくらいの量になると、エスケープがもう大変で大変で・・・
別途シェルスクリプトを組めば済む話ではありますが、ここまで来てそれでは面白くありません。
でも何度書き直してもうまく動かず、困り果てて諦めかけたその時、こちらの記事の中に解決案がありました。

alias function '\\
 <<"end function" sed -e '"'"'\\
#\\!/bin/sed -f\\
#\\
## Make the eval command\\
# quote quotes\\
s/'"'"'"'"'"'"'"'"'/'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'/g;\\
# enclose with quotes\\
1s/^/eval '"'"'"'"'"'"'"'"'/;\\
$s/$/'"'"'"'"'"'"'"'"'/;\\
#\\
## Make the alias command\\
# escape exclamation marks and newlines\\
s/\\!/\\\\!/g;\\
s/$/\\\\/g\\
# quote quotes\\
s/'"'"'"'"'"'"'"'"'/'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'/g;\\
# enclose with quotes\\
1s/^/alias @alias_name@ '"'"'"'"'"'"'"'"'/;\\
$a\\\
;echo >/dev/null'"'"'"'"'"'"'"'"'\\
#^^^^^^^^^^^^^^^ (workaround against printing of arguments)\\
'"'"' | \\
 sed -e s/@alias_name@/\!\!:1/ >/tmp/make_alias$$; \\
 source /tmp/make_alias$$; \\
 rm /tmp/make_alias$$; \\
'

元の記事からは少し編集しています。
要するに、「function」がないなら、「function」のような定義のできる「alias」を作っちゃえって事ですね。よね?
最初見た時は冗談か何かだと思いました。(汗)

これをひとまず「.cshrc」に置いてから、

function cdf
    set target=`osascript -e 'tell application "Finder" to if (count of Finder windows) > 0 then get POSIX path of (target of front Finder window as text)'`
    if ( $%target > 0 ) then
        cd "$target"; pwd
    else
        echo "No Finder window found"
    endif
    unset target
"end function"

alias f 'open -a Finder ./'

何度読み直しても不思議で仕方が無いのですが、こうすれば動きます。動くんです。
空白を含むフォルダも大丈夫だというおまけまでついて。

それにしても世の中には凄い方が数多くいらっしゃいますねぇ。
日頃の感謝を気持ちを込めて、ありがとうございます。

 

csh-no-function」への1件のフィードバック

  1. ピンバック: Hello, world! | VivaFan通信

コメントをどうぞ