Skip to content

Instantly share code, notes, and snippets.

@mobp
Created March 31, 2010 02:08
Show Gist options
  • Save mobp/349846 to your computer and use it in GitHub Desktop.
Save mobp/349846 to your computer and use it in GitHub Desktop.
line-mode directory browser(unstable)
#!/bin/bash
:<<'#license'
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
#license
:<<'#version'
0.0.1
#version
:<<'#keybind'
Default key bind is vi-like
press h => move up directory
press l(L) => chenge directory or edit file or execute file
press j => move up line
press k => move down line
press e => select next file
press b => select prev file
press : => eval mode
#keybind
#########################################################
declare STATUS=$(basename $(pwd)) # カレントディレクトリの名前
declare -a DIR=() # カレントディレクトリのファイルを一つづつ格納
declare -a LINE=() # DIRの要素を1行づつにくぎった値
declare -i array_length=0 # DIR配列の最大値
declare -i updown=0 # LINEの添字につかう
dir_read()
{
array_length=0
local -i i=0
local -i length=0
DIR=($(ls -F))
for DIR in ${DIR[@]};
do
if [ $length -ge 40 ]; then
LINE=("${LINE[@]}" $(expr $i - 1))
array_length=$(expr $array_length + 1)
length=0
fi
length=$(expr $length + ${#DIR[$i]})
i=$(expr $i + 1)
done
LINE=("${LINE[@]}" $(expr $i - 1))
array_length=$(expr $array_length + 1)
}
#行のクリアとカーソルのポジションを先頭に移動する
line_erase()
{ # \x1B[ => 16進数表記のESC文字
printf "\x1B[2K\x1B[1G" # 2K => カレント行の削除
}
declare -a word=(0 1)
declare -i x_max=0
body_print()
{
word=(0 1)
x_max=0
local -i i=0
local -i word_length=0
if [ $updown -eq 0 ]; then
while [ $i -lt ${LINE[0]} ];
do
printf "%s " ${DIR[$i]}
word_length=$(expr $word_length + ${#DIR[$i]})
word=("${word[@]}" $word_length)
i=$(expr $i + 1)
x_max=$(expr $x_max + 1)
done
else
i=$(expr ${LINE[$(expr $updown - 1 )]})
while [ $i -lt ${LINE[$updown]} ];
do
printf "%s " ${DIR[$i]}
word_length=$(expr $word_length + ${#DIR[$i]})
word=("${word[@]}" $word_length)
i=$(expr $i + 1)
x_max=$(expr $x_max + 1)
done
fi
}
line_print()
{
printf "< %-6s > " ${STATUS:0:6}
printf "\x1B[?25l"
body_print
printf "(%3d/%3d)" $(expr $updown + 1) $array_length
printf "\x1B[?25h"
printf "\x1B[10G"
}
move_cursor()
{
if [ $cursor_move_flag -ne 0 ]; then
if [ $x -gt $x_max ]; then
x=$(expr $x_max - 1)
elif [ $x -le 0 ]; then
x=0
elif [ $x -eq 0 ]; then
printf "\x1B[10G"
printf "\x1B[0C"
elif [ $x -eq 1 ]; then
printf "\x1B[10G"
printf "\x1B[2C"
else
printf "\x1B[10G"
printf "\x1B[%dC" $(expr ${word[$x]} + $x + 1)
fi
fi
}
line_down()
{
updown=$(expr $updown + 1)
if [ $updown -gt $(expr $array_length - 1) ]; then
updown=$(expr $updown - 1)
fi
}
line_up()
{
updown=$(expr $updown - 1)
if [ $updown -le -1 ]; then
updown=0
fi
}
declare -i cursor_move_flag=0
declare -i x=0
file_select()
{
local file
file=$(body_print | awk -v position="${x}" '{printf $position}' | tr '\*' ' ')
if [ -d "$file" ]; then
cd "$file" >/dev/null 2>&1
STATUS=$(basename $(pwd))
updown=0
dir_read
x=0
elif [ -x "$file" ]; then
line_erase
read -p "Do you want to run $file ? y/n: " anser
case $anser in
'y')
./"$file"
;;
'n')
:
;;
*)
;;
esac
elif [ -f "$file" ]; then
vim "$file"
fi
}
dir_read
line_erase
line_print
while :
do
read -s -n1 c
case $c in
'j')
line_down
x=0
line_erase
line_print
;;
'k')
line_up
line_erase
line_print
x=0
;;
'q')
break
;;
'h')
{ #もどるボタン( < )を押したっぽくみせる
printf "\x1B[1G"
sleep 0.1
printf "\x1B[10G"
}
#pushdするかどうかの判断
if [ "$STATUS" != "/" ]; then
pushd . >/dev/null 2>&1
cd ..
STATUS=$(basename $(pwd))
updown=0
fi
dir_read
x=0
line_erase
line_print
;;
"l")
if [ $cursor_move_flag -eq 0 ]; then
popd >/dev/null 2>&1
STATUS=$(basename $(pwd))
updown=0
dir_read
x=0
else
file_select
fi
line_erase
line_print
;;
'e')
x=$(expr $x + 1)
cursor_move_flag=1
move_cursor
;;
'b')
x=$(expr $x - 1)
move_cursor
;;
':') #入力した文字列をevalする
line_erase
read -e -p ": " command; eval "$command"
line_erase
line_print
;;
esac
done
line_erase
printf "\x1B[1Gbye!\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment