菜单

预览窗口

相关源文件

fzf 中的预览窗口是一个强大的功能,它允许您在不实际选择项目的情况下检查所选项目的内容。本文档将介绍如何配置和使用预览窗口,包括其外观、位置、大小和交互功能。有关自定义预览窗口颜色的信息,请参阅 颜色和主题。有关预览窗口导航相关按键绑定的详细信息,请参阅 按键绑定自定义

预览窗口概述

预览窗口显示的是使用 --preview 选项指定的命令的输出。该命令针对当前高亮的搜索结果项执行,使您可以在选择项目之前查看其附加信息。

预览窗口系统架构

来源:src/terminal.go363-365 src/terminal.go139-148

配置选项

基本预览命令

最基本的预览功能可以通过 --preview 选项启用,该选项指定了用于生成预览内容的要执行的命令。

fzf --preview 'cat {}'

占位符 {} 会被当前行(或与字段索引表达式一起使用时,会被特定字段)替换。

预览窗口选项

预览窗口的外观和行为可以通过 --preview-window 选项进行自定义,该选项接受一个由逗号分隔的规范列表。

预览窗口配置选项

来源:man/man1/fzf.1870-961

位置和大小

预览窗口可以放置在主窗口的任何一侧。

  • --preview-window up:预览窗口位于搜索结果上方。
  • --preview-window down:预览窗口位于搜索结果下方(默认)。
  • --preview-window left:预览窗口位于搜索结果左侧。
  • --preview-window right:预览窗口位于搜索结果右侧。

大小可以指定为终端的百分比或绝对数值。

fzf --preview 'cat {}' --preview-window right:50%
fzf --preview 'cat {}' --preview-window up:10

边框样式

您可以自定义预览窗口的边框。

fzf --preview 'cat {}' --preview-window border-rounded
fzf --preview 'cat {}' --preview-window border-sharp
fzf --preview 'cat {}' --preview-window border-bold
fzf --preview 'cat {}' --preview-window border-double
fzf --preview 'cat {}' --preview-window border-block
fzf --preview 'cat {}' --preview-window border-thinblock
fzf --preview 'cat {}' --preview-window border-horizontal
fzf --preview 'cat {}' --preview-window border-top
fzf --preview 'cat {}' --preview-window border-bottom
fzf --preview 'cat {}' --preview-window border-left
fzf --preview 'cat {}' --preview-window border-right
fzf --preview 'cat {}' --preview-window border-none

您也可以使用简写 --preview-border 选项。

fzf --preview 'cat {}' --preview-border=rounded

来源:man/man1/fzf.1829-867

预览窗口标签

您可以为预览窗口边框添加一个标签。

fzf --preview 'cat {}' --preview-label='File Content'

标签的位置可以自定义。

fzf --preview 'cat {}' --preview-label='File Content' --preview-label-pos=center
fzf --preview 'cat {}' --preview-label='File Content' --preview-label-pos=3
fzf --preview 'cat {}' --preview-label='File Content' --preview-label-pos=-3:bottom

来源:man/man1/fzf.1836-867

预览窗口内容

占位符表达式

预览命令可以使用各种占位符表达式。

占位符描述
{}当前行
{n}当前行的第 n 个字段
{n..m}当前行的第 n 个到第 m 个字段
{..m}当前行的第一个到第 m 个字段
{n..}当前行的第 n 个到最后一个字段
{q}当前查询字符串
{q:n}查询字符串的第 n 个字段
{+}所有选中的项目(与 --multi 一起使用)
{+n}选中项目的第 n 个字段

来源:man/man1/fzf.1742-805

占位符表达式中的标志

占位符表达式可以包含标志。

标志描述
+用于多选
s保留空格
f替换为临时文件路径
32位指针原始(未加引号)

示例

fzf --multi --preview 'head -10 {+f}'

来源:man/man1/fzf.1767-789

内部架构

预览窗口功能是 fzf 中 Terminal 结构的一部分。该系统包括管理预览选项、渲染预览窗口以及处理预览内容用户交互的组件。

预览窗口核心数据结构

来源:src/terminal.go139-159 src/terminal.go229-397

预览窗口事件和操作

fzf 提供了几个与预览窗口交互的操作。

操作描述
preview(CMD)执行给定的命令并在预览窗口中显示结果。
refresh-preview刷新预览窗口。
toggle-preview切换预览窗口的可见性。
toggle-preview-wrap切换预览窗口中的文本换行。
preview-up向上滚动预览。
preview-down向下滚动预览。
preview-page-up向上翻页滚动预览。
preview-page-down向下翻页滚动预览。
preview-half-page-up向上滚动预览半页。
preview-half-page-down向下滚动预览半页。
preview-top滚动到预览的顶部。
preview-bottom滚动到预览的底部。
show-preview如果预览窗口被隐藏,则显示它。
hide-preview隐藏预览窗口。

这些操作可以使用 --bind 选项绑定到按键。

fzf --preview 'cat {}' --bind 'ctrl-/:toggle-preview'

默认情况下,shift-upshift-down 分别绑定到 preview-uppreview-down

来源:man/man1/fzf.11671-1679 src/terminal.go727-730

预览窗口运行时环境

在执行预览命令时,fzf 会设置几个环境变量,预览命令可以使用这些环境变量来适当地格式化其输出。

可变描述
FZF_PREVIEW_LINES预览窗口中的行数。
FZF_PREVIEW_COLUMNS预览窗口中的列数。
FZF_PREVIEW_TOP预览窗口的顶部位置。
FZF_PREVIEW_LEFT预览窗口的左侧位置。
LINESFZF_PREVIEW_LINES 相同(仅为预览命令设置)。
COLUMNSFZF_PREVIEW_COLUMNS 相同(仅为预览命令设置)。

