# `Minga.Config.Loader`
[🔗](https://github.com/jsmestad/minga/blob/main/lib/minga/config/loader.ex#L1)

Discovers and evaluates config files and user modules at startup.

## Load order (both startup and reload)

1. `~/.config/minga/modules/*.ex` (compile user modules)
2. `~/.config/minga/themes/*.exs` (load user themes, before config eval)
3. `~/.config/minga/config.exs` (global config)
4. `.minga.exs` in the current working directory (project-local config)
5. `~/.config/minga/after.exs` (post-init hook)

Later sources override earlier ones (last-writer-wins for options and
keybindings). Errors at any stage are captured and stored for the
editor to display as status bar warnings.

## Config file locations

1. `$XDG_CONFIG_HOME/minga/config.exs` (if `$XDG_CONFIG_HOME` is set)
2. `~/.config/minga/config.exs`

If the file doesn't exist, the editor starts with defaults. No error,
no warning.

# `state`

```elixir
@type state() :: %{
  config_path: String.t(),
  load_error: String.t() | nil,
  loaded_modules: [module()],
  modules_errors: [String.t()],
  project_config_path: String.t() | nil,
  project_config_error: String.t() | nil,
  after_error: String.t() | nil
}
```

Loader state: stores paths, loaded modules, and any errors from each stage.

# `after_error`

```elixir
@spec after_error() :: String.t() | nil
```

Returns the after.exs load error, or `nil` if clean (or no after.exs).

# `after_error`

```elixir
@spec after_error(GenServer.server()) :: String.t() | nil
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `config_path`

```elixir
@spec config_path() :: String.t()
```

Returns the resolved global config file path.

This path is used by `SPC f p` to open the config file for editing.

# `config_path`

```elixir
@spec config_path(GenServer.server()) :: String.t()
```

# `load_error`

```elixir
@spec load_error() :: String.t() | nil
```

Returns the last global config load error, or `nil` if config loaded cleanly
(or no config file exists).

# `load_error`

```elixir
@spec load_error(GenServer.server()) :: String.t() | nil
```

# `loaded_modules`

```elixir
@spec loaded_modules() :: [module()]
```

Returns the list of modules compiled from the user's modules directory.

# `loaded_modules`

```elixir
@spec loaded_modules(GenServer.server()) :: [module()]
```

# `modules_errors`

```elixir
@spec modules_errors() :: [String.t()]
```

Returns compilation errors from user modules, or an empty list if all compiled cleanly.

# `modules_errors`

```elixir
@spec modules_errors(GenServer.server()) :: [String.t()]
```

# `project_config_error`

```elixir
@spec project_config_error() :: String.t() | nil
```

Returns the project-local config load error, or `nil` if clean (or no project config).

# `project_config_error`

```elixir
@spec project_config_error(GenServer.server()) :: String.t() | nil
```

# `reload`

```elixir
@spec reload() :: :ok | {:error, String.t()}
```

Reloads all config from scratch.

Purges previously loaded user modules, resets Options, Hooks,
Keymap.Active, and Command.Registry to defaults, then re-runs the
full load sequence. Returns `:ok` on success or `{:error, reason}`
if something went wrong (errors are also stored in state).

# `reload`

```elixir
@spec reload(GenServer.server()) :: :ok | {:error, String.t()}
```

# `start_link`

```elixir
@spec start_link(keyword()) :: Agent.on_start()
```

Starts the loader, compiles user modules, and evaluates all config files.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
