mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 15:37:46 +03:00
Start work on custom scope -> filetypes configuration
This commit is contained in:
parent
5fb456309a
commit
989bb86199
@ -110,6 +110,11 @@ describe "the `grammars` global", ->
|
||||
expect(-> atom.grammars.selectGrammar(null, '')).not.toThrow()
|
||||
expect(-> atom.grammars.selectGrammar(null, null)).not.toThrow()
|
||||
|
||||
describe "when the user has custom grammar filetypes", ->
|
||||
it "considers the custom filetypes as well as those defined in the grammar", ->
|
||||
atom.config.set('core.fileTypesByScope', 'source.ruby': ['Cheffile'])
|
||||
expect(atom.grammars.selectGrammar('build/Cheffile', 'cookbook "postgres"').scopeName).toBe 'source.ruby'
|
||||
|
||||
describe ".removeGrammar(grammar)", ->
|
||||
it "removes the grammar, so it won't be returned by selectGrammar", ->
|
||||
grammar = atom.grammars.selectGrammar('foo.js')
|
||||
|
@ -26,6 +26,9 @@ module.exports =
|
||||
default: []
|
||||
items:
|
||||
type: 'string'
|
||||
fileTypesByScope:
|
||||
type: 'object'
|
||||
default: {}
|
||||
themes:
|
||||
type: 'array'
|
||||
default: ['one-dark-ui', 'one-dark-syntax']
|
||||
|
@ -1,7 +1,11 @@
|
||||
_ = require 'underscore-plus'
|
||||
{Emitter} = require 'event-kit'
|
||||
{includeDeprecatedAPIs, deprecate} = require 'grim'
|
||||
FirstMate = require 'first-mate'
|
||||
Token = require './token'
|
||||
fs = require 'fs-plus'
|
||||
|
||||
PathSplitRegex = new RegExp("[/.]")
|
||||
|
||||
# Extended: Syntax class holding the grammars used for tokenizing.
|
||||
#
|
||||
@ -39,7 +43,7 @@ class GrammarRegistry extends FirstMate.GrammarRegistry
|
||||
bestMatch = null
|
||||
highestScore = -Infinity
|
||||
for grammar in @grammars
|
||||
score = grammar.getScore(filePath, fileContents)
|
||||
score = @getGrammarScore(grammar, filePath, fileContents)
|
||||
if score > highestScore or not bestMatch?
|
||||
bestMatch = grammar
|
||||
highestScore = score
|
||||
@ -47,6 +51,87 @@ class GrammarRegistry extends FirstMate.GrammarRegistry
|
||||
bestMatch = grammar unless grammar.bundledPackage
|
||||
bestMatch
|
||||
|
||||
# Extended: Returns a {Number} representing how well the grammar matches the
|
||||
# `filePath` and `contents`.
|
||||
getGrammarScore: (grammar, filePath, contents) ->
|
||||
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)
|
||||
|
||||
getGrammarPathScore: (grammar, filePath) ->
|
||||
return -1 unless filePath
|
||||
filePath = filePath.replace(/\\/g, '/') if process.platform is 'win32'
|
||||
|
||||
pathComponents = filePath.toLowerCase().split(PathSplitRegex)
|
||||
pathScore = -1
|
||||
|
||||
fileTypes = grammar.fileTypes
|
||||
if customFileTypes = atom.config.get('core.fileTypesByScope')?[grammar.scopeName]
|
||||
fileTypes = fileTypes.concat(customFileTypes)
|
||||
|
||||
for fileType in fileTypes
|
||||
fileTypeComponents = fileType.toLowerCase().split(PathSplitRegex)
|
||||
pathSuffix = pathComponents[-fileTypeComponents.length..-1]
|
||||
if _.isEqual(pathSuffix, fileTypeComponents)
|
||||
pathScore = Math.max(pathScore, fileType.length)
|
||||
pathScore
|
||||
|
||||
grammarMatchesContents: (grammar, contents) ->
|
||||
return false unless contents? and grammar.firstLineRegex?
|
||||
|
||||
escaped = false
|
||||
numberOfNewlinesInRegex = 0
|
||||
for character in grammar.firstLineRegex.source
|
||||
switch character
|
||||
when '\\'
|
||||
escaped = !escaped
|
||||
when 'n'
|
||||
numberOfNewlinesInRegex++ if escaped
|
||||
escaped = false
|
||||
else
|
||||
escaped = false
|
||||
lines = contents.split('\n')
|
||||
grammar.firstLineRegex.testSync(lines[0..numberOfNewlinesInRegex].join('\n'))
|
||||
|
||||
# Public: Get the grammar override for the given file path.
|
||||
#
|
||||
# * `filePath` A {String} file path.
|
||||
#
|
||||
# Returns a {Grammar} or undefined.
|
||||
grammarOverrideForPath: (filePath) ->
|
||||
@grammarOverridesByPath[filePath]
|
||||
|
||||
# Public: Set the grammar override for the given file path.
|
||||
#
|
||||
# * `filePath` A non-empty {String} file path.
|
||||
# * `scopeName` A {String} such as `"source.js"`.
|
||||
#
|
||||
# Returns a {Grammar} or undefined.
|
||||
setGrammarOverrideForPath: (filePath, scopeName) ->
|
||||
if filePath
|
||||
@grammarOverridesByPath[filePath] = scopeName
|
||||
|
||||
# Public: Remove the grammar override for the given file path.
|
||||
#
|
||||
# * `filePath` A {String} file path.
|
||||
#
|
||||
# Returns undefined.
|
||||
clearGrammarOverrideForPath: (filePath) ->
|
||||
delete @grammarOverridesByPath[filePath]
|
||||
undefined
|
||||
|
||||
# Public: Remove all grammar overrides.
|
||||
#
|
||||
# Returns undefined.
|
||||
clearGrammarOverrides: ->
|
||||
@grammarOverridesByPath = {}
|
||||
undefined
|
||||
|
||||
clearObservers: ->
|
||||
@off() if includeDeprecatedAPIs
|
||||
@emitter = new Emitter
|
||||
|
@ -68,7 +68,7 @@ class TokenizedBuffer extends Model
|
||||
if grammar.injectionSelector?
|
||||
@retokenizeLines() if @hasTokenForSelector(grammar.injectionSelector)
|
||||
else
|
||||
newScore = grammar.getScore(@buffer.getPath(), @getGrammarSelectionContent())
|
||||
newScore = atom.grammars.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent())
|
||||
@setGrammar(grammar, newScore) if newScore > @currentGrammarScore
|
||||
|
||||
setGrammar: (grammar, score) ->
|
||||
@ -76,7 +76,7 @@ class TokenizedBuffer extends Model
|
||||
|
||||
@grammar = grammar
|
||||
@rootScopeDescriptor = new ScopeDescriptor(scopes: [@grammar.scopeName])
|
||||
@currentGrammarScore = score ? grammar.getScore(@buffer.getPath(), @getGrammarSelectionContent())
|
||||
@currentGrammarScore = score ? atom.grammars.getGrammarScore(grammar, @buffer.getPath(), @getGrammarSelectionContent())
|
||||
|
||||
@grammarUpdateDisposable?.dispose()
|
||||
@grammarUpdateDisposable = @grammar.onDidUpdate => @retokenizeLines()
|
||||
|
Loading…
Reference in New Issue
Block a user