8#include "kshellcompletion.h"
11#include <KCompletionMatches>
14class KShellCompletionPrivate
17 KShellCompletionPrivate()
26 bool quoteText(
QString *text,
bool force,
bool skip_last)
const;
32 QChar m_word_break_char;
40 , d(new KShellCompletionPrivate)
44KShellCompletion::~KShellCompletion() =
default;
55 d->splitText(text, d->m_text_start, d->m_text_compl);
59 QString tmp = d->unquote(d->m_text_compl);
60 d->m_text_compl = tmp;
64 const bool is_exe_completion = !d->m_text_start.contains(d->m_word_break_char);
66 setMode(is_exe_completion ? ExeCompletion : FileCompletion);
81void KShellCompletion::postProcessMatch(
QString *match)
const
83 KUrlCompletion::postProcessMatch(
match);
85 if (
match->isNull()) {
90 d->quoteText(
match,
false,
true);
92 d->quoteText(
match,
false,
false);
95 match->prepend(d->m_text_start);
98void KShellCompletion::postProcessMatches(
QStringList *matches)
const
100 KUrlCompletion::postProcessMatches(
matches);
103 if (!
match.isNull()) {
105 d->quoteText(&
match,
false,
true);
107 d->quoteText(&
match,
false,
false);
110 match.prepend(d->m_text_start);
117 KUrlCompletion::postProcessMatches(
matches);
121 if (!matchString.
isNull()) {
123 d->quoteText(&matchString,
false,
true);
125 d->quoteText(&matchString,
false,
false);
128 matchString.
prepend(d->m_text_start);
141void KShellCompletionPrivate::splitText(
const QString &text,
QString &text_start,
QString &text_compl)
const
143 bool in_quote =
false;
144 bool escaped =
false;
145 QChar p_last_quote_char;
146 int last_unquoted_space = -1;
148 for (
int pos = 0; pos < text.
length(); pos++) {
151 }
else if (in_quote && text[pos] == p_last_quote_char) {
153 }
else if (!in_quote && text[pos] == m_quote_char1) {
154 p_last_quote_char = m_quote_char1;
156 }
else if (!in_quote && text[pos] == m_quote_char2) {
157 p_last_quote_char = m_quote_char2;
159 }
else if (text[pos] == m_escape_char) {
161 }
else if (!in_quote && text[pos] == m_word_break_char) {
162 while (pos + 1 < text.
length() && text[pos + 1] == m_word_break_char) {
166 if (pos + 1 == text.
length()) {
170 last_unquoted_space = pos;
174 text_start = text.
left(last_unquoted_space + 1);
177 text_compl = text.
mid(last_unquoted_space + 1);
188bool KShellCompletionPrivate::quoteText(
QString *text,
bool force,
bool skip_last)
const
193 pos = text->
indexOf(m_word_break_char);
194 if (skip_last && (pos == (
int)(text->
length()) - 1)) {
199 if (!force && pos == -1) {
200 pos = text->
indexOf(m_quote_char1);
201 if (skip_last && (pos == (
int)(text->
length()) - 1)) {
206 if (!force && pos == -1) {
207 pos = text->
indexOf(m_quote_char2);
208 if (skip_last && (pos == (
int)(text->
length()) - 1)) {
213 if (!force && pos == -1) {
214 pos = text->
indexOf(m_escape_char);
215 if (skip_last && (pos == (
int)(text->
length()) - 1)) {
220 if (force || (pos >= 0)) {
222 text->
replace(m_escape_char,
QString(m_escape_char) + m_escape_char);
225 text->
replace(m_quote_char1,
QString(m_escape_char) + m_quote_char1);
228 text->
insert(0, m_quote_char1);
249QString KShellCompletionPrivate::unquote(
const QString &text)
const
251 bool in_quote =
false;
252 bool escaped =
false;
253 QChar p_last_quote_char;
256 for (
const QChar ch : text) {
260 }
else if (in_quote && ch == p_last_quote_char) {
262 }
else if (!in_quote && ch == m_quote_char1) {
263 p_last_quote_char = m_quote_char1;
265 }
else if (!in_quote && ch == m_quote_char2) {
266 p_last_quote_char = m_quote_char2;
268 }
else if (ch == m_escape_char) {
279#include "moc_kshellcompletion.cpp"
void matches(const QStringList &matchlist)
void match(const QString &item)
QString makeCompletion(const QString &text) override
Finds completions to the given text.
KShellCompletion()
Constructs a KShellCompletion object.
This class does completion of URLs including user directories (~user) and environment variables.
QString makeCompletion(const QString &text) override
Finds completions to the given text.
virtual void setMode(Mode mode)
Changes the completion mode: exe or file completion.
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
QString & insert(qsizetype position, QChar ch)
bool isNull() const const
QString left(qsizetype n) const const
qsizetype length() const const
QString mid(qsizetype position, qsizetype n) const const
QString & prepend(QChar ch)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)