void InitMessageField( not_null<Window::Controller*> controller, not_null<Ui::InputField*> field) { field->setMinHeight(st::historySendSize.height() - 2 * st::historySendPadding); field->setMaxHeight(st::historyComposeFieldMaxHeight); field->setTagMimeProcessor(std::make_unique<FieldTagMimeProcessor>()); field->document()->setDocumentMargin(4.); field->setAdditionalMargin(convertScale(4) - 4); field->customTab(true); field->setInstantReplaces(Ui::InstantReplaces::Default()); field->setInstantReplacesEnabled(Global::ReplaceEmojiValue()); field->setMarkdownReplacesEnabled(rpl::single(true)); field->setEditLinkCallback( DefaultEditLinkCallback(controller, field)); }
AutocompleteQuery ParseMentionHashtagBotCommandQuery( not_null<const Ui::InputField*> field) { auto result = AutocompleteQuery(); const auto cursor = field->textCursor(); if (cursor.hasSelection()) { return result; } const auto position = cursor.position(); const auto document = field->document(); const auto block = document->findBlock(position); for (auto item = block.begin(); !item.atEnd(); ++item) { const auto fragment = item.fragment(); if (!fragment.isValid()) { continue; } const auto fragmentPosition = fragment.position(); const auto fragmentEnd = fragmentPosition + fragment.length(); if (fragmentPosition >= position || fragmentEnd < position) { continue; } const auto format = fragment.charFormat(); if (format.isImageFormat()) { continue; } bool mentionInCommand = false; const auto text = fragment.text(); for (auto i = position - fragmentPosition; i != 0; --i) { if (text[i - 1] == '@') { if ((position - fragmentPosition - i < 1 || text[i].isLetter()) && (i < 2 || !(text[i - 2].isLetterOrNumber() || text[i - 2] == '_'))) { result.fromStart = (i == 1) && (fragmentPosition == 0); result.query = text.mid(i - 1, position - fragmentPosition - i + 1); } else if ((position - fragmentPosition - i < 1 || text[i].isLetter()) && i > 2 && (text[i - 2].isLetterOrNumber() || text[i - 2] == '_') && !mentionInCommand) { mentionInCommand = true; --i; continue; } return result; } else if (text[i - 1] == '#') { if (i < 2 || !(text[i - 2].isLetterOrNumber() || text[i - 2] == '_')) { result.fromStart = (i == 1) && (fragmentPosition == 0); result.query = text.mid(i - 1, position - fragmentPosition - i + 1); } return result; } else if (text[i - 1] == '/') { if (i < 2) { result.fromStart = (i == 1) && (fragmentPosition == 0); result.query = text.mid(i - 1, position - fragmentPosition - i + 1); } return result; } if (position - fragmentPosition - i > 127 || (!mentionInCommand && (position - fragmentPosition - i > 63))) { break; } if (!text[i - 1].isLetterOrNumber() && text[i - 1] != '_') { break; } } break; } return result; }