File indexing completed on 2024-04-21 03:57:39

0001 /*
0002     SPDX-FileCopyrightText: 2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
0003     SPDX-FileCopyrightText: 2007 Sebastian Pipping <webmaster@hartwork.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "katematch.h"
0009 
0010 #include "katedocument.h"
0011 #include "kateregexpsearch.h"
0012 
0013 KateMatch::KateMatch(KTextEditor::DocumentPrivate *document, KTextEditor::SearchOptions options)
0014     : m_document(document)
0015     , m_options(options)
0016 {
0017     m_resultRanges.append(KTextEditor::Range::invalid());
0018 }
0019 
0020 KTextEditor::Range KateMatch::searchText(KTextEditor::Range range, const QString &pattern)
0021 {
0022     m_resultRanges = m_document->searchText(range, pattern, m_options);
0023 
0024     return m_resultRanges[0];
0025 }
0026 
0027 KTextEditor::Range KateMatch::replace(const QString &replacement, bool blockMode, int replacementCounter)
0028 {
0029     // Placeholders depending on search mode
0030     // skip place-holder stuff if we have no \ at all inside the replacement, the buildReplacement is expensive
0031     const bool usePlaceholders =
0032         (m_options.testFlag(KTextEditor::Regex) || m_options.testFlag(KTextEditor::EscapeSequences)) && replacement.contains(QLatin1Char('\\'));
0033 
0034     const QString finalReplacement = usePlaceholders ? buildReplacement(replacement, blockMode, replacementCounter) : replacement;
0035 
0036     // Track replacement operation, reuse range if already there
0037     if (m_afterReplaceRange) {
0038         m_afterReplaceRange->setRange(range());
0039     } else {
0040         m_afterReplaceRange.reset(m_document->newMovingRange(range(), KTextEditor::MovingRange::ExpandLeft | KTextEditor::MovingRange::ExpandRight));
0041     }
0042 
0043     // replace and return results range
0044     m_document->replaceText(range(), finalReplacement, blockMode && !range().onSingleLine());
0045     return m_afterReplaceRange->toRange();
0046 }
0047 
0048 KTextEditor::Range KateMatch::range() const
0049 {
0050     if (!m_resultRanges.isEmpty()) {
0051         return m_resultRanges[0];
0052     }
0053 
0054     return KTextEditor::Range::invalid();
0055 }
0056 
0057 bool KateMatch::isEmpty() const
0058 {
0059     return range().isEmpty();
0060 }
0061 
0062 bool KateMatch::isValid() const
0063 {
0064     return range().isValid();
0065 }
0066 
0067 QString KateMatch::buildReplacement(const QString &replacement, bool blockMode, int replacementCounter) const
0068 {
0069     QStringList capturedTexts;
0070     capturedTexts.reserve(m_resultRanges.size());
0071     for (KTextEditor::Range captureRange : std::as_const(m_resultRanges)) {
0072         // Copy capture content
0073         capturedTexts << m_document->text(captureRange, blockMode);
0074     }
0075 
0076     return KateRegExpSearch::buildReplacement(replacement, capturedTexts, replacementCounter);
0077 }