summaryrefslogtreecommitdiff
path: root/noncore/apps/tinykate/libkate/document/katecmds.cpp
Unidiff
Diffstat (limited to 'noncore/apps/tinykate/libkate/document/katecmds.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/tinykate/libkate/document/katecmds.cpp278
1 files changed, 278 insertions, 0 deletions
diff --git a/noncore/apps/tinykate/libkate/document/katecmds.cpp b/noncore/apps/tinykate/libkate/document/katecmds.cpp
new file mode 100644
index 0000000..3647853
--- a/dev/null
+++ b/noncore/apps/tinykate/libkate/document/katecmds.cpp
@@ -0,0 +1,278 @@
1/***************************************************************************
2 katecmds.cpp - description
3 -------------------
4 copyright : (C) 2001 by The Kate Team
5 (C) 2002 by Joseph Wenninger
6 email : kwrite-devel@kde.org
7 jowenn@kde.org
8
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19#include "katecmds.h"
20#include <qregexp.h>
21#include <qregexp3.h>
22#include <qdatetime.h>
23#include "katedocument.h"
24#include <kdebug.h>
25
26namespace KateCommands
27{
28
29
30bool InsertTime::execCmd(QString cmd, KateView *view)
31{
32 if (cmd.left(5) == "time")
33 {
34 view->insertText(QTime::currentTime().toString());
35 return true;
36 }
37
38 return false;
39}
40
41static void replace(QString &s, const QString &needle, const QString &with)
42{
43 int pos=0;
44 while (1)
45 {
46 pos=s.find(needle, pos);
47 if (pos==-1) break;
48 s.replace(pos, needle.length(), with);
49 pos+=with.length();
50 }
51
52}
53
54// stolen from QString::replace
55static void replace(QString &s, QRegExp3 &rx, const QString &with)
56{
57 if (s.isEmpty()) return;
58 int index = 0;
59 int slen = with.length();
60 int len;
61 while (index < (int)s.length())
62 {
63 index = rx.search(s, index);
64 len = rx.matchedLength();
65 if ( index >= 0 )
66 {
67 s.replace(index, len, with);
68 index += slen;
69 if (!len)
70 break; // Avoid infinite loop on 0-length matches, e.g. [a-z]*
71 }
72 else
73 break;
74 }
75}
76
77
78
79static int backslashString(const QString &haystack, const QString &needle, int index)
80{
81 int len=haystack.length();
82 int searchlen=needle.length();
83 bool evenCount=true;
84 while (index<len)
85 {
86 if (haystack[index]=='\\')
87 {
88 evenCount=!evenCount;
89 }
90 else
91 { // isn't a slash
92 if (!evenCount)
93 {
94 if (haystack.mid(index, searchlen)==needle)
95 return index-1;
96 }
97 evenCount=true;
98 }
99 index++;
100
101 }
102
103 return -1;
104}
105
106
107// exchange "\t" for the actual tab character, for example
108static void exchangeAbbrevs(QString &str)
109{
110 // the format is (findreplace)*[nullzero]
111 char *magic="a\x07t\t";
112
113 while (*magic)
114 {
115 int index=0;
116 char replace=magic[1];
117 while ((index=backslashString(str, QChar(*magic), index))!=-1)
118 {
119 str.replace(index, 2, QChar(replace));
120 index++;
121 }
122 magic++;
123 magic++;
124 }
125}
126
127QString SedReplace::sedMagic(QString textLine, QString find, QString rep, bool noCase, bool repeat)
128{
129 QRegExp3 matcher(find, noCase);
130
131 int start=0;
132 while (start!=-1)
133 {
134 start=matcher.search(textLine, start);
135
136 if (start==-1) break;
137
138 int length=matcher.matchedLength();
139
140
141 // now set the backreferences in the replacement
142 QStringList backrefs=matcher.capturedTexts();
143 int refnum=1;
144
145 QStringList::Iterator i = backrefs.begin();
146 ++i;
147
148 for (; i!=backrefs.end(); ++i)
149 {
150 // I need to match "\\" or "", but not "\"
151 QString number=QString::number(refnum);
152
153 int index=0;
154 while (index!=-1)
155 {
156 index=backslashString(rep, number, index);
157 if (index>=0)
158 {
159 rep.replace(index, 2, *i);
160 index+=(*i).length();
161 }
162 }
163
164 refnum++;
165 }
166
167 textLine.replace(start, length, rep);
168 if (!repeat) break;
169 start+=rep.length();
170 }
171
172 replace(textLine, "\\\\", "\\");
173 replace(textLine, "\\/", "/");
174
175 return textLine;
176}
177
178
179static void setLineText(KateView *view, int line, const QString &text)
180{
181 //view->doc()->removeLine(line);
182 //view->doc()->insertLine(text, line);
183 view->doc()->replaceLine(text,line);
184}
185
186bool SedReplace::execCmd(QString cmd, KateView *view)
187{
188 kdDebug(13010)<<"SedReplace::execCmd()"<<endl;
189 if (QRegExp("[$%]?s/.+/.*/[ig]*").find(cmd, 0)==-1)
190 return false;
191
192 bool fullFile=cmd[0]=='%';
193 bool noCase=cmd[cmd.length()-1]=='i' || cmd[cmd.length()-2]=='i';
194 bool repeat=cmd[cmd.length()-1]=='g' || cmd[cmd.length()-2]=='g';
195 bool onlySelect=cmd[0]=='$';
196
197 QRegExp3 splitter("^[$%]?s/((?:[^\\\\/]|\\\\[\\\\/\\$0-9tadDsSwW])*)/((?:[^\\\\/]|\\\\[\\\\/\\$0-9tadDsSwW])*)/[ig]*$");
198 if (splitter.search(cmd)<0) return false;
199
200 QString find=splitter.cap(1);
201 kdDebug(13010)<< "SedReplace: find=" << find.latin1() <<endl;
202
203 QString replace=splitter.cap(2);
204 exchangeAbbrevs(replace);
205 kdDebug(13010)<< "SedReplace: replace=" << replace.latin1() <<endl;
206
207
208 if (fullFile)
209 {
210 int numLines=view->doc()->numLines();
211 for (int line=0; line < numLines; line++)
212 {
213 QString text=view->textLine(line);
214 text=sedMagic(text, find, replace, noCase, repeat);
215 setLineText(view, line, text);
216 }
217 }
218 else if (onlySelect)
219 {
220 // Not implemented
221 }
222 else
223 { // just this line
224 QString textLine=view->currentTextLine();
225 int line=view->currentLine();
226 textLine=sedMagic(textLine, find, replace, noCase, repeat);
227 setLineText(view, line, textLine);
228 }
229 return true;
230}
231
232bool Character::execCmd(QString cmd, KateView *view)
233{
234 // hex, octal, base 9+1
235 QRegExp3 num("^char: *(0?x[0-9A-Fa-f]{1,4}|0[0-7]{1,6}|[0-9]{1,3})$");
236 if (num.search(cmd)==-1) return false;
237
238 cmd=num.cap(1);
239
240 // identify the base
241
242 unsigned short int number=0;
243 int base=10;
244 if (cmd[0]=='x' || cmd.left(2)=="0x")
245 {
246 cmd.replace(QRegExp("^0?x"), "");
247 base=16;
248 }
249 else if (cmd[0]=='0')
250 base=8;
251 bool ok;
252 number=cmd.toUShort(&ok, base);
253 if (!ok || number==0) return false;
254 if (number<=255)
255 {
256 char buf[2];
257 buf[0]=(char)number;
258 buf[1]=0;
259 view->insertText(QString(buf));
260 }
261 else
262 { // do the unicode thing
263 QChar c(number);
264 view->insertText(QString(&c, 1));
265 }
266
267 return true;
268}
269
270bool Fifo::execCmd(QString cmd, KateView *view)
271{
272
273}
274
275}
276
277// vim: noet
278