mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 13:39:02 +00:00
When the user input contains capital letters, use its case rather than the autosuggestion's case
Fixes https://github.com/fish-shell/fish-shell/issues/335
This commit is contained in:
parent
8d4a701f86
commit
85fdf587c0
4 changed files with 67 additions and 12 deletions
|
@ -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
|
||||
|
@ -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();
|
||||
|
|
51
reader.cpp
51
reader.cpp
|
@ -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
|
||||
|
@ -460,7 +507,9 @@ static void reader_repaint()
|
|||
// 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;
|
||||
|
|
3
reader.h
3
reader.h
|
@ -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
screen.h
10
screen.h
|
@ -179,16 +179,6 @@ public:
|
|||
\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,
|
||||
|
|
Loading…
Reference in a new issue