# How Superfile's Search Bar Filters Files in the Current Directory

> Discover how Superfile filters files in the current directory using a fuzzy-search pipeline and fzf-lib to rank matching entries. Learn about this powerful feature for efficient file management.

- Repository: [Yorukot/superfile](https://github.com/yorukot/superfile)
- Tags: internals
- Published: 2026-07-26

---

**Superfile filters the current directory by routing the file panel through a fuzzy-search pipeline whenever the panel's `SearchBar.Value()` is non-empty, using `fzf-lib` to score and rank matching `os.DirEntry` items.**

Superfile is a terminal-based file manager that implements real-time fuzzy search for directory navigation. Understanding how the **superfile search bar filters files** in the current directory requires examining the file panel's model-driven routing, candidate collection, and `fzf-lib` integration. The logic is implemented across the file panel model, the fuzzy utility package, and the main application model.

## Search Bar Model and Query Capture

Each file panel owns a `textinput.Model` called **SearchBar** that stores the current query and focus state. This component is created by `common.GenerateSearchBar()` and attached to the panel model at `Model.SearchBar`. When a user types, the query string is read from `m.SearchBar.Value()`, and this value acts as the gate for enabling the filtered view.

## Routing Logic in `getElements`

The routing decision happens in `Model.getElements` inside [`src/internal/ui/filepanel/get_elements.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/filepanel/get_elements.go). The method checks whether the search bar contains text before deciding which retrieval path to execute:

```go
if m.SearchBar.Value() != "" {
    return m.getDirectoryElementsBySearch(displayDotFile)
}
return m.getDirectoryElements(displayDotFile)

```

If the query is empty, the panel falls back to `getDirectoryElements` and renders the full directory. If text is present, control passes to `getDirectoryElementsBySearch` to perform the fuzzy filter.

## Gathering Candidates with `getDirectoryElementsBySearch`

The `getDirectoryElementsBySearch` function, defined in [`src/internal/ui/filepanel/get_elements.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/filepanel/get_elements.go) around lines 37–73, prepares the raw data for the fuzzy matcher. It performs three key steps:

- It reads the current directory using `os.ReadDir(m.Location)`.
- It builds a flat string slice named `fileAndDirectories` containing every entry name, including both files and sub-directories.
- It constructs a map called `folderElementMap` that associates each name with its original `os.DirEntry`.

This design allows the fuzzy matcher to work with simple strings while preserving the ability to map results back to full file system metadata.

## Fuzzy Matching: How the Superfile Search Bar Filters Files by Score

The actual filter is executed by `utils.FzfSearch`, a thin wrapper around the third-party `fzf-lib` library located in [`src/pkg/utils/fzf_utils.go`](https://github.com/yorukot/superfile/blob/main/src/pkg/utils/fzf_utils.go). The function initializes a new fzf searcher, runs the query, and waits for scored results:

```go
fzfSearcher := fzf.New(source, fzf.DefaultOptions())
fzfSearcher.Search(query)
fzfResults := <-fzfSearcher.GetResultChannel()

```

`utils.FzfSearch` returns a slice of `fzf.MatchResult` ordered by relevance score, with higher-scored matches appearing first. Because the results contain the candidate keys, the file panel cross-references them against `folderElementMap` to reconstruct the final element list.

## Mapping Matches Back and Sorting

After the fuzzy search completes, `getDirectoryElementsBySearch` iterates over the ranked results. For each match, it retrieves the original `os.DirEntry` from `folderElementMap` and appends it to the `dirElements` slice, as seen around lines 68–74 of [`src/internal/ui/filepanel/get_elements.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/filepanel/get_elements.go). Once reconstructed, the filtered slice is passed to `sortFileElement` to apply the user-selected sort option.

This flow ensures that the filtered list respects both the relevance ranking from `fzf-lib` and the user's preferred sorting configuration.

## Sidebar Search Consistency

Superfile applies the same fuzzy-search architecture to the sidebar. The sidebar implements an equivalent `fuzzySearch` path that delegates to `utils.FzfSearch`, ensuring that both the main file panel and the directory tree share a consistent search experience. This pattern reuses the `textinput.Model` infrastructure across different UI components.

## Practical Code Examples

You can interact with the search system programmatically through the internal API. To filter a panel with a specific query:

```go
// Assume panel is a *filepanel.Model
panel.SearchBar.SetValue("readme")          // user typed "readme"
panel.UpdateElementsIfNeeded(true, false) // force refresh
elements := panel.GetElements(false)       // returns only entries matching "readme"

```

To focus the search bar from the main model:

```go
// From the main model (m *model)
m.searchBarFocus() // triggers common.GenerateSearchBar width setup

```

To use the fuzzy matcher standalone:

```go
import "github.com/yorukot/superfile/src/pkg/utils"

names := []string{"README.md", "main.go", ".gitignore"}
matches := utils.FzfSearch("read", names)
// matches[0].Key == "README.md"

```

## Summary

- **Query detection:** `Model.getElements` in [`src/internal/ui/filepanel/get_elements.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/filepanel/get_elements.go) checks `m.SearchBar.Value()` to decide between filtered and unfiltered views.
- **Candidate preparation:** `getDirectoryElementsBySearch` builds a string slice and a lookup map from `os.ReadDir(m.Location)`.
- **Fuzzy ranking:** `utils.FzfSearch` wraps `fzf-lib` in [`src/pkg/utils/fzf_utils.go`](https://github.com/yorukot/superfile/blob/main/src/pkg/utils/fzf_utils.go) and returns `fzf.MatchResult` items ordered by score.
- **Result reconstruction:** Matches are mapped back to `os.DirEntry` objects via `folderElementMap` and then sorted.
- **UI consistency:** The same `textinput.Model` and `fzf-lib` integration powers both the main file panel and the sidebar.

## Frequently Asked Questions

### How does the superfile search bar filter files in the current directory?

When the `SearchBar.Value()` string is non-empty, `Model.getElements` routes the request to `getDirectoryElementsBySearch` instead of the standard `getDirectoryElements`. This branch is defined in [`src/internal/ui/filepanel/get_elements.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/filepanel/get_elements.go).

### What library does superfile use for fuzzy searching?

Superfile uses `fzf-lib` through a wrapper function called `utils.FzfSearch` defined in [`src/pkg/utils/fzf_utils.go`](https://github.com/yorukot/superfile/blob/main/src/pkg/utils/fzf_utils.go). The wrapper creates an `fzf.New` instance with default options and streams results through a result channel.

### Does superfile's search bar filter hidden files?

The search pipeline respects the `displayDotFile` parameter passed through `getElements`. If dot files are currently visible, they are included in the `fileAndDirectories` candidate slice and remain eligible for fuzzy matching.

### Why does superfile build a `folderElementMap` during search?

The map acts as a bridge between the string-based `fzf-lib` matcher and the rich `os.DirEntry` objects needed by the UI. After `fzf-lib` returns matching names, superfile uses `folderElementMap` to retrieve the corresponding directory entries in constant time.