此外,fzf 还导出了通用的环境变量,这些环境变量也可供预览命令使用。

可变描述
FZF_QUERY当前查询字符串。
FZF_PROMPT当前提示符字符串。
FZF_PREVIEW_LABEL预览窗口标签。
FZF_BORDER_LABEL边框标签。
FZF_TOTAL_COUNT项目总数。
FZF_MATCH_COUNT匹配的项目数。
FZF_SELECT_COUNT选中项目的数量。
FZF_POS列表中光标的位置。

使用示例

fzf --preview 'echo "Window size: $FZF_PREVIEW_COLUMNS x $FZF_PREVIEW_LINES"'

环境变量是在 environForPreview() 方法中设置的,该方法使用预览特定的环境变量来扩展通用环境变量。

来源:man/man1/fzf.1754-762 src/terminal.go1078-1138 src/terminal.go1091-1117

高级特性

条件化预览窗口布局

您可以根据尺寸阈值指定预览窗口的备用布局。这是通过 previewOpts 结构体中的 thresholdalternative 字段实现的。

fzf --preview 'cat {}' --preview-window 'right,border-left,<50(up,30%,border-bottom)'

在此示例中,如果预览窗口的宽度小于 50 列,它将切换到预览显示在搜索结果上方、高度为 30%、带有一个底部边框的布局。

该实现会在窗口调整大小时检查阈值。

您也可以在达到阈值时完全隐藏预览窗口。

fzf --preview 'cat {}' --preview-window '<50(hidden)'

阈值检查在 resizePreviewWindows() 方法中执行,如果满足阈值条件,该方法会递归调用自身并使用备用布局。

来源:man/man1/fzf.1958-966 src/terminal.go1971-1989

初始滚动位置

您可以设置预览窗口的初始滚动位置。

fzf --preview 'cat {}' --preview-window '+5'      # Scroll to line 5
fzf --preview 'cat {}' --preview-window '+{2}'    # Scroll to line from the 2nd field
fzf --preview 'cat {}' --preview-window '+{2}-5'  # 5 lines before the line from the 2nd field
fzf --preview 'cat {}' --preview-window '+{2}+3/2' # Put the target line in the middle with 3-line offset

来源:man/man1/fzf.1917-949

固定页眉行

您可以将特定行数固定在预览窗口的顶部。

fzf --preview 'cat {}' --preview-window '~3'

这会将预览内容的前 3 行固定,而其余内容可以滚动。

来源:man/man1/fzf.1926-956

跟随滚动(自动滚动)

预览窗口可以自动滚动以跟随新内容,类似于 tail -f 的行为。这是通过 previewer 结构体中的 following 字段实现的,该字段是一个 resumableState 类型,可以处于三种状态之一:disabledStatepausedStateenabledState

fzf --preview 'tail -f /var/log/system.log' --preview-window follow

跟随行为的工作方式如下:

  1. 当启用 follow 时,following 状态被设置为 enabledState
  2. 新内容会自动滚动预览窗口到底部。
  3. 如果您手动向上滚动,跟随行为将暂停(pausedState)。
  4. 如果您滚动回底部,它将恢复(enabledState)。

resumableState 类型具有控制此行为的方法。

  • Enabled():检查跟随功能当前是否已启用。
  • Force(flag bool):强制将状态设置为启用或禁用。
  • Set(flag bool):在未禁用时设置状态。

这使得与预览窗口中的流式内容进行直观的交互成为可能。

来源: man/man1/fzf.1890-902 src/terminal.go98-128 src/terminal.go146

预览窗口中的图像支持

fzf 支持通过各种终端图形协议在预览窗口中显示图像,目前处于实验阶段。这是通过对特定终端转义序列进行特殊传递处理来实现的。

协议支持
Kitty 图形协议通过以 \x1b_G 开头的转义序列支持。
Sixel 图形通过以 \x1bP 开头的转义序列支持。
iTerm2 内联图像协议通过以 \x1b]1337; 开头的转义序列支持。

该实现使用正则表达式来识别这些特殊序列,并将它们直接传递给终端,而不进行任何处理。

passThroughBeginRegex = regexp.MustCompile(`\x1bPtmux;\x1b\x1b|\x1b(_G|P[0-9;]*q)|\x1b]1337;`)
passThroughEndTmuxRegex = regexp.MustCompile(`[^\x1b]\x1b\\`)

使用辅助脚本的示例

fzf --preview='fzf-preview.sh {}'

当在预览内容中检测到图像时,previewed.image 标志将被设置为 true,这会影响预览窗口的渲染方式。

来源: man/man1/fzf.1819-825 src/terminal.go74-87 src/terminal.go152-159

渲染过程

以下图表说明了预览窗口内容是如何渲染的。

预览窗口渲染过程

来源: src/terminal.go658 src/terminal.go139-159 src/terminal.go444-446

内部实现细节

预览窗口是通过几个内部结构和方法实现的。

  1. previewOpts 结构体:存储预览窗口的配置选项。
  2. previewer 结构体:管理预览的内容和状态。
  3. previewed 结构体:跟踪预览显示的当前状态。
  4. previewRequest 结构体:封装了生成预览内容请求。
  5. previewResult 结构体:包含预览命令执行的结果。

fzf 通过其事件系统处理预览窗口的调整大小和内容更新,事件包括 reqPreviewReadyreqPreviewEnqueuereqPreviewDisplayreqPreviewRefresh

来源: src/terminal.go139-159 src/terminal.go645-658 src/terminal.go444-446