How Superfile Displays File Metadata with ExifTool Integration

Superfile displays detailed file metadata by maintaining a singleton ExifTool instance initialized at startup and merging extracted EXIF tags with base filesystem attributes through the GetMetadata function in src/internal/ui/metadata/metadata.go.

Superfile, the open-source terminal file manager from yorukot/superfile, delivers rich file information panels by combining native Go filesystem operations with the barasher/go-exiftool library. This integration allows the application to render comprehensive metadata views for images, videos, and documents directly in the terminal interface.

Initializing the ExifTool Singleton

Superfile follows a singleton pattern to manage the ExifTool process efficiently. During application startup, src/internal/config_function.go instantiates a single ExifTool manager that persists for the program's lifecycle.

// src/internal/config_function.go
et, err = exiftool.NewExiftool()   // line 67

This instance (et) is stored in the global application model defined in src/internal/model.go, specifically within a field typed as *exiftool.Exiftool. By reusing a single instance, Superfile avoids the performance overhead of spawning new ExifTool processes for every file inspection.

Core Metadata Collection

When a user focuses the metadata panel, Superfile invokes GetMetadata in src/internal/ui/metadata/metadata.go. This function orchestrates data collection in two phases.

First, it gathers basic filesystem attributes through getMetaDataUnsorted:

// src/internal/ui/metadata/metadata.go
meta := getMetaDataUnsorted(filePath, metadataFocused, et)  // line 78
sortMetadata(meta.data)                                    // line 80

This initial pass collects standard information including filename, size, modification date, permissions, and owner/group details. The function also conditionally adds computed values like MD5 checksums or binary architecture based on user configuration settings.

Merging ExifTool Extended Metadata

The second phase enriches the dataset using ExifTool's deep inspection capabilities. The helper function updateExiftoolMetadata invokes the singleton instance to extract embedded metadata:

// src/internal/ui/metadata/metadata.go
fileInfos := et.ExtractMetadata(filePath)               // line 61
for _, fileInfo := range fileInfos {
    if fileInfo.Err != nil { … }                       // lines 64-66
    for k, v := range fileInfo.Fields {                // lines 69-71
        res.data = append(res.data, [2]string{k, fmt.Sprintf("%v", v)})
    }
}

The ExtractMetadata method returns a slice of FileInfo structs. Superfile iterates through these results, checking for errors at lines 64-66, then maps the key-value pairs from fileInfo.Fields into the metadata response. This captures EXIF data from images, stream information from videos, and document properties from Office files.

Platform-Specific Implementation

Superfile handles operating system differences through platform-specific files:

These files ensure consistent metadata presentation across Linux, macOS, and Windows while respecting platform-specific filesystem attributes.

Configuration and Usage

Users control ExifTool integration through the Metadata boolean flag defined in src/internal/common/config_type.go. When enabled, Superfile renders the metadata panel by calling GetMetadata with the stored ExifTool instance:

func renderMetadataPanel(fp string) {
    // `model` holds the shared ExifTool instance
    meta := metadata.GetMetadata(fp, true, model.et)

    if meta.infoMsg != "" {
        ui.ShowWarning(meta.infoMsg)
    }
    for _, kv := range meta.GetData() {
        ui.AddRow(kv[0], kv[1])
    }
}

The resulting Metadata struct contains an ordered slice of [2]string pairs representing key-value metadata, plus an infoMsg field for displaying warnings (such as ExifTool execution errors).

Complete Working Example

To manually retrieve metadata using Superfile's internal logic:

package main

import (
    "fmt"
    "github.com/barasher/go-exiftool"
    "github.com/yorukot/superfile/src/internal/ui/metadata"
)

func main() {
    // Create a single ExifTool manager (normally done at startup)
    et, _ := exiftool.NewExiftool()
    defer et.Close()

    // Retrieve metadata for a file; `true` means the metadata panel is focused
    meta := metadata.GetMetadata("/path/to/image.jpg", true, et)

    fmt.Println("File:", meta.GetPath())
    for _, pair := range meta.GetData() {
        fmt.Printf("%s: %s\n", pair[0], pair[1])
    }
}

This example mirrors the production flow: initialize the ExifTool manager once, call GetMetadata with the file path, and iterate over the ordered key-value pairs.

Summary

  • Singleton Pattern: Superfile initializes one ExifTool instance in config_function.go (line 67) and stores it in the global model to minimize process overhead.
  • Two-Phase Collection: GetMetadata in metadata.go first gathers basic filesystem data, then calls updateExiftoolMetadata to merge extended EXIF information extracted at line 61.
  • Structured Output: Metadata returns as an ordered slice of [2]string pairs, with error handling for missing ExifTool binaries or unsupported files at lines 64-66.
  • Cross-Platform: Platform-specific files handle owner/group resolution separately for Unix and Windows systems.
  • Configurable: The Metadata configuration flag in config_type.go enables or disables the integration entirely.

Frequently Asked Questions

How does Superfile handle missing or corrupted ExifTool installations?

Superfile checks for errors when invoking et.ExtractMetadata at lines 64-66 of metadata.go. If ExifTool returns an error or is not found in the system PATH, the application captures this in the infoMsg field of the Metadata struct and displays a warning in the UI while still showing basic filesystem metadata collected in the first phase.

Can I disable ExifTool integration if I only want basic file information?

Yes. ExifTool integration is controlled by the Metadata boolean field in src/internal/common/config_type.go. Setting this to false prevents the application from initializing the ExifTool singleton and calling updateExiftoolMetadata, resulting in a metadata panel that displays only native filesystem attributes without EXIF extraction.

What types of file metadata can ExifTool extract in Superfile?

Through the barasher/go-exiftool library, Superfile can extract EXIF tags from images (camera model, GPS coordinates, exposure settings), stream metadata from video and audio files (codecs, duration, bitrates), and document properties from PDFs and Office files (author, creation date, software). The Fields map returned by ExtractMetadata (lines 69-71) contains these as generic key-value pairs appended to the result data.

Where is the ExifTool instance stored between file selections?

The active ExifTool instance is stored as et *exiftool.Exiftool in the global application model defined in src/internal/model.go. This singleton is created once during startup in config_function.go and passed as a parameter to GetMetadata whenever the metadata panel refreshes, ensuring efficient resource reuse across the session.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →