# Superfile Configuration File Loading and Validation Process

> Discover the Superfile configuration file loading and validation process. Learn how defaults merge with your TOML, fields auto-fix, and ranges validate for seamless application startup.

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

---

**Superfile loads its configuration by merging embedded defaults with a user-provided TOML file, optionally auto-fixing missing fields, and then validating numeric ranges, sidebar sections, and Unicode border widths before the application starts.**

The `yorukot/superfile` terminal file manager uses a robust configuration pipeline to ensure user settings are always valid and complete. This process involves resolving XDG-compliant paths, merging defaults with user overrides, and enforcing strict validation rules on fields like sidebar width and border characters. Understanding this flow helps users debug configuration errors and developers integrate Superfile's loader into custom tooling.

## Configuration File Location and Path Resolution

Superfile follows the XDG Base Directory specification to locate its configuration files. The paths are constructed in [`src/config/fixed_variable.go`](https://github.com/yorukot/superfile/blob/main/src/config/fixed_variable.go) at lines 65–66:

```go
SuperFileMainDir = filepath.Join(xdg.ConfigHome, "superfile")
ConfigFile       = filepath.Join(SuperFileMainDir, "config.toml")

```

By default, Superfile looks for [`config.toml`](https://github.com/yorukot/superfile/blob/main/config.toml) inside `$XDG_CONFIG_HOME/superfile/` (typically `~/.config/superfile/config.toml`). This global `ConfigFile` variable is referenced throughout the loading pipeline.

## Loading and Merging Configuration Data

The entry point for configuration loading is the `LoadConfigFile` function defined in [`src/internal/common/load_config.go`](https://github.com/yorukot/superfile/blob/main/src/internal/common/load_config.go). This function orchestrates the merge between **embedded default values** and the user's TOML file.

At lines 28–30, `LoadConfigFile` calls the generic TOML loader:

```go
err := utils.LoadTomlFile(variable.ConfigFile, ConfigTomlString, &Config,
                           variable.FixConfigFile, false)

```

The `LoadTomlFile` function in [`src/pkg/utils/file_utils.go`](https://github.com/yorukot/superfile/blob/main/src/pkg/utils/file_utils.go) executes a two-pass unmarshaling process:

1. It first unmarshals the embedded default data (`ConfigTomlString`) into the target struct.
2. It then reads the user-provided file, unmarshals it into a map to detect missing fields, and unmarshals again into the target struct to apply overrides.

If the function detects missing fields that exist in the defaults but not the user file, its behavior depends on the `fixFlag` parameter.

## Automatic Repair with the --fix-config-file Flag

Superfile can automatically repair incomplete configuration files when the `--fix-config-file` flag is enabled (stored in `variable.FixConfigFile`).

When `fixFlag` is **true**, `LoadTomlFile` creates a backup of the original user file, then writes a merged TOML containing defaults plus user overrides back to disk. It returns a non-fatal message indicating the backup location.

When `fixFlag` is **false**, the function returns a `TomlLoadError` containing a descriptive message about the missing fields, but allows the program to continue using the merged in-memory configuration.

Errors are surfaced to the user via `utils.PrintfAndExitf` or `utils.PrintlnAndExit`, which prints styled error messages and aborts execution if necessary.

## Validation Rules and Constraints

Once the file is successfully loaded, `LoadConfigFile` invokes `ValidateConfig(&Config)` at lines 49–53 of [`src/internal/common/load_config.go`](https://github.com/yorukot/superfile/blob/main/src/internal/common/load_config.go) to enforce runtime constraints:

- **`FilePreviewWidth`**: Must be between 2 and 10, or 0 to disable preview.
- **`SidebarWidth`**: Must be between 5 and 20, or 0 to hide the sidebar.
- **`SidebarSections`**: Each entry must be one of `home`, `pinned`, or `disks`.
- **`DefaultSortType`**: Must be an integer between 0 and 4.
- **`FilePanelNamePercent`**: Must fall between `FileNameRatioMin` and `FileNameRatioMax`.
- **Border Characters**: `BorderTop`, `BorderBottom`, `BorderLeft`, `BorderRight`, and corner characters must be exactly one cell wide, validated by the `validateBorders` function (lines 97–126) using `ansi.StringWidth`.

If any validation fails, `ValidateConfig` returns an error that triggers `utils.PrintlnAndExit`, terminating the application with a clear diagnostic message.

## Loading Hotkeys and Themes

Superfile applies a similar loading pattern to **hotkeys** and **themes** via `LoadHotkeysFile` and `LoadThemeFile`.

Hotkey values undergo additional inspection using Go reflection to guarantee each entry is a non-empty slice of strings (`[]string`). This ensures that key bindings are always parseable into actionable commands.

## First-Run Bootstrap Process

For initial setups, `LoadAllDefaultConfig` reads embedded defaults through `LoadConfigStringGlobals` (lines 62–66 in [`src/internal/common/load_config.go`](https://github.com/yorukot/superfile/blob/main/src/internal/common/load_config.go)) and writes theme files to disk if the stored theme version is outdated. This guarantees that new installations start with valid, complete configuration files without manual intervention.

## Practical Example: Loading Configuration in Your Own Tool

You can leverage Superfile's configuration loader in external Go programs. The following example demonstrates loading a custom configuration file with automatic fixing enabled:

```go
package main

import (
	"fmt"

	"github.com/yorukot/superfile/src/internal/common"
	"github.com/yorukot/superfile/src/config/fixed_variable"
)

func main() {
	// Simulate CLI flags
	variable.FixConfigFile = true   // auto-fix missing fields
	variable.ConfigFile = "/tmp/myconfig.toml"

	// Load & validate
	common.LoadConfigFile()

	fmt.Printf("Config loaded – preview width: %d, sidebar width: %d\n",
		common.Config.FilePreviewWidth, common.Config.SidebarWidth)
}

```

Running this program will read [`/tmp/myconfig.toml`](https://github.com/yorukot/superfile/blob/main//tmp/myconfig.toml), auto-fix any missing keys, and abort with a validation error if any configured value falls outside the supported ranges.

## Summary

- Superfile resolves configuration paths using XDG standards in [`src/config/fixed_variable.go`](https://github.com/yorukot/superfile/blob/main/src/config/fixed_variable.go).
- `LoadConfigFile` merges embedded defaults with user TOML via `utils.LoadTomlFile` in [`src/pkg/utils/file_utils.go`](https://github.com/yorukot/superfile/blob/main/src/pkg/utils/file_utils.go).
- The `--fix-config-file` flag triggers automatic backup and repair of missing configuration fields.
- `ValidateConfig` enforces strict constraints on widths, ratios, and Unicode border character widths (checked in `validateBorders`).
- Hotkeys and themes follow the same loading pattern, with additional type validation via reflection.

## Frequently Asked Questions

### What happens if my configuration file has missing fields?

If your [`config.toml`](https://github.com/yorukot/superfile/blob/main/config.toml) is missing fields present in the embedded defaults, Superfile detects this during the two-pass unmarshal process. Without the `--fix-config-file` flag, it continues with merged values but warns about the missing fields. With the flag enabled, it automatically backs up your original file and rewrites the configuration with complete default values preserved.

### How does Superfile validate Unicode border characters?

The `validateBorders` function (lines 97–126 of [`src/internal/common/load_config.go`](https://github.com/yorukot/superfile/blob/main/src/internal/common/load_config.go)) uses `ansi.StringWidth` to verify that each border character (`BorderTop`, `BorderBottom`, `BorderLeft`, `BorderRight`, and corners) occupies exactly one terminal cell. This prevents layout corruption from wide or zero-width Unicode characters.

### Where does Superfile store the default configuration values?

Default values are embedded directly into the binary as the `ConfigTomlString` constant. These defaults are loaded first by `utils.LoadTomlFile`, ensuring the application always has fallback values even if the user's configuration file is incomplete or missing.

### Can I load Superfile configuration in my own Go program?

Yes. Import the `github.com/yorukot/superfile/src/internal/common` and `github.com/yorukot/superfile/src/config/fixed_variable` packages, set `variable.ConfigFile` to your desired path, and call `common.LoadConfigFile()`. This imports the same validation and merging logic used by the main application.