Minga.Language.Registry (Minga v0.1.0)

Copy Markdown View Source

Provides O(1) language catalog lookups for %Minga.Language{} definitions registered by config and extension-owned language packs.

Backed by ETS with read_concurrency: true for lock-free reads on every keystroke, render frame, and comment toggle. The GenServer exists only to own the ETS table lifecycle. All reads go directly to ETS.

Lookup functions

  • get/1 — lookup by language name atom (e.g., :elixir)
  • for_extension/1 — lookup by file extension string (e.g., "ex")
  • for_filename/1 — lookup by exact filename (e.g., "Makefile")
  • for_shebang/1 — lookup by shebang interpreter (e.g., "python3")

Runtime registration

Extensions register languages via register/2 with {:extension, name} as the source. Reload and unload paths remove the whole %Minga.Language{} record, so its names, extensions, filenames, shebangs, devicons, grammar metadata, formatter, and LSP defaults disappear together.

Summary

Types

Source that contributed registry entries.

Functions

Returns all registered language definitions.

Returns the canonical tree-sitter grammar name for a language label.

Returns a specification to start this module under a supervisor.

Returns the language definition for a file extension, or nil.

Returns the language definition for an exact filename, or nil.

Returns the language definition for a shebang interpreter, or nil.

Returns the language definition for a name atom, or nil if unknown.

Returns the canonical grammar alias map (label => grammar name).

Registers a config-owned language at runtime.

Registers a language with an explicit source.

Returns the contribution source for a registry key, or nil if the key is unknown.

Starts the language registry.

Returns all language names that have definitions.

Removes every language and lookup index contributed by a source.

Types

contribution_source()

@type contribution_source() :: :builtin | :config | {:extension, atom()}

Source that contributed registry entries.

register_error()

@type register_error() ::
  {:duplicate_key, term(), contribution_source(), contribution_source()}

Functions

all()

@spec all() :: [Minga.Language.t()]

Returns all registered language definitions.

canonical_grammar(label)

@spec canonical_grammar(String.t()) :: String.t()

Returns the canonical tree-sitter grammar name for a language label.

Resolves short or alternate fence labels (e.g. "js", "c++", "py3") to the canonical grammar name we ship (e.g. "javascript", "cpp", "python"). Matching is case-insensitive. Labels that are already canonical, or that have no alias, are returned unchanged (lower-cased). This is the single source of truth for grammar-name aliasing on the Elixir side.

Examples

iex> Minga.Language.Registry.canonical_grammar("js")
"javascript"

iex> Minga.Language.Registry.canonical_grammar("C++")
"cpp"

iex> Minga.Language.Registry.canonical_grammar("elixir")
"elixir"

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

for_extension(ext)

@spec for_extension(String.t()) :: Minga.Language.t() | nil

Returns the language definition for a file extension, or nil.

The extension should not include the leading dot and is matched case-insensitively.

Examples

iex> lang = Minga.Language.Registry.for_extension("ex")
iex> lang.name
:elixir

for_filename(filename)

@spec for_filename(String.t()) :: Minga.Language.t() | nil

Returns the language definition for an exact filename, or nil.

Examples

iex> lang = Minga.Language.Registry.for_filename("Makefile")
iex> lang.name
:make

for_shebang(interpreter)

@spec for_shebang(String.t()) :: Minga.Language.t() | nil

Returns the language definition for a shebang interpreter, or nil.

Examples

iex> lang = Minga.Language.Registry.for_shebang("python3")
iex> lang.name
:python

get(name)

@spec get(atom()) :: Minga.Language.t() | nil

Returns the language definition for a name atom, or nil if unknown.

Examples

iex> lang = Minga.Language.Registry.get(:elixir)
iex> lang.label
"Elixir"

iex> Minga.Language.Registry.get(:unknown_language)
nil

grammar_aliases()

@spec grammar_aliases() :: %{required(String.t()) => String.t()}

Returns the canonical grammar alias map (label => grammar name).

register(lang)

@spec register(Minga.Language.t()) :: :ok | {:error, register_error()}

Registers a config-owned language at runtime.

Rebuilds the extension, filename, and shebang index entries and records source ownership so reloads and extension unloads can remove contributed data as a group.

register(lang, source)

@spec register(Minga.Language.t(), contribution_source()) ::
  :ok | {:error, register_error()}

Registers a language with an explicit source.

source_for(key)

@spec source_for(term()) :: contribution_source() | nil

Returns the contribution source for a registry key, or nil if the key is unknown.

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the language registry.

supported_names()

@spec supported_names() :: [atom()]

Returns all language names that have definitions.

unregister_source(source)

@spec unregister_source(contribution_source()) :: :ok

Removes every language and lookup index contributed by a source.