Fix Bash completion when last pre-defined value matches

This commit is contained in:
Martchus 2016-11-26 00:14:45 +01:00
parent 70869f24a8
commit 82b5bf3f1d
2 changed files with 19 additions and 4 deletions

View File

@ -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;

View File

@ -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;