File indexing completed on 2024-05-19 15:41:37

0001 /*
0002     SPDX-FileCopyrightText: 2013 Sven Brauch <svenbrauch@googlemail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "missingincludeitem.h"
0008 
0009 #include <language/codecompletion/codecompletionmodel.h>
0010 
0011 #include <KTextEditor/Document>
0012 #include <KTextEditor/View>
0013 
0014 #include <KLocalizedString>
0015 #include <QDebug>
0016 #include "codecompletiondebug.h"
0017 
0018 namespace Python {
0019 
0020 MissingIncludeItem::MissingIncludeItem(const QString& insertText, const QString& matchText, const QString& removeComponents)
0021     : m_text(insertText)
0022     , m_matchText(matchText)
0023     , m_removeComponents(removeComponents)
0024 {
0025 
0026 }
0027 
0028 QVariant MissingIncludeItem::data(const QModelIndex& index, int role, const KDevelop::CodeCompletionModel* /*model*/) const
0029 {
0030     switch ( role ) {
0031         case Qt::DisplayRole:
0032             switch ( index.column() ) {
0033                 case KDevelop::CodeCompletionModel::Name:
0034                     return m_matchText;
0035                 case KDevelop::CodeCompletionModel::Postfix:
0036                     return "";
0037                 case KDevelop::CodeCompletionModel::Prefix:
0038                     return i18nc("programming; %1 is a code statement to be added in the editor", "Add \"%1\"", m_text);
0039                 default:
0040                     return "";
0041             }
0042     }
0043     return QVariant();
0044 }
0045 
0046 void MissingIncludeItem::execute(KTextEditor::View* view, const KTextEditor::Range& word)
0047 {
0048     qCDebug(KDEV_PYTHON_CODECOMPLETION) << "executed with text" << m_text;
0049     // First, add the import statement to the top of the file
0050     // FIXME: deal with multi-line comments
0051     int insertAt = 0;
0052     for ( int i = 0; i < view->document()->lines(); i++ ) {
0053         const QString& line = view->document()->line(i);
0054         if ( line.trimmed().startsWith('#') || line.trimmed().isEmpty() ) {
0055             continue;
0056         }
0057 
0058         if (    ( line.startsWith("import") && m_text.startsWith("import") )
0059              || ( line.startsWith("from") && m_text.startsWith("from") ) )
0060         {
0061             insertAt = i;
0062             break;
0063         }
0064 
0065         if ( ! line.startsWith("import") && ! line.startsWith("from") ) {
0066             // non-empty, non-comment, non-import line, so we insert it here; the common
0067             // situation this occurs in is when there's no imports yet.
0068             insertAt = i;
0069             break;
0070         }
0071     }
0072 
0073     // Then, eventually replace the text the user was typing
0074     if ( ! m_removeComponents.isEmpty() ) {
0075         const KTextEditor::Cursor end = word.end();
0076         const KTextEditor::Cursor start = end - KTextEditor::Cursor(0, m_removeComponents.length());
0077         view->document()->replaceText(KTextEditor::Range(start, end), m_matchText);
0078     }
0079 
0080     // Do this only later, otherwise ranges change
0081     view->document()->insertLine(qMax(0, insertAt - 1), m_text);
0082 }
0083 
0084 }