How to display items as table? #4616
-
|
How can I display the list of items as a table? I've tried using something like Any clues? Image from the release notes, see https://github.com/junegunn/fzf/releases/tag/v0.67.0: |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
|
fzf doesn't have such an option. You have to pre-process the input list before feeding it to fzf. The screenshot is only meant to demonstrate how |
Beta Was this translation helpful? Give feedback.
-
|
With a little pre-processing of the data, and using the latest 'freeze' options, I was able to get a table-looking list pretty easily. I'm sharing it here in case someone else finds it useful, I hope it's ok. #!/usr/bin/env bash
# Example of how to show a list of items as a table on fzf.
# Strategy:
# - each item has three "parts" separated by "|"
# - keep the left most field (`--freeze-left 1`) visible,
# - keep the right most field (`--freeze-right 1`) visible,
# - pad the center field with spaces, this will make the short items push the
# rightmost part to the right, fzf will "trim" it accordingly
#
# Notes:
# - padding the center column as wide as longest field causes the table to be
# as wide as the longest field, a narrow "table" will be displayed if all items
# are short
JSON_FILE="data-fzf-issues.json"
# On this example I use a json file, a "max length" calculation using
# `jq` and a little bit of parsing to shape the data into table like rows, but
# it could be done with any other tool or just sending the right text shape and
# lengths to fzf.
parse_data() {
jq -r '
# Compute longest "title" length
(map(.title | length) | max) as $max |
# Output rows, fields joined with "|", titles padded to match longest
.[] |
"\(.number) | \(.title + (" " * ($max - (.title | length)))) | \(.createdAt)"
' "${JSON_FILE}"
}
# This function returns the longest "title" on all the items to show, used to pad
# the header to the max length, so fzf's trimming behaves the same on the
# header as for the items
longest_title() {
local max_length
max_length=$(jq -r '(map (.title | length) | max) as $max | $max' $JSON_FILE)
echo "$max_length"
}
# add spaces " " on the right of the given string
pad_string() {
local line_in=$1
local pad=$2
local line_out
line_out=$(printf '%-*.*s' "$pad" "$pad" "$line_in")
echo "$line_out"
}
# Construct header, pad strings according to the items' length
header=" Num "
header+="| "
len=$(longest_title)
header+=$(pad_string "Title" "$len")
# Extra padding to get same width as actual dates
# "2025-10-21T17:12:01Z"
header+=" | Created "
parse_data | \
fzf \
--reverse \
--freeze-right 1 \
--freeze-left 1 \
--delimiter "|" \
--header "$header" \
--input-border="rounded" \
--info="inline-right" \
--preview "echo issue number: {1}; echo; echo {2}" \
--preview-window down,wrap \
--accept-nth 1Example json dataGenerated using: [
{
"createdAt": "2025-11-27T21:03:24Z",
"number": 4619,
"title": "option to configure the arrow"
},
{
"createdAt": "2025-11-24T22:21:15Z",
"number": 4615,
"title": "--accept-nth ignored with --filter"
},
{
"createdAt": "2025-11-23T12:17:18Z",
"number": 4608,
"title": "Index out of range panic in FuzzyMatchV2 with very long matching pattern and text"
},
{
"createdAt": "2025-11-20T17:42:06Z",
"number": 4603,
"title": "_fzf_complete_${cmd} runs after aliases are resolved"
},
{
"createdAt": "2025-11-20T00:44:18Z",
"number": 4601,
"title": "Enhancement request: `--preview-json` to read previews from a simple key-value object instead of spawning an external process"
},
{
"createdAt": "2025-11-19T18:36:36Z",
"number": 4599,
"title": "[Feature] Add alt-gutter color option as an alternative for alt-bg"
},
{
"createdAt": "2025-11-18T18:14:25Z",
"number": 4598,
"title": "Custom fuzzy completion without using _fzf_complete"
},
{
"createdAt": "2025-11-17T13:59:12Z",
"number": 4592,
"title": "FZF_COMPLETION_DIR_OPTS not respected when _fzf_compgen_dir is defined"
},
{
"createdAt": "2025-11-12T16:07:12Z",
"number": 4588,
"title": "[Feature request] custom environment variables for child processes"
},
{
"createdAt": "2025-11-05T15:07:47Z",
"number": 4577,
"title": "--keep-right not keeping right on long lines with search term present"
},
{
"createdAt": "2025-11-03T23:47:24Z",
"number": 4576,
"title": "Feature Request: add `accept` / `accepted` / `on_accept` event"
},
{
"createdAt": "2025-10-25T18:56:06Z",
"number": 4569,
"title": "Installation script incompatible with fzf < 0.48.0 (--zsh flag)"
},
{
"createdAt": "2025-10-21T17:12:01Z",
"number": 4564,
"title": "unmatched '"
},
{
"createdAt": "2025-10-20T06:27:33Z",
"number": 4562,
"title": "Mcafee thinks fzf.exe is a virus"
},
{
"createdAt": "2025-10-18T13:15:43Z",
"number": 4559,
"title": "cursor position reset in raw mode"
},
{
"createdAt": "2025-10-13T07:17:02Z",
"number": 4549,
"title": "bat `--theme-{light,dark}` option is ignored"
},
{
"createdAt": "2025-10-11T07:29:00Z",
"number": 4547,
"title": "fzf border not visible on Linux TTY"
},
{
"createdAt": "2025-10-08T08:26:42Z",
"number": 4539,
"title": "Actions first/last are inconsistent with up/down"
},
{
"createdAt": "2025-09-20T10:29:17Z",
"number": 4524,
"title": "Problem using 'execute' action invoked via HTTP POST-request"
},
{
"createdAt": "2025-09-10T14:16:20Z",
"number": 4514,
"title": "fzf randomly breaks on Ctrl-Z"
},
{
"createdAt": "2025-09-07T20:28:59Z",
"number": 4510,
"title": "Feature Requeqst: vim keybinds in fzf (just like in fzf.vim)"
},
{
"createdAt": "2025-08-21T09:30:42Z",
"number": 4499,
"title": "`** + <TAB>` doesn't work in `bash` sometimes"
},
{
"createdAt": "2025-08-20T16:40:49Z",
"number": 4498,
"title": "CTRL-T binding not using last token with custom FZF_CTRL_T_COMMAND"
},
{
"createdAt": "2025-08-13T10:02:28Z",
"number": 4489,
"title": "feat: --color=auto"
},
{
"createdAt": "2025-08-11T04:27:32Z",
"number": 4483,
"title": "Selection lost when reload action is involved"
},
{
"createdAt": "2025-08-08T11:28:16Z",
"number": 4482,
"title": "Support for kitty text protocol"
},
{
"createdAt": "2025-07-31T19:36:17Z",
"number": 4471,
"title": "Image preview does not work with tmux popup"
},
{
"createdAt": "2025-07-16T14:29:17Z",
"number": 4460,
"title": "Disable-click but allow scroll"
},
{
"createdAt": "2025-06-03T15:51:39Z",
"number": 4409,
"title": "Reload with pre-selected items"
},
{
"createdAt": "2025-05-24T18:51:17Z",
"number": 4399,
"title": "fzf sixel support on Windows"
}
]
|
Beta Was this translation helpful? Give feedback.


With a little pre-processing of the data, and using the latest 'freeze' options, I was able to get a table-looking list pretty easily.
Here's how it looks:
I'm sharing it here in case someone else finds it useful, I hope it's ok.
I added comments to explain the script and tried to keep it usable and to the point so is not too long.