• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kio
kshellcompletion.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 David Smith <dsmith@algonet.se>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "kshellcompletion.h"
21
22#include <stdlib.h>
23#include <kdebug.h>
24#include <QtCore/QCharRef>
25#include <QtCore/QMutableStringListIterator>
26#include <QtCore/QRegExp>
27#include <kcompletion.h>
28
29class KShellCompletionPrivate
30{
31public:
32 KShellCompletionPrivate()
33 : m_word_break_char(' ')
34 , m_quote_char1( '\"' )
35 , m_quote_char2( '\'' )
36 , m_escape_char( '\\' )
37 {
38 }
39
40 void splitText(const QString &text, QString &text_start, QString &text_compl) const;
41 bool quoteText(QString *text, bool force, bool skip_last) const;
42 QString unquote(const QString &text) const;
43
44 QString m_text_start; // part of the text that was not completed
45 QString m_text_compl; // part of the text that was completed (unchanged)
46
47 QChar m_word_break_char;
48 QChar m_quote_char1;
49 QChar m_quote_char2;
50 QChar m_escape_char;
51};
52
53KShellCompletion::KShellCompletion()
54 : KUrlCompletion(),
55 d( new KShellCompletionPrivate )
56{
57}
58
59KShellCompletion::~KShellCompletion()
60{
61 delete d;
62}
63
64
65/*
66 * makeCompletion()
67 *
68 * Entry point for file name completion
69 */
70QString KShellCompletion::makeCompletion(const QString &text)
71{
72 // Split text at the last unquoted space
73 //
74 d->splitText(text, d->m_text_start, d->m_text_compl);
75
76 // Remove quotes from the text to be completed
77 //
78 QString tmp = d->unquote(d->m_text_compl);
79 d->m_text_compl = tmp;
80
81 // Do exe-completion if there was no unquoted space
82 //
83 bool is_exe_completion = true;
84
85 for ( int i = 0; i < d->m_text_start.length(); i++ ) {
86 if ( d->m_text_start[i] != d->m_word_break_char ) {
87 is_exe_completion = false;
88 break;
89 }
90 }
91
92 Mode mode = (is_exe_completion ? ExeCompletion : FileCompletion );
93
94 setMode(mode);
95
96 // Make completion on the last part of text
97 //
98 return KUrlCompletion::makeCompletion( d->m_text_compl );
99}
100
101/*
102 * postProcessMatch, postProcessMatches
103 *
104 * Called by KCompletion before emitting match() and matches()
105 *
106 * Add add the part of the text that was not completed
107 * Add quotes when needed
108 */
109void KShellCompletion::postProcessMatch( QString *match ) const
110{
111 KUrlCompletion::postProcessMatch( match );
112
113 if ( match->isNull() )
114 return;
115
116 if ( match->endsWith( QLatin1Char( '/' ) ) )
117 d->quoteText( match, false, true ); // don't quote the trailing '/'
118 else
119 d->quoteText( match, false, false ); // quote the whole text
120
121 match->prepend( d->m_text_start );
122}
123
124void KShellCompletion::postProcessMatches( QStringList *matches ) const
125{
126 KUrlCompletion::postProcessMatches( matches );
127
128 for ( QStringList::Iterator it = matches->begin();
129 it != matches->end(); ++it )
130 {
131 if ( !(*it).isNull() ) {
132 if ( (*it).endsWith( QLatin1Char( '/' ) ) )
133 d->quoteText( &(*it), false, true ); // don't quote trailing '/'
134 else
135 d->quoteText( &(*it), false, false ); // quote the whole text
136
137 (*it).prepend( d->m_text_start );
138 }
139 }
140}
141
142void KShellCompletion::postProcessMatches( KCompletionMatches *matches ) const
143{
144 KUrlCompletion::postProcessMatches( matches );
145
146 for ( KCompletionMatches::Iterator it = matches->begin();
147 it != matches->end(); ++it )
148 {
149 if ( !(*it).value().isNull() ) {
150 if ( (*it).value().endsWith( QLatin1Char( '/' ) ) )
151 d->quoteText( &(*it).value(), false, true ); // don't quote trailing '/'
152 else
153 d->quoteText( &(*it).value(), false, false ); // quote the whole text
154
155 (*it).value().prepend( d->m_text_start );
156 }
157 }
158}
159
160/*
161 * splitText
162 *
163 * Split text at the last unquoted space
164 *
165 * text_start = [out] text at the left, including the space
166 * text_compl = [out] text at the right
167 */
168void KShellCompletionPrivate::splitText(const QString &text, QString &text_start,
169 QString &text_compl) const
170{
171 bool in_quote = false;
172 bool escaped = false;
173 QChar p_last_quote_char;
174 int last_unquoted_space = -1;
175 int end_space_len = 0;
176
177 for (int pos = 0; pos < text.length(); pos++) {
178
179 end_space_len = 0;
180
181 if ( escaped ) {
182 escaped = false;
183 }
184 else if ( in_quote && text[pos] == p_last_quote_char ) {
185 in_quote = false;
186 }
187 else if ( !in_quote && text[pos] == m_quote_char1 ) {
188 p_last_quote_char = m_quote_char1;
189 in_quote = true;
190 }
191 else if ( !in_quote && text[pos] == m_quote_char2 ) {
192 p_last_quote_char = m_quote_char2;
193 in_quote = true;
194 }
195 else if ( text[pos] == m_escape_char ) {
196 escaped = true;
197 }
198 else if ( !in_quote && text[pos] == m_word_break_char ) {
199
200 end_space_len = 1;
201
202 while ( pos+1 < text.length() && text[pos+1] == m_word_break_char ) {
203 end_space_len++;
204 pos++;
205 }
206
207 if ( pos+1 == text.length() )
208 break;
209
210 last_unquoted_space = pos;
211 }
212 }
213
214 text_start = text.left( last_unquoted_space + 1 );
215
216 // the last part without trailing blanks
217 text_compl = text.mid( last_unquoted_space + 1 );
218}
219
220/*
221 * quoteText()
222 *
223 * Add quotations to 'text' if needed or if 'force' = true
224 * Returns true if quotes were added
225 *
226 * skip_last => ignore the last charachter (we add a space or '/' to all filenames)
227 */
228bool KShellCompletionPrivate::quoteText(QString *text, bool force, bool skip_last) const
229{
230 int pos = 0;
231
232 if ( !force ) {
233 pos = text->indexOf( m_word_break_char );
234 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
235 }
236
237 if ( !force && pos == -1 ) {
238 pos = text->indexOf( m_quote_char1 );
239 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
240 }
241
242 if ( !force && pos == -1 ) {
243 pos = text->indexOf( m_quote_char2 );
244 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
245 }
246
247 if ( !force && pos == -1 ) {
248 pos = text->indexOf( m_escape_char );
249 if ( skip_last && (pos == (int)(text->length())-1) ) pos = -1;
250 }
251
252 if ( force || (pos >= 0) ) {
253
254 // Escape \ in the string
255 text->replace( m_escape_char,
256 QString( m_escape_char ) + m_escape_char );
257
258 // Escape " in the string
259 text->replace( m_quote_char1,
260 QString( m_escape_char ) + m_quote_char1 );
261
262 // " at the beginning
263 text->insert( 0, m_quote_char1 );
264
265 // " at the end
266 if ( skip_last )
267 text->insert( text->length()-1, m_quote_char1 );
268 else
269 text->insert( text->length(), m_quote_char1 );
270
271 return true;
272 }
273
274 return false;
275}
276
277/*
278 * unquote
279 *
280 * Remove quotes and return the result in a new string
281 *
282 */
283QString KShellCompletionPrivate::unquote(const QString &text) const
284{
285 bool in_quote = false;
286 bool escaped = false;
287 QChar p_last_quote_char;
288 QString result;
289
290 for (int pos = 0; pos < text.length(); pos++) {
291
292 if ( escaped ) {
293 escaped = false;
294 result.insert( result.length(), text[pos] );
295 }
296 else if ( in_quote && text[pos] == p_last_quote_char ) {
297 in_quote = false;
298 }
299 else if ( !in_quote && text[pos] == m_quote_char1 ) {
300 p_last_quote_char = m_quote_char1;
301 in_quote = true;
302 }
303 else if ( !in_quote && text[pos] == m_quote_char2 ) {
304 p_last_quote_char = m_quote_char2;
305 in_quote = true;
306 }
307 else if ( text[pos] == m_escape_char ) {
308 escaped = true;
309 result.insert( result.length(), text[pos] );
310 }
311 else {
312 result.insert( result.length(), text[pos] );
313 }
314
315 }
316
317 return result;
318}
319
320#include "kshellcompletion.moc"
321
KCompletionMatches
KShellCompletion::KShellCompletion
KShellCompletion()
Constructs a KShellCompletion object.
Definition: kshellcompletion.cpp:53
KShellCompletion::makeCompletion
QString makeCompletion(const QString &text)
Finds completions to the given text.
Definition: kshellcompletion.cpp:70
KShellCompletion::postProcessMatches
void postProcessMatches(QStringList *matches) const
Definition: kshellcompletion.cpp:124
KShellCompletion::~KShellCompletion
~KShellCompletion()
Definition: kshellcompletion.cpp:59
KShellCompletion::postProcessMatch
void postProcessMatch(QString *match) const
Definition: kshellcompletion.cpp:109
KUrlCompletion
This class does completion of URLs including user directories (~user) and environment variables.
Definition: kurlcompletion.h:42
KUrlCompletion::setMode
virtual void setMode(Mode mode)
Changes the completion mode: exe or file completion.
Definition: kurlcompletion.cpp:559
KUrlCompletion::postProcessMatch
void postProcessMatch(QString *match) const
Definition: kurlcompletion.cpp:1268
KUrlCompletion::Mode
Mode
Determines how completion is done.
Definition: kurlcompletion.h:53
KUrlCompletion::ExeCompletion
@ ExeCompletion
Definition: kurlcompletion.h:53
KUrlCompletion::FileCompletion
@ FileCompletion
Definition: kurlcompletion.h:53
KUrlCompletion::makeCompletion
virtual QString makeCompletion(const QString &text)
Finds completions to the given text.
Definition: kurlcompletion.cpp:589
KUrlCompletion::mode
virtual Mode mode() const
Returns the completion mode: exe or file completion (default FileCompletion).
Definition: kurlcompletion.cpp:554
KUrlCompletion::postProcessMatches
void postProcessMatches(QStringList *matches) const
Definition: kurlcompletion.cpp:1317
kcompletion.h
kdebug.h
kshellcompletion.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal