diff --git a/application/argumentparser.cpp b/application/argumentparser.cpp index 7dec1da..e851d83 100644 --- a/application/argumentparser.cpp +++ b/application/argumentparser.cpp @@ -849,7 +849,7 @@ void ArgumentParser::printBashCompletion(int argc, const char *const *argv, unsi if(argc && nextArgumentOrValue) { if(currentWordIndex < argc) { opening = argv[currentWordIndex]; - // For some reasons completions for eg. "set --values disk=1 tag=a" are splitted so the + // For some reason completions for eg. "set --values disk=1 tag=a" are splitted so the // equation sign is an own argument ("set --values disk = 1 tag = a"). // This is not how values are treated by the argument parser. Hence the opening // must be joined again. In this case only the part after the equation sign needs to be @@ -911,8 +911,9 @@ void ArgumentParser::printBashCompletion(int argc, const char *const *argv, unsi if(!compoundOpeningStartLen || wordIndex >= compoundOpeningStartLen) { if(*i == '\'') { cout << "'\"'\"'"; + } else { + cout << *i; } - cout << *i; } ++i, ++wordIndex; switch(*i) { @@ -922,6 +923,9 @@ void ArgumentParser::printBashCompletion(int argc, const char *const *argv, unsi noWhitespace = true; equationSignAlreadyPresent = false; } + if(*i == '\0') { + cout << '\''; + } } } else { ++i; diff --git a/tests/argumentparsertests.cpp b/tests/argumentparsertests.cpp index 4f29e14..87a66af 100644 --- a/tests/argumentparsertests.cpp +++ b/tests/argumentparsertests.cpp @@ -406,6 +406,7 @@ void ArgumentParserTests::testBashCompletion() getArg.setSubArguments({&fieldsArg, &filesArg}); Argument setArg("set", 's', "sets tag values"); setArg.setSubArguments({&valuesArg, &filesArg}); + parser.setMainArguments({&helpArg, &displayFileInfoArg, &getArg, &setArg}); size_t index = 0; @@ -463,7 +464,7 @@ void ArgumentParserTests::testBashCompletion() cout.rdbuf(regularCoutBuffer); CPPUNIT_ASSERT_EQUAL(string("COMPREPLY=('display-file-info' 'get' 'set' '--help' )\n"), buffer.str()); - // values + // pre-defined values const char *const argv3[] = {"get", "--fields"}; index = 0, lastDetectedArg = nullptr, buffer.str(string()), getArg.reset(), setArg.reset(); cout.rdbuf(buffer.rdbuf()); @@ -473,7 +474,7 @@ void ArgumentParserTests::testBashCompletion() cout.rdbuf(regularCoutBuffer); CPPUNIT_ASSERT_EQUAL(string("COMPREPLY=('title' 'album' 'artist' 'trackpos' '--files' )\n"), buffer.str()); - // values with equation sign, one letter already present + // pre-defined values with equation sign, one letter already present const char *const argv4[] = {"set", "--values", "a"}; index = 0, lastDetectedArg = nullptr, buffer.str(string()), getArg.reset(), setArg.reset(); cout.rdbuf(buffer.rdbuf()); @@ -524,6 +525,16 @@ void ArgumentParserTests::testBashCompletion() cout.rdbuf(regularCoutBuffer); CPPUNIT_ASSERT_EQUAL(string("COMPREPLY=('--files' '--nested-sub' '--verbose' )\n"), buffer.str()); + // started pre-defined values with equation sign, one letter already present, last value matches + const char *const argv8[] = {"set", "--values", "t"}; + index = 0, lastDetectedArg = nullptr, buffer.str(string()), parser.resetArgs(); + cout.rdbuf(buffer.rdbuf()); + argv = argv8; + parser.readSpecifiedArgs(parser.m_mainArgs, index, argv, argv8 + 3, lastDetectedArg, argDenotation = nullptr, true); + parser.printBashCompletion(3, argv8, 2, lastDetectedArg); + cout.rdbuf(regularCoutBuffer); + CPPUNIT_ASSERT_EQUAL(string("COMPREPLY=('title=' 'trackpos=' ); compopt -o nospace\n"), buffer.str()); + } catch(...) { cout.rdbuf(regularCoutBuffer); throw;