languages

package module
v0.0.0-...-00c5692 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 4, 2026 License: MIT Imports: 20 Imported by: 0

README

languages

Detect programming languages from a filename, source content, or both. The Go library runs offline and supports WebAssembly. Results include candidate languages, confidence, and conflicting evidence.

Install

go get github.com/git-pkgs/languages

Detection

Pass a filename and source bytes to Detect:

package main

import (
    "fmt"

    "github.com/git-pkgs/languages"
)

func main() {
    source := []byte("const count = 1;\n")
    result := languages.Detect("app.ts", source)
    fmt.Println(result.Language, result.Confidence)
    // Output: TypeScript low
}

Use an empty filename for content-only detection, or nil content to use the filename alone:

source := []byte("use strict;\nuse warnings;\n")
fmt.Println(languages.Detect("", source).Language)      // Perl
fmt.Println(languages.Detect("main.go", nil).Language) // Go

Detect performs no I/O and examines all supplied bytes. You can pass a prefix when the rest of the file is unavailable. Only the final path component is used; conventional filenames are case-sensitive and extensions are case-insensitive. The exceptions are .C, which selects C++, and .H, which has C-family candidates.

For a file, use AnalyzeReader to read to EOF with bounded memory:

func detectFile(ctx context.Context, name string) (languages.Result, error) {
    file, err := os.Open(name)
    if err != nil {
        return languages.Result{}, err
    }
    defer file.Close()

    var content languages.Analysis
    options := languages.ReadOptions{Filename: name}
    if err := languages.AnalyzeReader(ctx, file, options, &content); err != nil {
        return languages.Result{}, err
    }
    return content.Detect(name), nil
}

Set ReadOptions{Bytes: 1024} to read at most 1 KiB; the default reads to EOF. The reader stops exactly at the budget, so reaching it before EOF leaves content.Prefix true. Use ReadOptions{Prefix: true} if the reader contains truncated input.

Read errors and cancellation clear the result; cancellation is checked between reads, and a reader blocked inside Read continues until it returns.

Set ReadOptions.Filename when the result will be detected under one filename. This limits extension heuristics to that name without changing content evidence. Call content.Detect(name) to combine the analysis with the filename. Leave Filename empty to retain extension heuristics for reuse under different names.

Results

Language is languages.Unknown when the result is ambiguous or empty. Check Candidates to distinguish an ambiguous result from an empty one:

result := languages.Detect("source.pl", nil)
switch {
case result.Conflict:
    fmt.Println("conflicting language evidence")
case result.Candidates.Empty():
    fmt.Println("no language detected")
case result.Language == languages.Unknown:
    names, err := json.Marshal(result.Candidates)
    if err != nil {
        panic(err)
    }
    fmt.Printf("ambiguous: %s\n", names)
default:
    fmt.Println(result.Language)
}

The example prints ambiguous: ["Perl","Raku","Prolog"]. Content such as use strict; can resolve the .pl ambiguity to Perl. Check a candidate with result.Candidates.Has(languages.Perl), or count them with result.Candidates.Len().

Language.String() returns the name, and languages.Parse(name) accepts canonical names and aliases regardless of case, including common-lisp.

Conflict indicates disagreement between strong content evidence and the filename, or between a declaration and strong syntax evidence. For example, a Ruby shebang in script.py produces a conflict. Shared syntax, such as JavaScript that is also valid TypeScript, can be narrowed by the filename.

Confidence describes the evidence supporting the result:

  • none: content and filename both unmatched.
  • low: a filename, weak syntax, statistical selection, or conflicting evidence.
  • medium: stronger syntax evidence.
  • high: a shebang or editor modeline, or multiple rules including a strong signal.

For a confidence threshold, compare result.Confidence.Rank() >= languages.Medium.Rank(). High confidence can have several candidates, so check Language as well when you need a single selection. Confidence is an ordinal rank rather than a probability. Statistical is true when the selection comes from the token classifier; these results have low confidence.

Analysis

Use Analyze when you have the complete content, need matched rules, or want to detect the same content under several filenames:

source := []byte("use strict;\nuse warnings;\n")
var content languages.Analysis
languages.Analyze(source, true, &content)

fmt.Println(content.Result().Language)            // Perl
fmt.Println(content.Detect("source.pl").Language) // Perl
fmt.Println(content.Detect("source.py").Conflict) // true

