Minga.Language (Minga v0.1.0)

Copy Markdown View Source

Unified per-language configuration struct.

Every supported language is described by a single %Language{} struct that consolidates data previously spread across Filetype, Comment, Formatter, LSP.ServerRegistry, Highlight.Grammar, Devicon, Modeline, and Project.Detector.

Language definitions live in modules that export a definition/0 function returning a %Language{} struct. Bundled definitions are grouped into language pack extensions under Minga.Extensions.LanguagePacks, and third-party packs register the same struct shape through Minga.Language.Registry.register/2.

Adding a new language

Create a language module inside a pack, return a %Language{} from definition/0, and add that module to the pack's language_modules/0 list. Removing the pack's registry source removes the whole language record, so the language name, filetypes, shebangs, devicon, grammar metadata, formatter, and LSP defaults go away together.

Extension languages

Extensions register languages at runtime via Minga.Language.Registry.register/2, passing a %Language{} struct and a {:extension, name} source.

Summary

Types

t()

A per-language configuration.

Functions

Returns all registered language definitions.

Returns language-owned block auto-close metadata for a language name.

Detects a file's language atom from its path.

Detects filetype using both path and first line content (shebang).

Returns the language definition for a name atom (e.g., :elixir), or nil.

Registers a new language with Minga.

Types

t()

@type t() :: %Minga.Language{
  comment_token: String.t(),
  extensions: [String.t()],
  filenames: [String.t()],
  formatter: String.t() | nil,
  grammar: String.t() | nil,
  icon: String.t() | nil,
  icon_color: non_neg_integer() | nil,
  indent_with: :spaces | :tabs,
  label: String.t(),
  language_servers: [Minga.LSP.ServerConfig.t()],
  name: atom(),
  project_type: atom() | nil,
  root_markers: [String.t()],
  shebangs: [String.t()],
  tab_width: pos_integer()
}

A per-language configuration.

Functions

all()

@spec all() :: [t()]

Returns all registered language definitions.

block_pairs(name)

@spec block_pairs(atom()) :: [Minga.Language.BlockPair.t()]

Returns language-owned block auto-close metadata for a language name.

detect_filetype(path)

@spec detect_filetype(String.t() | nil) :: atom()

Detects a file's language atom from its path.

detect_filetype_from_content(path, first_line)

@spec detect_filetype_from_content(String.t(), String.t()) :: atom()

Detects filetype using both path and first line content (shebang).

get(name)

@spec get(atom()) :: t() | nil

Returns the language definition for a name atom (e.g., :elixir), or nil.

register(name, source_dir, opts \\ [])

@spec register(String.t(), String.t(), [Minga.Language.TreeSitter.register_opt()]) ::
  :ok | {:error, String.t()}

Registers a new language with Minga.

Compiles the tree-sitter grammar sources, loads them into the parser, sends highlight/injection queries, and registers filetype mappings. Compilation and setup failures are reported synchronously; the parser-side load response is asynchronous, so callers decide whether to fail the extension or continue without highlighting.

name is the language identifier (e.g., "org"). source_dir is the path containing the grammar's parser.c and optionally scanner.c.

Options

  • :highlights - path to a highlights.scm query file
  • :injections - path to an injections.scm query file
  • :filetype_extensions - list of file extensions to map (e.g., [".org"])
  • :filetype_filenames - list of exact filenames to map (e.g., ["Orgfile"])
  • :filetype_atom - the filetype atom (e.g., :org)

Example

Minga.Language.register("org", "/path/to/tree-sitter-org/src",
  highlights: "/path/to/queries/org/highlights.scm",
  filetype_extensions: [".org"],
  filetype_atom: :org
)