Skip to content

Commit

Permalink
When the user input contains capital letters, use its case rather tha…
Browse files Browse the repository at this point in the history
…n the autosuggestion's case

Fixes #335
  • Loading branch information
ridiculousfish committed Jan 5, 2013
1 parent 8d4a701 commit 85fdf58
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 12 deletions.
13 changes: 13 additions & 0 deletions fish_tests.cpp
Expand Up @@ -1022,6 +1022,18 @@ static void test_autosuggest_suggest_special()
system("rm -Rf ~/test_autosuggest_suggest_special/");
}

static void test_autosuggestion_combining()
{
say(L"Testing autosuggestion combining");
assert(combine_command_and_autosuggestion(L"alpha", L"alphabeta") == L"alphabeta");

// when the last token contains no capital letters, we use the case of the autosuggestion
assert(combine_command_and_autosuggestion(L"alpha", L"ALPHABETA") == L"ALPHABETA");

// when the last token contains capital letters, we use its case
assert(combine_command_and_autosuggestion(L"alPha", L"alphabeTa") == L"alPhabeTa");
}


/**
Test speed of completion calculations
Expand Down Expand Up @@ -1625,6 +1637,7 @@ int main(int argc, char **argv)
test_word_motion();
test_is_potential_path();
test_colors();
test_autosuggestion_combining();
test_autosuggest_suggest_special();
history_tests_t::test_history();
history_tests_t::test_history_merge();
Expand Down
53 changes: 51 additions & 2 deletions reader.cpp
Expand Up @@ -449,6 +449,53 @@ int reader_exit_forced()
return exit_forced;
}

/* Given a command line and an autosuggestion, return the string that gets shown to the user */
wcstring combine_command_and_autosuggestion(const wcstring &cmdline, const wcstring &autosuggestion)
{
// We want to compute the full line, containing the command line and the autosuggestion
// They may disagree on whether characters are uppercase or lowercase
// Here we do something funny: if the last token of the command line contains any uppercase characters, we use its case
// Otherwise we use the case of the autosuggestion
// This is an idea from https://github.com/fish-shell/fish-shell/issues/335
wcstring full_line;
if (autosuggestion.size() <= cmdline.size() || cmdline.empty())
{
// No or useless autosuggestion, or no command line
full_line = cmdline;
}
else if (string_prefixes_string(cmdline, autosuggestion))
{
// No case disagreements, or no extra characters in the autosuggestion
full_line = autosuggestion;
}
else
{
// We have an autosuggestion which is not a prefix of the command line, i.e. a case disagreement
// Decide whose case we want to use
const wchar_t *begin = NULL, *cmd = cmdline.c_str();
parse_util_token_extent(cmd, cmdline.size() - 1, &begin, NULL, NULL, NULL);
bool last_token_contains_uppercase = false;
if (begin)
{
const wchar_t *end = begin + wcslen(begin);
last_token_contains_uppercase = (std::find_if(begin, end, iswupper) != end);
}
if (! last_token_contains_uppercase)
{
// Use the autosuggestion's case
full_line = autosuggestion;
}
else
{
// Use the command line case for its characters, then append the remaining characters in the autosuggestion
// Note that we know that autosuggestion.size() > cmdline.size() due to the first test above
full_line = cmdline;
full_line.append(autosuggestion, cmdline.size(), autosuggestion.size() - cmdline.size());
}
}
return full_line;
}

/**
Repaint the entire commandline. This means reset and clear the
commandline, write the prompt, perform syntax highlighting, write
Expand All @@ -457,10 +504,12 @@ int reader_exit_forced()

static void reader_repaint()
{
//Update the indentation
// Update the indentation
parser_t::principal_parser().test(data->command_line.c_str(), &data->indents[0], 0, 0);

wcstring full_line = (data->autosuggestion.empty() ? data->command_line : data->autosuggestion);
// Combine the command and autosuggestion into one string
wcstring full_line = combine_command_and_autosuggestion(data->command_line, data->autosuggestion);

size_t len = full_line.size();
if (len < 1)
len = 1;
Expand Down
3 changes: 3 additions & 0 deletions reader.h
Expand Up @@ -214,5 +214,8 @@ int reader_shell_test(const wchar_t *b);
*/
int reader_search_mode();

/* Given a command line and an autosuggestion, return the string that gets shown to the user. Exposed for testing purposes only. */
wcstring combine_command_and_autosuggestion(const wcstring &cmdline, const wcstring &autosuggestion);


#endif
10 changes: 0 additions & 10 deletions screen.h
Expand Up @@ -179,16 +179,6 @@ class screen_t
\param indent the indent to use for the command line
\param cursor_pos where the cursor is
*/
void s_write(screen_t *s,
const wchar_t *left_prompt,
const wchar_t *right_prompt,
const wchar_t *commandline,
size_t explicit_len,
const int *colors,
const int *indent,
size_t cursor_pos);


void s_write(screen_t *s,
const wcstring &left_prompt,
const wcstring &right_prompt,
Expand Down

0 comments on commit 85fdf58

Please sign in to comment.