diff options
author | Dwight <dwight@10gen.com> | 2010-06-07 11:17:15 -0400 |
---|---|---|
committer | Dwight <dwight@10gen.com> | 2010-06-07 11:17:15 -0400 |
commit | ed7cfda35f0fd281c531eff36ee752eaf7448dfe (patch) | |
tree | 969a6b605505eb38a44a70680db1cef7992a225d /shell | |
parent | 370f9a1bd2675a84dc13283bbd501a1d978b3092 (diff) | |
parent | 09c18ee468e20fd8704268ad0779c009e6939ec7 (diff) | |
download | mongo-ed7cfda35f0fd281c531eff36ee752eaf7448dfe.tar.gz |
Merge branch 'master' of github.com:mongodb/mongo
Diffstat (limited to 'shell')
-rw-r--r-- | shell/dbshell.cpp | 70 | ||||
-rw-r--r-- | shell/utils.js | 7 |
2 files changed, 72 insertions, 5 deletions
diff --git a/shell/dbshell.cpp b/shell/dbshell.cpp index 0a82393a5d1..5984c70537f 100644 --- a/shell/dbshell.cpp +++ b/shell/dbshell.cpp @@ -37,6 +37,11 @@ jmp_buf jbuf; using namespace std; using namespace boost::filesystem; +using mongo::BSONObj; +using mongo::BSONObjBuilder; +using mongo::BSONObjIterator; +using mongo::BSONElement; + string historyFile; bool gotInterrupted = 0; bool inMultiLine = 0; @@ -45,9 +50,60 @@ bool inMultiLine = 0; #define CTRLC_HANDLE #endif -static char** my_completion(const char* text , int start ,int end ){ - cout << "YO [" << text << "] " << start << " " << end << endl; - return 0; +mongo::Scope * shellMainScope; + +void generateCompletions( const string& prefix , vector<string>& all ){ + if ( prefix.find( '"' ) != string::npos ) + return; + shellMainScope->exec( "shellAutocomplete( \"" + prefix + "\" );" , "autocomplete help" , false , true , false ); + + BSONObjBuilder b; + shellMainScope->append( b , "" , "__autocomplete__" ); + BSONObj res = b.obj(); + BSONObj arr = res.firstElement().Obj(); + + BSONObjIterator i(arr); + while ( i.more() ){ + BSONElement e = i.next(); + all.push_back( e.String() ); + } + +} + +static char** completionHook(const char* text , int start ,int end ){ + static map<string,string> m; + + vector<string> all; + + if ( start == 0 ){ + generateCompletions( string(text,end) , all ); + } + + if ( all.size() == 0 ){ + rl_bind_key('\t',rl_abort); + return 0; + } + + string longest = all[0]; + for ( vector<string>::iterator i=all.begin(); i!=all.end(); ++i ){ + string s = *i; + for ( unsigned j=0; j<s.size(); j++ ){ + if ( longest[j] == s[j] ) + continue; + longest = longest.substr(0,j); + break; + } + } + + char ** matches = (char**)malloc( sizeof(char*) * (all.size()+2) ); + unsigned x=0; + matches[x++] = strdup( longest.c_str() ); + for ( unsigned i=0; i<all.size(); i++ ){ + matches[x++] = strdup( all[i].c_str() ); + } + matches[x++] = 0; + + return matches; } void shellHistoryInit(){ @@ -61,9 +117,9 @@ void shellHistoryInit(){ using_history(); read_history( historyFile.c_str() ); - + // TODO: do auto-completion - //rl_attempted_completion_function = my_completion; + rl_attempted_completion_function = completionHook; #else //cout << "type \"exit\" to exit" << endl; @@ -121,6 +177,9 @@ void quitNicely( int sig ){ char * shellReadline( const char * prompt , int handlesigint = 0 ){ #ifdef USE_READLINE + rl_bind_key('\t',rl_complete); + + #ifdef CTRLC_HANDLE if ( ! handlesigint ) return readline( prompt ); @@ -458,6 +517,7 @@ int _main(int argc, char* argv[]) { mongo::ScriptEngine::setup(); mongo::globalScriptEngine->setScopeInitCallback( mongo::shellUtils::initScope ); auto_ptr< mongo::Scope > scope( mongo::globalScriptEngine->newScope() ); + shellMainScope = scope.get(); if ( !script.empty() ) { mongo::shellUtils::MongoProgramScope s; diff --git a/shell/utils.js b/shell/utils.js index 48868092a75..f28508058a3 100644 --- a/shell/utils.js +++ b/shell/utils.js @@ -750,6 +750,13 @@ shellPrintHelper = function( x ){ print( tojson( x ) ); } +shellAutocomplete = function( prefix ){ + var a = []; + //a.push( prefix + "z" ) + //a.push( prefix + "y" ) + __autocomplete__ = a; +} + shellHelper = function( command , rest , shouldPrint ){ command = command.trim(); var args = rest.trim().replace(/;$/,"").split( "\s+" ); |