Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit cc47043

Browse files
committed
Cleanups to status bar language-switcher:
* Make LanguageManager the official public API that is used to set per-file overrides, rather than proxying through Document objects - remove Document.setLanguageOverride() * Clear path overrides when switching projects, so it's more obvious that it's not something that gets persisted across sessions * Simplify how JS Code Hints listen for language updates: remove dependency on "currentDocumentLanguageChanged" event; remove unneeded extra 'if' tests
1 parent ce7e691 commit cc47043

7 files changed

Lines changed: 63 additions & 70 deletions

File tree

src/document/Document.js

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -672,19 +672,7 @@ define(function (require, exports, module) {
672672
};
673673

674674
/**
675-
* Overrides the default language of this document and sets it to the given
676-
* language. This change is not persisted if the document is closed.
677-
* @param {?Language} language The language to be set for this document; if
678-
* null, the language will be set back to the default.
679-
*/
680-
Document.prototype.setLanguageOverride = function (language) {
681-
LanguageManager._setLanguageOverrideForPath(this.file.fullPath, language);
682-
this._updateLanguage();
683-
};
684-
685-
/**
686-
* Updates the language according to the file extension. If the current
687-
* language was forced (set manually by user), don't change it.
675+
* Updates the language to match the current mapping given by LanguageManager
688676
*/
689677
Document.prototype._updateLanguage = function () {
690678
var oldLanguage = this.language;

src/editor/EditorStatusBar.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,9 +365,9 @@ define(function (require, exports, module) {
365365
var document = EditorManager.getActiveEditor().document,
366366
fullPath = document.file.fullPath,
367367
defaultLang = LanguageManager.getLanguageForPath(fullPath, true);
368-
// if default language selected, don't "force" it
369-
// (passing in null will reset the force flag)
370-
document.setLanguageOverride(lang === defaultLang ? null : lang);
368+
369+
// if default language selected, pass null to clear the override
370+
LanguageManager.setLanguageOverrideForPath(fullPath, lang === defaultLang ? null : lang);
371371
});
372372

373373
$statusOverwrite.on("click", _updateEditorOverwriteMode);

src/extensions/default/JavaScriptCodeHints/ScopeManager.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,8 +1037,8 @@ define(function (require, exports, module) {
10371037
* Do the work to initialize a code hinting session.
10381038
*
10391039
* @param {Session} session - the active hinting session
1040-
* @param {Document} document - the document the editor has changed to
1041-
* @param {Document} previousDocument - the document the editor has changed from
1040+
* @param {!Document} document - the document the editor has changed to
1041+
* @param {?Document} previousDocument - the document the editor has changed from
10421042
*/
10431043
function doEditorChange(session, document, previousDocument) {
10441044
var file = document.file,
@@ -1138,7 +1138,7 @@ define(function (require, exports, module) {
11381138
*
11391139
* @param {Session} session - the active hinting session
11401140
* @param {Document} document - the document of the editor that has changed
1141-
* @param {Document} previousDocument - the document of the editor is changing from
1141+
* @param {?Document} previousDocument - the document of the editor is changing from
11421142
*/
11431143
function handleEditorChange(session, document, previousDocument) {
11441144
if (addFilesPromise === null) {
@@ -1376,7 +1376,7 @@ define(function (require, exports, module) {
13761376
*
13771377
* @param {Session} session - the active hinting session
13781378
* @param {Document} document - the document of the editor that has changed
1379-
* @param {Document} previousDocument - the document of the editor is changing from
1379+
* @param {?Document} previousDocument - the document of the editor is changing from
13801380
*/
13811381
function handleEditorChange(session, document, previousDocument) {
13821382

src/extensions/default/JavaScriptCodeHints/main.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ define(function (require, exports, module) {
564564
* information, and reject any pending deferred requests.
565565
*
566566
* @param {Editor} editor - editor context to be initialized.
567-
* @param {Editor} previousEditor - the previous editor.
567+
* @param {?Editor} previousEditor - the previous editor.
568568
*/
569569
function initializeSession(editor, previousEditor) {
570570
session = new Session(editor);
@@ -579,7 +579,7 @@ define(function (require, exports, module) {
579579
*
580580
* @param {Editor} editor - editor context on which to listen for
581581
* changes
582-
* @param {Editor} previousEditor - the previous editor
582+
* @param {?Editor} previousEditor - the previous editor
583583
*/
584584
function installEditorListeners(editor, previousEditor) {
585585
// always clean up cached scope and hint info
@@ -624,18 +624,21 @@ define(function (require, exports, module) {
624624
* @param {Editor} previous - the previous editor context
625625
*/
626626
function handleActiveEditorChange(event, current, previous) {
627-
// Uninstall "languageChanged" event listeners on the previous editor's document
628-
if (previous && previous !== current) {
627+
// Uninstall "languageChanged" event listeners on previous editor's document & put them on current editor's doc
628+
if (previous) {
629629
$(previous.document)
630630
.off(HintUtils.eventName("languageChanged"));
631631
}
632-
if (current && current.document !== DocumentManager.getCurrentDocument()) {
632+
if (current) {
633633
$(current.document)
634634
.on(HintUtils.eventName("languageChanged"), function () {
635+
// If current doc's language changed, reset our state by treating it as if the user switched to a
636+
// different document altogether
635637
uninstallEditorListeners(current);
636638
installEditorListeners(current);
637639
});
638640
}
641+
639642
uninstallEditorListeners(previous);
640643
installEditorListeners(current, previous);
641644
}
@@ -803,13 +806,6 @@ define(function (require, exports, module) {
803806
.on(HintUtils.eventName("activeEditorChange"),
804807
handleActiveEditorChange);
805808

806-
$(DocumentManager)
807-
.on("currentDocumentLanguageChanged", function (e) {
808-
var activeEditor = EditorManager.getActiveEditor();
809-
uninstallEditorListeners(activeEditor);
810-
installEditorListeners(activeEditor);
811-
});
812-
813809
$(ProjectManager).on("beforeProjectClose", function () {
814810
ScopeManager.handleProjectClose();
815811
});

src/language/LanguageManager.js

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -227,28 +227,6 @@ define(function (require, exports, module) {
227227
_modeToLanguageMap[mode] = language;
228228
}
229229

230-
/**
231-
* Adds a language mapping for the specified fullPath. If language is falsy (null or undefined), the mapping
232-
* is removed.
233-
*
234-
* @param {!fullPath} fullPath absolute path of the file
235-
* @param {?object} language language to associate the file with or falsy value to remove the existing mapping
236-
*/
237-
function _setLanguageOverrideForPath(fullPath, language) {
238-
if (!language) {
239-
delete _filePathToLanguageMap[fullPath];
240-
} else {
241-
_filePathToLanguageMap[fullPath] = language;
242-
}
243-
}
244-
245-
/**
246-
* Resets all the language overrides for file paths. Used by unit tests only.
247-
*/
248-
function _resetLanguageOverrides() {
249-
_filePathToLanguageMap = {};
250-
}
251-
252230
/**
253231
* Resolves a language ID to a Language object.
254232
* File names have a higher priority than file extensions.
@@ -260,7 +238,9 @@ define(function (require, exports, module) {
260238
}
261239

262240
/**
263-
* Resolves a language to a file extension
241+
* Resolves a file extension to a Language object.
242+
* *Warning:* it is almost always better to use getLanguageForPath(), since Language can depend
243+
* on file name and even full path. Use this API only if no relevant file/path exists.
264244
* @param {!string} extension Extension that language should be resolved for
265245
* @return {?Language} The language for the provided extension or null if none exists
266246
*/
@@ -383,6 +363,37 @@ define(function (require, exports, module) {
383363
$(exports).triggerHandler("languageModified", [language]);
384364
}
385365

366+
/**
367+
* Adds a language mapping for the specified fullPath. If language is falsy (null or undefined), the mapping
368+
* is removed. The override is NOT persisted across Brackets sessions.
369+
*
370+
* @param {!fullPath} fullPath absolute path of the file
371+
* @param {?object} language language to associate the file with or falsy value to remove any existing override
372+
*/
373+
function setLanguageOverrideForPath(fullPath, language) {
374+
var oldLang = getLanguageForPath(fullPath);
375+
if (!language) {
376+
delete _filePathToLanguageMap[fullPath];
377+
} else {
378+
_filePathToLanguageMap[fullPath] = language;
379+
}
380+
var newLang = getLanguageForPath(fullPath);
381+
382+
// Old language changed since this path is no longer mapped to it
383+
_triggerLanguageModified(oldLang);
384+
// New language changed since a path is now mapped to it that wasn't before
385+
_triggerLanguageModified(newLang);
386+
}
387+
388+
/**
389+
* Resets all the language overrides for file paths. Used by unit tests only.
390+
*/
391+
function _resetPathLanguageOverrides() {
392+
_filePathToLanguageMap = {};
393+
}
394+
395+
396+
386397

387398
/**
388399
* Model for a language.
@@ -1100,11 +1111,7 @@ define(function (require, exports, module) {
11001111
// Private for unit tests
11011112
exports._EXTENSION_MAP_PREF = _EXTENSION_MAP_PREF;
11021113
exports._NAME_MAP_PREF = _NAME_MAP_PREF;
1103-
exports._resetLanguageOverrides = _resetLanguageOverrides;
1104-
// Internal use only
1105-
// _setLanguageOverrideForPath is used by Document to help LanguageManager keeping track of
1106-
// in-document language overrides
1107-
exports._setLanguageOverrideForPath = _setLanguageOverrideForPath;
1114+
exports._resetPathLanguageOverrides = _resetPathLanguageOverrides;
11081115

11091116
// Public methods
11101117
exports.ready = _ready;
@@ -1113,4 +1120,5 @@ define(function (require, exports, module) {
11131120
exports.getLanguageForExtension = getLanguageForExtension;
11141121
exports.getLanguageForPath = getLanguageForPath;
11151122
exports.getLanguages = getLanguages;
1123+
exports.setLanguageOverrideForPath = setLanguageOverrideForPath;
11161124
});

src/project/ProjectManager.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,8 +1117,8 @@ define(function (require, exports, module) {
11171117
}
11181118

11191119
/**
1120-
* Loads the given folder as a project. Normally, you would call openProject() instead to let the
1121-
* user choose a folder.
1120+
* Loads the given folder as a project. Does NOT prompt about any unsaved changes - use openProject()
1121+
* instead to check for unsaved changes and (optionally) let the user choose the folder to open.
11221122
*
11231123
* @param {!string} rootPath Absolute path to the root folder of the project.
11241124
* A trailing "/" on the path is optional (unlike many Brackets APIs that assume a trailing "/").
@@ -1155,8 +1155,9 @@ define(function (require, exports, module) {
11551155
DocumentManager.closeAll();
11561156

11571157
_unwatchProjectRoot().always(function () {
1158-
// Done closing old project (if any)
1158+
// Finish closing old project (if any)
11591159
if (_projectRoot) {
1160+
LanguageManager._resetPathLanguageOverrides();
11601161
PreferencesManager._reloadUserPrefs(_projectRoot);
11611162
$(exports).triggerHandler("projectClose", _projectRoot);
11621163
}

test/spec/LanguageManager-test.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ define(function (require, exports, module) {
4747
});
4848

4949
afterEach(function () {
50-
LanguageManager._resetLanguageOverrides();
50+
LanguageManager._resetPathLanguageOverrides();
5151
});
5252

5353
function defineLanguage(definition) {
@@ -544,7 +544,7 @@ define(function (require, exports, module) {
544544

545545
var renameDeferred = $.Deferred();
546546
runs(function () {
547-
DocumentManager.setCurrentDocument(doc);
547+
DocumentManager.setCurrentDocument(doc);
548548
javascript = LanguageManager.getLanguage("javascript");
549549

550550
// sanity check language
@@ -705,7 +705,7 @@ define(function (require, exports, module) {
705705
// make active
706706
doc.addRef();
707707

708-
doc.setLanguageOverride(phpLang);
708+
LanguageManager.setLanguageOverrideForPath(doc.file.fullPath, phpLang);
709709

710710
// language should change
711711
expect(doc.getLanguage()).toBe(phpLang);
@@ -747,7 +747,7 @@ define(function (require, exports, module) {
747747
// make active
748748
doc.addRef();
749749

750-
doc.setLanguageOverride(phpLang);
750+
LanguageManager.setLanguageOverrideForPath(doc.file.fullPath, phpLang);
751751

752752
// language should change
753753
expect(doc.getLanguage()).toBe(phpLang);
@@ -756,7 +756,7 @@ define(function (require, exports, module) {
756756
expect(spy.mostRecentCall.args[2]).toBe(phpLang);
757757
expect(LanguageManager.getLanguageForPath(doc.file.fullPath)).toBe(phpLang);
758758

759-
doc.setLanguageOverride(null);
759+
LanguageManager.setLanguageOverrideForPath(doc.file.fullPath, null);
760760

761761
// language should revert
762762
expect(doc.getLanguage()).toBe(unknownLang);
@@ -777,7 +777,7 @@ define(function (require, exports, module) {
777777
expect(LanguageManager.getLanguageForPath(doc.file.fullPath)).toBe(modifiedLanguage);
778778

779779
// override again
780-
doc.setLanguageOverride(phpLang);
780+
LanguageManager.setLanguageOverrideForPath(doc.file.fullPath, phpLang);
781781

782782
expect(doc.getLanguage()).toBe(phpLang);
783783
expect(spy.callCount).toBe(4);
@@ -786,7 +786,7 @@ define(function (require, exports, module) {
786786
expect(LanguageManager.getLanguageForPath(doc.file.fullPath)).toBe(phpLang);
787787

788788
// remove override, should restore to modifiedLanguage
789-
doc.setLanguageOverride(null);
789+
LanguageManager.setLanguageOverrideForPath(doc.file.fullPath, null);
790790

791791
expect(doc.getLanguage()).toBe(modifiedLanguage);
792792
expect(spy.callCount).toBe(5);

0 commit comments

Comments
 (0)