forked from qt-creator/qt-creator
FakeVim: Fix case insensitivity handling for forward searching
Change-Id: I1f5b13022f3ae06916434b48cf3c6ba6d4722746 Reviewed-by: Lukas Holecek <hluk@email.cz> Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -278,6 +278,23 @@ QDebug operator<<(QDebug ts, const CursorPosition &pos)
|
||||
return ts << "(line: " << pos.line << ", column: " << pos.column << ")";
|
||||
}
|
||||
|
||||
// vi style configuration
|
||||
static QVariant config(int code)
|
||||
{
|
||||
return theFakeVimSetting(code)->value();
|
||||
}
|
||||
|
||||
static bool hasConfig(int code)
|
||||
{
|
||||
return config(code).toBool();
|
||||
}
|
||||
|
||||
static bool hasConfig(int code, const QString &value)
|
||||
{
|
||||
return config(code).toString().contains(value);
|
||||
}
|
||||
|
||||
|
||||
class Mark
|
||||
{
|
||||
public:
|
||||
@@ -387,7 +404,7 @@ static bool eatString(const QString &prefix, QString *str)
|
||||
return true;
|
||||
}
|
||||
|
||||
static QRegularExpression vimPatternToQtPattern(QString needle, bool ignoreCaseOption, bool smartCaseOption)
|
||||
static QRegularExpression vimPatternToQtPattern(const QString &needle)
|
||||
{
|
||||
/* Transformations (Vim regexp -> QRegularExpression):
|
||||
* \a -> [A-Za-z]
|
||||
@@ -418,9 +435,15 @@ static QRegularExpression vimPatternToQtPattern(QString needle, bool ignoreCaseO
|
||||
* \c - set ignorecase for rest
|
||||
* \C - set noignorecase for rest
|
||||
*/
|
||||
|
||||
// FIXME: Option smartcase should be used only if search was typed by user.
|
||||
bool ignorecase = ignoreCaseOption
|
||||
const bool ignoreCaseOption = hasConfig(ConfigIgnoreCase);
|
||||
const bool smartCaseOption = hasConfig(ConfigSmartCase);
|
||||
const bool initialIgnoreCase = ignoreCaseOption
|
||||
&& !(smartCaseOption && needle.contains(QRegularExpression("[A-Z]")));
|
||||
|
||||
bool ignorecase = initialIgnoreCase;
|
||||
|
||||
QString pattern;
|
||||
pattern.reserve(2 * needle.size());
|
||||
|
||||
@@ -429,7 +452,7 @@ static QRegularExpression vimPatternToQtPattern(QString needle, bool ignoreCaseO
|
||||
bool embraced = false;
|
||||
bool range = false;
|
||||
bool curly = false;
|
||||
foreach (const QChar &c, needle) {
|
||||
for (const QChar &c : needle) {
|
||||
if (brace) {
|
||||
brace = false;
|
||||
if (c == ']') {
|
||||
@@ -530,7 +553,8 @@ static QRegularExpression vimPatternToQtPattern(QString needle, bool ignoreCaseO
|
||||
else if (brace)
|
||||
pattern.append('[');
|
||||
|
||||
return QRegularExpression(pattern);
|
||||
return QRegularExpression(pattern, initialIgnoreCase ? QRegularExpression::CaseInsensitiveOption
|
||||
: QRegularExpression::NoPatternOption);
|
||||
}
|
||||
|
||||
static bool afterEndOfLine(const QTextDocument *doc, int position)
|
||||
@@ -544,17 +568,21 @@ static void searchForward(QTextCursor *tc, const QRegularExpression &needleExp,
|
||||
const QTextDocument *doc = tc->document();
|
||||
const int startPos = tc->position();
|
||||
|
||||
QTextDocument::FindFlags flags = {};
|
||||
if (!(needleExp.patternOptions() & QRegularExpression::CaseInsensitiveOption))
|
||||
flags |= QTextDocument::FindCaseSensitively;
|
||||
|
||||
// Search from beginning of line so that matched text is the same.
|
||||
tc->movePosition(StartOfLine);
|
||||
|
||||
// forward to current position
|
||||
*tc = doc->find(needleExp, *tc);
|
||||
*tc = doc->find(needleExp, *tc, flags);
|
||||
while (!tc->isNull() && tc->anchor() < startPos) {
|
||||
if (!tc->hasSelection())
|
||||
tc->movePosition(Right);
|
||||
if (tc->atBlockEnd())
|
||||
tc->movePosition(NextBlock);
|
||||
*tc = doc->find(needleExp, *tc);
|
||||
*tc = doc->find(needleExp, *tc, flags);
|
||||
}
|
||||
|
||||
if (tc->isNull())
|
||||
@@ -567,7 +595,7 @@ static void searchForward(QTextCursor *tc, const QRegularExpression &needleExp,
|
||||
tc->movePosition(Right);
|
||||
if (tc->atBlockEnd())
|
||||
tc->movePosition(NextBlock);
|
||||
*tc = doc->find(needleExp, *tc);
|
||||
*tc = doc->find(needleExp, *tc, flags);
|
||||
if (tc->isNull())
|
||||
return;
|
||||
--*repeat;
|
||||
@@ -2117,12 +2145,6 @@ public:
|
||||
CursorPosition markLessPosition() const { return mark('<').position(document()); }
|
||||
CursorPosition markGreaterPosition() const { return mark('>').position(document()); }
|
||||
|
||||
// vi style configuration
|
||||
QVariant config(int code) const { return theFakeVimSetting(code)->value(); }
|
||||
bool hasConfig(int code) const { return config(code).toBool(); }
|
||||
bool hasConfig(int code, const QString &value) const
|
||||
{ return config(code).toString().contains(value); }
|
||||
|
||||
int m_targetColumn; // -1 if past end of line
|
||||
int m_visualTargetColumn; // 'l' can move past eol in visual mode only
|
||||
int m_targetColumnWrapped; // column in current part of wrapped line
|
||||
@@ -5559,9 +5581,7 @@ bool FakeVimHandler::Private::handleExSubstituteCommand(const ExCommand &cmd)
|
||||
if (g.lastSubstituteFlags.contains('i'))
|
||||
needle.prepend("\\c");
|
||||
|
||||
const QRegularExpression pattern = vimPatternToQtPattern(needle,
|
||||
hasConfig(ConfigIgnoreCase),
|
||||
hasConfig(ConfigSmartCase));
|
||||
const QRegularExpression pattern = vimPatternToQtPattern(needle);
|
||||
|
||||
QTextBlock lastBlock;
|
||||
QTextBlock firstBlock;
|
||||
@@ -6355,9 +6375,8 @@ void FakeVimHandler::Private::searchBalanced(bool forward, QChar needle, QChar o
|
||||
QTextCursor FakeVimHandler::Private::search(const SearchData &sd, int startPos, int count,
|
||||
bool showMessages)
|
||||
{
|
||||
const QRegularExpression needleExp = vimPatternToQtPattern(sd.needle,
|
||||
hasConfig(ConfigIgnoreCase),
|
||||
hasConfig(ConfigSmartCase));
|
||||
const QRegularExpression needleExp = vimPatternToQtPattern(sd.needle);
|
||||
|
||||
if (!needleExp.isValid()) {
|
||||
if (showMessages) {
|
||||
QString error = needleExp.errorString();
|
||||
|
Reference in New Issue
Block a user