for _, match := range content.Signals[:content.Count] {
    evidence := match.Evidence()
    fmt.Println(evidence.ID, evidence.Description, evidence.Offset)
}

Pass true only when the supplied bytes are the complete file. Use false for a prefix with an unavailable suffix. Detect always treats content as a prefix. content.Prefix records whether the input is incomplete; content.Bytes is the number of original bytes examined.

Emacs and Vim modelines are checked in the first five lines. The last five lines are checked when Analyze or AnalyzeReader receives the complete file.

Analyze resets its destination on each call and does not retain the input buffer. Reuse the buffer and analysis for successive files, with a separate destination for each concurrent call. Result and Detect read the analysis without changing it or rescanning the source.

Rule evidence contains an ID, description, candidate languages, and a byte offset into the original input. Statistical scores lack source offsets and are omitted from Signals. Keep cached analyses in memory; JSON encoding drops their classifier state.

Command line

go install github.com/git-pkgs/languages/cmd/languages@latest

For a file, the CLI writes JSON and combines the filename with content by default. Pass a file, or pipe content to stdin and supply its name with -name:

languages source.pl
printf 'use strict;\n' | languages -name source.pl

Use -mode content to ignore the filename, or -mode path to inspect a filename without opening the file:

languages -mode content source.pl
languages -mode path -name source.pl

The path-only example returns:

{
  "confidence": "low",
  "candidates": ["Perl", "Raku", "Prolog"],
  "bytes_examined": 0,
  "prefix": false,
  "path_evidence": {
    "reason": "extension",
    "candidates": ["Perl", "Raku", "Prolog"]
  }
}

language is omitted for ambiguous and empty results. Unknown, ambiguous, and conflicting results exit successfully, so scripts must inspect the JSON. Argument, file-reading, and output errors produce a nonzero exit status.

The CLI reads full files and stdin to EOF by default. Set a read budget with -bytes, or use -bytes 0 for full input. This command reads up to 1 KiB:

languages -bytes 1024 source.pl

Reaching the budget without EOF sets prefix: true. For input that was truncated before reaching stdin, use -prefix:

languages -prefix -name source.pl < exported-prefix

Directories

Pass a directory to see language totals for the whole tree and each subdirectory:

languages ./project

For a project with Go and TypeScript files, output looks like:

project/  Go 75.0%, TypeScript 25.0% (3 files, 4.0 KiB)
├── api/  Go 100.0% (2 files, 3.0 KiB)
│   └── lib/  Go 100.0% (1 file, 1.0 KiB)
└── web/  TypeScript 100.0% (1 file, 1.0 KiB)

Each directory includes all descendant files, and percentages use full file sizes even when detection reads only a prefix. Unknown, ambiguous, conflicting, and binary files have separate totals and remain in the percentage denominator. partial counts files whose content exceeds the read limit.

Scan a subdirectory on its own, limit the displayed depth, or request JSON:

languages ./project/api
languages -depth 1 ./project
languages -json ./project
languages -bytes 1024 ./project

-depth 0 shows only the root; the default shows every directory containing included files. Depth limits affect text and JSON output without changing the totals. JSON contains path, summary, and children; each summary contains file counts and byte totals, with language names under languages. JSON sizes are integer byte counts so callers can calculate their own shares.

Scans work without Git metadata. They skip .git, symlinks, and non-regular files, and include untracked, ignored, vendored, and generated files. Directory scans use file sizes to identify complete input, including files exactly as large as the read limit.

In Go, Scan accepts an fs.FS:

root, err := os.OpenRoot("project")
if err != nil {
    panic(err)
}
defer root.Close()
tree, err := languages.Scan(context.Background(), root.FS(), languages.ScanOptions{})
if err != nil {
    panic(err)
}
fmt.Println(tree.Root().Summary)
if api, ok := tree.Subtree("api"); ok {
    fmt.Println(api.Summary)
}

Use os.OpenRoot("project/api") or fs.Sub(root.FS(), "api") to scan only a subdirectory. For a mutable or untrusted directory, prefer os.Root; see the Scan documentation for confinement caveats.

Set ScanOptions.Bytes for a read budget, and supply ScanOptions.Exclude to omit files or directories. It receives root-relative paths; returning true for a directory skips its contents:

