@@ -32,17 +32,20 @@ define(function (require, exports, module) {
3232 "use strict" ;
3333
3434 // Load dependent modules
35- var AppInit = require ( "utils/AppInit" ) ,
36- AnimationUtils = require ( "utils/AnimationUtils" ) ,
37- EditorManager = require ( "editor/EditorManager" ) ,
38- Editor = require ( "editor/Editor" ) . Editor ,
39- KeyEvent = require ( "utils/KeyEvent" ) ,
40- StatusBar = require ( "widgets/StatusBar" ) ,
41- Strings = require ( "strings" ) ,
42- StringUtils = require ( "utils/StringUtils" ) ;
35+ var _ = require ( "thirdparty/lodash" ) ,
36+ AnimationUtils = require ( "utils/AnimationUtils" ) ,
37+ AppInit = require ( "utils/AppInit" ) ,
38+ DropdownButton = require ( "widgets/DropdownButton" ) . DropdownButton ,
39+ EditorManager = require ( "editor/EditorManager" ) ,
40+ Editor = require ( "editor/Editor" ) . Editor ,
41+ KeyEvent = require ( "utils/KeyEvent" ) ,
42+ LanguageManager = require ( "language/LanguageManager" ) ,
43+ StatusBar = require ( "widgets/StatusBar" ) ,
44+ Strings = require ( "strings" ) ,
45+ StringUtils = require ( "utils/StringUtils" ) ;
4346
4447 /* StatusBar indicators */
45- var $languageInfo ,
48+ var languageSelect , // this is a DropdownButton instance
4649 $cursorInfo ,
4750 $fileInfo ,
4851 $indentType ,
@@ -67,7 +70,15 @@ define(function (require, exports, module) {
6770 * @param {Editor } editor Current editor
6871 */
6972 function _updateLanguageInfo ( editor ) {
70- $languageInfo . text ( editor . document . getLanguage ( ) . getName ( ) ) ;
73+ var doc = editor . document ,
74+ lang = doc . getLanguage ( ) ;
75+
76+ // Ensure width isn't left locked by a previous click of the dropdown (which may not have resulted in a "change" event at the time)
77+ languageSelect . $button . css ( "width" , "auto" ) ;
78+ // Setting Untitled documents to non-text mode isn't supported yet, so disable the switcher in that case for now
79+ languageSelect . $button . prop ( "disabled" , doc . isUntitled ( ) ) ;
80+ // Show the current language as button title
81+ languageSelect . $button . text ( lang . getName ( ) ) ;
7182 }
7283
7384 /**
@@ -260,7 +271,9 @@ define(function (require, exports, module) {
260271 $ ( current ) . on ( "overwriteToggle.statusbar" , _updateOverwriteLabel ) ;
261272
262273 current . document . addRef ( ) ;
263- $ ( current . document ) . on ( "languageChanged.statusbar" , function ( ) { _updateLanguageInfo ( current ) ; } ) ;
274+ $ ( current . document ) . on ( "languageChanged.statusbar" , function ( ) {
275+ _updateLanguageInfo ( current ) ;
276+ } ) ;
264277
265278 _updateCursorInfo ( null , current ) ;
266279 _updateLanguageInfo ( current ) ;
@@ -271,18 +284,55 @@ define(function (require, exports, module) {
271284 }
272285 }
273286
287+ /**
288+ * Populate the languageSelect DropdownButton's menu with all registered Languages
289+ */
290+ function _populateLanguageDropdown ( ) {
291+ // Get all non-binary languages
292+ var languages = _ . values ( LanguageManager . getLanguages ( ) ) . filter ( function ( language ) {
293+ return ! language . isBinary ( ) ;
294+ } ) ;
295+
296+ // sort dropdown alphabetically
297+ languages . sort ( function ( a , b ) {
298+ return a . getName ( ) . toLowerCase ( ) . localeCompare ( b . getName ( ) . toLowerCase ( ) ) ;
299+ } ) ;
300+
301+ languageSelect . items = languages ;
302+
303+ }
304+
274305 /**
275306 * Initialize
276307 */
277308 function _init ( ) {
278- $languageInfo = $ ( "#status-language" ) ;
309+
279310 $cursorInfo = $ ( "#status-cursor" ) ;
280311 $fileInfo = $ ( "#status-file" ) ;
281312 $indentType = $ ( "#indent-type" ) ;
282313 $indentWidthLabel = $ ( "#indent-width-label" ) ;
283314 $indentWidthInput = $ ( "#indent-width-input" ) ;
284315 $statusOverwrite = $ ( "#status-overwrite" ) ;
285316
317+ languageSelect = new DropdownButton ( "" , [ ] , function ( item , index ) {
318+ var document = EditorManager . getActiveEditor ( ) . document ,
319+ defaultLang = LanguageManager . getLanguageForPath ( document . file . fullPath , true ) ,
320+ html = _ . escape ( item . getName ( ) ) ;
321+
322+ // Show indicators for currently selected & default languages for the current file
323+ if ( item === defaultLang ) {
324+ html += " <span class='default-language'>" + Strings . STATUSBAR_DEFAULT_LANG + "</span>" ;
325+ }
326+ if ( item === document . getLanguage ( ) ) {
327+ html = "<span class='checked-language'></span>" + html ;
328+ }
329+ return html ;
330+ } ) ;
331+
332+ languageSelect . dropdownExtraClasses = "dropdown-status-bar" ;
333+ languageSelect . $button . addClass ( "btn-status-bar" ) ;
334+ $ ( "#status-language" ) . append ( languageSelect . $button ) ;
335+
286336 // indentation event handlers
287337 $indentType . on ( "click" , _toggleIndentType ) ;
288338 $indentWidthLabel
@@ -310,6 +360,16 @@ define(function (require, exports, module) {
310360
311361 $indentWidthInput . focus ( function ( ) { $indentWidthInput . select ( ) ; } ) ;
312362
363+ // Language select change handler
364+ $ ( languageSelect ) . on ( "select" , function ( e , lang , index ) {
365+ var document = EditorManager . getActiveEditor ( ) . document ,
366+ fullPath = document . file . fullPath ,
367+ 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 ) ;
371+ } ) ;
372+
313373 $statusOverwrite . on ( "click" , _updateEditorOverwriteMode ) ;
314374
315375 _onActiveEditorChange ( null , EditorManager . getActiveEditor ( ) , null ) ;
@@ -319,4 +379,5 @@ define(function (require, exports, module) {
319379 $ ( EditorManager ) . on ( "activeEditorChange" , _onActiveEditorChange ) ;
320380
321381 AppInit . htmlReady ( _init ) ;
382+ AppInit . appReady ( _populateLanguageDropdown ) ;
322383} ) ;
0 commit comments