File indexing completed on 2024-04-28 11:20:40

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-or-later
0003     SPDX-FileCopyrightText: 2010 Oleksiy Protas <elfy.ua@gmail.com>
0004 */
0005 
0006 #include "rcompletionobject.h"
0007 #include "rkeywords.h"
0008 #include "rsession.h"
0009 #include "result.h"
0010 
0011 using namespace Cantor;
0012 
0013 RCompletionObject::RCompletionObject(const QString& command, int index, RSession* session):
0014     CompletionObject(session),
0015     m_expression(nullptr)
0016 {
0017     setLine(command, index);
0018 }
0019 
0020 RCompletionObject::~RCompletionObject()
0021 {
0022     if (m_expression)
0023         m_expression->setFinishingBehavior(Expression::FinishingBehavior::DeleteOnFinish);
0024 }
0025 
0026 void RCompletionObject::fetchCompletions()
0027 {
0028     if (session()->status() != Session::Done)
0029     {
0030         QStringList allCompletions;
0031 
0032         allCompletions << RKeywords::instance()->keywords();
0033 
0034         setCompletions(allCompletions);
0035         emit fetchingDone();
0036     }
0037     else
0038     {
0039         if (m_expression)
0040             return;
0041 
0042         const QString cmd = QLatin1String("%completion ")+command();
0043         m_expression = session()->evaluateExpression(cmd, Expression::FinishingBehavior::DoNotDelete, true);
0044         connect(m_expression, &Expression::statusChanged, this, &RCompletionObject::receiveCompletions);
0045     }
0046 }
0047 
0048 void RCompletionObject::receiveCompletions(Cantor::Expression::Status status)
0049 {
0050     switch(status)
0051     {
0052         case Expression::Status::Done:
0053         {
0054             if (!m_expression->result())
0055                 break;
0056 
0057             const QChar recordSep(30);
0058             const QChar unitSep(31);
0059 
0060             const QString output = m_expression->result()->data().toString();
0061 
0062             const QString& token = output.section(unitSep, 0, 0);
0063             const QStringList& options = output.section(unitSep, 1, 1).split(recordSep, QString::SkipEmptyParts);
0064 
0065             // TODO: investigate the empty token problem
0066             /* Not so fast, evidently KCompletion requires a nonempty token, hence this stub */
0067             if (token.length()==0 && command().length()!=0)
0068             {
0069                 /* Adding previous symbol to token, ugly but effective */
0070                 QString lastchar(command().at(command().length()-1));
0071                 setCommand(lastchar);
0072                 setCompletions(QStringList(options).replaceInStrings(QRegExp(QLatin1String("^")), lastchar));
0073             }
0074             else
0075             {
0076                 setCommand(token);
0077                 setCompletions(options);
0078             }
0079             break;
0080         }
0081         case Expression::Status::Error:
0082             qWarning() << "R code for completion command finishs with error message: " << m_expression->errorMessage();
0083             break;
0084 
0085         case Expression::Status::Interrupted:
0086             break;
0087 
0088         default:
0089             return;
0090     }
0091 
0092     m_expression->deleteLater();
0093     m_expression = nullptr;
0094     emit fetchingDone();
0095 }