#!/usr/bin/env zsh # fzf-history-widget with duplicate removal, preview and syntax highlighting (requires `bat`). # # Disable preview: # # zstyle :z4h:fzf-history fzf-flags --no-preview eval "$_z4h_opt" [[ -v _z4h_tty_fd ]] || return local preview='printf "%s" {} | command cut -f2- -d'$'\1' (( $+commands[bat] )) && preview+=' | command bat -l bash --color always -pp --wrap=character --terminal-width=$((FZF_PREVIEW_COLUMNS-1))' { -z4h-show-dots '' autoload +X -Uz -- -z4h-cursor-show local cursor_y cursor_x -z4h-get-cursor-pos || return local query=${(j: :)${(@Z:cn:)BUFFER}} [[ -n $query ]] && query+=' ' if (( _z4h_can_save_restore_screen )) && zstyle -T :z4h:fzf-history fzf-preview; then local opts=( --read0 --no-multi --no-sort --cycle --exact --no-mouse --tabstop 1 --query=$query --color=hl:201,hl+:201 --no-clear --layout=default --preview-window=wrap:4:down:noborder --preview=$preview --height=$LINES ) local move=$'\e[0m\e[H' local _z4h_saved_screen -z4h-save-screen || return else # A big chunk of this branch is dead code because _z4h_can_save_restore_screen is false. # I'm keeping it for a while in case I decide to change this logic. local -i pct=80 (( _z4h_can_save_restore_screen )) && pct=100 local -i space if (( _z4h_can_save_restore_screen )); then (( space = LINES - cursor_y < cursor_y - 1 ? cursor_y - 1 : LINES - cursor_y )) else (( space = LINES - 1 )) fi (( space <= pct * LINES / 100 )) || (( space = pct * LINES / 100 )) local opts=( --read0 --no-multi --no-sort --cycle --exact --no-mouse --tabstop 1 --query=$query --color=hl:201,hl+:201 ) local -i preview_lines=6 local -i height=$(($#history + 2)) (( height >= 4 )) || (( height = 4 )) local preview_window=wrap:$preview_lines if (( height + preview_lines <= space || space > preview_lines + 5 )) && zstyle -T :z4h:fzf-history fzf-preview; then (( height += preview_lines )) else preview_lines=0 fi (( height <= pct * LINES / 100 )) || (( height = pct * LINES / 100 )) (( height <= LINES - 1 )) || (( height = LINES - 1 )) if (( _z4h_can_save_restore_screen )); then opts+=(--no-clear) if { (( height <= cursor_y - 1 )) && zstyle -T :z4h: prompt-at-bottom } || (( cursor_y - 1 > LINES - cursor_y && cursor_y - 1 > 5 + preview_lines )) && { (( height > LINES - cursor_y )) || zstyle -T :z4h: prompt-at-bottom }; then preview_window+=':up' (( preview_lines )) || opts+=(--border=horizontal) (( height <= cursor_y - 1 )) || (( height = cursor_y - 1 )) local move=$'\e[0m\e['$((cursor_y-height))';1H' opts+=(--layout=default) elif (( LINES - cursor_y > 5 + preview_lines )); then preview_window+=':down' (( height <= LINES - cursor_y )) || (( height = LINES - cursor_y )) local move=$'\e[0m\n\r' opts+=(--layout=reverse) else preview_window+=':down' local -i extra=$((height - LINES + cursor_y)) print -rnu $_z4h_tty_fd -- ${(pl:$height::\n:)} || return (( cursor_y += LINES - cursor_y - height )) local move=$'\e[0m\e['$((cursor_y+1))';1H' opts+=(--layout=reverse) fi local _z4h_saved_screen -z4h-save-screen || return else print -u $_z4h_tty_fd || return preview_window+=':down' local move= opts+=(--layout=reverse) fi opts+=(--height=$height) if (( preview_lines )); then opts+=( --preview-window=$preview_window --preview=$preview ) fi fi { local choice choice=$( unsetopt pipe_fail { # This `noglob` is a workaround for a bug in zsh that can be # triggered by certain corrupted history files. # # https://github.com/romkatv/zsh4humans/issues/313 (( $#history )) && noglob printf '%s\000' "${history[@]}" } | { { print -rnu $_z4h_tty_fd -- $move -z4h-cursor-show 2>&$_z4h_tty_fd -z4h-fzf $opts } always { -z4h-cursor-hide } }) [[ -n $choice ]] || return BUFFER=${choice#*$'\n'} typeset -gi CURSOR='_z4h_cursor_max()' if (( _z4h_use[zsh-autosuggestions] )); then typeset -g _z4h_autosuggest_buffer=$BUFFER unset _z4h_autosuggestion POSTDISPLAY fi if (( _z4h_use[zsh-autosuggestions] || _z4h_use[zsh-syntax-highlighting] )); then -z4h-redraw-buffer fi return 0 } always { if (( _z4h_can_save_restore_screen )); then -z4h-restore-screen print -rn -- $'\e[0m\e['$cursor_y';'$cursor_x'H' else builtin echoti cuu 1 (( cursor_x > 1 )) && builtin echoti cuf $((cursor_x-1)) fi } } always { zle -R -z4h-cursor-show }