preview.sh (4339B) - raw


      1 #!/usr/bin/env zsh
      2 
      3 0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
      4 0="${${(M)0:#/*}:-$PWD/$0}"
      5 
      6 # Desc: dynamic preview command; borrowed & modified from fzf.vim
      7 # can export FZFGIT_PREVIEW='bat -Pf --style auto'
      8 #
      9 # @params
     10 # Globals:
     11 #   reverse_seq: reverse highlight sequence for easier print
     12 #   reset_seq: reset highlight sequence for eaiser print
     13 #   input_option: the array containing informaiton from cmd argument
     14 #   preview_file: the file path to be previewed
     15 #   preview_center: the center/highlight line of the preview, if not set, display entire file
     16 #   preview_lines: total lines to be previed, used to determine the first line and last line to be printed
     17 #   preview_first: the first line number of the file to be printed
     18 #   preview_last: the last line number of the file to be printed
     19 #   file_mime: mime of the file, used to display information for binary file
     20 # Arguments:
     21 #   $1: The filename and line info to be previewed
     22 #     Format: filepath[:lineno][:ignored]
     23 # Example:
     24 #   preview "$HOME/.bashrc:15"
     25 
     26 #######################################
     27 # display the preview of the file
     28 # construct argument for the action, execute and exit
     29 # Arguments:
     30 #   $1: the file path to be previewed
     31 #   $2: the first line number to be previewd, optional
     32 #   $3: the center/highlight line in the preview, optional
     33 #   $4: the last line number to be previewed, optional
     34 # Note:
     35 #   if the line number information such as $2 $3 $4 is not given, the entire
     36 #   file will be printed.
     37 #   Otherwise only the $2-$4 parts of the file will be printed and $3 will be highlighted
     38 #######################################
     39 
     40 display_preview() {
     41   local fallback_cmd preview_cmd preview_file preview_first preview_last preview_center
     42   preview_file="$1"
     43   preview_first="$2"
     44   preview_center="$3"
     45   preview_last="$4"
     46   fallback_cmd="highlight -O ansi -l {} || coderay {} || rougify {} || cat {}"
     47   preview_cmd=${fallback_cmd}
     48   preview_cmd=${preview_cmd//{\}/$(printf %q "${preview_file}")}
     49 
     50   if [[ -z "${preview_first}" ]] || [[ -z "${preview_center}" ]] || [[ -z "${preview_last}" ]]; then
     51     if [[ -z "${FZFGIT_PREVIEW}" ]] && command -v bat > /dev/null; then
     52       bat --color=always --pager=never "${preview_file}"
     53       exit $?
     54     fi
     55     eval "${preview_cmd}" 2> /dev/null
     56     exit 0
     57   else
     58     if [ -z "${FZFGIT_PREVIEW}" ] && command -v bat > /dev/null; then
     59       bat --color=always --pager=never \
     60           --line-range="${preview_first}":"${preview_last}" --highlight-line="${preview_center}" "${preview_file}"
     61       exit $?
     62     fi
     63     eval "${preview_cmd}" 2> /dev/null \
     64       | awk "NR >= ${preview_first} && NR <= ${preview_last} { \
     65           if (NR == ${preview_center}) \
     66             { gsub(/\x1b[[0-9;]*m/, \"&${reverse_seq}\"); printf(\"${reverse_seq}%s\n${reset_seq}\", \$0); } \
     67           else \
     68             printf(\"${reset_seq}%s\n\", \$0); \
     69         }"
     70     exit 0
     71   fi
     72 }
     73 
     74 reverse_seq="\x1b[7m"
     75 reset_seq="\x1b[m"
     76 
     77 IFS=':' read -r -a input_option <<< "$1"
     78 preview_file=${input_option[0]}
     79 preview_center=${input_option[1]}
     80 
     81 if [[ $1 =~ ^[A-Z]:\\ ]]; then
     82   preview_file=$preview_file:${input_option[1]}
     83   preview_center=${input_option[2]}
     84 fi
     85 
     86 preview_file="${preview_file/#\~\//$HOME/}"
     87 if [ ! -r "${preview_file}" ]; then
     88   echo "File not found ${preview_file}"
     89   exit 1
     90 fi
     91 
     92 # if binary, display binary info and exit
     93 file_mime=$(file --dereference --mime "${preview_file}")
     94 [[ "${file_mime}" =~ binary ]] \
     95   && echo "${file_mime}" \
     96   && exit 0
     97 
     98 # if no line number was given, just preview the entire file
     99 [[ -z "${preview_center}" ]] && display_preview "${preview_file}"
    100 
    101 # if invalid line number was given, just preview the entire file
    102 [[ -n "${preview_center}" && ! "${preview_center}" =~ ^[0-9] ]] && display_preview "${preview_file}"
    103 
    104 # get the size of the termianl window and determine the first line and last line
    105 preview_center=${preview_center/[^0-9]*/}
    106 
    107 if [ -n "${FZF_PREVIEW_LINES}" ]; then
    108   preview_lines="${FZF_PREVIEW_LINES}"
    109 else
    110   if [ -r /dev/tty ]; then
    111     preview_lines=$(stty size < /dev/tty | cut -d' ' -f1)
    112   else
    113     preview_lines=40
    114   fi
    115 fi
    116 
    117 preview_first=$((preview_center-preview_lines/3))
    118 preview_first=$((preview_first < 1 ? 1 : preview_first))
    119 preview_last=$((preview_first+preview_lines-1))
    120 
    121 display_preview "${preview_file}" "${preview_first}" "${preview_center}" "${preview_last}"