Properly handle empty completions (e.g. tab-complete 'foo' with extant files 'foo' and 'foobar' should offer both)

Fixes issue described in https://github.com/fish-shell/fish-shell/issues/290
This commit is contained in:
ridiculousfish 2012-08-20 13:09:21 -07:00
parent 3606664cf7
commit 670e33ab27
2 changed files with 23 additions and 41 deletions

View file

@ -975,18 +975,15 @@ static void run_pager( const wcstring &prefix, int is_quoted, const std::vector<
long base_len=-1; long base_len=-1;
const completion_t &el = comp.at( i ); const completion_t &el = comp.at( i );
wchar_t *foo=0; wcstring completion_text;
wchar_t *baz=0; wcstring description_text;
if( has_case_sensitive && (el.flags & COMPLETE_NO_CASE )) if( has_case_sensitive && (el.flags & COMPLETE_NO_CASE ))
{ {
continue; continue;
} }
if( el.completion.empty() ){ // Note that an empty completion is perfectly sensible here, e.g. tab-completing 'foo' with a file called 'foo' and another called 'foobar'
continue;
}
if( el.flags & COMPLETE_NO_CASE ) if( el.flags & COMPLETE_NO_CASE )
{ {
if( base_len == -1 ) if( base_len == -1 )
@ -997,39 +994,29 @@ static void run_pager( const wcstring &prefix, int is_quoted, const std::vector<
base_len = data->buff_pos - (begin-buff); base_len = data->buff_pos - (begin-buff);
} }
wcstring foo_wstr = escape_string( el.completion.c_str() + base_len, ESCAPE_ALL | ESCAPE_NO_QUOTED ); completion_text = escape_string( el.completion.c_str() + base_len, ESCAPE_ALL | ESCAPE_NO_QUOTED );
foo = wcsdup(foo_wstr.c_str());
} }
else else
{ {
wcstring foo_wstr = escape_string( el.completion, ESCAPE_ALL | ESCAPE_NO_QUOTED ); completion_text = escape_string( el.completion, ESCAPE_ALL | ESCAPE_NO_QUOTED );
foo = wcsdup(foo_wstr.c_str());
} }
if( ! el.description.empty() ) if( ! el.description.empty() )
{ {
wcstring baz_wstr = escape_string( el.description, 1 ); description_text = escape_string( el.description, true );
baz = wcsdup(baz_wstr.c_str());
} }
if( !foo ) /* It's possible (even common) to have an empty completion with no description. An example would be completing 'foo' with extant files 'foo' and 'foobar'. But fish_pager ignores blank lines. So if our completion text is empty, always include a description, even if it's empty.
*/
msg.reserve(msg.size() + completion_text.size() + description_text.size() + 2);
msg.append(completion_text);
if (! description_text.empty() || completion_text.empty())
{ {
debug( 0, L"Run pager called with bad argument." ); msg.append(escaped_separator);
bugreport(); msg.append(description_text);
show_stackframe();
} }
else if( baz ) msg.push_back(L'\n');
{
append_format(msg, L"%ls%ls%ls\n", foo, escaped_separator, baz);
}
else
{
append_format(msg, L"%ls\n", foo);
}
free( foo );
free( baz );
} }
free( escaped_separator ); free( escaped_separator );

View file

@ -250,13 +250,8 @@ static bool wildcard_complete_internal(const wcstring &orig,
} }
if (! out_completion.empty()) /* Note: out_completion may be empty if the completion really is empty, e.g. tab-completing 'foo' when a file 'foo' exists. */
{ append_completion(out, out_completion, out_desc, flags);
append_completion( out,
out_completion,
out_desc,
flags );
}
return true; return true;
} }