File indexing completed on 2024-04-28 15:30:55
0001 /* 0002 SPDX-FileCopyrightText: 2003-2005 Anders Lund <anders@alweb.dk> 0003 SPDX-FileCopyrightText: 2001-2010 Christoph Cullmann <cullmann@kde.org> 0004 SPDX-FileCopyrightText: 2001 Charles Samuels <charles@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KATE_SED_CMD_H 0010 #define KATE_SED_CMD_H 0011 0012 #include "kateregexpsearch.h" 0013 #include <KTextEditor/Command> 0014 0015 #include <QSharedPointer> 0016 #include <QStringList> 0017 0018 namespace KTextEditor 0019 { 0020 class DocumentPrivate; 0021 class ViewPrivate; 0022 } 0023 0024 /** 0025 * The KateCommands namespace collects subclasses of KTextEditor::Command 0026 * for specific use in kate. 0027 */ 0028 namespace KateCommands 0029 { 0030 /** 0031 * Support vim/sed style search and replace 0032 * @author Charles Samuels <charles@kde.org> 0033 **/ 0034 class SedReplace : public KTextEditor::Command 0035 { 0036 static SedReplace *m_instance; 0037 0038 protected: 0039 SedReplace() 0040 : KTextEditor::Command({QStringLiteral("s"), QStringLiteral("%s"), QStringLiteral("$s")}) 0041 { 0042 } 0043 0044 public: 0045 ~SedReplace() override 0046 { 0047 m_instance = nullptr; 0048 } 0049 0050 /** 0051 * Execute command. Valid command strings are: 0052 * - s/search/replace/ find @c search, replace it with @c replace 0053 * on this line 0054 * - \%s/search/replace/ do the same to the whole file 0055 * - s/search/replace/i do the search and replace case insensitively 0056 * - $s/search/replace/ do the search are replacement to the 0057 * selection only 0058 * 0059 * @note $s/// is currently unsupported 0060 * @param view view to use for execution 0061 * @param cmd cmd string 0062 * @param errorMsg error to return if no success 0063 * @return success 0064 */ 0065 bool exec(class KTextEditor::View *view, const QString &cmd, QString &errorMsg, const KTextEditor::Range &r) override; 0066 0067 bool supportsRange(const QString &) override 0068 { 0069 return true; 0070 } 0071 0072 /** This command does not have help. @see KTextEditor::Command::help */ 0073 bool help(class KTextEditor::View *, const QString &, QString &) override 0074 { 0075 return false; 0076 } 0077 0078 static SedReplace *self() 0079 { 0080 if (m_instance == nullptr) { 0081 m_instance = new SedReplace(); 0082 } 0083 return m_instance; 0084 } 0085 0086 /** 0087 * Parses @c sedReplaceString to see if it is a valid sed replace expression (e.g. "s/find/replace/gi"). 0088 * If it is, returns true and sets @c delimiter to the delimiter used in the expression; 0089 * @c destFindBeginPos and @c destFindEndPos to the positions in * @c sedReplaceString of the 0090 * begin and end of the "find" term; and @c destReplaceBeginPos and @c destReplaceEndPos to the begin 0091 * and end positions of the "replace" term. 0092 */ 0093 static bool 0094 parse(const QString &sedReplaceString, QString &destDelim, int &destFindBeginPos, int &destFindEndPos, int &destReplaceBeginPos, int &destReplaceEndPos); 0095 0096 class InteractiveSedReplacer 0097 { 0098 public: 0099 InteractiveSedReplacer(KTextEditor::DocumentPrivate *doc, 0100 const QString &findPattern, 0101 const QString &replacePattern, 0102 bool caseSensitive, 0103 bool onlyOnePerLine, 0104 int startLine, 0105 int endLine); 0106 /** 0107 * Will return invalid Range if there are no further matches. 0108 */ 0109 KTextEditor::Range currentMatch(); 0110 void skipCurrentMatch(); 0111 void replaceCurrentMatch(); 0112 void replaceAllRemaining(); 0113 QString currentMatchReplacementConfirmationMessage(); 0114 QString finalStatusReportMessage() const; 0115 0116 private: 0117 const QString m_findPattern; 0118 const QString m_replacePattern; 0119 bool m_onlyOnePerLine; 0120 int m_endLine; 0121 KTextEditor::DocumentPrivate *m_doc; 0122 KateRegExpSearch m_regExpSearch; 0123 Qt::CaseSensitivity m_caseSensitive; 0124 0125 int m_numReplacementsDone; 0126 int m_numLinesTouched; 0127 int m_lastChangedLineNum; 0128 0129 KTextEditor::Cursor m_currentSearchPos; 0130 const QVector<KTextEditor::Range> fullCurrentMatch(); 0131 QString replacementTextForCurrentMatch(); 0132 }; 0133 0134 protected: 0135 virtual bool interactiveSedReplace(KTextEditor::ViewPrivate *kateView, QSharedPointer<InteractiveSedReplacer> interactiveSedReplace); 0136 }; 0137 0138 } // namespace KateCommands 0139 #endif