reader_expand_abbreviation_in_command to return maybe_t<wcstring>

This commit is contained in:
ridiculousfish 2019-08-06 16:09:23 -07:00
parent 575fdb5492
commit 0dc5eaeb97
3 changed files with 39 additions and 46 deletions

View file

@ -1875,54 +1875,48 @@ static void test_abbreviations() {
if (!mresult) err(L"Unexpected failure with foo abbreviation");
if (*mresult != L"bar") err(L"Wrong abbreviation result for foo");
bool expanded;
wcstring result;
expanded = reader_expand_abbreviation_in_command(L"just a command", 3, vars, &result);
if (expanded) err(L"Command wrongly expanded on line %ld", (long)__LINE__);
expanded = reader_expand_abbreviation_in_command(L"gc somebranch", 0, vars, &result);
if (!expanded) err(L"Command not expanded on line %ld", (long)__LINE__);
maybe_t<wcstring> result;
result = reader_expand_abbreviation_in_command(L"just a command", 3, vars);
if (result) err(L"Command wrongly expanded on line %ld", (long)__LINE__);
result = reader_expand_abbreviation_in_command(L"gc somebranch", 0, vars);
if (!result) err(L"Command not expanded on line %ld", (long)__LINE__);
expanded =
reader_expand_abbreviation_in_command(L"gc somebranch", std::wcslen(L"gc"), vars, &result);
if (!expanded) err(L"gc not expanded");
result = reader_expand_abbreviation_in_command(L"gc somebranch", std::wcslen(L"gc"), vars);
if (!result) err(L"gc not expanded");
if (result != L"git checkout somebranch")
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result->c_str());
// Space separation.
expanded =
reader_expand_abbreviation_in_command(L"gx somebranch", std::wcslen(L"gc"), vars, &result);
if (!expanded) err(L"gx not expanded");
result = reader_expand_abbreviation_in_command(L"gx somebranch", std::wcslen(L"gc"), vars);
if (!result) err(L"gx not expanded");
if (result != L"git checkout somebranch")
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result->c_str());
expanded = reader_expand_abbreviation_in_command(L"echo hi ; gc somebranch",
std::wcslen(L"echo hi ; g"), vars, &result);
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__);
result = reader_expand_abbreviation_in_command(L"echo hi ; gc somebranch",
std::wcslen(L"echo hi ; g"), vars);
if (!result) err(L"gc not expanded on line %ld", (long)__LINE__);
if (result != L"echo hi ; git checkout somebranch")
err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
expanded = reader_expand_abbreviation_in_command(
L"echo (echo (echo (echo (gc ", std::wcslen(L"echo (echo (echo (echo (gc"), vars, &result);
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__);
result = reader_expand_abbreviation_in_command(
L"echo (echo (echo (echo (gc ", std::wcslen(L"echo (echo (echo (echo (gc"), vars);
if (!result) err(L"gc not expanded on line %ld", (long)__LINE__);
if (result != L"echo (echo (echo (echo (git checkout ")
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result->c_str());
// If commands should be expanded.
expanded =
reader_expand_abbreviation_in_command(L"if gc", std::wcslen(L"if gc"), vars, &result);
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__);
result = reader_expand_abbreviation_in_command(L"if gc", std::wcslen(L"if gc"), vars);
if (!result) err(L"gc not expanded on line %ld", (long)__LINE__);
if (result != L"if git checkout")
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result.c_str());
err(L"gc incorrectly expanded on line %ld to '%ls'", (long)__LINE__, result->c_str());
// Others should not be.
expanded =
reader_expand_abbreviation_in_command(L"of gc", std::wcslen(L"of gc"), vars, &result);
if (expanded) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
result = reader_expand_abbreviation_in_command(L"of gc", std::wcslen(L"of gc"), vars);
if (result) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
// Others should not be.
expanded = reader_expand_abbreviation_in_command(L"command gc", std::wcslen(L"command gc"),
vars, &result);
if (expanded) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
result = reader_expand_abbreviation_in_command(L"command gc", std::wcslen(L"command gc"), vars);
if (result) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
vars.pop();
}

View file

@ -729,8 +729,8 @@ void reader_data_t::pager_selection_changed() {
}
/// Expand abbreviations at the given cursor position. Does NOT inspect 'data'.
bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos,
const environment_t &vars, wcstring *output) {
maybe_t<wcstring> reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos,
const environment_t &vars) {
// See if we are at "command position". Get the surrounding command substitution, and get the
// extent of the first token.
const wchar_t *const buff = cmdline.c_str();
@ -778,18 +778,16 @@ bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t curso
}
// Now if we found a command node, expand it.
bool result = false;
maybe_t<wcstring> result{};
if (matching_cmd_node) {
const wcstring token = matching_cmd_node.get_source(subcmd);
if (auto abbreviation = expand_abbreviation(token, vars)) {
// There was an abbreviation! Replace the token in the full command. Maintain the
// relative position of the cursor.
if (output != NULL) {
output->assign(cmdline);
source_range_t r = *matching_cmd_node.source_range();
output->replace(subcmd_offset + r.start, r.length, *abbreviation);
}
result = true;
wcstring output = cmdline;
source_range_t r = *matching_cmd_node.source_range();
output.replace(subcmd_offset + r.start, r.length, *abbreviation);
result = std::move(output);
}
}
return result;
@ -804,15 +802,15 @@ bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) {
if (expand_abbreviations && el == &command_line) {
// Try expanding abbreviations.
wcstring new_cmdline;
size_t cursor_pos = el->position - std::min(el->position, cursor_backtrack);
if (reader_expand_abbreviation_in_command(el->text, cursor_pos, vars(), &new_cmdline)) {
if (auto new_cmdline =
reader_expand_abbreviation_in_command(el->text, cursor_pos, vars())) {
// We expanded an abbreviation! The cursor moves by the difference in the command line
// lengths.
size_t new_buff_pos = el->position + new_cmdline.size() - el->text.size();
size_t new_buff_pos = el->position + new_cmdline->size() - el->text.size();
el->text = std::move(new_cmdline);
el->text = std::move(*new_cmdline);
update_buff_pos(el, new_buff_pos);
command_line_changed(el);
result = true;

View file

@ -216,8 +216,9 @@ wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
const wcstring &autosuggestion);
/// Expand abbreviations at the given cursor position. Exposed for testing purposes only.
bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos,
const environment_t &vars, wcstring *output);
/// \return none if no abbreviations were expanded, otherwise the new command line.
maybe_t<wcstring> reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos,
const environment_t &vars);
/// Apply a completion string. Exposed for testing only.
wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flags_t flags,