00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "katecmds.h"
00020 #include <qregexp.h>
00021 #include <qregexp3.h>
00022 #include <qdatetime.h>
00023 #include "katedocument.h"
00024 #include <kdebug.h>
00025
00026 namespace KateCommands
00027 {
00028
00029
00030 bool InsertTime::execCmd(QString cmd, KateView *view)
00031 {
00032 if (cmd.left(5) == "time")
00033 {
00034 view->insertText(QTime::currentTime().toString());
00035 return true;
00036 }
00037
00038 return false;
00039 }
00040
00041 static void replace(QString &s, const QString &needle, const QString &with)
00042 {
00043 int pos=0;
00044 while (1)
00045 {
00046 pos=s.find(needle, pos);
00047 if (pos==-1) break;
00048 s.replace(pos, needle.length(), with);
00049 pos+=with.length();
00050 }
00051
00052 }
00053
00054
00055 static void replace(QString &s, QRegExp3 &rx, const QString &with)
00056 {
00057 if (s.isEmpty()) return;
00058 int index = 0;
00059 int slen = with.length();
00060 int len;
00061 while (index < (int)s.length())
00062 {
00063 index = rx.search(s, index);
00064 len = rx.matchedLength();
00065 if ( index >= 0 )
00066 {
00067 s.replace(index, len, with);
00068 index += slen;
00069 if (!len)
00070 break;
00071 }
00072 else
00073 break;
00074 }
00075 }
00076
00077
00078
00079 static int backslashString(const QString &haystack, const QString &needle, int index)
00080 {
00081 int len=haystack.length();
00082 int searchlen=needle.length();
00083 bool evenCount=true;
00084 while (index<len)
00085 {
00086 if (haystack[index]=='\\')
00087 {
00088 evenCount=!evenCount;
00089 }
00090 else
00091 {
00092 if (!evenCount)
00093 {
00094 if (haystack.mid(index, searchlen)==needle)
00095 return index-1;
00096 }
00097 evenCount=true;
00098 }
00099 index++;
00100
00101 }
00102
00103 return -1;
00104 }
00105
00106
00107
00108 static void exchangeAbbrevs(QString &str)
00109 {
00110
00111 char *magic="a\x07t\t";
00112
00113 while (*magic)
00114 {
00115 int index=0;
00116 char replace=magic[1];
00117 while ((index=backslashString(str, QChar(*magic), index))!=-1)
00118 {
00119 str.replace(index, 2, QChar(replace));
00120 index++;
00121 }
00122 magic++;
00123 magic++;
00124 }
00125 }
00126
00127 QString SedReplace::sedMagic(QString textLine, QString find, QString rep, bool noCase, bool repeat)
00128 {
00129 QRegExp3 matcher(find, noCase);
00130
00131 int start=0;
00132 while (start!=-1)
00133 {
00134 start=matcher.search(textLine, start);
00135
00136 if (start==-1) break;
00137
00138 int length=matcher.matchedLength();
00139
00140
00141
00142 QStringList backrefs=matcher.capturedTexts();
00143 int refnum=1;
00144
00145 QStringList::Iterator i = backrefs.begin();
00146 ++i;
00147
00148 for (; i!=backrefs.end(); ++i)
00149 {
00150
00151 QString number=QString::number(refnum);
00152
00153 int index=0;
00154 while (index!=-1)
00155 {
00156 index=backslashString(rep, number, index);
00157 if (index>=0)
00158 {
00159 rep.replace(index, 2, *i);
00160 index+=(*i).length();
00161 }
00162 }
00163
00164 refnum++;
00165 }
00166
00167 textLine.replace(start, length, rep);
00168 if (!repeat) break;
00169 start+=rep.length();
00170 }
00171
00172 replace(textLine, "\\\\", "\\");
00173 replace(textLine, "\\/", "/");
00174
00175 return textLine;
00176 }
00177
00178
00179 static void setLineText(KateView *view, int line, const QString &text)
00180 {
00181
00182
00183 view->doc()->replaceLine(text,line);
00184 }
00185
00186 bool SedReplace::execCmd(QString cmd, KateView *view)
00187 {
00188 kdDebug(13010)<<"SedReplace::execCmd()"<<endl;
00189 if (QRegExp("[$%]?s/.+/.*/[ig]*").find(cmd, 0)==-1)
00190 return false;
00191
00192 bool fullFile=cmd[0]=='%';
00193 bool noCase=cmd[cmd.length()-1]=='i' || cmd[cmd.length()-2]=='i';
00194 bool repeat=cmd[cmd.length()-1]=='g' || cmd[cmd.length()-2]=='g';
00195 bool onlySelect=cmd[0]=='$';
00196
00197 QRegExp3 splitter("^[$%]?s/((?:[^\\\\/]|\\\\[\\\\/\\$0-9tadDsSwW])*)/((?:[^\\\\/]|\\\\[\\\\/\\$0-9tadDsSwW])*)/[ig]*$");
00198 if (splitter.search(cmd)<0) return false;
00199
00200 QString find=splitter.cap(1);
00201 kdDebug(13010)<< "SedReplace: find=" << find.latin1() <<endl;
00202
00203 QString replace=splitter.cap(2);
00204 exchangeAbbrevs(replace);
00205 kdDebug(13010)<< "SedReplace: replace=" << replace.latin1() <<endl;
00206
00207
00208 if (fullFile)
00209 {
00210 int numLines=view->doc()->numLines();
00211 for (int line=0; line < numLines; line++)
00212 {
00213 QString text=view->textLine(line);
00214 text=sedMagic(text, find, replace, noCase, repeat);
00215 setLineText(view, line, text);
00216 }
00217 }
00218 else if (onlySelect)
00219 {
00220
00221 }
00222 else
00223 {
00224 QString textLine=view->currentTextLine();
00225 int line=view->currentLine();
00226 textLine=sedMagic(textLine, find, replace, noCase, repeat);
00227 setLineText(view, line, textLine);
00228 }
00229 return true;
00230 }
00231
00232 bool Character::execCmd(QString cmd, KateView *view)
00233 {
00234
00235 QRegExp3 num("^char: *(0?x[0-9A-Fa-f]{1,4}|0[0-7]{1,6}|[0-9]{1,3})$");
00236 if (num.search(cmd)==-1) return false;
00237
00238 cmd=num.cap(1);
00239
00240
00241
00242 unsigned short int number=0;
00243 int base=10;
00244 if (cmd[0]=='x' || cmd.left(2)=="0x")
00245 {
00246 cmd.replace(QRegExp("^0?x"), "");
00247 base=16;
00248 }
00249 else if (cmd[0]=='0')
00250 base=8;
00251 bool ok;
00252 number=cmd.toUShort(&ok, base);
00253 if (!ok || number==0) return false;
00254 if (number<=255)
00255 {
00256 char buf[2];
00257 buf[0]=(char)number;
00258 buf[1]=0;
00259 view->insertText(QString(buf));
00260 }
00261 else
00262 {
00263 QChar c(number);
00264 view->insertText(QString(&c, 1));
00265 }
00266
00267 return true;
00268 }
00269
00270 bool Fifo::execCmd(QString cmd, KateView *view)
00271 {
00272
00273 }
00274
00275 }
00276
00277
00278