@@ -30,7 +30,6 @@ async function analyse(input?: string | string[], opts: T.Options = {}): Promise
30
30
31
31
// Setup main variables
32
32
const fileAssociations : Record < T . FilePath , T . LanguageResult [ ] > = { } ;
33
- const definiteness : Record < T . FilePath , true | undefined > = { } ;
34
33
const extensions : Record < T . FilePath , string > = { } ;
35
34
const overrides : Record < T . FilePath , T . LanguageResult > = { } ;
36
35
const results : T . Results = {
@@ -164,6 +163,8 @@ async function analyse(input?: string | string[], opts: T.Options = {}): Promise
164
163
} ;
165
164
const overridesArray = Object . entries ( overrides ) ;
166
165
// List all languages that could be associated with a given file
166
+ const definiteness : Record < T . FilePath , true | undefined > = { } ;
167
+ const fromShebang : Record < T . FilePath , true | undefined > = { } ;
167
168
for ( const file of files ) {
168
169
let firstLine : string | null ;
169
170
if ( useRawContent ) {
@@ -197,11 +198,13 @@ async function analyse(input?: string | string[], opts: T.Options = {}): Promise
197
198
matches . push ( lang ) ;
198
199
}
199
200
}
201
+ // Add identified language(s)
200
202
if ( matches . length ) {
201
- // Add explicitly-identified language
202
- const forcedLang = matches [ 0 ] ;
203
- addResult ( file , forcedLang ) ;
204
- definiteness [ file ] = true ;
203
+ for ( const match of matches )
204
+ addResult ( file , match ) ;
205
+ if ( matches . length === 1 )
206
+ definiteness [ file ] = true ;
207
+ fromShebang [ file ] = true ;
205
208
continue ;
206
209
}
207
210
}
@@ -268,9 +271,8 @@ async function analyse(input?: string | string[], opts: T.Options = {}): Promise
268
271
// Parse heuristics if applicable
269
272
if ( opts . checkHeuristics ) for ( const heuristics of heuristicsData . disambiguations ) {
270
273
// Make sure the extension matches the current file
271
- if ( ! heuristics . extensions . includes ( extensions [ file ] ) ) {
274
+ if ( ! fromShebang [ file ] && ! heuristics . extensions . includes ( extensions [ file ] ) )
272
275
continue ;
273
- }
274
276
// Load heuristic rules
275
277
for ( const heuristic of heuristics . rules ) {
276
278
// Make sure the language is not an array
@@ -281,7 +283,8 @@ async function analyse(input?: string | string[], opts: T.Options = {}): Promise
281
283
const languageGroup = langData [ heuristic . language ] ?. group ;
282
284
const matchesLang = fileAssociations [ file ] . includes ( heuristic . language ) ;
283
285
const matchesParent = languageGroup && fileAssociations [ file ] . includes ( languageGroup ) ;
284
- if ( ! matchesLang && ! matchesParent ) continue ;
286
+ if ( ! matchesLang && ! matchesParent )
287
+ continue ;
285
288
// Normalise heuristic data
286
289
const patterns : string [ ] = [ ] ;
287
290
const normalise = ( contents : string | string [ ] ) => patterns . push ( ...[ contents ] . flat ( ) ) ;
0 commit comments