How Superfile Handles File Compression and Extraction: A Deep Dive into the Source Code
Superfile handles file compression and extraction through dedicated Go routines in file_operations_compress.go and handle_file_operations.go, supporting ZIP creation and multi-format extraction via ctrl+a and ctrl+e hotkeys with real-time UI progress bars.
Superfile is a terminal-based file manager that treats compressed-file operations as first-class citizens. Understanding how superfile handles file compression and extraction reveals a clean separation between the compression engine (ZIP-only) and the extraction dispatcher (multi-format). This article examines the actual implementation in the yorukot/superfile repository, including the specific file paths, function signatures, and third-party libraries involved.
Compression Workflow: Creating ZIP Archives
Superfile implements compression exclusively through the ZIP format, utilizing Go's standard library alongside custom UI integration.
The zipSources Function Implementation
The core compression logic resides in src/internal/file_operations_compress.go. The zipSources function orchestrates the entire ZIP creation process:
- Input validation – Verifies each source path exists before processing
- File counting – The
countFileshelper walks source directories to calculate total progress units - UI initialization – Creates a process entry via
processBar.SendAddProcessMsgwithOpCompresstype - Archive creation – Opens the target file with
os.Createand aborts if the file already exists (handled bygetZipArchiveNamededuplication) - Streaming compression –
zipSourcesCorewalks sources andwriteZipFilecreates headers withDeflatemethod
// From file_operations_compress.go (lines 17-67)
func zipSources(sources []string, target string, processBar *processbar.Model) error {
// Validation and counting logic...
f, err := os.Create(target) // Creates destination file
writer := zip.NewWriter(f) // Initializes ZIP writer
zipSourcesCore(sources, processBar, &p, writer)
// Final UI update sets state to Successful
return nil
}
Progress Tracking and Cancellation
Every compression operation integrates with Superfile's processbar.Model. The system sends real-time updates after each file entry is written, and users can cancel the operation through the UI. The process state transitions from Running to Successful upon completion, triggering an automatic interface refresh.
Extraction Workflow: Multi-Format Support
Unlike compression, extraction supports multiple archive formats through a unified dispatch system in src/internal/handle_file_operations.go.
Supported Archive Formats
The extractFile function (around line 412) supports the following formats:
- .zip – Native
archive/zipreader - .tar, .tar.gz, .tgz –
archive/tarwith optionalcompress/gzipwrapper - .gz – Standalone gzip decompression
- .bz2 – Bzip2 via
github.com/klauspost/compress/bzip2 - .xz – XZ compression via
github.com/klauspost/compress/xz - .zst – Zstandard via
github.com/klauspost/compress/zstd - .Z – Legacy Unix compress via
github.com/sshaman1101/dcompress
Extension Validation and Dispatch
Before extraction, IsExtensionExtractable (defined in src/internal/common/string_function.go at line 210) validates the file extension. The dispatcher then selects the appropriate extractor based on the detected format, writing entries to the destination directory while updating the progress bar.
// Conceptual flow from handle_file_operations.go
func extractFile(archivePath, destDir string) error {
if !IsExtensionExtractable(archivePath) {
return errors.New("unsupported format")
}
// Dispatches to zip, tar, or third-party extractors...
}
Third-Party Dependencies
For high-performance decompression of modern formats, Superfile depends on github.com/klauspost/compress for BZIP2, XZ, and ZSTD. The legacy .Z format uses github.com/sshaman1101/dcompress, as referenced in go.mod.
Configuration and Hotkeys
Superfile exposes these operations through configurable keyboard shortcuts and menu items.
Default Keybindings
The default configuration in src/superfile_config/hotkeys.toml defines:
ctrl+a– Triggerscompress_filectrl+e– Triggersextract_file
These bindings map to the structs defined in src/internal/common/config_type.go (ExtractFile and CompressFile types).
UI Help Menu Integration
The help interface (located at src/internal/ui/helpmenu/data.go line 243) displays "Extract compressed file" as a searchable operation, ensuring users can discover the functionality without memorizing hotkeys.
Linux-Specific Flags
On Linux systems, src/internal/ui/metadata/metadata_linux.go defines the FS_NOCOMP_FL flag (line 32). This filesystem attribute marks files that should not be compressed, preventing redundant compression of already-compressed data.
Practical Code Examples
You can leverage Superfile's internal packages for programmatic archive operations.
Programmatic Compression
import (
"github.com/yorukot/superfile/src/internal"
"github.com/yorukot/superfile/src/internal/ui/processbar"
)
func compressDemo() error {
sources := []string{"./myfolder", "./README.md"}
target, _ := internal.GetZipArchiveName("myfolder") // Returns "myfolder.zip"
bar := processbar.New() // UI progress bar instance
return internal.ZipSources(sources, target, bar)
}
Programmatic Extraction
import (
"github.com/yorukot/superfile/src/internal"
)
func extractDemo() error {
archive := "./project.tar.gz"
destDir := "./extracted"
// Automatically detects format and dispatches correct extractor
return internal.ExtractFile(archive, destDir)
}
CLI Usage
The terminal interface mirrors the hotkey functionality:
# Compression (equivalent to ctrl+a)
superfile compress ./src ./docs -o backup.zip
# Extraction (equivalent to ctrl+e)
superfile extract backup.zip -d ./output
Summary
- Compression is ZIP-only: The
zipSourcesfunction infile_operations_compress.gocreates ZIP archives using Go'sarchive/zipwithDeflatecompression and real-time progress reporting. - Extraction is multi-format: The
extractFilefunction inhandle_file_operations.godispatches to format-specific extractors supporting ZIP, TAR, GZIP, BZIP2, XZ, ZSTD, and legacy .Z files. - UI integration: Both operations use the
processbar.Modelfor cancellable progress tracking, triggered byctrl+a(compress) andctrl+e(extract) perhotkeys.toml. - Extension validation:
IsExtensionExtractableinstring_function.gofilters supported formats before dispatch. - Linux protection: The
FS_NOCOMP_FLflag prevents double-compression of system files.
Frequently Asked Questions
What compression formats does superfile support?
Superfile supports ZIP only for creating archives. For extraction, it supports ZIP, TAR (including .tar.gz and .tgz), GZIP, BZIP2, XZ, Zstandard (.zst), and legacy Unix .Z compressed files. The extraction logic uses format-specific libraries from klauspost/compress and the standard archive/ packages.
How does superfile prevent overwriting existing files during compression?
The getZipArchiveName function automatically deduplicates target names, and os.Create in zipSources will fail if the target path already exists. The UI presents a clear error message before any compression begins, protecting existing data.
Where are the compression hotkeys configured?
Keybindings are defined in src/superfile_config/hotkeys.toml. By default, ctrl+a triggers compression and ctrl+e triggers extraction. These map to the CompressFile and ExtractFile configuration types in src/internal/common/config_type.go, and appear in the help menu at src/internal/ui/helpmenu/data.go.
Can extraction operations be cancelled mid-process?
Yes. Both compression and extraction operations integrate with Superfile's processbar.Model, which provides cancellable progress updates. The process state updates in real-time, allowing users to abort long-running extractions without leaving partial files (extractors write to temporary locations before final placement).
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →