File indexing completed on 2024-04-21 07:44:43

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 #ifndef _KATE_REGEXPSEARCH_H_
0009 #define _KATE_REGEXPSEARCH_H_
0010 
0011 #include <QObject>
0012 #include <QRegularExpression>
0013 
0014 #include <ktexteditor/range.h>
0015 
0016 #include <ktexteditor_export.h>
0017 
0018 namespace KTextEditor
0019 {
0020 class Document;
0021 }
0022 
0023 /**
0024  * Object to help to search for regexp.
0025  * This should be NO QObject, it is created to often!
0026  * I measured that, if you create it 20k times to replace for example " " in a document, that takes seconds on a modern machine!
0027  */
0028 class KTEXTEDITOR_EXPORT KateRegExpSearch
0029 {
0030 public:
0031     explicit KateRegExpSearch(const KTextEditor::Document *document);
0032     ~KateRegExpSearch() = default;
0033 
0034     //
0035     // KTextEditor::SearchInterface stuff
0036     //
0037 public:
0038     /**
0039      * Search for the regular expression \p pattern inside the range
0040      * \p inputRange. If \p backwards is \e true, the search direction will
0041      * be reversed. \p options is a set of QRegularExpression::PatternOptions
0042      * OR flags that control certain aspects of the search, e.g. case
0043      * sensitivity and if the dot "." metacharacter matches any character
0044      * including a newline.
0045      *
0046      * Note: Unicode support is always enabled (QRegularExpression::UseUnicodePropertiesOption).
0047      * If the pattern is multi-line the QRegularExpression::MultilineOption is enabled.
0048      *
0049      * \param pattern text to search for
0050      * \param inputRange Range to search in
0051      * \param backwards if \e true, the search will be backwards
0052      * \param options QRegularExpression pattern options, we will internally add QRegularExpression::UseUnicodePropertiesOption
0053      * \return Vector of ranges, one for each capture group. The first range (index
0054      *         zero) spans the whole match. If no matches are found, the vector will
0055      *         contain one element, an invalid range (see Range::isValid()).
0056      * \see KTextEditor::Range, QRegularExpression
0057      */
0058     QList<KTextEditor::Range> search(const QString &pattern,
0059                                      KTextEditor::Range inputRange,
0060                                      bool backwards = false,
0061                                      QRegularExpression::PatternOptions options = QRegularExpression::NoPatternOption);
0062 
0063     /**
0064      * Returns a modified version of text where escape sequences are resolved, e.g. "\\n" to "\n".
0065      *
0066      * \param text text containing escape sequences
0067      * \return text with resolved escape sequences
0068      */
0069     static QString escapePlaintext(const QString &text);
0070 
0071     /**
0072      * Returns a modified version of text where
0073      * \li escape sequences are resolved, e.g. "\\n" to "\n",
0074      * \li references are resolved, e.g. "\\1" to <i>1st entry in capturedTexts</i>, and
0075      * \li counter sequences are resolved, e.g. "\\#...#" to <i>replacementCounter</i>.
0076      *
0077      * \param text text containing escape sequences, references, and counter sequences
0078      * \param capturedTexts list of substitutes for references
0079      * \param replacementCounter value for replacement counter
0080      * \return resolved text
0081      */
0082     static QString buildReplacement(const QString &text, const QStringList &capturedTexts, int replacementCounter);
0083 
0084 private:
0085     /**
0086      * Implementation of escapePlainText() and public buildReplacement().
0087      *
0088      * \param text text containing escape sequences and possibly references and counters
0089      * \param capturedTexts list of substitutes for references
0090      * \param replacementCounter value for replacement counter (only used when replacementGoodies == true)
0091      * \param replacementGoodies @c true for buildReplacement(), @c false for escapePlainText()
0092      * \return resolved text
0093      */
0094     KTEXTEDITOR_NO_EXPORT
0095     static QString buildReplacement(const QString &text, const QStringList &capturedTexts, int replacementCounter, bool replacementGoodies);
0096 
0097     /**
0098      * Checks the pattern for special characters and escape sequences that can
0099      * make a match span multiple lines; if any are found, \p stillMultiLine is
0100      * set to true.
0101      *
0102      * "\s" is treated specially so that it doesn't match new line characters; this
0103      * is achieved by replacing any occurences of "\s" with "[ \t]" in the search
0104      * \p pattern.
0105      *
0106      * \param pattern the regular expression search pattern
0107      * \param stillMultiLine is set to \c true if the search pattern may still match
0108      * multiple lines even after replacing "\s" with "[ \t]"; otherwise it's set to false
0109      * \return the modified pattern
0110      */
0111     KTEXTEDITOR_NO_EXPORT
0112     static QString repairPattern(const QString &pattern, bool &stillMultiLine);
0113 
0114 private:
0115     const KTextEditor::Document *const m_document;
0116     class ReplacementStream;
0117 };
0118 
0119 #endif