File indexing completed on 2023-05-30 09:03:12
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2013 Filipe Saraiva <filipe@kde.org> 0004 */ 0005 0006 #include "pythoncompletionobject.h" 0007 0008 #include <QDebug> 0009 0010 #include "result.h" 0011 0012 #include "pythonsession.h" 0013 #include "pythonkeywords.h" 0014 0015 using namespace Cantor; 0016 0017 PythonCompletionObject::PythonCompletionObject(const QString& command, int index, PythonSession* session) : Cantor::CompletionObject(session), 0018 m_expression(nullptr) 0019 { 0020 setLine(command, index); 0021 } 0022 0023 PythonCompletionObject::~PythonCompletionObject() 0024 { 0025 if (m_expression) 0026 m_expression->setFinishingBehavior(Expression::DeleteOnFinish); 0027 } 0028 0029 void PythonCompletionObject::fetchCompletions() 0030 { 0031 if (session()->status() != Session::Done) 0032 { 0033 QStringList allCompletions; 0034 0035 allCompletions << PythonKeywords::instance()->variables(); 0036 allCompletions << PythonKeywords::instance()->functions(); 0037 allCompletions << PythonKeywords::instance()->keywords(); 0038 0039 setCompletions(allCompletions); 0040 0041 emit fetchingDone(); 0042 } 0043 else 0044 { 0045 if (m_expression) 0046 return; 0047 0048 qDebug() << "run fetchCompletions"; 0049 const QString& expr = QString::fromLatin1( 0050 "from __main__ import __dict__;" 0051 "import rlcompleter;" 0052 "print('|'.join(rlcompleter.Completer(__dict__).global_matches('%1')+rlcompleter.Completer(__dict__).attr_matches('%1')))" 0053 ).arg(command()); 0054 m_expression = session()->evaluateExpression(expr, Cantor::Expression::FinishingBehavior::DoNotDelete, true); 0055 connect(m_expression, &Cantor::Expression::statusChanged, this, &PythonCompletionObject::extractCompletions); 0056 } 0057 } 0058 0059 0060 0061 void PythonCompletionObject::fetchIdentifierType() 0062 { 0063 if (session()->status() != Cantor::Session::Done) 0064 { 0065 if (std::binary_search(PythonKeywords::instance()->functions().begin(), 0066 PythonKeywords::instance()->functions().end(), identifier())) 0067 emit fetchingTypeDone(FunctionType); 0068 else if (std::binary_search(PythonKeywords::instance()->keywords().begin(), 0069 PythonKeywords::instance()->keywords().end(), identifier())) 0070 emit fetchingTypeDone(KeywordType); 0071 else 0072 emit fetchingTypeDone(VariableType); 0073 } 0074 else 0075 { 0076 if (m_expression) 0077 return; 0078 0079 const QString& expr = QString::fromLatin1("callable(%1)").arg(identifier()); 0080 m_expression = session()->evaluateExpression(expr, Cantor::Expression::FinishingBehavior::DoNotDelete, true); 0081 connect(m_expression, &Cantor::Expression::statusChanged, this, &PythonCompletionObject::extractIdentifierType); 0082 } 0083 } 0084 0085 void PythonCompletionObject::extractCompletions(Cantor::Expression::Status status) 0086 { 0087 switch(status) 0088 { 0089 case Cantor::Expression::Error: 0090 qDebug() << "Error with PythonCompletionObject" << (m_expression->result() ? m_expression->result()->toHtml() : QLatin1String("extractCompletions")); 0091 break; 0092 0093 case Cantor::Expression::Interrupted: 0094 qDebug() << "PythonCompletionObject was interrupted"; 0095 break; 0096 0097 case Cantor::Expression::Done: 0098 if (m_expression->result()) 0099 setCompletions(m_expression->result()->data().toString().remove(QLatin1Char('(')).split(QLatin1Char('|'))); 0100 break; 0101 default: 0102 return; 0103 } 0104 m_expression->deleteLater(); 0105 m_expression = nullptr; 0106 emit fetchingDone(); 0107 } 0108 0109 void PythonCompletionObject::extractIdentifierType(Cantor::Expression::Status status) 0110 { 0111 switch(status) 0112 { 0113 case Cantor::Expression::Error: 0114 0115 if (m_expression->errorMessage().contains(QLatin1String("SyntaxError: invalid syntax"))) 0116 emit fetchingTypeDone(KeywordType); 0117 else 0118 { 0119 qDebug() << "Error with PythonCompletionObject" << (m_expression->result() ? m_expression->result()->toHtml() : QLatin1String("extractIdentifierType")); 0120 emit fetchingTypeDone(UnknownType); 0121 } 0122 break; 0123 0124 case Cantor::Expression::Interrupted: 0125 qDebug() << "PythonCompletionObject was interrupted"; 0126 emit fetchingTypeDone(UnknownType); 0127 break; 0128 0129 case Cantor::Expression::Done: 0130 if (m_expression->result()) 0131 { 0132 if (m_expression->result()->data().toString() == QLatin1String("True")) 0133 emit fetchingTypeDone(FunctionType); 0134 else 0135 emit fetchingTypeDone(VariableType); 0136 } 0137 else 0138 emit fetchingTypeDone(UnknownType); 0139 break; 0140 default: 0141 return; 0142 } 0143 m_expression->deleteLater(); 0144 m_expression = nullptr; 0145 } 0146 0147 bool PythonCompletionObject::mayIdentifierContain(QChar c) const 0148 { 0149 return c.isLetter() || c.isDigit() || c == QLatin1Char('_') || c == QLatin1Char('%') || c == QLatin1Char('$') || c == QLatin1Char('.'); 0150 } 0151 0152 bool PythonCompletionObject::mayIdentifierBeginWith(QChar c) const 0153 { 0154 return c.isLetter() || c == QLatin1Char('_') || c == QLatin1Char('%') || c == QLatin1Char('$'); 0155 }