今天,终于把这个终端文件预览脚本写好了。这个脚本(其实是两个脚本)能干些什么事情呢 ?
- 立马在终端预览预览文件,不用离开终端
- 集成
fzf, 可以用于目录切换,文件打开
一个脚本叫做 pre,(只能)用于在终端打印文件的预览; 支持目录, 文本,图片, tar(.gz), zip, PDF, Djvu, Epub, 视频以及字体的预览.
另一个脚本(函数)叫做 ipre, 它把 pre 和 fzf 进行了深度的集成. 为什么要分成两个文件 ? 大概这样做更加符合 Unix 哲学吧 ?
Do one thing and do it well !
其实这个 ipre 函数还是比较简单的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| function ipre() { local cmd file if [[ -n "$IPRE_LS" ]]; then cmd=(${=IPRE_LS}) else cmd=( fd --hidden --follow -E .git -E target -E .cargo -E build -E .npm -E node_modules -E .cache -E dist -E out -E lsp-bridge -E .java -E .gradle -E .nuget -E .steam -E .android -E .ipython -E .vscode -E .vscode-oss -E .oh-my-zsh -E .emacs-tmp -E .pub-cache -E .proxyman . ) fi if [[ $# -gt 0 ]]; then cmd+=("$@") fi cmd_str=$(printf '%q ' "${cmd[@]}") FZF_STATE_FILE="$HOME/.cache/pre_thumbs/fzf_state" echo "file" > "$FZF_STATE_FILE" file=$( "${cmd[@]}" | fzf \ --multi \ --prompt "ipre > " \ --preview 'pre {}' \ --height=50% --reverse \ --preview-window=right:60% \ --bind 'resize:refresh-preview' \ --bind 'focus,load:transform-header:file --brief {}' \ --bind "\`:reload(\ if grep -qxF 'file' '$FZF_STATE_FILE'; then \ echo 'directory' > '$FZF_STATE_FILE' && \ $cmd_str --type f $dir; \ elif grep -qxF 'directory' '$FZF_STATE_FILE'; then \ echo 'all' > '$FZF_STATE_FILE' && \ $cmd_str --type d $dir; \ else \ echo 'file' > '$FZF_STATE_FILE' && \ $cmd_str $dir; \ fi)" \ --bind 'alt-a:select-all' \ --bind 'alt-a:+execute-silent(echo {+} | wl-copy)' \ --bind 'alt-y:execute-silent(echo {} | wl-copy)' \ --bind "alt-r:execute-silent(rm -f {})+reload($cmd_str)" \ --bind "alt-left:reload($cmd_str $dir)" \ --bind "alt-right:reload(\ if [[ -d '{}' ]]; then \ $cmd_str {}; \ else \ $cmd_str \$(dirname {}); \ fi)" ) [[ -z "$file" ]] && return if [[ -d "$file" ]]; then cd "$file" exit 0 fi case "${file:l}" in *.png|*.jpg|*.jpeg|*.gif|*.webp|*.bmp|*.tiff) nohup imv "$file" &>/dev/null & ;; *.pdf|*.djvu|*.epub|*.mobi) nohup zathura "$file" &>/dev/null & ;; *.tar|*.tar.gz|*.tgz|*.tar.xz|*.txz|*.tar.bz2|*.tbz2) return ;; *.zip) return ;; *) ${EDITOR:-nvim} "$file" ;; esac }
|
相比于 lf, ranger, yazi 等成熟的软件, 该脚本的优势(我最喜欢的一点)就是, 我可以不用离开当前终端,在选择,浏览或预览文件时还可以看到之前命令的输出. 另一些比较小的优势, 轻量化以及完全掌控.
目前, 该项目已经在 Github 上开源, 点击 ipre - terminal inline previewer 跳转.
在些这个脚本的过程中,参考了一些类似项目, 比如: fzf-preview, 以及 fzf 的官方手册. 遇到了哪些困难呢 ? 最大的困难应该是 不熟悉 fzf 的命令参数, 也不能怪我,这个命令的参数真的太多了(所以, 人们对 fzf 的开发不到 1% >_<)
和 fzf 类似的一个软件叫做 skim, 不错,又是一个 Rust 重写万物的产物 … 还没有体验过,不过,看官方文档的介绍,skim 有一个什么 interasctive mode, 这个是它的特色. 之后有时间了就去试试.
之后,我也许还会用 fzf 写一写脚本,用于和 ps, kill, cd, 之类的命令集成一下,这个应该不难,毕竟 fzf 官方已经提供了一些详细的(高级的)使用案例, 参见 fzf advanced examples.