1
0
mirror of https://github.com/adobe/brackets.git synced 2024-11-20 09:53:00 +01:00

Fixing issue #2923 - Getting mode from file extension won't always work

This commit is contained in:
Mark Murphy 2013-03-03 11:49:45 -04:00
parent d4a54913d2
commit 6fee2100fe
6 changed files with 86 additions and 18 deletions

5
.gitignore vendored
View File

@ -19,4 +19,7 @@ src/extensions/disabled
# unit test working directory
test/temp
test/results
test/results
# Netbeans
/nbproject

View File

@ -952,8 +952,7 @@ define(function (require, exports, module) {
*/
Document.prototype._updateLanguage = function () {
var oldLanguage = this.language;
var ext = PathUtils.filenameExtension(this.file.fullPath);
this.language = LanguageManager.getLanguageForFileExtension(ext);
this.language = LanguageManager.getLanguageFromFilePath(this.file.fullPath);
if (oldLanguage && oldLanguage !== this.language) {
$(this).triggerHandler("languageChanged", [oldLanguage, this.language]);

View File

@ -1225,7 +1225,7 @@ define(function (require, exports, module) {
*
* @return {?(Object|string)} Name of syntax-highlighting mode, or object containing a "name" property
* naming the mode along with configuration options required by the mode.
* See {@link LanguageManager#getLanguageForFileExtension()} and {@link Language#getMode()}.
* See {@link LanguageManager#getLanguageFromFilePath()} and {@link Language#getMode()}.
*/
Editor.prototype.getModeForSelection = function () {
// Check for mixed mode info
@ -1258,7 +1258,7 @@ define(function (require, exports, module) {
/**
* Gets the syntax-highlighting mode for the document.
*
* @return {Object|String} Object or Name of syntax-highlighting mode; see {@link LanguageManager#getLanguageForFileExtension()} and {@link Language#getMode()}.
* @return {Object|String} Object or Name of syntax-highlighting mode; see {@link LanguageManager#getLanguageFromFilePath()} and {@link Language#getMode()}.
*/
Editor.prototype.getModeForDocument = function () {
return this._codeMirror.getOption("mode");

View File

@ -440,7 +440,7 @@ define(function (require, exports, module) {
file = split.file;
if (file.indexOf(".") > 1) { // ignore /.dotfiles
var mode = LanguageManager.getLanguageForFileExtension(entry.fullPath).getMode();
var mode = LanguageManager.getLanguageFromFilePath(entry.fullPath).getMode();
if (mode === HintUtils.MODE_NAME) {
DocumentManager.getDocumentForPath(path).done(function (document) {
refreshOuterScope(dir, file, document.getText());

View File

@ -95,6 +95,7 @@ define(function (require, exports, module) {
_pendingLanguages = {},
_languages = {},
_fileExtensionToLanguageMap = {},
_fileNameToLanguageMap = {},
_modeToLanguageMap = {},
_ready;
@ -161,7 +162,7 @@ define(function (require, exports, module) {
*/
function _setLanguageForMode(mode, language) {
if (_modeToLanguageMap[mode]) {
console.warn("CodeMirror mode \"" + mode + "\" is already used by language " + _modeToLanguageMap[mode]._name + ", won't register for " + language._name);
console.warn("CodeMirror mode \"" + mode + "\" is already used by language " + _modeToLanguageMap[mode].name + ", won't register for " + language.name);
return;
}
@ -178,16 +179,19 @@ define(function (require, exports, module) {
}
/**
* Resolves a file extension to a Language object.
* @param {!string} path Path to or extension of the file to find a language for
* Resolves a file path to a Language object.
* @param {!string} path Path to the file to find a language for
* @return {Language} The language for the provided file type or the fallback language
*/
function getLanguageForFileExtension(path) {
function getLanguageFromFilePath(path) {
var extension = _normalizeFileExtension(PathUtils.filenameExtension(path)),
language = _fileExtensionToLanguageMap[extension];
filename = PathUtils.filename(path),
language = extension ? _fileExtensionToLanguageMap[extension]
: _fileNameToLanguageMap[filename];
if (!language) {
console.log("Called LanguageManager.getLanguageForFileExtension with an unhandled file extension:", extension);
extension ? console.log("Called LanguageManager.getLanguageFromFilePath with an unhandled file extension:", extension)
: console.log("Called LanguageManager.getLanguageFromFilePath with an unhandled file name:", filename);
}
return language || _fallbackLanguage;
@ -233,6 +237,7 @@ define(function (require, exports, module) {
this._name = name;
this._fileExtensions = [];
this._fileNames = [];
this._modeToLanguageMap = {};
}
@ -249,6 +254,9 @@ define(function (require, exports, module) {
/** @type {Array.<string>} File extensions that use this language */
Language.prototype._fileExtensions = null;
/** @type {Array.<string>} File names for extensionless files that use this language */
Language.prototype._fileNames = null;
/** @type {{ prefix: string }} Line comment syntax */
Language.prototype._lineCommentSyntax = null;
@ -351,6 +359,15 @@ define(function (require, exports, module) {
// Use concat to create a copy of this array, preventing external modification
return this._fileExtensions.concat();
};
/**
* Returns an array of file names for extensionless files that use this language.
* @return {Array.<string>} Extensionless file names used by this language
*/
Language.prototype.getFileNames = function () {
// Use concat to create a copy of this array, preventing external modification
return this._fileNames.concat();
};
/**
* Adds a file extension to this language.
@ -367,7 +384,7 @@ define(function (require, exports, module) {
var language = _fileExtensionToLanguageMap[extension];
if (language) {
console.warn("Cannot register file extension \"" + extension + "\" for " + this._name + ", it already belongs to " + language._name);
console.warn("Cannot register file extension \"" + extension + "\" for " + this.name + ", it already belongs to " + language.name);
} else {
_fileExtensionToLanguageMap[extension] = this;
@ -379,6 +396,31 @@ define(function (require, exports, module) {
}
};
/**
* Adds a file name to the language which is used to match files that don't have extensions like "Makefile" for example.
* Private for now since dependent code would need to by kept in sync with such changes.
* See https://github.com/adobe/brackets/issues/2966 for plans to make this public.
* @param {!string} extension An extensionless file name used by this language
* @private
*/
Language.prototype._addFileName = function (name) {
if (this._fileNames.indexOf(name) === -1) {
this._fileNames.push(name);
var language = _fileNameToLanguageMap[name];
if (language) {
console.warn("Cannot register file name \"" + name + "\" for " + this.name + ", it already belongs to " + language.name);
} else {
_fileNameToLanguageMap[name] = this;
// TODO (issue #2966) Allow extensions to add new file names to existing languages
// Notify on the Language and on LanguageManager?
// $(this).triggerHandler("fileNameAdded", [name]);
// $(exports).triggerHandler("fileNameAdded", [name, this]);
}
}
};
/**
* Returns whether the line comment syntax is defined for this language.
* @return {boolean} Whether line comments are supported
@ -504,6 +546,8 @@ define(function (require, exports, module) {
var language = new Language(id, definition.name),
fileExtensions = definition.fileExtensions,
fileNames = definition.fileNames,
l,
i;
var blockComment = definition.blockComment;
@ -522,10 +566,17 @@ define(function (require, exports, module) {
language._loadAndSetMode(definition.mode).done(function () {
// register language file extensions after mode has loaded
if (fileExtensions) {
for (i = 0; i < fileExtensions.length; i++) {
for (i = 0, l = fileExtensions.length; i < l; i++) {
language._addFileExtension(fileExtensions[i]);
}
}
// register language file names after mode has loaded
if (fileNames) {
for (i = 0, l= fileNames.length; i < l; i++) {
language._addFileName(fileNames[i]);
}
}
// globally associate mode to language
_setLanguageForMode(language.getMode(), language);
@ -584,5 +635,5 @@ define(function (require, exports, module) {
exports.ready = _ready;
exports.defineLanguage = defineLanguage;
exports.getLanguage = getLanguage;
exports.getLanguageForFileExtension = getLanguageForFileExtension;
exports.getLanguageFromFilePath = getLanguageFromFilePath;
});

View File

@ -35,7 +35,7 @@
"xml": {
"name": "XML",
"mode": "xml",
"fileExtensions": ["svg", "xml", "wxs", "wxl"],
"fileExtensions": ["svg", "xml", "wxs", "wxl", "wsdl", "rss", "atom", "rdf", "xslt", "xul", "xbl", "mathml"],
"blockComment": ["<!--", "-->"]
},
@ -85,7 +85,8 @@
"coffeescript": {
"name": "CoffeeScript",
"mode": "coffeescript",
"fileExtensions": ["coffee"]
"fileExtensions": ["coffee", "cf", "cson"],
"fileNames": ["Cakefile"]
},
"clojure": {
@ -103,7 +104,7 @@
"ruby": {
"name": "Ruby",
"mode": "ruby",
"fileExtensions": ["rb"]
"fileExtensions": ["rb", "ru", "gemspec", "rake"]
},
"python": {
@ -135,12 +136,26 @@
"mode": "diff",
"fileExtensions": ["diff", "patch"]
},
"makefile": {
"name": "Makefile",
"mode": "makefile",
"fileExtensions": ["make"],
"fileNames": ["GNUmakefile", "makefile", "Makefile", "OCamlMakefile"],
"lineComment": "#"
},
"markdown": {
"name": "Markdown",
"mode": "markdown",
"fileExtensions": ["md", "markdown"]
},
"typescript": {
"name": "TypeScript",
"mode": ["javascript", "application/typescript"],
"fileExtensions": ["typescript", "ts", "str"]
},
"yaml": {
"name": "YAML",