Show dashes in suggestions

This commit is contained in:
Martchus 2018-05-11 16:15:02 +02:00
parent 24720bbbc1
commit 5e8d8cb7d1
3 changed files with 31 additions and 16 deletions

View File

@ -65,8 +65,8 @@ ArgumentCompletionInfo::ArgumentCompletionInfo(const ArgumentReader &reader)
} }
struct ArgumentSuggestion { struct ArgumentSuggestion {
ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion); ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion, bool hasDashPrefix);
ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion, size_t suggestionSize); ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion, size_t suggestionSize, bool hasDashPrefix);
bool operator<(const ArgumentSuggestion &other) const; bool operator<(const ArgumentSuggestion &other) const;
bool operator==(const ArgumentSuggestion &other) const; bool operator==(const ArgumentSuggestion &other) const;
void addTo(multiset<ArgumentSuggestion> &suggestions, size_t limit) const; void addTo(multiset<ArgumentSuggestion> &suggestions, size_t limit) const;
@ -74,17 +74,19 @@ struct ArgumentSuggestion {
const char *const suggestion; const char *const suggestion;
const size_t suggestionSize; const size_t suggestionSize;
const size_t editingDistance; const size_t editingDistance;
const bool hasDashPrefix;
}; };
ArgumentSuggestion::ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion, size_t suggestionSize) ArgumentSuggestion::ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion, size_t suggestionSize, bool isOperation)
: suggestion(suggestion) : suggestion(suggestion)
, suggestionSize(suggestionSize) , suggestionSize(suggestionSize)
, editingDistance(MiscUtilities::computeDamerauLevenshteinDistance(unknownArg, unknownArgSize, suggestion, suggestionSize)) , editingDistance(MiscUtilities::computeDamerauLevenshteinDistance(unknownArg, unknownArgSize, suggestion, suggestionSize))
, hasDashPrefix(isOperation)
{ {
} }
ArgumentSuggestion::ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion) ArgumentSuggestion::ArgumentSuggestion(const char *unknownArg, size_t unknownArgSize, const char *suggestion, bool isOperation)
: ArgumentSuggestion(unknownArg, unknownArgSize, suggestion, strlen(suggestion)) : ArgumentSuggestion(unknownArg, unknownArgSize, suggestion, strlen(suggestion), isOperation)
{ {
} }
@ -1204,13 +1206,20 @@ string ArgumentParser::findSuggestions(int argc, const char *const *argv, unsign
// determine completion info // determine completion info
const auto completionInfo(determineCompletionInfo(argc, argv, cursorPos, reader)); const auto completionInfo(determineCompletionInfo(argc, argv, cursorPos, reader));
// determine the unknown/misspelled argument
const auto *unknownArg(*reader.argv);
auto unknownArgSize(strlen(unknownArg));
// -> remove dashes since argument names internally don't have them
if (unknownArgSize >= 2 && unknownArg[0] == '-' && unknownArg[1] == '-') {
unknownArg += 2;
unknownArgSize -= 2;
}
// find best suggestions limiting the results to 2 // find best suggestions limiting the results to 2
const auto *const unknownArg(*reader.argv);
const auto unknownArgSize(strlen(unknownArg));
multiset<ArgumentSuggestion> bestSuggestions; multiset<ArgumentSuggestion> bestSuggestions;
// -> consider relevant arguments // -> consider relevant arguments
for (const Argument *const arg : completionInfo.relevantArgs) { for (const Argument *const arg : completionInfo.relevantArgs) {
ArgumentSuggestion(unknownArg, unknownArgSize, arg->name()).addTo(bestSuggestions, 2); ArgumentSuggestion(unknownArg, unknownArgSize, arg->name(), !arg->denotesOperation()).addTo(bestSuggestions, 2);
} }
// -> consider relevant values // -> consider relevant values
for (const Argument *const arg : completionInfo.relevantPreDefinedValues) { for (const Argument *const arg : completionInfo.relevantPreDefinedValues) {
@ -1219,7 +1228,7 @@ string ArgumentParser::findSuggestions(int argc, const char *const *argv, unsign
const char *wordEnd(wordStart + 1); const char *wordEnd(wordStart + 1);
for (; *wordEnd && *wordEnd != ' '; ++wordEnd) for (; *wordEnd && *wordEnd != ' '; ++wordEnd)
; ;
ArgumentSuggestion(unknownArg, unknownArgSize, wordStart, static_cast<size_t>(wordEnd - wordStart)).addTo(bestSuggestions, 2); ArgumentSuggestion(unknownArg, unknownArgSize, wordStart, static_cast<size_t>(wordEnd - wordStart), false).addTo(bestSuggestions, 2);
i = wordEnd; i = wordEnd;
} }
} }
@ -1231,6 +1240,9 @@ string ArgumentParser::findSuggestions(int argc, const char *const *argv, unsign
size_t requiredSize = 15; size_t requiredSize = 15;
for (const auto &suggestion : bestSuggestions) { for (const auto &suggestion : bestSuggestions) {
requiredSize += suggestion.suggestionSize + 2; requiredSize += suggestion.suggestionSize + 2;
if (suggestion.hasDashPrefix) {
requiredSize += 2;
}
} }
suggestionStr.reserve(requiredSize); suggestionStr.reserve(requiredSize);
@ -1243,6 +1255,9 @@ string ArgumentParser::findSuggestions(int argc, const char *const *argv, unsign
} else if (i > 1) { } else if (i > 1) {
suggestionStr += ", "; suggestionStr += ", ";
} }
if (suggestion.hasDashPrefix) {
suggestionStr += "--";
}
suggestionStr.append(suggestion.suggestion, suggestion.suggestionSize); suggestionStr.append(suggestion.suggestion, suggestion.suggestionSize);
} }
suggestionStr += '?'; suggestionStr += '?';

View File

@ -768,10 +768,10 @@ inline void Argument::setCombinable(bool value)
} }
/*! /*!
* \brief Returns whether the argument denotes the operation. * \brief Returns whether the argument denotes an operation.
* *
* An argument which denotes the operation might be specified * An argument which denotes an operation might be specified
* withouth "--" or "-" prefix as first main argument. * without "--" or "-" prefix.
* *
* The default value is false, except for OperationArgument instances. * The default value is false, except for OperationArgument instances.
* *

View File

@ -196,7 +196,7 @@ void ArgumentParserTests::testParsing()
parser.parseArgs(6, argv3); parser.parseArgs(6, argv3);
CPPUNIT_FAIL("Exception expected."); CPPUNIT_FAIL("Exception expected.");
} catch (const Failure &e) { } catch (const Failure &e) {
CPPUNIT_ASSERT_EQUAL("The specified argument \"album\" is unknown.\nDid you mean get or help?"s, string(e.what())); CPPUNIT_ASSERT_EQUAL("The specified argument \"album\" is unknown.\nDid you mean get or --help?"s, string(e.what()));
} }
// error about unknown argument: mistake in final argument // error about unknown argument: mistake in final argument
@ -206,7 +206,7 @@ void ArgumentParserTests::testParsing()
parser.parseArgs(7, argv18); parser.parseArgs(7, argv18);
CPPUNIT_FAIL("Exception expected."); CPPUNIT_FAIL("Exception expected.");
} catch (const Failure &e) { } catch (const Failure &e) {
CPPUNIT_ASSERT_EQUAL("The specified argument \"--fi\" is unknown.\nDid you mean files or no-color?"s, string(e.what())); CPPUNIT_ASSERT_EQUAL("The specified argument \"--fi\" is unknown.\nDid you mean --files or --no-color?"s, string(e.what()));
} }
// warning about unknown argument // warning about unknown argument
@ -310,7 +310,7 @@ void ArgumentParserTests::testParsing()
CPPUNIT_FAIL("Exception expected."); CPPUNIT_FAIL("Exception expected.");
} catch (const Failure &e) { } catch (const Failure &e) {
CPPUNIT_ASSERT(!qtConfigArgs.qtWidgetsGuiArg().isPresent()); CPPUNIT_ASSERT(!qtConfigArgs.qtWidgetsGuiArg().isPresent());
CPPUNIT_ASSERT_EQUAL("The specified argument \"-f\" is unknown.\nDid you mean get or help?"s, string(e.what())); CPPUNIT_ASSERT_EQUAL("The specified argument \"-f\" is unknown.\nDid you mean get or --help?"s, string(e.what()));
} }
// equation sign syntax // equation sign syntax
@ -410,7 +410,7 @@ void ArgumentParserTests::testParsing()
CPPUNIT_FAIL("Exception expected."); CPPUNIT_FAIL("Exception expected.");
} catch (const Failure &e) { } catch (const Failure &e) {
CPPUNIT_ASSERT(!qtConfigArgs.qtWidgetsGuiArg().isPresent()); CPPUNIT_ASSERT(!qtConfigArgs.qtWidgetsGuiArg().isPresent());
CPPUNIT_ASSERT_EQUAL("The specified argument \"--hel\" is unknown.\nDid you mean help or get?"s, string(e.what())); CPPUNIT_ASSERT_EQUAL("The specified argument \"--hel\" is unknown.\nDid you mean --help or get?"s, string(e.what()));
} }
// nested operations // nested operations