mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-14 05:53:59 +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/");
|
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
|
Test speed of completion calculations
|
||||||
|
@ -1625,6 +1637,7 @@ int main(int argc, char **argv)
|
||||||
test_word_motion();
|
test_word_motion();
|
||||||
test_is_potential_path();
|
test_is_potential_path();
|
||||||
test_colors();
|
test_colors();
|
||||||
|
test_autosuggestion_combining();
|
||||||
test_autosuggest_suggest_special();
|
test_autosuggest_suggest_special();
|
||||||
history_tests_t::test_history();
|
history_tests_t::test_history();
|
||||||
history_tests_t::test_history_merge();
|
history_tests_t::test_history_merge();
|
||||||
|
|
53
reader.cpp
53
reader.cpp
|
@ -449,6 +449,53 @@ int reader_exit_forced()
|
||||||
return 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
|
Repaint the entire commandline. This means reset and clear the
|
||||||
commandline, write the prompt, perform syntax highlighting, write
|
commandline, write the prompt, perform syntax highlighting, write
|
||||||
|
@ -457,10 +504,12 @@ int reader_exit_forced()
|
||||||
|
|
||||||
static void reader_repaint()
|
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);
|
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();
|
size_t len = full_line.size();
|
||||||
if (len < 1)
|
if (len < 1)
|
||||||
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();
|
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
|
#endif
|
||||||
|
|
10
screen.h
10
screen.h
|
@ -179,16 +179,6 @@ public:
|
||||||
\param indent the indent to use for the command line
|
\param indent the indent to use for the command line
|
||||||
\param cursor_pos where the cursor is
|
\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,
|
void s_write(screen_t *s,
|
||||||
const wcstring &left_prompt,
|
const wcstring &left_prompt,
|
||||||
const wcstring &right_prompt,
|
const wcstring &right_prompt,
|
||||||
|
|
Loading…
Reference in a new issue