-
-
Save UndeadDemidov/8dfcd27d05fc4a75563ca86939b6ff8f to your computer and use it in GitHub Desktop.
Revisions
-
jacksluong revised this gist
Dec 23, 2023 . 2 changed files with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,5 @@ # cdp: Change Directory Pro  How do you navigate in your terminal? Do you chain sequences of `cd` commands together, or copy a file path and paste it? Sometimes to a destination directory that's not adjacent to your current one? `cdp` might be the solution for you. It's a command that activates an interactive way to navigate directories smoothly and easily. Compatible with bash and zsh. Binary file not shown. -
jacksluong revised this gist
Dec 23, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,5 @@ # cdp: Change Directory Pro  How do you navigate in your terminal? Do you chain sequences of `cd` commands together, or copy a file path and paste it? Sometimes to a destination directory that's not adjacent to your current one? `cdp` might be the solution for you. It's a command that activates an interactive way to navigate directories smoothly and easily. Compatible with bash and zsh. -
jacksluong revised this gist
Dec 23, 2023 . 3 changed files with 1 addition and 0 deletions.There are no files selected for viewing
Binary file not shown.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,5 @@ # cdp: Change Directory Pro (recording)[recording.gif] How do you navigate in your terminal? Do you chain sequences of `cd` commands together, or copy a file path and paste it? Sometimes to a destination directory that's not adjacent to your current one? `cdp` might be the solution for you. It's a command that activates an interactive way to navigate directories smoothly and easily. Compatible with bash and zsh. LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
jacksluong revised this gist
Dec 23, 2023 . 3 changed files with 257 additions and 112 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,25 +1,23 @@ # cdp: Change Directory Pro How do you navigate in your terminal? Do you chain sequences of `cd` commands together, or copy a file path and paste it? Sometimes to a destination directory that's not adjacent to your current one? `cdp` might be the solution for you. It's a command that activates an interactive way to navigate directories smoothly and easily. Compatible with bash and zsh. ## Controls - `cdp` to activate - ↑/↓ to change the selected subdirectory - ← to move into the parent subdirectory (disallowed when in $HOME) - → to make the selected subdirectory the active one (i.e. `cd` into it) - ↵ (return) to exit navigation in the new active directory - Ctrl+C to cancel navigation, staying in the initial directory - Any characters (except backslash) to search for a specific substring ## Installation Download `cdp.sh` and place it wherever you want. You can source this file in your `.{zsh|bash}rc`, or you can directly copy the contents in. The following commands can help with that (replace `.zshrc` with `.bashrc` as appropriate): ```zsh # source file from .zshrc echo "source <path-to-file>" >> ~/.zshrc # copy into .zshrc tail -n +3 <path-to-file> >> ~/.zshrc ``` This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,102 +1,249 @@ #!/bin/bash # `cdp` to activate an interactive way to navigate directories # note: for consistency, treat all arrays as 0-indexed cdp() { local MAX_VOPTS=8 MAX_DIR_WIDTH=60 SEARCH_ICON="⌕" local SEARCH_PREFIX=" $(tput bold)${SEARCH_ICON}$(tput sgr0)$(tput el) " local is_bash=$([[ -n $BASH ]] && echo true || echo false) local is_zsh=$([[ -n $ZSH_NAME ]] && echo true || echo false) # helper functions translate_input() { # args: input case $1 in $'\n'|'') echo enter;; $'\177'|$'\b') echo backspace;; "[A") echo up;; "[B") echo down;; "[C") echo right;; "[D") echo left;; *) echo "$1";; esac } zsh_key_input() { read -sk1 key [[ $key = $'\e' ]] && read -sk2 -t 0.1 key translate_input "$key" } bash_key_input() { IFS='' read -rsn1 key [[ $key = $'\e' ]] && read -rsn2 -t 1 key translate_input "$key" } index_array() { # args: index, array local i=$1 shift 1 echo "${@:$((i+1)):1}" # only way for array indexing to work for both bash and zsh # ${@:0:1} will return the function name } index_of() { # args: element, array local e=$1 shift 1 local i=0 for s in "$@"; do if [[ $s = "$e" ]]; then echo $i return fi ((i++)) done echo -1 } cursor_to_first_option() { tput rc; tput cud1; tput cud1 } print_option() { echo " $1 $(tput el)" } print_selected() { echo " $(tput setab 7)$(tput setaf 0) $1 $(tput sgr0)$(tput el)" } render_options() { # precondition: cursor is at the first line of the options # args: selected index (of visible options), all visible options (as array) local selected=$1 shift 1 local options=("$@") local i=0 for s in "${options[@]}"; do if [[ $i -eq $selected ]]; then print_selected "$s"; else print_option "$s"; fi ((i++)) done } render_search_string() { # args: search string # postcondition: cursor is at the first line of the options tput rc; tput cud1; tput cuf 4 echo "$(tput setaf 3)${search_str}$(tput el)$(tput sgr0)_" } render_heading() { # args: none tput rc local pwd_str=$(pwd) local lim_width=$(($(tput cols) - 20 - 5)) # 20 for "Change directory to ", 5 for buffer [[ lim_width -gt MAX_DIR_WIDTH ]] && lim_width=$MAX_DIR_WIDTH [[ ${#pwd_str} -gt $lim_width ]] && pwd_str="...${pwd_str:$((${#pwd_str} - lim_width + 3))}" echo "$(tput smul)Change directory to $(tput bold)${pwd_str}$(tput sgr0)$(tput el)" } # initialize variables local search_str='' prev_dir='' orig_dir=$PWD local num_vopts=$(($(tput lines) - 2 - 1)) # 2 fixed lines, 1 for buffer [[ $num_vopts -gt $MAX_VOPTS ]] && num_vopts=$MAX_VOPTS local regex_chars='$^.?+*(){}[]/' escape_regex() { # args: string local str=$1 c='' for ((i=0; i<${#regex_chars}; i++)); do c=${regex_chars:$i:1} str=${str//"$c"/\\$c} done echo "$str" } # initialize interface tput civis stty -echo tpuc sc && render_heading echo -e "$SEARCH_PREFIX" for ((i=0; i<num_vopts; i++)); do echo; done tput cuu $((num_vopts + 2)) tput sc # expected output: # - directory line (fixed line) # - search string line (fixed line) # - options (opts, each on their own line) # - blank lines to fill up the rest of the screen as needed # cleanup functions cleanup_base() { tput rc tput ed tput cnorm stty echo trap - INT } cleanup_exit() { cleanup_base echo "Working directory changed: $(tput bold)$(pwd)$(tput el)$(tput sgr0)" } cleanup_interrupt() { cleanup_base cd $orig_dir echo "Restored working directory: $(tput bold)$(pwd)$(tput el)$(tput sgr0)" return } trap 'cleanup_interrupt; return' INT # main loop # opts: options, fopts: filtered options, vopts: visible options while true; do # determine the options local fopts=() opts=() local subdirs=$( (ls -F | grep /$ | sort -f) ) if [[ -n $subdirs ]]; then [[ $is_bash = true ]] && IFS=$'\n' read -r -d '' -a opts <<< "$subdirs" [[ $is_zsh = true ]] && opts+=("${(f)subdirs}") fi opts+=('../') # jump to previous dir option (if left arrow key was pressed) local sel=0 local prev_dir_index=$(index_of "$prev_dir" "${opts[@]}") [[ $prev_dir_index -ne -1 ]] && sel=$prev_dir_index; local inp='' local first_vopt=$((sel - num_vopts + 1)) [[ $first_vopt -lt 0 ]] && first_vopt=0 local do_rerender_opts=true did_update_search=true render_heading # loop while still in the same directory while true; do if [[ $did_update_search = true ]]; then render_search_string "$search_str" # filter options by search string fopts=() if [[ -z $search_str ]]; then fopts=("${opts[@]}") else for opt in "${opts[@]}"; do local opt_l="" regex="" if [[ $is_bash = true ]]; then opt_l=$(echo "$opt" | tr '[:upper:]' '[:lower:]') regex=$(echo "$search_str" | tr '[:upper:]' '[:lower:]') else opt_l=${opt:l} regex=${search_str:l} fi regex=$(escape_regex "$regex") [[ "$opt_l" =~ $regex ]] && fopts+=("$opt") done fi [[ "${#fopts[@]}" -eq 0 ]] && fopts+=('../') local num_fopts=${#fopts[@]} else cursor_to_first_option fi did_update_search=false if [[ $do_rerender_opts = true ]]; then # determine "scroll" position if [[ $sel -lt $first_vopt ]]; then first_vopt=$sel elif [[ $sel -ge $((first_vopt + num_vopts)) ]]; then first_vopt=$((sel - num_vopts + 1)); fi # print options vopts=( "${fopts[@]:$first_vopt:$num_vopts}" ) render_options $((sel - first_vopt)) "${vopts[@]}" tput ed fi do_rerender_opts=true # user key control [[ $is_bash = true ]] && inp=$(bash_key_input) || inp=$(zsh_key_input) case $inp in left) [[ $PWD != "$HOME" ]] && break;; up) ((sel--)); [[ $sel -lt 0 ]] && sel=$((num_fopts - 1));; down) ((sel++)); [[ $sel -ge $num_fopts ]] && sel=0;; right|enter) break;; '\') do_rerender_opts=false;; backspace) search_str="${search_str%?}" sel=0 did_update_search=true;; *) search_str+=$inp sel=0 did_update_search=true;; esac done # cd accordingly case $inp in right) cd "$(index_array "$sel" "${fopts[@]}")"; prev_dir='';; left) prev_dir=$(printf '%s/' "${PWD##*/}"); cd ..;; enter) break;; esac search_str='' done cleanup_exit } -
jacksluong revised this gist
Oct 6, 2023 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,9 +16,10 @@ How do you navigate in your terminal? Do you chain sequences of `cd` commands to - Ctrl+C to cancel navigation, staying in the initial directory ## Installation Just copy the code below into your .zshrc! (Alternatively, place it in a different file and source that file in .zshrc to keep it from getting bloated.) Note 1: Only works for Zsh (not Bash). Note 2: If the formatting of the code below looks ugly for whatever reason, reload the page. ###### Based on https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu -
jacksluong revised this gist
Dec 27, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,7 +18,7 @@ How do you navigate in your terminal? Do you chain sequences of `cd` commands to ## Installation Just copy the code below into your .zshrc! (Alternatively, place it in a different file and source that file in .zshrc to keep those files from getting bloated.) Note 1: Only works for Zsh (not Bash). Note 2: If the formatting of the code below looks ugly for whatever reason, reload the page. ###### Based on https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu -
jacksluong revised this gist
Sep 7, 2022 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -18,6 +18,7 @@ How do you navigate in your terminal? Do you chain sequences of `cd` commands to ## Installation Just copy the code below into your .zshrc! (Alternatively, place it in a different file and source that file in .zshrc to keep those files from getting bloated.) Note 1: Not yet tested for Bash or PowerShell. Note 2: If the formatting of the code below looks ugly for whatever reason, reload the page. ###### Based on https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu -
jacksluong revised this gist
Sep 5, 2022 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,6 +16,8 @@ How do you navigate in your terminal? Do you chain sequences of `cd` commands to - Ctrl+C to cancel navigation, staying in the initial directory ## Installation Just copy the code below into your .zshrc! (Alternatively, place it in a different file and source that file in .zshrc to keep those files from getting bloated.) Not yet tested for Bash or PowerShell. ###### Based on https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu -
jacksluong revised this gist
Sep 5, 2022 . 2 changed files with 1 addition and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,6 +16,6 @@ How do you navigate in your terminal? Do you chain sequences of `cd` commands to - Ctrl+C to cancel navigation, staying in the initial directory ## Installation Just copy the code below into your .zshrc (Zsh) or .profile (Bash)! (Alternatively, place it in a different file and source that file in .zshrc/.profile to keep those files from getting bloated.) ###### Based on https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,5 @@ # `cdp` to activate an interactive way to navigate directories function cdp { # helpers for terminal print control, key input, and other things ESC=$( printf "\033" ) cursor_blink_on() { printf "${ESC}[?25h"; } -
jacksluong revised this gist
Sep 5, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,5 @@ # cdp: Change Directory Pro  How do you navigate in your terminal? Do you chain sequences of `cd` commands together, or copy a file path and paste it? Sometimes to a destination directory that's not adjacent to your current one? -
jacksluong revised this gist
Sep 5, 2022 . 1 changed file with 3 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,6 @@ # cdp: Change Directory Pro  How do you navigate in your terminal? Do you chain sequences of `cd` commands together, or copy a file path and paste it? Sometimes to a destination directory that's not adjacent to your current one? `cdp` might be the solution for you. It's a command that activates an interactive way to navigate directories smoothly and easily. @@ -16,8 +18,4 @@ How do you navigate in your terminal? Do you chain sequences of `cd` commands to ## Installation Just copy the code below into your .zshrc (Zsh) or .profile (Bash)! ###### Based on https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu -
jacksluong created this gist
Sep 5, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ # cdp: Change Directory Pro How do you navigate in your terminal? Do you chain sequences of `cd` commands together, or copy a file path and paste it? Sometimes to a destination directory that's not adjacent to your current one? `cdp` might be the solution for you. It's a command that activates an interactive way to navigate directories smoothly and easily. ## Controls - `cdp` to activate - ↑/↓ to change the selected subdirectory - ← to move into the parent subdirectory (disallowed when in $HOME) - → to make the selected subdirectory the active one (i.e. `cd` into it) - ↵ (return) to exit navigation in the new active directory - ⎵ (space) to make $HOME the active directory - [0-9] to make active the subdirectory is listed next to that number - Ctrl+C to cancel navigation, staying in the initial directory ## Installation Just copy the code below into your .zshrc (Zsh) or .profile (Bash)! ## Demo  ###### Based on https://unix.stackexchange.com/questions/146570/arrow-key-enter-menu Just copy the code below into your .zshrc (Zsh) or .profile (Bash)! This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,105 @@ # `cdp` to activate an interactive way to navigate directories function cdp { # derived from: https://unix.stackexchange.com/a/415155 (converted to zsh) # tput usage: https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux/20983251#20983251 # helpers for terminal print control, key input, and other things ESC=$( printf "\033" ) cursor_blink_on() { printf "${ESC}[?25h"; } cursor_blink_off() { printf "${ESC}[?25l"; } cursor_to() { printf "${ESC}[$1;${2:-1}H"; } print_option() { printf " $1 $(tput el)"; } print_selected() { printf "${ESC}[7m $1 ${ESC}[27m$(tput el)"; } get_cursor_row() { IFS=';' read -sdR $'?\E[6n' ROW COL; echo ${ROW#*\[}; } key_input() { read -sk1 'key?' case $key in $'\n') echo enter;; ' ') echo space;; 0) echo 10;; 1|2|3|4|5|6|7|8|9) echo $key;; "${ESC}") read -sk2 key if [[ $key = "[A" ]]; then echo up elif [[ $key = "[B" ]]; then echo down elif [[ $key = "[C" ]]; then echo right elif [[ $key = "[D" ]]; then echo left fi;; esac } min() { printf "%s\n" "$@" | sort -g | head -n1 } max() { printf "%s\n" "$@" | sort -gr | head -n1 } # initialize persistent variables MAX_SIZE=10 local prev_dir='' local orig_dir=$PWD while true; do # determine the options local subdirs=$((ls -1d */) 2> /dev/null) local opts=("$(tput smul)Change directory to $(tput bold)$(pwd)$(tput sgr0)$(tput el)") [[ ! -z $subdirs ]] && opts+=("${(f)subdirs}") opts+=('../') local num_opts=${#opts[@]} # initialize interaction area and screen positions of first and last row (used for overwriting) # note: indices are all 1-indexed with row 1 being the line displaying the working directory local num_opt_rows=$(min $(tput lines) $MAX_SIZE $((num_opts - 1))) for _ in {1..$num_opt_rows}; do echo; done local last_row=$(get_cursor_row) local first_row=$((last_row - num_opt_rows)) cursor_to $first_row echo " $opts[1]" # ensure cursor and input echoing back on upon a ctrl+c during read trap "cd $orig_dir; cursor_blink_on; stty echo; printf '\n'; return" 2 cursor_blink_off # jump to previous dir option (if left arrow key was pressed) local selected=2 for i in {2..$#opts}; do [[ $opts[$i] = $prev_dir ]] && selected=$i; done local inp='' local top_row=$(max $((selected - num_opt_rows + 2)) 2) while true; do # determine "scroll" position if [[ $selected -lt $top_row ]]; then top_row=$selected elif [[ $selected -ge $((top_row + num_opt_rows)) ]]; then top_row=$((selected - num_opt_rows + 1)); fi # print options by overwriting the last lines for opt_index in {$top_row..$((top_row + num_opt_rows - 1))}; do cursor_to $((first_row + opt_index - top_row + 1)) printf " [%i] " $(((opt_index - top_row + 1) % 10)) if [[ $opt_index -eq $selected ]]; then print_selected $opts[$((opt_index))] else print_option $opts[$((opt_index))]; fi done # user key control inp=$(key_input) case $inp in left) [[ $PWD != $HOME ]] && break;; up) ((selected--)); [[ $selected -lt 2 ]] && selected=$num_opts;; down) ((selected++)); [[ $selected -gt $num_opts ]] && selected=2;; right|enter|space|1|2|3|4|5|6|7|8|9|10) break;; esac done # reset interaction area cursor_to $first_row for row_offset in {1..$num_opt_rows}; do cursor_to $((first_row + row_offset)); echo -n $(tput el); done cursor_to $first_row # cd accordingly case $inp in right) cd $opts[$selected]; prev_dir='';; enter) break;; space) cd; prev_dir='';; left) prev_dir=$(printf '%s/' "${PWD##*/}"); cd ..;; *) local dest=$opts[$((top_row + inp - 1))] [[ $dest == '../' ]] && prev_dir=$(printf '%s/' "${PWD##*/}") cd $dest;; esac done cursor_blink_on }