Help us understand the problem. What is going on with this article?

ディレクトリ一覧を文字数でソートする

More than 3 years have passed since last update.

概要

pecoは僕の生活の中で欠かせないものとなっています。
導入やその他は過去にも記事を書いたので良かったら参考にしてください。

そのうち、履歴からディレクトリ移動をするものがあったのですが、少し不満があったので改良しました。

不満点

# ### search a destination from cdr list
function peco-get-destination-from-cdr() {
  cdr -l | \
  sed -e 's/^[[:digit:]]*[[:blank:]]*//' | \
  peco --query "$LBUFFER"
}

### search a destination from cdr list and cd the destination
function peco-cdr() {
  local destination="$(peco-get-destination-from-cdr)"
  if [ -n "$destination" ]; then
    BUFFER="cd $destination"
    zle accept-line
  else
    zle reset-prompt
  fi
}
zle -N peco-cdr
bindkey '^x' peco-cdr

今まで上のようなコードを書いていたのですが、これだと履歴の順番で表示されます。
これはこれで便利なのですが、よく以下の様な状態になったりします。

~/a/b/c/d/
~/a/b/
~/a/b/e/
~/a/b/c/
~/a/

このとき、~/a/に移動したかった場合、絞り込む方法がありません。(少なくとも僕の知る限りでは)
なので、いちいちカーソルを移動するか、適当に~/a/b/に移動してからcd ..したりしていました。

改良

なので、表示される順番を文字数でソートするようにしました。

# ### search a destination from cdr list
function peco-get-destination-from-cdr() {
  cdr -l | \
  sed -e 's/^[[:digit:]]*[[:blank:]]*//' | \
  awk '{c=gsub("/","/"); print c,length($0),$0}' | \
  sort -n | \
  cut -d' ' -f1- | \
  peco --query "$LBUFFER"
}

### search a destination from cdr list and cd the destination
function peco-cdr() {
  local destination="$(peco-get-destination-from-cdr)"
  if [ -n "$destination" ]; then
    BUFFER="cd $destination"
    zle accept-line
  else
    zle reset-prompt
  fi
}
zle -N peco-cdr
bindkey '^x' peco-cdr

単純にawkで'/'の数と文字数を足して、ソートして、文字数の部分をcutしてからpecoに渡しているだけです。
処理速度が気になるところですが、自分の環境だとそこまで遅くないのでとりあえずこのままにしています。

これで上記の例だと以下のように表示されるので~/a/に行きやすくなりました!

~/a/
~/a/b/
~/a/b/e/
~/a/b/c/
~/a/b/c/d/

改良

このままだと消去したディレクトリも記録に残っているので、それが上位に来てしまい邪魔になってしまいます。
そこで下記のスクリプトで定期的に存在しないディレクトリをcdrの記録から除去します。

#!/bin/sh

CDRFILE=~/.chpwd-recent-dirs
TMPFILE="$CDRFILE-tmp"
# exec < $CDRFILE
while read line; do
  dir=$(echo $line | sed -e 's/\$//g')
  # sed -e 's/'\''/"/g' |sed -e 's/\$//g')
  eval test -d $dir
  if [ $? -eq 0 ]; then
    echo $line
  fi
done < $CDRFILE > $TMPFILE

mv -f $TMPFILE $CDRFILE

問題点

これの問題点というか不満は、文字数でソートしているので最初の画面に/,~,/var,'/etc'などで埋め尽くされる点です。
移動先の名前をある程度覚えていないと使えないです。
ただ、まあ文字数順=ディレクトリ構造の順ともいえるので、
us loとかで /usr/local/がヒットし、上の方は/usr/local/以下の子ディレクトリが表示されるのでそこまで不満では無いのですが…

vintersnow
情熱のない大人になってしまった
http://vintersnow.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした