File indexing completed on 2024-12-01 09:37:27

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-or-later
0003     SPDX-FileCopyrightText: 2016 Ivan Lakhtanov <ivan.lakhtanov@gmail.com>
0004 */
0005 
0006 #include "juliacompletionobject.h"
0007 
0008 #include "juliasession.h"
0009 #include "juliakeywords.h"
0010 
0011 #include "result.h"
0012 
0013 #include <QDebug>
0014 
0015 JuliaCompletionObject::JuliaCompletionObject(const QString &command, int index, JuliaSession *session):
0016     Cantor::CompletionObject(session),
0017     m_expression(nullptr)
0018 {
0019     setLine(command, index);
0020 }
0021 
0022 JuliaCompletionObject::~JuliaCompletionObject()
0023 {
0024     if (m_expression)
0025         m_expression->setFinishingBehavior(Cantor::Expression::FinishingBehavior::DeleteOnFinish);
0026 }
0027 
0028 void JuliaCompletionObject::fetchCompletions()
0029 {
0030     if (session()->status() != Cantor::Session::Done)
0031     {
0032         QStringList allCompletions;
0033 
0034         allCompletions << JuliaKeywords::instance()->keywords();
0035         allCompletions << JuliaKeywords::instance()->variables();
0036         allCompletions << JuliaKeywords::instance()->functions();
0037 
0038         setCompletions(allCompletions);
0039         emit fetchingDone();
0040     }
0041     else
0042     {
0043         if (m_expression)
0044             return;
0045 
0046         const QString cmd =
0047             QString::fromLatin1(
0048                 "using REPL; "
0049                 "join("
0050                 "map(REPL.REPLCompletions.completion_text, REPL.REPLCompletions.completions(\"%1\", %2)[1]),"
0051                 "\"__CANTOR_DELIM__\")"
0052             ).arg(command()).arg(command().size());
0053         m_expression = session()->evaluateExpression(cmd, Cantor::Expression::FinishingBehavior::DoNotDelete, true);
0054         connect(m_expression, &Cantor::Expression::statusChanged, this, &JuliaCompletionObject::extractCompletions);
0055     }
0056 }
0057 
0058 void JuliaCompletionObject::extractCompletions(Cantor::Expression::Status status)
0059 {
0060     switch(status)
0061     {
0062         case Cantor::Expression::Done:
0063         {
0064             auto result = m_expression->result()->data().toString();
0065             result.chop(1);
0066             result.remove(0, 1);
0067             QStringList completions = result.split(QLatin1String("__CANTOR_DELIM__"));
0068             if (command().contains(QLatin1Char('.')))
0069                 for(QString& word : completions)
0070                 {
0071                     const int i = command().lastIndexOf(QLatin1Char('.'));
0072                     const QString& prefix = command().remove(i, command().size()-i) + QLatin1Char('.');
0073                     if (!word.startsWith(prefix))
0074                         word.prepend(prefix);
0075                 }
0076 
0077             setCompletions(completions);
0078             break;
0079         }
0080         case Cantor::Expression::Interrupted:
0081         case Cantor::Expression::Error:
0082         {
0083             qDebug() << "fetching expression finished with status" << (status == Cantor::Expression::Error? "Error" : "Interrupted");
0084 
0085             break;
0086         }
0087         default:
0088             return;
0089     }
0090 
0091     m_expression->deleteLater();
0092     m_expression = nullptr;
0093     emit fetchingDone();
0094 }
0095 
0096 bool JuliaCompletionObject::mayIdentifierContain(QChar c) const
0097 {
0098     return c.isLetter() || c.isDigit() || c == QLatin1Char('_') ||
0099         c == QLatin1Char('%') || c == QLatin1Char('$') || c == QLatin1Char('.');
0100 }
0101 
0102 bool JuliaCompletionObject::mayIdentifierBeginWith(QChar c) const
0103 {
0104     return c.isLetter() || c == QLatin1Char('_') || c == QLatin1Char('%') ||
0105         c == QLatin1Char('$');
0106 }