├── .gitignore ├── img └── gif.gif ├── install.sh ├── README.md └── cdi.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ -------------------------------------------------------------------------------- /img/gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonioolf/cdi/HEAD/img/gif.gif -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | INSTALL_PATH="/usr/local/bin" 4 | 5 | install() { 6 | uninstall 7 | 8 | SCRIPT_URL="https://raw.githubusercontent.com/antonioolf/cdi/master/cdi.sh" 9 | TMP_FILE="$(mktemp)" 10 | 11 | if [ ! -d "$INSTALL_PATH" ]; then 12 | sudo mkdir -p $INSTALL_PATH 13 | fi 14 | 15 | echo "Downloading CDI..." 16 | 17 | wget -q --show-progress -O "$TMP_FILE" "$SCRIPT_URL" && 18 | sudo mv $TMP_FILE "$INSTALL_PATH/cdi.sh" 19 | 20 | # Add execution permission 21 | sudo chmod +x "$INSTALL_PATH/cdi.sh" 22 | 23 | # Appends alias for cdi execution in .bashrc file and source it 24 | echo " 25 | 26 | alias cdi='. $INSTALL_PATH/cdi.sh' 27 | 28 | " >> ~/.bashrc 29 | . ~/.bashrc 30 | } 31 | 32 | uninstall() { 33 | # Deletes cdi script from installation folder 34 | sudo rm -f "$INSTALL_PATH/cdi.sh" 35 | 36 | echo "Removing older versions of CDI" 37 | # Remove alias for cdi in in .bashrc 38 | sed '/alias cdi=/d' -i ~/.bashrc 39 | . ~/.bashrc 40 | } 41 | 42 | install 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # CDI - Change directory interactive 3 | 4 | Don't waste more time in the terminal browsing folders with CD 5 | 6 | ![CDI in action](img/gif.gif) 7 | 8 | ## Installation 9 | 10 | #### Automatic installer 11 | 12 | Copy paste and run in your terminal 13 | ```bash 14 | curl -fsSL https://raw.githubusercontent.com/antonioolf/cdi/master/install.sh | bash 15 | ``` 16 | 17 | #### Manual installation 18 | If you prefer to install it manually, the process is also very simple, it can be done with just two steps. 19 | 20 | - Download the main **CDI** script [cdi.sh](https://raw.githubusercontent.com/antonioolf/cdi/master/cdi.sh) and place it in the `/usr/local/bin` directory (or any other of your choice). 21 | - Add an alias for the script to your `.bashrc` file as follows: 22 | ```bash 23 | alias cdi='. /usr/local/bin/cdi.sh' 24 | ``` 25 | 26 | - Run `source ~/.bashrc` for the change to take effect 27 | 28 | ## Usage 29 | 30 | Just type `cdi` 31 | 32 | ## Contributing 33 | Pull requests and issues are welcome! 34 | 35 | ## License 36 | [MIT](https://opensource.org/licenses/MIT) 37 | -------------------------------------------------------------------------------- /cdi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # CDI - Change Dir Interactively 4 | # Don't waste more time in the terminal browsing folders with CD 5 | 6 | # helper function to colorize terminal text 7 | color_print() { 8 | # function call syntax 9 | # print_color "text to print" 10 | 11 | # Foreground colors 12 | get_foreground() { 13 | case $1 in 14 | 'black') printf "\033[30m" ;; 15 | 'red') printf "\033[31m" ;; 16 | 'green') printf "\033[32m" ;; 17 | 'orange') printf "\033[33m" ;; 18 | 'blue') printf "\033[34m" ;; 19 | 'magenta') printf "\033[35m" ;; 20 | 'cyan') printf "\033[36m" ;; 21 | 'gray') printf "\033[37m" ;; 22 | *) printf "\033[39m" ;; # default or anything else 23 | esac 24 | } 25 | 26 | # Formatting 27 | get_formatting() { 28 | case $1 in 29 | 'bold') printf '\033[1m' ;; 30 | 'underline') printf '\033[4m' ;; 31 | 'bold-underline') printf '\033[4m\033[1m' ;; 32 | *) printf '\033[22m\033[24m' ;; # code 22 to disable bold, 24 for underline 33 | esac 34 | } 35 | 36 | # Background colors 37 | get_background() { 38 | case $1 in 39 | 'black') printf '\033[40m' ;; 40 | 'red') printf '\033[41m' ;; 41 | 'green') printf '\033[42m' ;; 42 | 'orange') printf '\033[43m' ;; 43 | 'blue') printf '\033[44m' ;; 44 | 'magenta') printf '\033[45m' ;; 45 | 'cyan') printf '\033[46m' ;; 46 | 'light-gray') printf '\033[47m' ;; 47 | 'gray') printf '\033[100m' ;; 48 | 'light-red') printf '\033[101m' ;; 49 | 'light-green') printf '\033[102m' ;; 50 | 'yellow') printf '\033[103m' ;; 51 | 'light-blue') printf '\033[104m' ;; 52 | 'light-purple') printf '\033[105m' ;; 53 | 'teal') printf '\033[106m' ;; 54 | 'white') printf '\033[107m' ;; 55 | *) printf '\033[49m' ;; # default or anything else 56 | esac 57 | } 58 | 59 | FORE=`get_foreground $2` 60 | BACK=`get_background $4` 61 | FMT=`get_formatting $3` 62 | 63 | printf "$FORE$BACK$FMT$1\n" 64 | # reset all formatting, can be combined to a single line for reduced code 65 | printf '\033[39m' # default foreground 66 | printf '\033[49m' # default background 67 | printf '\033[22m\033[24m' # default formatting 68 | } 69 | 70 | print_folders() { 71 | # $1 = current_dir 72 | # $2 = current_selection 73 | 74 | # List files and filter only those ending with "/" 75 | array=($(ls -p $1 | grep /)) 76 | folders_list_size=$((${#array[@]}-1)) 77 | 78 | if [ "${#array[@]}" -ne 0 ]; then 79 | for i in "${!array[@]}"; do 80 | if test "$i" -eq $2; then 81 | # echo -e "\033[1m→ ${array[i]}\033[0m" 82 | printf "→ " # print selection arrow on same line 83 | color_print "${array[i]}" green bold-underline 84 | else 85 | # echo " ${array[i]}" 86 | color_print " ${array[i]}" 87 | fi 88 | done 89 | else 90 | #echo -e 'No folders here, press \033[1m←\033[0m to back' 91 | color_print 'No folders here, press ← to back' red 92 | fi 93 | } 94 | 95 | print_status() { 96 | #echo -e "[ \033[1m$1\033[0m ]\n" 97 | color_print " [ $1 ]\n" orange bold 98 | #echo -e "Selection $2 \n" 99 | } 100 | 101 | get_selected_folder() { 102 | # $1 = current_dir 103 | # $2 = current_selection 104 | 105 | array=($(ls -p $1 | grep /)) 106 | for i in "${!array[@]}"; do 107 | 108 | if test "$i" -eq $2 109 | then 110 | selected_folder=${array[i]::-1} 111 | fi 112 | done 113 | } 114 | 115 | init() { 116 | # Initial values 117 | current_dir=$(pwd) 118 | current_selection=0 119 | 120 | clear 121 | 122 | escape_char=$(printf "\u1b") 123 | while 124 | print_status $current_dir $current_selection 125 | print_folders $current_dir $current_selection 126 | 127 | read -rsn1 mode 128 | clear 129 | do 130 | 131 | if [[ $mode == "$escape_char" ]]; then 132 | read -rsn2 mode 133 | fi 134 | 135 | # echo $mode 136 | case $mode in 137 | '[A') # UP 138 | 139 | if [ "$current_selection" -eq 0 ]; then 140 | current_selection=$folders_list_size 141 | else 142 | current_selection=$((current_selection-1)) 143 | fi 144 | 145 | ;; 146 | '[B') # DOWN 147 | 148 | if [ "$current_selection" -eq "$folders_list_size" ]; then 149 | current_selection=0 150 | else 151 | current_selection=$((current_selection+1)) 152 | fi 153 | 154 | ;; 155 | 156 | '[D') # LEFT 157 | # Removes the last path level 158 | current_dir=${current_dir%/*} 159 | current_selection=0 160 | ;; 161 | 162 | '[C') # RIGHT 163 | get_selected_folder $current_dir $current_selection 164 | current_dir="$current_dir/$selected_folder" 165 | current_selection=0 166 | ;; 167 | 168 | *) 169 | # Change to directory 170 | # Since script was invoked through the source command (. ./Script) we are still in the same Shell instance, 171 | # so it is possible to execute the CD command and thus change the directory. 172 | cd "$current_dir" || exit 173 | return 174 | esac 175 | done 176 | } 177 | 178 | init 179 | --------------------------------------------------------------------------------