Commit c37e508e authored by Jonathan Hanks's avatar Jonathan Hanks

Expand the search if only one entry is returned.

With bash auto completion if only one entry is returned it is assumed
to be the final completion.  This make sense if it is a full channel
name.  However if there is a series of one or more segments of the name
that are common through all the channels in question, you need to return
information that includes the next block that is different.  This is a
first reworking to handling this case.
parent cc15cc18
......@@ -50,19 +50,20 @@ load_database( const std::string& path )
return db;
}
template < typename It >
string_list
search( const Database& db, const std::string& key )
search( It begin_it, It end_it, const std::string& key )
{
string_list results;
auto lower = std::lower_bound(
db.channels.begin( ), db.channels.end( ), key, key_comparison );
auto upper =
std::upper_bound( lower, db.channels.end( ), key, key_comparison );
auto lower = std::lower_bound( begin_it, end_it, key, key_comparison );
auto upper = std::upper_bound( lower, end_it, key, key_comparison );
auto key_size = key.size( );
std::for_each(
lower, upper, [key_size, &results]( const std::string& entry ) {
static const std::string delimiters( "-_" );
auto pos = entry.find_first_of( delimiters, key_size );
auto pos = entry.find_first_of( delimiters, key_size );
volatile bool debug = false;
if ( pos == key_size )
{
pos = entry.find_first_of( delimiters, key_size + 1 );
......@@ -75,13 +76,17 @@ search( const Database& db, const std::string& key )
{
results.emplace_back( entry.c_str( ), pos );
}
if ( results.size( ) <= 1 && pos != std::string::npos )
{
pos = entry.find_first_of( delimiters, pos + 1 );
pos = ( pos == std::string::npos ? entry.size( ) : pos );
}
}
else
{
results.emplace_back( entry );
}
} );
return results;
}
......@@ -160,7 +165,18 @@ main( int argc, char* argv[] )
Database db = load_database( channel_db_path );
if ( opts.search )
{
auto choices = search( db, opts.key );
string_list choices;
std::string key = opts.key;
std::string prev_key;
do
{
choices = search( db.channels.begin( ), db.channels.end( ), key );
prev_key = key;
if ( !choices.empty( ) )
{
key = choices.front( );
}
} while ( choices.size( ) == 1 && prev_key != key );
std::copy( choices.begin( ),
choices.end( ),
std::ostream_iterator< std::string >( std::cout, "\n" ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment