Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

katecmds.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           katecmds.cpp  -  description
00003                              -------------------
00004     copyright            : (C) 2001 by The Kate Team
00005                            (C) 2002 by Joseph Wenninger
00006     email                : kwrite-devel@kde.org
00007                            jowenn@kde.org
00008 
00009  ***************************************************************************/
00010 
00011 /***************************************************************************
00012  *                                                                         *
00013  *   This program is free software; you can redistribute it and/or modify  *
00014  *   it under the terms of the GNU General Public License as published by  *
00015  *   the Free Software Foundation; either version 2 of the License, or     *
00016  *   (at your option) any later version.                                   *
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 // stolen from QString::replace
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;  // Avoid infinite loop on 0-length matches, e.g. [a-z]*
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                 {  // isn't a slash
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 // exchange "\t" for the actual tab character, for example
00108 static void exchangeAbbrevs(QString &str)
00109 {
00110         // the format is (findreplace)*[nullzero]
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                 // now set the backreferences in the replacement
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                         // I need to match "\\" or "", but not "\"
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 //      view->doc()->removeLine(line);
00182 //      view->doc()->insertLine(text, line);
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                 // Not implemented
00221         }
00222         else
00223         { // just this line
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         // hex, octal, base 9+1
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         // identify the base
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         { // do the unicode thing
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 // vim: noet
00278 

Generated on Sat Nov 5 16:17:09 2005 for OPIE by  doxygen 1.4.2