diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index ebaa42f2c..7c20ff49c 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -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 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(); } diff --git a/src/reader.cpp b/src/reader.cpp index 37eca2b7b..7efe0d929 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -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 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 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; diff --git a/src/reader.h b/src/reader.h index efd768304..76d7a6137 100644 --- a/src/reader.h +++ b/src/reader.h @@ -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 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,