3.3 KiB · text 5af55d9
defmodule GitGud.Languages do
@moduledoc """
Filename → language *display name* detection.
Used by the language-stats walker. Returns the same display strings
the `LanguageColors` palette is keyed on (e.g. "Elixir", "C++", "Go")
so the bar + detail page can color segments without an intermediate
lookup.
Returns `nil` for filenames we don't recognize, which is also how we
skip non-source files (images, binaries, LICENSE, …) from the bar.
"""
@ext %{
".ada" => "Ada",
".adb" => "Ada",
".ads" => "Ada",
".asm" => "Assembly",
".s" => "Assembly",
".bash" => "Bash",
".c" => "C",
".h" => "C",
".cc" => "C++",
".cpp" => "C++",
".cxx" => "C++",
".hpp" => "C++",
".hh" => "C++",
".hxx" => "C++",
".cs" => "C#",
".clj" => "Clojure",
".cljs" => "Clojure",
".cljc" => "Clojure",
".coffee" => "CoffeeScript",
".cr" => "Crystal",
".css" => "CSS",
".dart" => "Dart",
".eex" => "HTML",
".elm" => "Elm",
".erl" => "Erlang",
".hrl" => "Erlang",
".ex" => "Elixir",
".exs" => "Elixir",
".fs" => "F#",
".fsi" => "F#",
".fsx" => "F#",
".go" => "Go",
".graphql" => "GraphQL",
".gql" => "GraphQL",
".hs" => "Haskell",
".hcl" => "HCL",
".tf" => "HCL",
".tfvars" => "HCL",
".heex" => "HTML",
".htm" => "HTML",
".html" => "HTML",
".java" => "Java",
".jl" => "Julia",
".js" => "JavaScript",
".cjs" => "JavaScript",
".mjs" => "JavaScript",
".jsx" => "JavaScript",
".json" => "JSON",
".kt" => "Kotlin",
".kts" => "Kotlin",
".lua" => "Lua",
".md" => "Markdown",
".markdown" => "Markdown",
".ml" => "OCaml",
".mli" => "OCaml",
".nim" => "Nim",
".nix" => "Nix",
".php" => "PHP",
".pl" => "Perl",
".pm" => "Perl",
".ps1" => "PowerShell",
".py" => "Python",
".raku" => "Raku",
".r" => "R",
".rb" => "Ruby",
".rs" => "Rust",
".scala" => "Scala",
".sc" => "Scala",
".scss" => "SCSS",
".sass" => "SCSS",
".sh" => "Bash",
".sol" => "Solidity",
".sql" => "SQL",
".svelte" => "Svelte",
".swift" => "Swift",
".tex" => "LaTeX",
".toml" => "TOML",
".ts" => "TypeScript",
".tsx" => "TypeScript",
".vim" => "Vim Script",
".vue" => "Vue",
".wat" => "WebAssembly",
".yaml" => "YAML",
".yml" => "YAML",
".zig" => "Zig",
".zsh" => "Bash"
}
@basename %{
"dockerfile" => "Dockerfile",
"containerfile" => "Dockerfile",
"makefile" => "Makefile",
"gnumakefile" => "Makefile",
"rakefile" => "Ruby",
"gemfile" => "Ruby",
"mix.exs" => "Elixir",
"mix.lock" => "Elixir",
"rebar.config" => "Erlang"
}
@doc """
Returns the language display name for a filename, or `nil` if we
don't recognize it. Matches case-insensitively on basename and
extension.
"""
@spec detect(String.t() | nil) :: String.t() | nil
def detect(nil), do: nil
def detect(name) when is_binary(name) do
basename = name |> Path.basename() |> String.downcase()
case Map.get(@basename, basename) do
nil ->
ext = basename |> Path.extname()
Map.get(@ext, ext)
lang ->
lang
end
end
@doc false
def ext_map, do: @ext
@doc false
def basename_map, do: @basename
end