1/*
2 SPDX-FileCopyrightText: 2003-2005 Anders Lund <anders@alweb.dk>
3 SPDX-FileCopyrightText: 2001-2010 Christoph Cullmann <cullmann@kde.org>
4 SPDX-FileCopyrightText: 2001 Charles Samuels <charles@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#ifndef KATE_SED_CMD_H
10#define KATE_SED_CMD_H
11
12#include "kateregexpsearch.h"
13#include <KTextEditor/Command>
14
15#include <QStringList>
16
17namespace KTextEditor
18{
19class DocumentPrivate;
20class ViewPrivate;
21}
22
23/**
24 * The KateCommands namespace collects subclasses of KTextEditor::Command
25 * for specific use in kate.
26 */
27namespace KateCommands
28{
29/**
30 * Support vim/sed style search and replace
31 * @author Charles Samuels <charles@kde.org>
32 **/
33class SedReplace : public KTextEditor::Command
34{
35 static SedReplace *m_instance;
36
37protected:
38 SedReplace()
39 : KTextEditor::Command({QStringLiteral("s"), QStringLiteral("%s"), QStringLiteral("$s")})
40 {
41 }
42
43public:
44 ~SedReplace() override
45 {
46 m_instance = nullptr;
47 }
48
49 /**
50 * Execute command. Valid command strings are:
51 * - s/search/replace/ find @c search, replace it with @c replace
52 * on this line
53 * - \%s/search/replace/ do the same to the whole file
54 * - s/search/replace/i do the search and replace case insensitively
55 * - $s/search/replace/ do the search are replacement to the
56 * selection only
57 *
58 * @note $s/// is currently unsupported
59 * @param view view to use for execution
60 * @param cmd cmd string
61 * @param errorMsg error to return if no success
62 * @return success
63 */
64 bool exec(class KTextEditor::View *view, const QString &cmd, QString &errorMsg, const KTextEditor::Range &r) override;
65
66 bool supportsRange(const QString &) override
67 {
68 return true;
69 }
70
71 /** This command does not have help. @see KTextEditor::Command::help */
72 bool help(class KTextEditor::View *, const QString &, QString &) override
73 {
74 return false;
75 }
76
77 static SedReplace *self()
78 {
79 if (m_instance == nullptr) {
80 m_instance = new SedReplace();
81 }
82 return m_instance;
83 }
84
85 /**
86 * Parses @c sedReplaceString to see if it is a valid sed replace expression (e.g. "s/find/replace/gi").
87 * If it is, returns true and sets @c delimiter to the delimiter used in the expression;
88 * @c destFindBeginPos and @c destFindEndPos to the positions in * @c sedReplaceString of the
89 * begin and end of the "find" term; and @c destReplaceBeginPos and @c destReplaceEndPos to the begin
90 * and end positions of the "replace" term.
91 */
92 static bool
93 parse(const QString &sedReplaceString, QString &destDelim, int &destFindBeginPos, int &destFindEndPos, int &destReplaceBeginPos, int &destReplaceEndPos);
94
95 class InteractiveSedReplacer
96 {
97 public:
98 InteractiveSedReplacer(KTextEditor::DocumentPrivate *doc,
99 const QString &findPattern,
100 const QString &replacePattern,
101 bool caseSensitive,
102 bool onlyOnePerLine,
103 int startLine,
104 int endLine);
105 /**
106 * Will return invalid Range if there are no further matches.
107 */
108 KTextEditor::Range currentMatch();
109 void skipCurrentMatch();
110 void replaceCurrentMatch();
111 void replaceAllRemaining();
112 QString currentMatchReplacementConfirmationMessage();
113 QString finalStatusReportMessage() const;
114
115 private:
116 const QString m_findPattern;
117 const QString m_replacePattern;
118 bool m_onlyOnePerLine;
119 int m_endLine;
120 KTextEditor::DocumentPrivate *m_doc;
121 KateRegExpSearch m_regExpSearch;
122 Qt::CaseSensitivity m_caseSensitive;
123
124 int m_numReplacementsDone;
125 int m_numLinesTouched;
126 int m_lastChangedLineNum;
127
128 KTextEditor::Cursor m_currentSearchPos;
129 const QList<KTextEditor::Range> fullCurrentMatch();
130 QString replacementTextForCurrentMatch();
131 };
132
133protected:
134 virtual bool interactiveSedReplace(KTextEditor::ViewPrivate *kateView, std::shared_ptr<InteractiveSedReplacer> interactiveSedReplace);
135};
136
137} // namespace KateCommands
138#endif
139

source code of ktexteditor/src/utils/katesedcmd.h