# How Superfile’s Process Bar Displays File Operation Progress

> Discover how Superfile's process bar displays file operation progress in real-time. Learn about its struct, percentage calculation, and Bubble Tea integration for a clear visual experience.

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

---

**Superfile renders real-time file operation progress by maintaining a `Process` struct for each task, computing a percentage from completed items, and drawing a gradient-coloured bar via the Bubble Tea `progress.Model` component.**

Superfile is an open-source terminal file manager that surfaces live feedback for copy, move, paste, and delete actions through a dedicated process bar UI component. The implementation ties together a structured process model, file-operation handlers, and Bubble Tea rendering logic to produce a smooth, theme-aware progress indicator directly in the terminal.

## Process Bar Architecture

At the core of superfile's progress reporting is the `Process` struct defined in [`src/internal/ui/processbar/process.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/process.go). This struct tracks everything Bubble Tea needs to animate and colour each bar.

### The Process Struct

Each running operation is represented by a `Process` value with the following fields:

- `ID`, `CurrentFile`, and `Operation` store basic metadata about the task.
- `Progress` holds a `progress.Model` from `charm.land/bubbles/v2/progress` that draws the actual bar.
- `State`, `Total`, `Done`, and `DoneTime` track execution state and completion metrics.

When an operation starts, `NewProcess` initializes the progress model using the active UI theme:

```go
prog := progress.New(
    progress.WithColors(
        lipgloss.Color(common.Theme.GradientColor[0]),
        lipgloss.Color(common.Theme.GradientColor[1]),
    ),
    progress.WithScaled(true),
)
prog.PercentageStyle = common.FooterStyle

```

The `WithColors` option applies a two-stop gradient from the theme, and `WithScaled(true)` ensures the bar stretches to fit the terminal width.

## Updating File Operation Progress in Real Time

Superfile updates the process bar while iterating over files in [`src/internal/handle_file_operations.go`](https://github.com/yorukot/superfile/blob/main/src/internal/handle_file_operations.go). During each step of a copy, move, or delete loop, the application increments counters and refreshes the percentage.

The typical lifecycle begins with `NewProcess`:

```go
// Starting a copy operation (simplified)
proc := processbar.NewProcess(reqID, srcPath, processbar.Copy, totalFiles)
m.processes[reqID] = proc

```

Inside the file loop, the code performs three actions for every item:

1. Sets `process.CurrentFile` to the file currently being handled.
2. Increments `process.Done` to reflect another completed item.
3. Recalculates the percentage and pushes it to the progress model:

```go
// Inside the copy loop
proc.CurrentFile = file.Name()
proc.Done++
proc.Progress.SetPercent(float64(proc.Done) / float64(proc.Total))

```

When the operation finishes, the `State` field switches to `Successful`, `Cancelled`, or `Failed`. The terminal icon updates accordingly via `ProcessState.Icon()` in [`src/internal/ui/processbar/process.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/process.go).

## Rendering the Process Bar UI

The process bar rendering pipeline lives in [`src/internal/ui/processbar/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/model.go), while update messages are propagated through [`src/internal/ui/processbar/model_update.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/model_update.go). Bubble Tea calls the model's `View()` method to repaint active processes on every frame.

### View Assembly

For each active `Process`, the renderer:

- Calls `process.GetDisplayName()` to build a textual description combining the operation verb, current file name, and a state icon.
- Invokes `process.Progress.ViewAs(percent)` to generate the bar string.
- Concatenates the display name and bar, respecting `progressBarRightPadding = 3` from [`src/internal/ui/processbar/const.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/const.go) so the status icon remains visible.

A simplified version of the loop looks like this:

```go
// Rendering a single process (inside model.go)
func (m *Model) View() string {
    for _, p := range m.activeProcesses {
        pct := float64(p.Done) / float64(p.Total)
        line := fmt.Sprintf("%s %s",
            p.GetDisplayName(),
            p.Progress.ViewAs(pct),
        )
        // …append line to output buffer…
    }
    return buffer.String()
}

```

The result is a live line such as:

```

📂 Copy file.txt  ────────────────────── 45%

```

As `Done` approaches `Total`, the gradient bar expands to 100 % and the leading icon flips to a checkmark for success or a cross for failure.

## Summary

- Superfile defines every file task as a `Process` struct in [`src/internal/ui/processbar/process.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/process.go), pairing operation metadata with a Bubble Tea `progress.Model`.
- `NewProcess` configures a gradient, width-scaled bar using theme colours from `common.Theme.GradientColor`.
- File loops in [`src/internal/handle_file_operations.go`](https://github.com/yorukot/superfile/blob/main/src/internal/handle_file_operations.go) advance `Done`, refresh `CurrentFile`, and call `SetPercent` to update the bar in real time.
- [`src/internal/ui/processbar/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/model.go) composites each line with `GetDisplayName()` and `ViewAs`, while [`const.go`](https://github.com/yorukot/superfile/blob/main/const.go) reserves right-hand padding for status icons.

## Frequently Asked Questions

### How does superfile calculate the process bar percentage?

Superfile divides the number of completed items by the total item count. In [`src/internal/handle_file_operations.go`](https://github.com/yorukot/superfile/blob/main/src/internal/handle_file_operations.go), it computes `float64(process.Done) / float64(process.Total)` and passes the result to `process.Progress.SetPercent`.

### What library draws the progress bar in superfile?

The bar is rendered by `progress.Model` from the `charm.land/bubbles/v2/progress` package. Superfile wraps this model inside its own `Process` struct located in [`src/internal/ui/processbar/process.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/process.go).

### Can the process bar colours be customized?

Yes. During initialization in [`process.go`](https://github.com/yorukot/superfile/blob/main/process.go), `NewProcess` feeds `common.Theme.GradientColor[0]` and `common.Theme.GradientColor[1]` into `progress.WithColors`. Changing the theme therefore changes the gradient applied to every process bar.

### Where does superfile store active process state during rendering?

Active processes are held in the model within [`src/internal/ui/processbar/model.go`](https://github.com/yorukot/superfile/blob/main/src/internal/ui/processbar/model.go). The `View()` method iterates over `m.activeProcesses`, calling `GetDisplayName()` and `ViewAs` to produce the final terminal output on every Bubble Tea frame.