diff --git a/spec/fixtures/packages/package-with-rb-filetype/grammars/rb.cson b/spec/fixtures/packages/package-with-rb-filetype/grammars/rb.cson new file mode 100644 index 000000000..8b4d85412 --- /dev/null +++ b/spec/fixtures/packages/package-with-rb-filetype/grammars/rb.cson @@ -0,0 +1,11 @@ +'name': 'Test Ruby' +'scopeName': 'test.rb' +'fileTypes': [ + 'rb' +] +'patterns': [ + { + 'match': 'ruby' + 'name': 'meta.class.ruby' + } +] diff --git a/spec/fixtures/packages/package-with-rb-filetype/package.json b/spec/fixtures/packages/package-with-rb-filetype/package.json new file mode 100644 index 000000000..350967dc5 --- /dev/null +++ b/spec/fixtures/packages/package-with-rb-filetype/package.json @@ -0,0 +1,4 @@ +{ + "name": "package-with-rb-filetype", + "version": "1.0.0" +} diff --git a/spec/syntax-spec.coffee b/spec/grammars-spec.coffee similarity index 86% rename from spec/syntax-spec.coffee rename to spec/grammars-spec.coffee index ecc0c0406..cc975468f 100644 --- a/spec/syntax-spec.coffee +++ b/spec/grammars-spec.coffee @@ -2,7 +2,7 @@ path = require 'path' fs = require 'fs-plus' temp = require 'temp' -describe "the `syntax` global", -> +describe "the `grammars` global", -> beforeEach -> waitsForPromise -> atom.packages.activatePackage('language-text') @@ -25,9 +25,9 @@ describe "the `syntax` global", -> filePath = '/foo/bar/file.js' expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby' atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby') - syntax2 = atom.deserializers.deserialize(atom.grammars.serialize()) - syntax2.addGrammar(grammar) for grammar in atom.grammars.grammars when grammar isnt atom.grammars.nullGrammar - expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby' + grammars2 = atom.deserializers.deserialize(atom.grammars.serialize()) + grammars2.addGrammar(grammar) for grammar in atom.grammars.grammars when grammar isnt atom.grammars.nullGrammar + expect(grammars2.selectGrammar(filePath).name).toBe 'Ruby' describe ".selectGrammar(filePath)", -> it "can use the filePath to load the correct grammar based on the grammar's filetype", -> @@ -94,6 +94,16 @@ describe "the `syntax` global", -> grammar2 = atom.grammars.loadGrammarSync(grammarPath2) expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar2 + it "favors non-bundled packages when breaking scoring ties", -> + waitsForPromise -> + atom.packages.activatePackage(path.join(__dirname, 'fixtures', 'packages', 'package-with-rb-filetype')) + + runs -> + atom.grammars.grammarForScopeName('source.ruby').bundledPackage = true + atom.grammars.grammarForScopeName('test.rb').bundledPackage = false + + expect(atom.grammars.selectGrammar('test.rb').scopeName).toBe 'test.rb' + describe "when there is no file path", -> it "does not throw an exception (regression)", -> expect(-> atom.grammars.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow() diff --git a/src/grammar-registry.coffee b/src/grammar-registry.coffee index 568de483a..7b1ef823f 100644 --- a/src/grammar-registry.coffee +++ b/src/grammar-registry.coffee @@ -35,7 +35,17 @@ class GrammarRegistry extends FirstMate.GrammarRegistry # * `fileContents` A {String} of text for the file path. # # Returns a {Grammar}, never null. - selectGrammar: (filePath, fileContents) -> super + selectGrammar: (filePath, fileContents) -> + bestMatch = null + highestScore = -Infinity + for grammar in @grammars + score = grammar.getScore(filePath, fileContents) + if score > highestScore or not bestMatch? + bestMatch = grammar + highestScore = score + else if score is highestScore and bestMatch?.bundledPackage + bestMatch = grammar unless grammar.bundledPackage + bestMatch clearObservers: -> @off() if includeDeprecatedAPIs diff --git a/src/package.coffee b/src/package.coffee index b48ed8014..65c7af822 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -303,6 +303,7 @@ class Package try grammar = atom.grammars.readGrammarSync(grammarPath) grammar.packageName = @name + grammar.bundledPackage = @bundledPackage @grammars.push(grammar) grammar.activate() catch error @@ -322,6 +323,7 @@ class Package atom.notifications.addFatalError("Failed to load a #{@name} package grammar", {stack, detail, dismissable: true}) else grammar.packageName = @name + grammar.bundledPackage = @bundledPackage @grammars.push(grammar) grammar.activate() if @grammarsActivated callback()