diff --git a/git-recall b/git-recall index 6b2e787..4e188fb 100644 --- a/git-recall +++ b/git-recall @@ -22,7 +22,9 @@ FETCH=false GIT_FORMAT="" GIT_LOG="" COMMITS="" +COMMITS_UNCOL=() # commits without colors LESSKEY=false +SED_BIN="" # Sed option to use according OS. VERSION="1.1.4" # Are we in a git repo? @@ -138,11 +140,23 @@ if [[ $NI = 0 ]]; then fi fi -# Add +1 to OFFSET if a commit's length is bigger than the current terminal session's width. (This is to fix a redraw issue) -for C in "${COMMITS[@]}" +# Set correct sed option according OS's type +case "$OSTYPE" in + darwin*) SED_BIN="sed -E" ;; + *) SED_BIN="sed -r" ;; +esac + +# Create array with uncolred commits (removing escape sequences using sed) +for elt in "${COMMITS[@]}" do - ELT="$(echo "$C" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")" # remove colors escape codes - if [[ ${#ELT} -gt $CN ]]; then + ELT="$(echo "$elt" | $SED_BIN "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")" # remove colors escape codes + COMMITS_UNCOL+=("$ELT") +done + +# Add +1 to OFFSET if a commit's length is bigger than the current terminal session's width. (This is to fix a redraw issue) +for C in "${COMMITS_UNCOL[@]}" +do + if [[ ${#C} -gt $CN ]]; then OFFSET=$(( OFFSET + 1 )) fi done @@ -162,16 +176,13 @@ fi ## Get commit's diff. function get_diff() { - case "$OSTYPE" in - darwin*) SED_BIN="sed -E" ;; - *) SED_BIN="sed -r" ;; - esac - - ELT="$(echo "${COMMITS[$CP-1]}" | $SED_BIN "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")" # remove colors escape codes + ELT="$(echo "${COMMITS_UNCOL[$CP-1]}")" DIFF_TIP=${ELT:0:7} DIFF_CMD="git show $DIFF_TIP --color=always" DIFF=$(eval ${DIFF_CMD} 2>/dev/null) + off=$(echo "$DIFF" | grep -c ".\{$CN\}") #Number of lines in the diff that are longer than terminal width. DIFF_LINES_NUMBER="$(echo "$DIFF" | wc -l)" + DIFF_LINES_NUMBER=$(( DIFF_LINES_NUMBER + off )) } ## This function will print the diff according the commit's tip. If the diff is too long, the result will be displayed using 'less'. @@ -179,7 +190,7 @@ function print_diff() { get_diff - if [[ $(( TN + DIFF_LINES_NUMBER )) -ge $(( `tput lines` - 1 )) ]]; then + if [[ $(( TN + DIFF_LINES_NUMBER + OFFSET )) -ge $(( `tput lines` - 1 )) ]]; then if [[ $LESSKEY = true ]]; then echo "$DIFF" | less -r -k $HOME/.lsh_less_keys_tmp else @@ -217,18 +228,19 @@ function print_diff() { fi } -# Calculate OFFSET to avoid bad redraw. (Really bad performance.) +# Calculate OFFSET to avoid bad redraw. function calculate_offset { - # Add +1 to OFFSET if a commit's length is bigger than the current terminal session's width. (This is to fix a redraw issue) - OFFSET=0 - limit=$(( SN + SI )) - tmp=("${COMMITS[@]:$SI:$limit}") - for C in "${tmp[@]}" + tmp=1 + index=$(( SI -1 )) + while [[ $tmp -lt $SN ]] do - ELT="$(echo "$C" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g")" # remove colors escape codes - if [[ ${#ELT} -gt $CN ]]; then - OFFSET=$(( OFFSET + 1 )) - fi + el=${COMMITS_UNCOL[$index]} + if [[ ${#el} -gt $CN ]] && [[ $CP -lt $((SN -1)) ]]; then + OFFSET_2=$(( OFFSET_2 + 1 )) + tmp=$(( tmp + 1 )) + fi + tmp=$(( tmp + 1 )) + index=$(( index + 1 )) done } @@ -238,20 +250,27 @@ tput civis # hide cursor. CP=1 # current position SI=1 # index END=false # end while loop +EXT=0 # Used to extend the number of lines to display. ## Loops, reads inputs and prints commits until user presses 'q' to exit or TAB to show the diff. while ! $END do + + END_INDEX=0 # Index for the last item to display + # When the number of item is higher than screen's number of lines, OFFSET_2 is recalculated each time we select a new item # Set last index to print. (based on OFFSET) if [[ $TN == $NI ]]; then END_INDEX=$TN + OFFSET_2=$OFFSET elif [[ $TN == $(( SN - 1 )) ]]; then # Calculate new OFFSET. if [[ $OFFSET != 0 ]]; then - calculate_offset #This involve really bad performance. Should be reconsidered. + [[ $CP -lt $((SN -1)) ]] && OFFSET_2=0 + EXT=1 + calculate_offset fi - END_INDEX=$(( TN + SI -1 - OFFSET )) + END_INDEX=$(( TN + SI -1 + EXT - OFFSET_2 )) fi # Loop and echo commits @@ -273,29 +292,30 @@ do "$au" | "$au_1") CP=$(( CP - 1 )) - [[ $CP == 0 ]] && [[ $SI=1 ]] && [[ $TN == $(( SN - 1 )) ]] && CP=$(( NI - OFFSET )) && SI=$(( NI - SN + 2 )) + [[ $CP == 0 ]] && [[ $SI=1 ]] && [[ $TN == $(( SN - 1 )) ]] && CP=$NI && SI=$(( NI - SN + 2 + OFFSET_2 )) [[ $CP == 0 ]] && [[ $SI=1 ]] && [[ $TN == $NI ]] && CP=$TN [[ $CP == $(( SI - 1 )) ]] && [[ $SI != 1 ]] && SI=$(( SI - 1 )) - [[ $TN != $(( SN - 1 )) ]] && tput cuu $(( TN + OFFSET )) - [[ $TN == $(( SN - 1 )) ]] && tput cuu $(( SN - 1 )) + [[ $TN != $(( SN - 1 )) ]] && tput cuu $(( TN + OFFSET_2 )) + [[ $TN == $(( SN - 1 )) ]] && tput cuu $(( TN + EXT )) [[ $SI != 1 ]] && tput ed # clear screen ;; "$ad" | "$ad_1") CP=$(( CP + 1 )) [[ $CP == $(( NI + 1 )) ]] && CP=1 && SI=1 - [[ $CP == $(( SN + SI - 1 - OFFSET )) ]] && [[ $TN == $(( SN - 1 )) ]] && SI=$(( SI + 1 )) + [[ $CP == $(( SN + SI - 1 + EXT - OFFSET_2 )) ]] && [[ $TN == $(( SN - 1 )) ]] && SI=$(( SI + 1 )) - [[ $TN != $(( SN - 1 )) ]] && tput cuu $(( TN + OFFSET )) - [[ $TN == $(( SN - 1 )) ]] && tput cuu $(( SN - 1 )) + [[ $TN != $(( SN - 1 )) ]] && tput cuu $(( TN + OFFSET_2 )) + [[ $TN == $(( SN - 1 )) ]] && tput cuu $(( TN + EXT )) [[ $SI != 1 ]] && tput ed # clear screen [[ $SI = 1 ]] && [[ $CP = 1 ]] && tput ed # clear screen ;; "$nl") - tput cuu $(( TN + OFFSET )) - print_diff + [[ $TN == $NI ]] && tput cuu $(( TN + OFFSET_2 )) + [[ $TN != $NI ]] && tput cuu $(( TN + EXT )) + print_diff ;; "q") @@ -305,7 +325,7 @@ do ;; * ) - tput cuu $(( TN + OFFSET )) + tput cuu $(( TN + OFFSET_2 )) esac done