5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-04-12

概要

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/以下の子ディレクトリが表示されるのでそこまで不満では無いのですが…

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?