diff --git a/spec/grammars-spec.coffee b/spec/grammars-spec.coffee index 82a29892a..a36a10170 100644 --- a/spec/grammars-spec.coffee +++ b/spec/grammars-spec.coffee @@ -142,9 +142,13 @@ describe "the `grammars` global", -> expect(atom.grammars.selectGrammar('Rakefile', '').scopeName).toBe 'source.coffee' expect(atom.grammars.selectGrammar('Cakefile', '').scopeName).toBe 'source.ruby' - it "favors grammars with matching first-line-regexps even if custom file types match the file", -> + it "favors user-defined file types over grammars with matching first-line-regexps", -> atom.config.set('core.customFileTypes', 'source.ruby': ['bootstrap']) - expect(atom.grammars.selectGrammar('bootstrap', '#!/usr/bin/env node').scopeName).toBe 'source.js' + expect(atom.grammars.selectGrammar('bootstrap', '#!/usr/bin/env node').scopeName).toBe 'source.ruby' + + describe "when there is a grammar with a first line pattern, the file type of the file is known, but from a different grammar", -> + it "favors file type over the matching pattern", -> + expect(atom.grammars.selectGrammar('foo.rb', '#!/usr/bin/env node').scopeName).toBe 'source.ruby' describe ".removeGrammar(grammar)", -> it "removes the grammar, so it won't be returned by selectGrammar", -> diff --git a/src/grammar-registry.coffee b/src/grammar-registry.coffee index 4a5352275..383d4d776 100644 --- a/src/grammar-registry.coffee +++ b/src/grammar-registry.coffee @@ -36,21 +36,21 @@ class GrammarRegistry extends FirstMate.GrammarRegistry if score > highestScore or not bestMatch? bestMatch = grammar highestScore = score - else if score is highestScore and bestMatch?.bundledPackage - bestMatch = grammar unless grammar.bundledPackage bestMatch # Extended: Returns a {Number} representing how well the grammar matches the # `filePath` and `contents`. getGrammarScore: (grammar, filePath, contents) -> + return Infinity if @grammarOverrideForPath(filePath) is grammar.scopeName + contents = fs.readFileSync(filePath, 'utf8') if not contents? and fs.isFileSync(filePath) - if @grammarOverrideForPath(filePath) is grammar.scopeName - 2 + (filePath?.length ? 0) - else if @grammarMatchesContents(grammar, contents) - 1 + (filePath?.length ? 0) - else - @getGrammarPathScore(grammar, filePath) + score = @getGrammarPathScore(grammar, filePath) + if score > 0 and not grammar.bundledPackage + score += 0.25 + if @grammarMatchesContents(grammar, contents) + score += 0.125 + score getGrammarPathScore: (grammar, filePath) -> return -1 unless filePath