@@ -9,10 +9,13 @@ var dom = require("./lib/dom");
99var  snippetManager  =  require ( "./snippets" ) . snippetManager ; 
1010var  config  =  require ( "./config" ) ; 
1111
12- var  Autocomplete  =  function ( )  { 
13-     this . autoInsert  =  false ; 
14-     this . autoSelect  =  true ; 
15-     this . exactMatch  =  false ; 
12+ var  Autocomplete  =  function ( options )  { 
13+     if  ( ! options )  { 
14+         options  =  { } ; 
15+     } 
16+     this . autoInsert  =  options . autoInsert  ||  false ; 
17+     this . autoSelect  =  options . autoSelect  ||  true ; 
18+     this . exactMatch  =  options . exactMatch  ||  false ; 
1619    this . gatherCompletionsId  =  0 ; 
1720    this . keyboardHandler  =  new  HashHandler ( ) ; 
1821    this . keyboardHandler . bindKeys ( this . commands ) ; 
@@ -219,7 +222,7 @@ var Autocomplete = function() {
219222        return  true ; 
220223    } ; 
221224
222-     this . showPopup  =  function ( editor ,  options )  { 
225+     this . show   =   this . showPopup  =  function ( editor ,  options )  { 
223226        if  ( this . editor ) 
224227            this . detach ( ) ; 
225228
@@ -444,51 +447,75 @@ var Autocomplete = function() {
444447
445448} ) . call ( Autocomplete . prototype ) ; 
446449
450+ var  destroyCompleter  =  function ( e ,  editor )  { 
451+     editor . completer  &&  editor . completer . destroy ( ) ; 
452+ } ; 
447453
448- Autocomplete . for  =  function ( editor )  { 
454+ Autocomplete . for  =  function ( editor ,   options )  { 
449455    if  ( editor . completer )  { 
450-         return  editor . completer ; 
456+         if  ( editor . completer  instanceof  Autocomplete )  { 
457+             return  editor . completer ; 
458+         }  else  { 
459+             editor . off ( "destroy" ,  destroyCompleter ) ; 
460+             editor . completer . destroy ( ) ; 
461+         } 
451462    } 
452463    if  ( config . get ( "sharedPopups" ) )  { 
453-         if  ( ! Autocomplete . $shared  ) 
454-             Autocomplete . $sharedInstance  =  new  Autocomplete ( ) ; 
464+         if  ( ! Autocomplete . $sharedInstance  ) 
465+             Autocomplete . $sharedInstance  =  new  Autocomplete ( options ) ; 
455466        editor . completer  =  Autocomplete . $sharedInstance ; 
456467    }  else  { 
457-         editor . completer  =  new  Autocomplete ( ) ; 
458-         editor . once ( "destroy" ,  function ( e ,  editor )  { 
459-             editor . completer . destroy ( ) ; 
460-         } ) ; 
468+         editor . completer  =  new  Autocomplete ( options ) ; 
469+         editor . once ( "destroy" ,  destroyCompleter ) ; 
461470    } 
462471    return  editor . completer ; 
463472} ; 
464473
465474Autocomplete . startCommand  =  { 
466475    name : "startAutocomplete" , 
467476    exec : function ( editor ,  options )  { 
468-         var  completer  =  Autocomplete . for ( editor ) ; 
469-         completer . autoInsert  =  false ; 
470-         completer . autoSelect  =  true ; 
471-         completer . showPopup ( editor ,  options ) ; 
472-         // prevent ctrl-space opening context menu on firefox on mac 
473-         completer . cancelContextMenu ( ) ; 
477+         var  completer  =  Autocomplete . for ( editor ,  options ) ; 
478+         if  ( completer  instanceof  Autocomplete )  { 
479+             completer . autoInsert  =  false ; 
480+             completer . autoSelect  =  true ; 
481+             completer . showPopup ( editor ,  options ) ; 
482+             // prevent ctrl-space opening context menu on firefox on mac 
483+             completer . cancelContextMenu ( ) ; 
484+         } 
485+         return  completer ; 
474486    } , 
475487    bindKey : "Ctrl-Space|Ctrl-Shift-Space|Alt-Space" 
476488} ; 
477489
478- var  FilteredList  =  function ( array ,  filterText )  { 
490+ var  FilteredList  =  function ( array ,  filterText ,   prefix )  { 
479491    this . all  =  array ; 
480492    this . filtered  =  array ; 
481493    this . filterText  =  filterText  ||  "" ; 
494+     this . prefix  =  prefix  ||  "" ; 
482495    this . exactMatch  =  false ; 
483496} ; 
484497( function ( ) { 
498+     this . setPrefix  =  function ( str )  { 
499+         var  nextPrefix  =  str ; 
500+         var  currentPrefix  =  this . prefix ; 
501+         if  ( nextPrefix . startsWith ( currentPrefix ) )  { 
502+             var  matches  =  this . filtered ; 
503+         }  else  { 
504+             var  matches  =  this . all ; 
505+         } 
506+         this . prefix  =  str ; 
507+         matches  =  this . filterCompletionsByPrefix ( matches ,  this . prefix ) ; 
508+         this . filterCompletions ( matches ,  this . filterText ) ; 
509+     } ; 
510+ 
485511    this . setFilter  =  function ( str )  { 
486512        if  ( str . length  >  this . filterText  &&  str . lastIndexOf ( this . filterText ,  0 )  ===  0 ) 
487513            var  matches  =  this . filtered ; 
488514        else 
489515            var  matches  =  this . all ; 
490516
491517        this . filterText  =  str ; 
518+         matches  =  this . filterCompletionsByPrefix ( matches ,  this . prefix ) ; 
492519        matches  =  this . filterCompletions ( matches ,  this . filterText ) ; 
493520        matches  =  matches . sort ( function ( a ,  b )  { 
494521            return  b . exactMatch  -  a . exactMatch  ||  b . $score  -  a . $score  
@@ -506,6 +533,14 @@ var FilteredList = function(array, filterText) {
506533
507534        this . filtered  =  matches ; 
508535    } ; 
536+ 
537+     this . filterCompletionsByPrefix  =  function ( items ,  prefix )  { 
538+         return  items . filter ( function  ( item )  { 
539+             var  testItem  =  item . snippet  ||  item . value ; 
540+             return  testItem . startsWith ( prefix ) ; 
541+         } ) ; 
542+     } ; 
543+ 
509544    this . filterCompletions  =  function ( items ,  needle )  { 
510545        var  results  =  [ ] ; 
511546        var  upper  =  needle . toUpperCase ( ) ; 
0 commit comments