katecmd.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2001, 2003 Christoph Cullmann <cullmann@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 */ 00018 00019 #include "katecmd.h" 00020 00021 #include <kstaticdeleter.h> 00022 #include <kdebug.h> 00023 00024 //BEGIN KateCmd 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 // a command can be named ".*[\w\-]+" with the constrain that it must 00071 // contain at least one letter. 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 //END KateCmd 00117 00118 //BEGIN KateCmdShellCompletion 00119 /* 00120 A lot of the code in the below class is copied from 00121 kdelibs/kio/kio/kshellcompletion.cpp 00122 Copyright (C) 2000 David Smith <dsmith@algonet.se> 00123 Copyright (C) 2004 Anders Lund <anders@alweb.dk> 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 // Split text at the last unquoted space 00137 // 00138 splitText(text, m_text_start, m_text_compl); 00139 00140 // Make completion on the last part of text 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 // the last part without trailing blanks 00218 text_compl = text.mid( last_unquoted_space + 1 ); 00219 } 00220 00221 //END KateCmdShellCompletion 00222 00223