options := languages.ScanOptions{
    Exclude: func(name string, entry fs.DirEntry) bool {
        return entry.IsDir() && entry.Name() == "vendor"
    },
}

Pass these options as the third argument to Scan; if a file read fails or the context is cancelled, the scan returns an error and discards the partial tree.

If your application already traverses files, feed its analyses into a Tree instead of scanning again:

var tree languages.Tree
source := []byte("package main\n")
var analysis languages.Analysis
languages.Analyze(source, true, &analysis)
if err := tree.Add("api/main.go", int64(len(source)), &analysis); err != nil {
    panic(err)
}
fmt.Println(tree.Root().Summary)

For prefix analyses, pass the full file size to Add. Paths must be unique, slash-separated, and relative to the tree root, without . or .. components. You can reuse the content buffer and analysis after each call. Root and Subtree return independent snapshots with children sorted by path and languages sorted by size, then file count and name. Subtree paths remain relative to the original root; empty directories are omitted.

Limits

Detection matches byte patterns and token frequencies without validating syntax. Comment and string handling is partial, including for heredocs. Embedded languages, minified code, and short fragments may be missed or misidentified.

Go template actions such as {{.Title}} are detected in text and markup; custom delimiters are ignored.

Language metadata and extension heuristics come from Linguist, as do the classifier training samples. Extension heuristics inspect the first 50 KiB; syntax rules and the token classifier process all supplied content. Binary content sets Analysis.Binary and leaves the language unselected.

BOM-marked UTF-16 and UTF-32 are decoded before language analysis. Evidence offsets refer to the original bytes, and a prefix may end inside a code point. Malformed BOM-marked input is rejected. Other non-UTF-8 input is analyzed as raw bytes when its encoding is unrecognized; detection quality may be lower.

License

MIT. Imported Linguist metadata, heuristics, and sample-derived model data are covered by the upstream MIT notice.

Documentation

Overview

Code generated by tools/registrygen; DO NOT EDIT. Linguist heuristics: 5fbdfcb8133be2bed88bf3ce62b2335f50474525. Copyright (c) 2017 GitHub, Inc. MIT license: LICENSE.linguist.

Package languages identifies source languages from content and paths. Content analysis does not require or retain a filename or the input buffer.

Code generated by tools/registrygen; DO NOT EDIT. Linguist metadata: 5fbdfcb8133be2bed88bf3ce62b2335f50474525. Copyright (c) 2017 GitHub, Inc. MIT license: LICENSE.linguist.

Index

Examples

Constants

View Source
const DefaultBytes = 0

DefaultBytes reads the entire file. Positive read budgets select a prefix.

View Source
const MaxSignals = 128

Variables

This section is empty.

Functions

func Analyze

func Analyze(data []byte, complete bool, dst *Analysis)

Analyze inspects all supplied bytes. complete must be false for a prefix whose suffix is unavailable. dst must be non-nil and owned by the calling goroutine.

Example
package main

import (
	"fmt"
	"github.com/git-pkgs/languages"
)

func main() {
	var content languages.Analysis
	languages.Analyze([]byte("use strict;\nuse warnings;\n"), false, &content)
	r := content.Result()
	fmt.Println(r.Language, r.Confidence)
	fmt.Println(languages.AnalyzePath("source.pl").Candidates.Has(languages.Prolog))
	fmt.Println(languages.Combine(&content, languages.AnalyzePath("source.pl")).Language)
}
Output:
Perl high
true
Perl

func AnalyzeReader

func AnalyzeReader(ctx context.Context, reader io.Reader, options ReadOptions, dst *Analysis) error

AnalyzeReader reads content with bounded memory. Reaching a byte budget without EOF leaves Prefix true. Errors clear dst. Cancellation is checked between reads; it cannot interrupt an io.Reader blocked inside Read.

Types

type Analysis

type Analysis struct {
	Signals [MaxSignals]Match
	Count   int
	Bytes   int64
	Prefix  bool
	Binary  bool
	// contains filtered or unexported fields
}

Analysis is a reusable, value-copyable content result with no input references. Only Signals[:Count] is populated. It can be stored with a content object's ID. Prefix is true unless the caller supplied the complete object. JSON encoding omits classifier state.

func (*Analysis) Detect

func (a *Analysis) Detect(filename string) Result

Detect combines reusable content evidence with an optional filename. It does not change the analysis or retain the filename.

func (*Analysis) Result

func (a *Analysis) Result() Result

type Confidence

type Confidence string
const (
	None   Confidence = "none"
	Low    Confidence = "low"
	Medium Confidence = "medium"
	High   Confidence = "high"
)

func (Confidence) Rank

func (c Confidence) Rank() int

Rank orders confidence from none (0) to high (3). Unknown values rank as none.

type Context

type Context struct {
	Candidates Set
	Reason     string
	// contains filtered or unexported fields
}

Context is occurrence-specific evidence. No path string is retained.

func AnalyzePath

func AnalyzePath(path string) Context

AnalyzePath examines only the final path component, with either path separator. Filenames are case-sensitive; extensions are case-insensitive.

func (Context) Result

func (c Context) Result() Result

type Directory

type Directory struct {
	Path     string      `json:"path"`
	Summary  Summary     `json:"summary"`
	Children []Directory `json:"children,omitempty"`
}

Directory includes totals for all descendants. Path is relative to the tree root.

type Evidence

type Evidence struct {
	ID          string `json:"id"`
	Description string `json:"description"`
	Languages   Set    `json:"languages"`
	Offset      uint64 `json:"offset"`
}

type FileTotals

type FileTotals struct {
	Files int64 `json:"files"`
	Bytes int64 `json:"bytes"`
}

type Language

type Language uint16

Language identifies a language within a detector build. Store names, not indices.

const (
	Unknown Language = iota
	Python
	Ruby
	Go
	Rust
	Java
	C
	CPP
	ObjectiveC
	MATLAB
	JavaScript
	TypeScript
	JSX
	TSX
	Shell
	Bash
	Zsh
	Fish
	Perl
	Raku
	CommonLisp
	Scheme
	Clojure
	Racket
	PHP
	Lua
	CSharp
	HTML
	XML
	Jinja
	Twig
	ERB
	SQL
	Prolog
)
const (
	Language1CEnterprise Language = Prolog + 1 + iota
	Language2DimensionalArray
	Language4D
	ABAP
	ABAPCDS
	ABNF
	AGSScript
	AIDL
	AL
	ALGOL
	AMPL
	ANTLR
	APIBlueprint
	APL
	ASL
	ASN1
	ASPNET
	ATS
	ActionScript
	Ada
	AdblockFilterList
	AdobeFontMetrics
	Agda
	Aiken
	Aleo
	Alloy
	AlpineAbuild
	AltiumDesigner
	AngelScript
	AnswerSetProgramming
	AntBuildSystem
	Antlers
	ApacheConf
	Apex
	ApolloGuidanceComputer
	AppleScript
	Arc
	ArkTS
	AsciiDoc
	AspectJ
	Assembly
	Astro
	Asymptote
	Augeas
	AutoHotkey
	AutoIt
	AvroIDL
	Awk
	B
	BFormalMethod
	B4X
	BAML
	BASIC
	BBCode
	BIRD2
	BQN
	Ballerina
	Batchfile
	Beef
	Befunge
	Bend
	Berry
	BibTeX
	BibTeXStyle
	Bicep
	Bikeshed
	Bison
	BitBake
	Blade
	BlitzBasic
	BlitzMax
	Blueprint
	Bluespec
	BluespecBH
	Boo
	Boogie
	Brainfuck
	BrighterScript
	Brightscript
	Browserslist
	Bru
	BuildStream
	CObjDump
	C2hsHaskell
	C3
	CAPCDS
	CIL
	CLIPS
	CMake
	COBOL
	CODEOWNERS
	COLLADA
	CQL
	CSON
	CSS
	CSV
	CUE
	CWeb
	CabalConfig
	Caddyfile
	Cadence
	Cairo
	CairoZero
	CameLIGO
	Cangjie
	CapNProto
	Carbon
	CartoCSS
	Ceylon
	Chapel
	Charity
	Checksums
	ChucK
	Circom
	Cirru
	Clarion
	Clarity
	ClassicASP
	Clean
	Click
	ClosureTemplates
	CloudFirestoreSecurityRules
	Clue
	CoNLLU
	CodeQL
	CoffeeScript
	ColdFusion
	ColdFusionCFC
	CommonWorkflowLanguage
	ComponentPascal
	Cooklang
	Cool
	CppObjDump
	Creole
	Crystal
	Csound
	CsoundDocument
	CsoundScore
	Cuda
	CueSheet
	Curry
	Cycript
	Cylc
	Cypher
	Cython
	D
	DObjDump
	D2
	DIGITALCommandLanguage
	DM
	DNSZone
	DTrace
	Dafny
	DarcsPatch
	Dart
	Daslang
	DataWeave
	DebianPackageControlFile
	DenizenScript
	Dhall
	Diff
	DirectX3DFile
	Dockerfile
	Dogescript
	Dotenv
	Dune
	Dylan
	E
	EMail
	EBNF
	ECL
	ECLiPSe
	EJS
	EQ
	Eagle
	Earthly
	Easybuild
	EcereProjects
	Ecmarkup
	Edge
	EdgeQL
	EditorConfig
	EdjeDataCollection
	Eiffel
	Elixir
	Elm
	Elvish
	ElvishTranscript
	EmacsLisp
	EmberScript
	Erlang
	Euphoria
	FSharp
	F
	FIGletFont
	FIRRTL
	FLUX
	FPP
	Factor
	Fancy
	Fantom
	Faust
	Fennel
	FilebenchWML
	Filterscript
	FlatBuffers
	Flix
	Fluent
	Formatted
	Forth
	Fortran
	FortranFreeForm
	FreeBASIC
	FreeMarker
	Frege
	Futhark
	GCode
	GAML
	GAMS
	GAP
	GCCMachineDescription
	GDB
	GDScript
	GDShader
	GEDCOM
	GLSL
	GN
	GSC
	GameMakerLanguage
	GemfileLock
	Gemini
	Genero4gl
	GeneroPer
	Genie
	Genshi
	GentooEbuild
	GentooEclass
	GerberImage
	GettextCatalog
	Gherkin
	GitAttributes
	GitCommit
	GitConfig
	GitRevisionList
	Gleam
	GlimmerJS
	GlimmerTS
	Glyph
	GlyphBitmapDistributionFormat
	Gno
	Gnuplot
	GoChecksums
	GoModule
	GoTemplate
	GoWorkspace
	GodotResource
	Golo
	Gosu
	Grace
	Gradle
	GradleKotlinDSL
	GrammaticalFramework
	GraphModelingLanguage
	GraphQL
	GraphvizDOT
	Groovy
	GroovyServerPages
	GtkRC
	HAProxy
	HCL
	HIP
	HLSL
	HOCON
	HTMLPlusECR
	HTMLPlusEEX
	HTMLPlusRazor
	HTTP
	HXML
	Hack
	Haml
	Handlebars
	Harbour
	Hare
	Haskell
	Haxe
	HiveQL
	HolyC
	HostsFile
	Hurl
	Hy
	HyPhy
	IDL
	IGORPro
	ILAssembly
	INI
	IRCLog
	ISPC
	Idris
	IgnoreList
	ImHexPatternLanguage
	ImageJMacro
	Imba
	Inform7
	Ink
	InnoSetup
	Io
	Ioke
	Isabelle
	IsabelleROOT
	J
	JARManifest
	JASS
	JCL
	JFlex
	JSON
	JSONWithComments
	JSON5
	JSONLD
	JSONiq
	Jac
	Jai
	Janet
	Jasmin
	JavaProperties
	JavaServerPages
	JavaTemplateEngine
	JavaScriptPlusERB
	JestSnapshot
	JetBrainsMPS
	Jison
	JisonLex
	Jolie
	Jsonnet
	Julia
	JuliaREPL
	JupyterNotebook
	Just
	KCL
	KDL
	KFramework
	KRL
	KaitaiStruct
	KakouneScript
	KerboScript
	KiCadLayout
	KiCadLegacyLayout
	KiCadSchematic
	Kickstart
	Kit
	KoLmafiaASH
	Koka
	Kotlin
	Kusto
	LFE
	LLVM
	LLVMTableGen
	LOLCODE
	LSL
	LTspiceSymbol
	LabVIEW
	Lambdapi
	Langium
	Lark
	Lasso
	Latte
	Lean
	Lean4
	Leo
	Less
	Lex
	LigoLANG
	LilyPond
	Limbo
	LinearProgramming
	LinkerScript
	LinuxKernelModule
	Liquid
	Liquidsoap
	LiterateAgda
	LiterateCoffeeScript
	LiterateHaskell
	LiveCodeScript
	LiveScript
	Lobster
	Logos
	Logtalk
	LookML
	LoomScript
	Luau
	M
	M3U
	M4
	M4Sugar
	MAXScript
	MDX
	MLIR
	MQL4
	MQL5
	MTML
	MUF
	Macaulay2
	Makefile
	Mako
	Markdown
	Marko
	Mask
	MathematicalProgrammingSystem
	MavenPOM
	Max
	MeTTa
	Mercury
	Mermaid
	Meson
	Metal
	MicrosoftDeveloperStudioProject
	MicrosoftVisualStudioSolution
	MiniD
	MiniScript
	MiniYAML
	MiniZinc
	MiniZincData
	Mint
	Mirah
	Modelica
	Modula2
	Modula3
	ModuleManagementSystem
	Mojo
	Monkey
	MonkeyC
	Moocode
	MoonBit
	MoonScript
	Motoko
	Motorola68KAssembly
	Move
	Muse
	Mustache
	Myghty
	NASL
	NCL
	NEON
	NL
	NMODL
	NPMConfig
	NSIS
	NWScript
	Nasal
	Nearley
	Nemerle
	NetLinx
	NetLinxPlusERB
	NewLisp
	Nextflow
	Nginx
	Nickel
	Nim
	Ninja
	Nit
	Nix
	Noir
	Nu
	NumPy
	Nunjucks
	Nushell
	OASv2Json
	OASv2Yaml
	OASv3Json
	OASv3Yaml
	OCaml
	OMNeTPlusPlusMSG
	OMNeTPlusPlusNED
	Oberon
	ObjDump
	ObjectDataInstanceNotation
	ObjectScript
	ObjectiveCPlusPlus
	ObjectiveJ
	Odin
	Omgrofl
	Opa
	Opal
	OpenPolicyAgent
	OpenAPISpecificationV2
	OpenAPISpecificationV3
	OpenCL
	OpenEdgeABL
	OpenQASM
	OpenRCRunscript
	OpenSCAD
	OpenStepPropertyList
	OpenTypeFeatureFile
	OptionList
	Org
	OverPy
	OverpassQL
	Ox
	Oxygene
	Oz
	P4
	PDDL
	PEGJs
	PLSQL
	PLpgSQL
	POVRaySDL
	Pact
	Pan
	Papyrus
	Parrot
	ParrotAssembly
	ParrotInternalRepresentation
	Pascal
	Pawn
	Pep8
	Pic
	Pickle
	PicoLisp
	PigLatin
	Pike
	PipRequirements
	Pkl
	PlantUML
	Pod
	Pod6
	PogoScript
	Polar
	Pony
	Portugol
	PostCSS
	PostScript
	PowerQuery
	PowerBuilder
	PowerShell
	Praat
	Prisma
	ProC
	Processing
	Procfile
	Proguard
	Promela
	PropellerSpin
	ProtocolBuffer
	ProtocolBufferTextFormat
	PublicKey
	Pug
	Puppet
	PureData
	PureBasic
	PureScript
	Pyret
	PythonConsole
	PythonTraceback
	QSharp
	QML
	QMake
	QtScript
	Quake
	QuakeC
	QuartusSimulationIP
	QuickBASIC
	Quint
	R
	RAML
	RAScript
	RBS
	RDoc
	REALbasic
	REXX
	RMarkdown
	RON
	ROSInterface
	RPC
	RPGLE
	RPMSpec
	RUNOFF
	Ragel
	Rascal
	RawTokenData
	ReScript
	ReadlineConfig
	Reason
	ReasonLIGO
	Rebol
	RecordJar
	Red
	Redcode
	RedirectRules
	Redscript
	RegularExpression
	RenPy
	RenderScript
	Rez
	Rhai
	RichTextFormat
	Ring
	Riot
	RobotFramework
	RobotsExclusionRules
	Roc
	RocqProver
	Roff
	RoffManpage
	Rouge
	RouterOSScript
	SAS
	SCSS
	SELinuxPolicy
	SIP
	SMT
	SPARQL
	SQF
	SQLPL
	SRecodeTemplate
	SSHConfig
	STAR
	STL
	STON
	SVG
	SWIG
	Sage
	Sail
	Salt
	Sass
	Scala
	Scaml
	Scenic
	Scilab
	Self
	ShaderLab
	ShellCheckConfig
	ShellSession
	Shen
	Sieve
	SimpleFileVerification
	Singularity
	Slang
	Slash
	Slice
	Slim
	Slint
	SmPL
	Smali
	Smalltalk
	Smarty
	Smithy
	Snakemake
	Solidity
	Soong
	SourcePawn
	SpiceDBSchema
	SplineFontDatabase
	Squirrel
	Stan
	StandardML
	Starlark
	Stata
	StringTemplate
	Stylus
	SubRipText
	SugarSS
	SuperCollider
	SurrealQL
	SurvexData
	Svelte
	Sway
	Sweave
	Swift
	SystemVerilog
	TIProgram
	TLVerilog
	TLA
	TMDL
	TOML
	TSPLIBData
	TSQL
	TSV
	TXL
	Tact
	Talon
	Tape
	Tcl
	Tcsh
	TeX
	Tea
	Teal
	Terra
	TerraformTemplate
	Texinfo
	Text
	TextGrid
	TextMateProperties
	Textile
	Thrift
	Toit
	Tolk
	TorConfig
	TreeSitterQuery
	Turing
	Turtle
	TypeLanguage
	TypeSpec
	Typst
	UnifiedParallelC
	Unity3DAsset
	UnixAssembly
	Uno
	UnrealScript
	UntypedPlutusCore
	UrWeb
	V
	VBA
	VBScript
	VCL
	VHDL
	Vala
	ValveDataFormat
	VelocityTemplateLanguage
	Vento
	Verilog
	Verse
	VespaSchemaDefinition
	VimHelpFile
	VimSnippet
	VimScript
	VisualBasicNET
	VisualBasic60
	Volt
	Vue
	Vyper
	WDL
	WGSL
	WavefrontMaterial
	WavefrontObject
	WebOntologyLanguage
	WebAssembly
	WebAssemblyInterfaceType
	WebIDL
	WebVTT
	WgetConfig
	Whiley
	Wikitext
	Win32MessageFile
	WindowsRegistryEntries
	WitcherScript
	WolframLanguage
	Wollok
	WorldOfWarcraftAddonData
	Wren
	XBitMap
	XFontDirectoryIndex
	XPixMap
	X10
	XC
	XCompose
	XMLPropertyList
	XPages
	XProc
	XQuery
	XS
	XSLT
	Xmake
	Xojo
	Xonsh
	Xtend
	YAML
	YANG
	YARA
	YASnippet
	Yacc
	Yul
	ZAP
	ZIL
	Zeek
	ZenScript
	Zephir
	Zig
	Zimpl
	Zmodel
	CURLConfig
	Crontab
	Desktop
	Dircolors
	EC
	Edn
	Hoon
	ICalendar
	Jq
	Kvlang
	MIRCScript
	Mcfunction
	Mdsvex
	Mupad
	Nanorc
	NesC
	Ooc
	PkgConfig
	Q
	ReStructuredText
	Sed
	Templ
	Ucode
	VCard
	Wisp
	XBase
	LanguageCount
)

func Parse

func Parse(name string) Language

func (Language) String

func (l Language) String() string

type LanguageTotals

type LanguageTotals struct {
	Language string `json:"language"`
	FileTotals
}

type Match

type Match struct {
	Rule   uint16
	Offset uint64
}

Match records the first occurrence of a rule. Offsets refer to the original bytes. Rule indices are build-specific; use Evidence().ID for stored results.

func (Match) Evidence

func (m Match) Evidence() Evidence

type ReadOptions

type ReadOptions struct {
	Bytes  int64 // Zero reads to EOF; positive values set an exact read budget.
	Prefix bool  // The reader contains a prefix even if it reaches EOF.
	// Filename limits extension heuristics to this name; empty evaluates all groups.
	Filename string
}

type Result

type Result struct {
	Language    Language
	Confidence  Confidence
	Candidates  Set
	Conflict    bool
	Statistical bool
}

Result leaves Language empty when the evidence supports multiple candidates. Confidence describes rule support, not an empirical probability.

func Combine

func Combine(a *Analysis, c Context) Result

Combine narrows content candidates with a path, preserving declaration conflicts.

func Detect

func Detect(filename string, content []byte) Result

Detect identifies source from a filename and the supplied content. Either input may be empty. Content is treated as a prefix; use Analyze with complete=true and Analysis.Detect when the supplied content is complete.

Example
package main

import (
	"fmt"
	"github.com/git-pkgs/languages"
)

func main() {
	result := languages.Detect("app.ts", []byte("const count = 1;\n"))
	fmt.Println(result.Language)
}
Output:
TypeScript

type ScanOptions

type ScanOptions struct {
	Bytes int64 // Zero reads each entire file; positive values limit bytes per file.
	// Exclude receives root-relative paths. Excluding a directory skips its descendants.
	Exclude func(string, fs.DirEntry) bool
}

type Set

type Set struct {
	// contains filtered or unexported fields
}

Set stores language candidates without allocation. Its zero value is empty.

func NewSet

func NewSet(languages ...Language) (s Set)

func (Set) Empty

func (s Set) Empty() bool

func (Set) Has

func (s Set) Has(l Language) bool

func (Set) Intersect

func (s Set) Intersect(other Set) Set

func (Set) Len

func (s Set) Len() int

func (Set) MarshalJSON

func (s Set) MarshalJSON() ([]byte, error)

MarshalJSON writes candidate names, independent of numeric language indices.

func (Set) Only

func (s Set) Only() Language

func (Set) Union

func (s Set) Union(other Set) Set

func (*Set) UnmarshalJSON

func (s *Set) UnmarshalJSON(data []byte) error

