Kate
katecmd.cpp
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #include "katecmd.h"
00020 
00021 #include <kstaticdeleter.h>
00022 #include <kdebug.h>
00023 
00024 
00025 #define CMD_HIST_LENGTH 256
00026 
00027 KateCmd *KateCmd::s_self = 0;
00028 
00029 KateCmd::KateCmd ()
00030 {
00031 }
00032 
00033 KateCmd::~KateCmd ()
00034 {
00035 }
00036 
00037 bool KateCmd::registerCommand (Kate::Command *cmd)
00038 {
00039   QStringList l = cmd->cmds ();
00040 
00041   for (uint z=0; z<l.count(); z++)
00042     if (m_dict[l[z]])
00043       return false;
00044 
00045   for (uint z=0; z<l.count(); z++) {
00046     m_dict.insert (l[z], cmd);
00047     kdDebug()<<"Inserted command:"<<l[z]<<endl;
00048   }
00049 
00050   m_cmds += l;
00051 
00052   return true;
00053 }
00054 
00055 bool KateCmd::unregisterCommand (Kate::Command *cmd)
00056 {
00057   QStringList l;
00058   QDictIterator<Kate::Command> it(m_dict);
00059   for( ; it.current(); ++it )
00060     if (it.current()==cmd) l<<it.currentKey();
00061   for ( QStringList::Iterator it1 = l.begin(); it1 != l.end(); ++it1 ) {
00062     m_dict.remove(*it1);
00063     kdDebug()<<"Removed command:"<<*it1<<endl;
00064   }
00065   return true;
00066 }
00067 
00068 Kate::Command *KateCmd::queryCommand (const QString &cmd)
00069 {
00070   
00071   
00072   uint f = 0;
00073   bool b = false;
00074   for ( ; f < cmd.length(); f++ )
00075   {
00076     if ( cmd[f].isLetter() )
00077       b = true;
00078     if ( b && ( ! cmd[f].isLetterOrNumber() && cmd[f] != '-' && cmd[f] != '_' ) )
00079       break;
00080   }
00081   return m_dict[cmd.left(f)];
00082 }
00083 
00084 QStringList KateCmd::cmds ()
00085 {
00086   return m_cmds;
00087 }
00088 
00089 static KStaticDeleter<KateCmd> sdCmd;
00090 
00091 KateCmd *KateCmd::self ()
00092 {
00093   if (!s_self)
00094     sdCmd.setObject(s_self, new KateCmd ());
00095 
00096   return s_self;
00097 }
00098 
00099 void KateCmd::appendHistory( const QString &cmd )
00100 {
00101   if ( !m_history.isEmpty() && m_history.last() == cmd )
00102     return;
00103 
00104   if ( m_history.count() == CMD_HIST_LENGTH )
00105     m_history.remove( m_history.first() );
00106 
00107   m_history.append( cmd );
00108 }
00109 
00110 const QString KateCmd::fromHistory( uint index ) const
00111 {
00112   if ( index > m_history.count() - 1 )
00113     return QString();
00114   return m_history[ index ];
00115 }
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 KateCmdShellCompletion::KateCmdShellCompletion()
00126   : KCompletion()
00127 {
00128   m_word_break_char = ' ';
00129   m_quote_char1 = '\"';
00130   m_quote_char2 = '\'';
00131   m_escape_char = '\\';
00132 }
00133 
00134 QString KateCmdShellCompletion::makeCompletion( const QString &text )
00135 {
00136         
00137   
00138   splitText(text, m_text_start, m_text_compl);
00139 
00140   
00141   
00142   return KCompletion::makeCompletion( m_text_compl );
00143 }
00144 
00145 void KateCmdShellCompletion::postProcessMatch( QString *match ) const
00146 {
00147   if ( match->isNull() )
00148     return;
00149 
00150   match->prepend( m_text_start );
00151 }
00152 
00153 void KateCmdShellCompletion::postProcessMatches( QStringList *matches ) const
00154 {
00155   for ( QStringList::Iterator it = matches->begin();
00156         it != matches->end(); it++ )
00157     if ( !(*it).isNull() )
00158       (*it).prepend( m_text_start );
00159 }
00160 
00161 void KateCmdShellCompletion::postProcessMatches( KCompletionMatches *matches ) const
00162 {
00163   for ( KCompletionMatches::Iterator it = matches->begin();
00164         it != matches->end(); it++ )
00165     if ( !(*it).value().isNull() )
00166       (*it).value().prepend( m_text_start );
00167 }
00168 
00169 void KateCmdShellCompletion::splitText(const QString &text, QString &text_start,
00170                                  QString &text_compl) const
00171 {
00172   bool in_quote = false;
00173   bool escaped = false;
00174   QChar p_last_quote_char;
00175   int last_unquoted_space = -1;
00176   int end_space_len = 0;
00177 
00178   for (uint pos = 0; pos < text.length(); pos++) {
00179 
00180     end_space_len = 0;
00181 
00182     if ( escaped ) {
00183       escaped = false;
00184     }
00185     else if ( in_quote && text[pos] == p_last_quote_char ) {
00186       in_quote = false;
00187     }
00188     else if ( !in_quote && text[pos] == m_quote_char1 ) {
00189       p_last_quote_char = m_quote_char1;
00190       in_quote = true;
00191     }
00192     else if ( !in_quote && text[pos] == m_quote_char2 ) {
00193       p_last_quote_char = m_quote_char2;
00194       in_quote = true;
00195     }
00196     else if ( text[pos] == m_escape_char ) {
00197       escaped = true;
00198     }
00199     else if ( !in_quote && text[pos] == m_word_break_char ) {
00200 
00201       end_space_len = 1;
00202 
00203       while ( pos+1 < text.length() && text[pos+1] == m_word_break_char ) {
00204         end_space_len++;
00205         pos++;
00206       }
00207 
00208       if ( pos+1 == text.length() )
00209         break;
00210 
00211       last_unquoted_space = pos;
00212     }
00213   }
00214 
00215   text_start = text.left( last_unquoted_space + 1 );
00216 
00217   
00218   text_compl = text.mid( last_unquoted_space + 1 );
00219 }
00220 
00221 
00222 
00223