Skip to content

Conversation

@elifarley
Copy link

What

The filter mode (-e/--show-matches) outputs matched values. This adds a flag to output their original 0-based indexes instead.

Why

When using fzy in scripts (specifically in filter mode, -e), it is often far more robust to receive the index of the selected item rather than its string value.

This becomes critical when the input list is pre-formatted with rich content. Consider a script that displays a list of git branches, formatting each line with:

  • The branch name
  • The commit hash in yellow
  • The commit message in grey with emojis
  • ANSI control characters to apply the colors

If fzy returns the full selected string, the calling script must parse this complex line, full of control characters and extra data, just to figure out which original item was selected. This process is brittle and error-prone.

The -I flag provides a much cleaner solution. The script receives a simple integer (the index), which it can directly use to reference its original, unformatted data array. This makes index-based selection patterns simple and reliable.

Changes

Core implementation:

  • Added index field to scored_result struct to preserve original positions during search
  • Implemented choices_getindex() with bounds checking
  • Modified filter output in fzy.c to emit indexes when flag is set

CLI interface:

  • Added -I/--show-indexes flag to options parsing
  • Updated help text and man page

Testing:

  • Added test_choices_get_index() to verify index tracking through search and sort

Usage

Without the flag, fzy outputs the matched values, sorted by relevance:

$ echo -e "apple\nbanana\napricot\navocado" | fzy -e "a"
apple
apricot
avocado
banana

With the -I flag, fzy outputs the 0-based indexes of those same matches:

$ echo -e "apple\nbanana\napricot\navocado" | fzy -e "a" -I
0
2
3
1

This enables robust index-based selection patterns in scripts:

# Create an array of files
FILES=($(find -type f))

# Let the user select a file using fzy and get its index
# Then, use the index to retrieve the original, clean filename from the array
SELECTED_INDEX=$(printf '%s\n' "${FILES[@]}" | fzy -e "query" -I)

# Open the selected file
vi "${FILES[$SELECTED_INDEX]}"

Copilot AI and others added 6 commits November 7, 2025 19:54
Co-authored-by: elifarley <519940+elifarley@users.noreply.github.com>
Co-authored-by: elifarley <519940+elifarley@users.noreply.github.com>
Co-authored-by: elifarley <519940+elifarley@users.noreply.github.com>
… page quote

Co-authored-by: elifarley <519940+elifarley@users.noreply.github.com>
Co-authored-by: elifarley <519940+elifarley@users.noreply.github.com>
Copilot AI review requested due to automatic review settings November 7, 2025 20:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds an -I/--show-indexes flag to fzy's filter mode that outputs 0-based indexes of matched items instead of their string values, enabling more robust scripting when working with formatted input data.

Key Changes:

  • Added index tracking to the search result structure to preserve original positions during sorting
  • Implemented choices_getindex() function with bounds checking to retrieve original indexes
  • Added CLI flag -I/--show-indexes with corresponding option parsing and documentation

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/choices.h Added index field to scored_result struct and declared choices_getindex() function
src/choices.c Implemented index tracking in search worker and added choices_getindex() with bounds checking
src/options.h Added show_indexes field to options struct
src/options.c Added -I/--show-indexes flag parsing and help text
src/fzy.c Modified filter output to print indexes when flag is set
test/test_choices.c Added test case to verify index tracking through search and sort
fzy.1 Updated man page with flag documentation and usage example
_codeql_detected_source_root Added CodeQL configuration file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +325 to +329
if (n < c->available) {
return c->results[n].score;
} else {
return 0;
}
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding bounds checking to choices_getscore() changes its behavior for out-of-bounds access from potentially undefined behavior to returning 0. This is inconsistent with choices_get() which has no bounds checking. Either add bounds checking to choices_get() as well, or remove it from both functions to maintain consistent error handling across the API.

Copilot uses AI. Check for mistakes.
elifarley and others added 2 commits November 7, 2025 17:49
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant