1 // This module defines interface to the QsciAPIs class. 2 // 3 // Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com> 4 // 5 // This file is part of QScintilla. 6 // 7 // This file may be used under the terms of the GNU General Public License 8 // version 3.0 as published by the Free Software Foundation and appearing in 9 // the file LICENSE included in the packaging of this file. Please review the 10 // following information to ensure the GNU General Public License version 3.0 11 // requirements will be met: http://www.gnu.org/copyleft/gpl.html. 12 // 13 // If you do not wish to use this file under the terms of the GPL version 3.0 14 // then you may purchase a commercial license. For more information contact 15 // info@riverbankcomputing.com. 16 // 17 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 18 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 20 21 #ifndef QSCIAPIS_H 22 #define QSCIAPIS_H 23 24 #include <QList> 25 #include <QObject> 26 #include <QPair> 27 #include <QStringList> 28 29 #include <Qsci/qsciabstractapis.h> 30 #include <Qsci/qsciglobal.h> 31 #include <Qsci/qsciscintilla.h> 32 33 34 class QsciAPIsPrepared; 35 class QsciAPIsWorker; 36 class QsciLexer; 37 38 39 //! \brief The QsciAPIs class provies an implementation of the textual API 40 //! information used in call tips and for auto-completion. 41 //! 42 //! Raw API information is read from one or more files. Each API function is 43 //! described by a single line of text comprising the function's name, followed 44 //! by the function's optional comma separated parameters enclosed in 45 //! parenthesis, and finally followed by optional explanatory text. 46 //! 47 //! A function name may be followed by a `?' and a number. The number is used 48 //! by auto-completion to display a registered QPixmap with the function name. 49 //! 50 //! All function names are used by auto-completion, but only those that include 51 //! function parameters are used in call tips. 52 //! 53 //! QScintilla only deals with prepared API information and not the raw 54 //! information described above. This is done so that large APIs can be 55 //! handled while still being responsive to user input. The conversion of raw 56 //! information to prepared information is time consuming (think tens of 57 //! seconds) and implemented in a separate thread. Prepared information can 58 //! be quickly saved to and loaded from files. Such files are portable between 59 //! different architectures. 60 //! 61 //! QScintilla based applications that want to support large APIs would 62 //! normally provide the user with the ability to specify a set of, possibly 63 //! project specific, raw API files and convert them to prepared files that are 64 //! loaded quickly when the application is invoked. 65 class QSCINTILLA_EXPORT QsciAPIs : public QsciAbstractAPIs 66 { 67 Q_OBJECT 68 69 public: 70 //! Constructs a QsciAPIs instance attached to lexer \a lexer. \a lexer 71 //! becomes the instance's parent object although the instance can also be 72 //! subsequently attached to other lexers. 73 QsciAPIs(QsciLexer *lexer); 74 75 //! Destroy the QsciAPIs instance. 76 virtual ~QsciAPIs(); 77 78 //! Add the single raw API entry \a entry to the current set. 79 //! 80 //! \sa clear(), load(), remove() 81 void add(const QString &entry); 82 83 //! Deletes all raw API information. 84 //! 85 //! \sa add(), load(), remove() 86 void clear(); 87 88 //! Load the API information from the file named \a filename, adding it to 89 //! the current set. Returns true if successful, otherwise false. 90 bool load(const QString &filename); 91 92 //! Remove the single raw API entry \a entry from the current set. 93 //! 94 //! \sa add(), clear(), load() 95 void remove(const QString &entry); 96 97 //! Convert the current raw API information to prepared API information. 98 //! This is implemented by a separate thread. 99 //! 100 //! \sa cancelPreparation() 101 void prepare(); 102 103 //! Cancel the conversion of the current raw API information to prepared 104 //! API information. 105 //! 106 //! \sa prepare() 107 void cancelPreparation(); 108 109 //! Return the default name of the prepared API information file. It is 110 //! based on the name of the associated lexer and in the directory defined 111 //! by the QSCIDIR environment variable. If the environment variable isn't 112 //! set then $HOME/.qsci is used. 113 QString defaultPreparedName() const; 114 115 //! Check to see is a prepared API information file named \a filename 116 //! exists. If \a filename is empty then the value returned by 117 //! defaultPreparedName() is used. Returns true if successful, otherwise 118 //! false. 119 //! 120 //! \sa defaultPreparedName() 121 bool isPrepared(const QString &filename = QString()) const; 122 123 //! Load the prepared API information from the file named \a filename. If 124 //! \a filename is empty then a name is constructed based on the name of 125 //! the associated lexer and saved in the directory defined by the QSCIDIR 126 //! environment variable. If the environment variable isn't set then 127 //! $HOME/.qsci is used. Returns true if successful, otherwise false. 128 bool loadPrepared(const QString &filename = QString()); 129 130 //! Save the prepared API information to the file named \a filename. If 131 //! \a filename is empty then a name is constructed based on the name of 132 //! the associated lexer and saved in the directory defined by the QSCIDIR 133 //! environment variable. If the environment variable isn't set then 134 //! $HOME/.qsci is used. Returns true if successful, otherwise false. 135 bool savePrepared(const QString &filename = QString()) const; 136 137 //! \reimp 138 virtual void updateAutoCompletionList(const QStringList &context, 139 QStringList &list); 140 141 //! \reimp 142 virtual void autoCompletionSelected(const QString &sel); 143 144 //! \reimp 145 virtual QStringList callTips(const QStringList &context, int commas, 146 QsciScintilla::CallTipsStyle style, QList<int> &shifts); 147 148 //! \internal Reimplemented to receive termination events from the worker 149 //! thread. 150 virtual bool event(QEvent *e); 151 152 //! Return a list of the installed raw API file names for the associated 153 //! lexer. 154 QStringList installedAPIFiles() const; 155 156 signals: 157 //! This signal is emitted when the conversion of raw API information to 158 //! prepared API information has been cancelled. 159 //! 160 //! \sa apiPreparationFinished(), apiPreparationStarted() 161 void apiPreparationCancelled(); 162 163 //! This signal is emitted when the conversion of raw API information to 164 //! prepared API information starts and can be used to give some visual 165 //! feedback to the user. 166 //! 167 //! \sa apiPreparationCancelled(), apiPreparationFinished() 168 void apiPreparationStarted(); 169 170 //! This signal is emitted when the conversion of raw API information to 171 //! prepared API information has finished. 172 //! 173 //! \sa apiPreparationCancelled(), apiPreparationStarted() 174 void apiPreparationFinished(); 175 176 private: 177 friend class QsciAPIsPrepared; 178 friend class QsciAPIsWorker; 179 180 // This indexes a word in a set of raw APIs. The first part indexes the 181 // entry in the set, the second part indexes the word within the entry. 182 typedef QPair<quint32, quint32> WordIndex; 183 184 // This is a list of word indexes. 185 typedef QList<WordIndex> WordIndexList; 186 187 QsciAPIsWorker *worker; 188 QStringList old_context; 189 QStringList::const_iterator origin; 190 int origin_len; 191 QString unambiguous_context; 192 QStringList apis; 193 QsciAPIsPrepared *prep; 194 195 static bool enoughCommas(const QString &s, int commas); 196 197 QStringList positionOrigin(const QStringList &context, QString &path); 198 bool originStartsWith(const QString &path, const QString &wsep); 199 const WordIndexList *wordIndexOf(const QString &word) const; 200 void lastCompleteWord(const QString &word, QStringList &with_context, 201 bool &unambig); 202 void lastPartialWord(const QString &word, QStringList &with_context, 203 bool &unambig); 204 void addAPIEntries(const WordIndexList &wl, bool complete, 205 QStringList &with_context, bool &unambig); 206 QString prepName(const QString &filename, bool mkpath = false) const; 207 void deleteWorker(); 208 209 QsciAPIs(const QsciAPIs &); 210 QsciAPIs &operator=(const QsciAPIs &); 211 }; 212 213 #endif 214