type Summary

type Summary struct {
	FileTotals
	Languages  []LanguageTotals `json:"languages"`
	Unknown    FileTotals       `json:"unknown"`
	Ambiguous  FileTotals       `json:"ambiguous"`
	Conflicts  FileTotals       `json:"conflicts"`
	Binary     FileTotals       `json:"binary"`
	Incomplete int64            `json:"incomplete"`
}

Summary counts each file once, including files with no selected language.

type Tree

type Tree struct {
	// contains filtered or unexported fields
}

Tree accumulates file analyses without retaining their content or analysis buffers. Its zero value is ready to use. Add must not run concurrently with other operations.

func Scan

func Scan(ctx context.Context, fsys fs.FS, options ScanOptions) (*Tree, error)

Scan summarizes regular files in fsys. Git metadata and symlinks are skipped. Use fs.Sub to select a subtree. On an error no partial tree is returned.

Confinement depends on fsys: a file replaced after enumeration is opened as-is, and os.DirFS and fs.Sub follow the replacement. For a mutable or untrusted directory, pass os.Root.FS, subject to its documented platform guarantees.

func (*Tree) Add

func (t *Tree) Add(name string, size int64, analysis *Analysis) error

Add records one file using its full size and filename-contextual detection. Names must be unique, slash-separated relative file paths without dot components.

func (*Tree) Root

func (t *Tree) Root() Directory

Root returns an independent snapshot, with children sorted by path.

func (*Tree) Subtree

func (t *Tree) Subtree(name string) (Directory, bool)

Subtree returns a snapshot of an existing directory, retaining root-relative paths. Language totals are ordered by bytes, then file count, then language name.

Directories

Path Synopsis
cmd
evaluate command
languages command
localscan command
internal
benchbatch command
benchbatch measures retained heap while scanning without retaining results.
benchbatch measures retained heap while scanning without retaining results.
classifier
Package classifier scores content with a generated lexical model.
Package classifier scores content with a generated lexical model.
cli
localscan
Package localscan measures local repository scans and builds weakly labelled samples.
Package localscan measures local repository scans and builds weakly labelled samples.
modelgen command
modelgen builds a bounded content classifier from Linguist samples.
modelgen builds a bounded content classifier from Linguist samples.
tokenize
Package tokenize extracts lexical features for training and classification.
Package tokenize extracts lexical features for training and classification.
wasmcheck command
wasmcheck exercises the module API under native Go and WebAssembly.
wasmcheck exercises the module API under native Go and WebAssembly.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL