fix: don't autocomplete commands mid-sentence (#6273)
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
- Minor: Made nicknames searchable in the Settings dialog search bar. (#5886)
|
||||
- Minor: Added hotkey Action for opening account selector. (#6192)
|
||||
- Minor: Add a setting to change the emote and badge thumbnail size. (#6126)
|
||||
- Bugfix: Commands are no longer tab-completable in the middle of messages. (#6273)
|
||||
- Bugfix: Automatic streamer mode detection now works from Flatpak. (#6250)
|
||||
- Bugfix: Don't create native messaging manifest file if browser directory doesn't exist. (#6116)
|
||||
- Bugfix: Fixed scrolling now working on inputs in the settings. (#6128)
|
||||
|
||||
@@ -27,7 +27,7 @@ void TabCompletionModel::updateResults(const QString &query,
|
||||
const QString &fullTextContent,
|
||||
int cursorPosition, bool isFirstWord)
|
||||
{
|
||||
this->updateSourceFromQuery(query);
|
||||
this->updateSourceFromQuery(query, isFirstWord);
|
||||
|
||||
if (this->source_)
|
||||
{
|
||||
@@ -56,9 +56,10 @@ void TabCompletionModel::updateResults(const QString &query,
|
||||
}
|
||||
}
|
||||
|
||||
void TabCompletionModel::updateSourceFromQuery(const QString &query)
|
||||
void TabCompletionModel::updateSourceFromQuery(const QString &query,
|
||||
bool isFirstWord)
|
||||
{
|
||||
auto deducedKind = this->deduceSourceKind(query);
|
||||
auto deducedKind = this->deduceSourceKind(query, isFirstWord);
|
||||
if (!deducedKind)
|
||||
{
|
||||
// unable to determine what kind of completion is occurring
|
||||
@@ -71,7 +72,8 @@ void TabCompletionModel::updateSourceFromQuery(const QString &query)
|
||||
}
|
||||
|
||||
std::optional<TabCompletionModel::SourceKind>
|
||||
TabCompletionModel::deduceSourceKind(const QString &query) const
|
||||
TabCompletionModel::deduceSourceKind(const QString &query,
|
||||
bool isFirstWord) const
|
||||
{
|
||||
if (query.length() < 2 || !this->channel_.isTwitchChannel())
|
||||
{
|
||||
@@ -88,7 +90,7 @@ std::optional<TabCompletionModel::SourceKind>
|
||||
{
|
||||
return SourceKind::Emote;
|
||||
}
|
||||
else if (query.startsWith('/') || query.startsWith('.'))
|
||||
else if (isFirstWord && (query.startsWith('/') || query.startsWith('.')))
|
||||
{
|
||||
return SourceKind::Command;
|
||||
}
|
||||
@@ -97,14 +99,27 @@ std::optional<TabCompletionModel::SourceKind>
|
||||
// Therefore, we must also consider that the user could be completing an emote
|
||||
// OR a mention depending on their completion settings.
|
||||
|
||||
if (getSettings()->userCompletionOnlyWithAt)
|
||||
if (isFirstWord)
|
||||
{
|
||||
// All kinds but user are possible
|
||||
return SourceKind::EmoteCommand;
|
||||
if (getSettings()->userCompletionOnlyWithAt)
|
||||
{
|
||||
// All kinds but user are possible
|
||||
return SourceKind::EmoteCommand;
|
||||
}
|
||||
|
||||
// Any kind is possible
|
||||
return SourceKind::EmoteUserCommand;
|
||||
}
|
||||
|
||||
// Any kind is possible
|
||||
return SourceKind::EmoteUserCommand;
|
||||
// We don't allow for mid-message command completions,
|
||||
// which means only emote or user tab completions are possible.
|
||||
|
||||
if (getSettings()->userCompletionOnlyWithAt)
|
||||
{
|
||||
return SourceKind::Emote;
|
||||
}
|
||||
|
||||
return SourceKind::EmoteUser;
|
||||
}
|
||||
|
||||
std::unique_ptr<completion::Source> TabCompletionModel::buildSource(
|
||||
@@ -121,6 +136,14 @@ std::unique_ptr<completion::Source> TabCompletionModel::buildSource(
|
||||
case SourceKind::Command: {
|
||||
return this->buildCommandSource();
|
||||
}
|
||||
case SourceKind::EmoteUser: {
|
||||
std::vector<std::unique_ptr<completion::Source>> sources;
|
||||
sources.push_back(this->buildEmoteSource());
|
||||
sources.push_back(this->buildUserSource(false));
|
||||
|
||||
return std::make_unique<completion::UnifiedSource>(
|
||||
std::move(sources));
|
||||
}
|
||||
case SourceKind::EmoteCommand: {
|
||||
std::vector<std::unique_ptr<completion::Source>> sources;
|
||||
sources.push_back(this->buildEmoteSource());
|
||||
|
||||
@@ -41,6 +41,8 @@ private:
|
||||
User,
|
||||
// Known to be a command, i.e. started with / or .
|
||||
Command,
|
||||
// Emote or user without : or @ .
|
||||
EmoteUser,
|
||||
// Emote or command without : or / .
|
||||
EmoteCommand,
|
||||
// Emote, user, or command without :, @, / .
|
||||
@@ -51,14 +53,17 @@ private:
|
||||
/// The completion source will only change if the deduced completion kind
|
||||
/// changes (see deduceSourceKind).
|
||||
/// @param query Completion query
|
||||
void updateSourceFromQuery(const QString &query);
|
||||
/// @param isFirstWord Whether the completion is the first word in the input
|
||||
void updateSourceFromQuery(const QString &query, bool isFirstWord);
|
||||
|
||||
/// @brief Attempts to deduce the source kind from the current query. If the
|
||||
/// bound Channel is not a TwitchChannel or if the query is too short, no
|
||||
/// query type will be deduced to prevent completions.
|
||||
/// @param query Completion query
|
||||
/// @param isFirstWord Whether the completion is the first word in the input
|
||||
/// @return An optional SourceKind deduced from the query
|
||||
std::optional<SourceKind> deduceSourceKind(const QString &query) const;
|
||||
std::optional<SourceKind> deduceSourceKind(const QString &query,
|
||||
bool isFirstWord) const;
|
||||
|
||||
std::unique_ptr<completion::Source> buildSource(SourceKind kind) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user