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) err(L"Unexpected failure with foo abbreviation");
if (*mresult != L"bar") err(L"Wrong abbreviation result for foo"); if (*mresult != L"bar") err(L"Wrong abbreviation result for foo");
bool expanded; maybe_t<wcstring> result;
wcstring result; result = reader_expand_abbreviation_in_command(L"just a command", 3, vars);
expanded = reader_expand_abbreviation_in_command(L"just a command", 3, vars, &result); if (result) err(L"Command wrongly expanded on line %ld", (long)__LINE__);
if (expanded) err(L"Command wrongly expanded on line %ld", (long)__LINE__); result = reader_expand_abbreviation_in_command(L"gc somebranch", 0, vars);
expanded = reader_expand_abbreviation_in_command(L"gc somebranch", 0, vars, &result); if (!result) err(L"Command not expanded on line %ld", (long)__LINE__);
if (!expanded) err(L"Command not expanded on line %ld", (long)__LINE__);
expanded = result = reader_expand_abbreviation_in_command(L"gc somebranch", std::wcslen(L"gc"), vars);
reader_expand_abbreviation_in_command(L"gc somebranch", std::wcslen(L"gc"), vars, &result); if (!result) err(L"gc not expanded");
if (!expanded) err(L"gc not expanded");
if (result != L"git checkout somebranch") 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. // Space separation.
expanded = result = reader_expand_abbreviation_in_command(L"gx somebranch", std::wcslen(L"gc"), vars);
reader_expand_abbreviation_in_command(L"gx somebranch", std::wcslen(L"gc"), vars, &result); if (!result) err(L"gx not expanded");
if (!expanded) err(L"gx not expanded");
if (result != L"git checkout somebranch") 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", result = reader_expand_abbreviation_in_command(L"echo hi ; gc somebranch",
std::wcslen(L"echo hi ; g"), vars, &result); std::wcslen(L"echo hi ; g"), vars);
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__); if (!result) err(L"gc not expanded on line %ld", (long)__LINE__);
if (result != L"echo hi ; git checkout somebranch") if (result != L"echo hi ; git checkout somebranch")
err(L"gc incorrectly expanded on line %ld", (long)__LINE__); err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
expanded = reader_expand_abbreviation_in_command( result = reader_expand_abbreviation_in_command(
L"echo (echo (echo (echo (gc ", std::wcslen(L"echo (echo (echo (echo (gc"), vars, &result); L"echo (echo (echo (echo (gc ", std::wcslen(L"echo (echo (echo (echo (gc"), vars);
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__); if (!result) err(L"gc not expanded on line %ld", (long)__LINE__);
if (result != L"echo (echo (echo (echo (git checkout ") 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. // If commands should be expanded.
expanded = result = reader_expand_abbreviation_in_command(L"if gc", std::wcslen(L"if gc"), vars);
reader_expand_abbreviation_in_command(L"if gc", std::wcslen(L"if gc"), vars, &result); if (!result) err(L"gc not expanded on line %ld", (long)__LINE__);
if (!expanded) err(L"gc not expanded on line %ld", (long)__LINE__);
if (result != L"if git checkout") 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. // Others should not be.
expanded = result = reader_expand_abbreviation_in_command(L"of gc", std::wcslen(L"of gc"), vars);
reader_expand_abbreviation_in_command(L"of gc", std::wcslen(L"of gc"), vars, &result); if (result) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
if (expanded) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
// Others should not be. // Others should not be.
expanded = reader_expand_abbreviation_in_command(L"command gc", std::wcslen(L"command gc"), result = reader_expand_abbreviation_in_command(L"command gc", std::wcslen(L"command gc"), vars);
vars, &result); if (result) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
if (expanded) err(L"gc incorrectly expanded on line %ld", (long)__LINE__);
vars.pop(); 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'. /// Expand abbreviations at the given cursor position. Does NOT inspect 'data'.
bool reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos, maybe_t<wcstring> reader_expand_abbreviation_in_command(const wcstring &cmdline, size_t cursor_pos,
const environment_t &vars, wcstring *output) { const environment_t &vars) {
// See if we are at "command position". Get the surrounding command substitution, and get the // See if we are at "command position". Get the surrounding command substitution, and get the
// extent of the first token. // extent of the first token.
const wchar_t *const buff = cmdline.c_str(); 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. // Now if we found a command node, expand it.
bool result = false; maybe_t<wcstring> result{};
if (matching_cmd_node) { if (matching_cmd_node) {
const wcstring token = matching_cmd_node.get_source(subcmd); const wcstring token = matching_cmd_node.get_source(subcmd);
if (auto abbreviation = expand_abbreviation(token, vars)) { if (auto abbreviation = expand_abbreviation(token, vars)) {
// There was an abbreviation! Replace the token in the full command. Maintain the // There was an abbreviation! Replace the token in the full command. Maintain the
// relative position of the cursor. // relative position of the cursor.
if (output != NULL) { wcstring output = cmdline;
output->assign(cmdline); source_range_t r = *matching_cmd_node.source_range();
source_range_t r = *matching_cmd_node.source_range(); output.replace(subcmd_offset + r.start, r.length, *abbreviation);
output->replace(subcmd_offset + r.start, r.length, *abbreviation); result = std::move(output);
}
result = true;
} }
} }
return result; return result;
@ -804,15 +802,15 @@ bool reader_data_t::expand_abbreviation_as_necessary(size_t cursor_backtrack) {
if (expand_abbreviations && el == &command_line) { if (expand_abbreviations && el == &command_line) {
// Try expanding abbreviations. // Try expanding abbreviations.
wcstring new_cmdline;
size_t cursor_pos = el->position - std::min(el->position, cursor_backtrack); 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 // We expanded an abbreviation! The cursor moves by the difference in the command line
// lengths. // 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); update_buff_pos(el, new_buff_pos);
command_line_changed(el); command_line_changed(el);
result = true; result = true;

View file

@ -216,8 +216,9 @@ wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
const wcstring &autosuggestion); const wcstring &autosuggestion);
/// Expand abbreviations at the given cursor position. Exposed for testing purposes only. /// 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, /// \return none if no abbreviations were expanded, otherwise the new command line.
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);
/// Apply a completion string. Exposed for testing only. /// Apply a completion string. Exposed for testing only.
wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flags_t flags, wcstring completion_apply_to_command_line(const wcstring &val_str, complete_flags_t flags,