File indexing completed on 2024-05-05 16:41:32

0001 /*
0002     SPDX-FileCopyrightText: 2010-2014 Sven Brauch <svenbrauch@googlemail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "model.h"
0008 
0009 #include <KTextEditor/View>
0010 #include <KTextEditor/Document>
0011 #include <KTextEditor/CodeCompletionModelControllerInterface>
0012 
0013 #include <QDebug>
0014 #include "codecompletiondebug.h"
0015 
0016 #include "context.h"
0017 #include "worker.h"
0018 
0019 namespace Python {
0020 
0021 PythonCodeCompletionModel::PythonCodeCompletionModel(QObject* parent)
0022     : CodeCompletionModel(parent)
0023 {
0024     // This avoids flickering of the completion-list when full code-completion mode is used
0025     setForceWaitForModel(true);
0026 }
0027 
0028 PythonCodeCompletionModel::~PythonCodeCompletionModel() { }
0029 
0030 bool PythonCodeCompletionModel::shouldStartCompletion(KTextEditor::View* view, const QString& inserted,
0031                                                 bool userInsertion, const KTextEditor::Cursor& position)
0032 {
0033     QList<QString> words;
0034     words << "for" << "raise" << "except" << "in";
0035     foreach ( const QString& word, words ) {
0036         if ( view->document()->line(position.line()).mid(0, position.column()).endsWith(word + " ") ) {
0037             return true;
0038         }
0039     }
0040     // shebang / encoding lines
0041     if ( view->document()->line(position.line()).mid(0, position.column()).endsWith("#") && 
0042          position.line() < 2 )
0043     {
0044         return true;
0045     }
0046 
0047     // we're probably dealing with string formatting completion
0048     // is there any other case where this condition is true?
0049     if ( ! userInsertion && inserted.startsWith('{') ) {
0050         return true;
0051     }
0052 
0053     return KDevelop::CodeCompletionModel::shouldStartCompletion(view, inserted, userInsertion, position);
0054 }
0055 
0056 bool PythonCodeCompletionModel::shouldAbortCompletion(KTextEditor::View* view, const KTextEditor::Range& range, const QString& currentCompletion)
0057 {
0058     const QString text = view->document()->text(range);
0059     if ( completionContext() ) {
0060         auto context = static_cast<PythonCodeCompletionContext*>(completionContext().data());
0061         if ( context->completionContextType() == PythonCodeCompletionContext::StringFormattingCompletion ) {
0062             if ( text.endsWith('"') || text.endsWith("'") || text.endsWith(' ') ) {
0063                 return true;
0064             }
0065         }
0066     }
0067     return KTextEditor::CodeCompletionModelControllerInterface::shouldAbortCompletion(view, range, currentCompletion);
0068 }
0069 
0070 QString PythonCodeCompletionModel::filterString(KTextEditor::View *view, const KTextEditor::Range &range, const KTextEditor::Cursor &position)
0071 {
0072     // TODO The completion context may be null, so we need to check it first. This might a bug.
0073     if ( completionContext() ) {
0074         auto context = static_cast<PythonCodeCompletionContext*>(completionContext().data());
0075         if (context->completionContextType() == PythonCodeCompletionContext::StringFormattingCompletion) {
0076            return QString();
0077         }
0078     }
0079     return CodeCompletionModel::filterString(view, range, position);
0080 }
0081 
0082 KTextEditor::Range PythonCodeCompletionModel::completionRange(KTextEditor::View* view, const KTextEditor::Cursor& position)
0083 {
0084     m_currentDocument = view->document()->url();
0085     return KTextEditor::CodeCompletionModelControllerInterface::completionRange(view, position);
0086 }
0087 
0088 KDevelop::CodeCompletionWorker* PythonCodeCompletionModel::createCompletionWorker()
0089 {
0090     return new PythonCodeCompletionWorker(this, m_currentDocument);
0091 }
0092 
0093 }
0094 
0095 #include "moc_model.cpp"