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