1 /**************************************************************************
2 ** This file is part of LiteIDE
3 **
4 ** Copyright (c) 2011-2019 LiteIDE. All rights reserved.
5 **
6 ** This library is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Lesser General Public
8 ** License as published by the Free Software Foundation; either
9 ** version 2.1 of the License, or (at your option) any later version.
10 **
11 ** This library is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ** Lesser General Public License for more details.
15 **
16 ** In addition, as a special exception,  that plugins developed for LiteIDE,
17 ** are allowed to remain closed sourced and can be distributed under any license .
18 ** These rights are included in the file LGPL_EXCEPTION.txt in this package.
19 **
20 **************************************************************************/
21 // Module: liteeditorapi.h
22 // Creator: visualfc <visualfc@gmail.com>
23 
24 #ifndef LITEEDITORAPI_H
25 #define LITEEDITORAPI_H
26 
27 #include "liteapi/liteapi.h"
28 #include <QTextCursor>
29 #include <QTextBlock>
30 #include <QCompleter>
31 #include <QStandardItem>
32 
33 namespace TextEditor {
34 class SyntaxHighlighter;
35 }
36 
37 namespace LiteApi {
38 
39 class ILiteEditor;
40 class IWordApi
41 {
42 public:
~IWordApi()43     virtual ~IWordApi() {}
44     virtual QString package() const = 0;
45     virtual QStringList apiFiles() const = 0;
46     virtual bool loadApi() = 0;
47     virtual QStringList wordList() const = 0;
48     virtual QStringList expList() const = 0;
49     virtual void appendExp(const QStringList &list) = 0;
50 };
51 
52 struct Snippet
53 {
54     QString Name;
55     QString Info;
56     QString Text;
57 };
58 
59 class ISnippetApi
60 {
61 public:
~ISnippetApi()62     virtual ~ISnippetApi() {}
63     virtual QString package() const = 0;
64     virtual QStringList apiFiles() const = 0;
65     virtual bool loadApi() = 0;
66     virtual QList<Snippet*> snippetList() const = 0;
67 };
68 
69 class IEditorApiManager : public IManager
70 {
71     Q_OBJECT
72 public:
IManager(parent)73     IEditorApiManager(QObject *parent = 0) : IManager(parent) {}
74     virtual void addWordApi(IWordApi *api) = 0;
75     virtual void removeWordApi(IWordApi *api) = 0;
76     virtual IWordApi *findWordApi(const QString &mimeType) = 0;
77     virtual QList<IWordApi*> wordApiList() const = 0;
78     virtual void addSnippetApi(ISnippetApi *api) = 0;
79     virtual void removeSnippetApi(ISnippetApi *api) = 0;
80     virtual ISnippetApi *findSnippetApi(const QString &mimeType) = 0;
81     virtual QList<ISnippetApi*> snippetApiList() const = 0;
82 };
83 
84 enum CompletionContext {
85     CompleterCodeContext = 0,
86     CompleterImportContext,
87 };
88 
89 class ICompleter : public QObject
90 {
91     Q_OBJECT
92 public:
ICompleter(QObject * parent)93     ICompleter(QObject *parent): QObject(parent) {}
94     virtual void setEditor(QPlainTextEdit *editor) = 0;
95     virtual QStandardItem *findRoot(const QString &name) = 0;
96     virtual void clearChildItem(QStandardItem *root) = 0;
97     virtual void appendChildItem(QStandardItem *root,QString name,const QString &kind, const QString &info,const QIcon &icon, bool temp) = 0;
98     virtual bool appendItem(const QString &name,const QIcon &icon, bool temp) = 0;
99     virtual bool appendItemEx(const QString &name,const QString &kind, const QString &info,const QIcon &icon, bool temp) = 0;
100     virtual void appendItems(QStringList items, const QString &kind, const QString &info,const QIcon &icon, bool temp) = 0;
101     virtual void appendSnippetItem(const QString &name, const QString &info, const QString &content) = 0;
102     virtual void clearItemChilds(const QString &name) = 0;
103     virtual void clearTemp() = 0;
104     virtual void clear() = 0;
105     virtual void setSearchSeparator(bool b) = 0;
106     virtual bool searchSeparator() const = 0;
107     virtual void setExternalMode(bool b) = 0;
108     virtual bool externalMode() const = 0;
109     virtual void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity) = 0;
110     virtual void setFuzzy(bool fuzzy) = 0;
111     virtual void setCompletionPrefix(const QString &prefix) = 0;
112     virtual QString completionPrefix() const = 0;
113     virtual void setCompletionContext(CompletionContext ctx) = 0;
114     virtual CompletionContext completionContext() const = 0;
115     virtual void setSeparator(const QString &sep) = 0;
116     virtual QString separator() const = 0;
117     virtual void showPopup() = 0;
118     virtual void hidePopup() = 0;
119     virtual QAbstractItemView *popup() const = 0;
120     virtual QModelIndex currentIndex() const = 0;
121     virtual QString currentCompletion() const = 0;
122     virtual QAbstractItemModel *completionModel() const = 0;
123     virtual bool startCompleter(const QString &completionPrefix) = 0;
124     virtual void updateCompleterModel() = 0;
125     virtual void updateCompleteInfo(QModelIndex index) = 0;
126     virtual void setImportList(const QStringList &importList) = 0;
127     virtual void setPrefixMin(int min) = 0;
128     virtual int prefixMin() const = 0;
129 signals:
130     void prefixChanged(QTextCursor,QString,bool force);
131     void wordCompleted(const QString &func, const QString &kind, const QString &info);
132 };
133 
134 class IEditorMark : public QObject
135 {
136     Q_OBJECT
137 public:
IEditorMark(QObject * parent)138     IEditorMark(QObject *parent) : QObject(parent) {}
139     virtual void addMark(int line, int type) = 0;
140     virtual void addMarkList(const QList<int> &lines, int type) = 0;
141     virtual void removeMark(int line, int type) = 0;
142     virtual void removeMarkList(const QList<int> &lines, int type) = 0;
143     virtual QList<int> markLinesByType(int type) const = 0;
144     virtual QList<QTextBlock> markBlocksByType(int type) const = 0;
145     virtual QList<int> markTypesByLine(int line) const = 0;
146     virtual ILiteEditor *editor() const = 0;
147     virtual QString filePath() const = 0;
148 signals:
149     void markListChanged(int type);
150 };
151 
152 class IEditorMarkNode : public QObject
153 {
154     Q_OBJECT
155 public:
QObject(parent)156     IEditorMarkNode(QObject *parent = 0) : QObject(parent) {}
~IEditorMarkNode()157     virtual ~IEditorMarkNode() {}
158 
159     virtual int blockNumber() const = 0;
160     virtual int type() const = 0;
161     virtual QTextBlock block() const = 0;
162 };
163 
164 class IEditorMarkManager : public IManager
165 {
166     Q_OBJECT
167 public:
IManager(parent)168     IEditorMarkManager(QObject *parent = 0) : IManager(parent) {}
169     virtual void registerMark(int type, const QIcon &icon) = 0;
170     virtual QList<int> markTypeList() const = 0;
171     virtual QIcon iconForType(int type) const = 0;
172     virtual int indexOfType(int type) const = 0;
173     virtual QList<LiteApi::IEditorMark*> editorMarkList() const = 0;
174 signals:
175     void editorMarkCreated(LiteApi::IEditorMark *mark);
176     void editorMarkRemoved(LiteApi::IEditorMark *mark);
177     void editorMarkListChanged(LiteApi::IEditorMark *mark, int type);
178     void editorMarkNodeCreated(LiteApi::IEditorMark *mark, LiteApi::IEditorMarkNode *node);
179     void editorMarkNodeRemoved(LiteApi::IEditorMark *mark, LiteApi::IEditorMarkNode *node);
180     void editorMarkNodeChanged(LiteApi::IEditorMark *mark, LiteApi::IEditorMarkNode *node);
181 };
182 
183 enum EditorNaviagteType{
184     EditorNavigateNormal = 1,
185     EditorNavigateWarning = 2,
186     EditorNavigateError = 4,
187     EditorNavigateReload = 8,
188     EditorNavigateFind = 16,
189     EditorNavigateSelection = 32,
190     EditorNavigateBad = EditorNavigateWarning|EditorNavigateError
191 };
192 
193 enum ExtraSelectionKind {
194     CurrentLineSelection,
195     ParenthesesMatchingSelection,
196     LinkSelection,
197 };
198 
199 struct Link
200 {
LinkLink201     Link(): linkTextStart(-1)
202         , linkTextEnd(-1)
203         , targetLine(-1)
204         , targetColumn(-1)
205         , showTip(false)
206         , showNav(false)
207     {}
208 
clearLink209     void clear()
210     {
211         linkTextStart = -1;
212         linkTextEnd = -1;
213         targetOpenDir.clear();
214         targetOpenDirInfo.clear();
215         targetFileName.clear();
216         targetInfo.clear();
217         sourceInfo.clear();
218         targetLine = 0;
219         targetColumn = 0;
220         showTip = false;
221         showNav = false;
222         text.clear();
223     }
224 
hasValidTargetLink225     bool hasValidTarget() const
226     { return !targetFileName.isEmpty(); }
227 
hasValidLinkTextLink228     bool hasValidLinkText() const
229     { return linkTextStart != linkTextEnd; }
230 
231     bool operator==(const Link &other) const
232     { return linkTextStart == other.linkTextStart && linkTextEnd == other.linkTextEnd; }
233 
234     int linkTextStart;
235     int linkTextEnd;
236     int targetLine;
237     int targetColumn;
238     bool    showTip;
239     bool    showNav;
240     QString targetOpenDir;
241     QString targetOpenDirInfo;
242     QString targetFileName;
243     QString targetInfo;
244     QString sourceInfo;
245     QPoint cursorPos;
246     QString text;
247 };
248 
249 class ITextLexer : public QObject
250 {
251 public:
QObject(parent)252     ITextLexer(QObject *parent = 0) : QObject(parent)
253     {}
~ITextLexer()254     virtual ~ITextLexer()
255     {}
256     virtual bool isLangSupport() const = 0;
257     virtual bool isInComment(const QTextCursor &cursor) const = 0;
258     virtual bool isInString(const QTextCursor &cursor) const = 0;
259     virtual bool isInEmptyString(const QTextCursor &cursor) const = 0;
260     virtual bool isEndOfString(const QTextCursor &cursor) const = 0;
261     virtual bool isInStringOrComment(const QTextCursor &cursor) const = 0;
262     virtual bool isCanAutoCompleter(const QTextCursor &cursor) const = 0;
263     virtual bool isInImport(const QTextCursor &cursor) const = 0;
264     virtual int startOfFunctionCall(const QTextCursor &cursor) const = 0;
265     virtual QString fetchFunctionTip(const QString &func, const QString &kind, const QString &info) = 0;
266     virtual bool fetchFunctionArgs(const QString &str, int &argnr, int &parcount) = 0;
267     virtual QString stringQuoteList() const = 0;
268     virtual bool hasStringBackslash() const = 0;
269 };
270 
271 class ILiteEditor : public ITextEditor
272 {
273     Q_OBJECT
274 public:
ITextEditor(parent)275     ILiteEditor(QObject *parent = 0) : ITextEditor(parent) {}
276     virtual QTextDocument* document() const = 0;
277     virtual void setCompleter(ICompleter *complter) = 0;
278     virtual void setEditorMark(IEditorMark *mark) = 0;
279     virtual void setTextLexer(ITextLexer *lexer) = 0;
280     virtual void setSpellCheckZoneDontComplete(bool b) = 0;
281     virtual void insertNavigateMark(int line, EditorNaviagteType type, const QString &msg, const QString &tag = "", int offset = 0, int selection = 0) = 0;
282     virtual void clearNavigateMarak(int line) = 0;
283     virtual void clearAllNavigateMarks() = 0;
284     virtual void clearAllNavigateMark(EditorNaviagteType types, const QString &tag = "") = 0;
285     virtual void setNavigateHead(EditorNaviagteType type, const QString &msg) = 0;
286     virtual void showLink(const Link &link) = 0;
287     virtual void clearLink() = 0;
288     virtual void setTabOption(int tabSize, bool tabToSpace) = 0;
289     virtual void setEnableAutoIndentAction(bool b) = 0;
290     virtual bool isLineEndUnix() const = 0;
291     virtual void setLineEndUnix(bool b) = 0;
292     virtual void showToolTipInfo(const QPoint & pos, const QString & text) = 0;
293     virtual void loadDiff(const QString &diff) = 0;
294     virtual void loadTextUseDiff(const QString &text) = 0;
295 signals:
296     void updateLink(const QTextCursor &cursor, const QPoint &pos, bool nav);
297 };
298 
getLiteEditor(IEditor * editor)299 inline ILiteEditor *getLiteEditor(IEditor *editor)
300 {
301     if (editor && editor->extension()) {
302         return findExtensionObject<ILiteEditor*>(editor->extension(),"LiteApi.ILiteEditor");
303     }
304     return 0;
305 }
306 
getTextLexer(IEditor * editor)307 inline ITextLexer *getTextLexer(IEditor *editor) {
308     if (editor && editor->extension()) {
309         return findExtensionObject<ITextLexer*>(editor->extension(),"LiteApi.ITextLexer");
310     }
311     return 0;
312 }
313 
getEditorMark(IEditor * editor)314 inline IEditorMark *getEditorMark(IEditor *editor) {
315     if (editor && editor->extension()) {
316         return findExtensionObject<IEditorMark*>(editor->extension(),"LiteApi.IEditorMark");
317     }
318     return 0;
319 }
320 
getEditorMarkManager(IApplication * app)321 inline IEditorMarkManager *getEditorMarkManager(IApplication *app) {
322     if (app && app->extension()) {
323         return findExtensionObject<IEditorMarkManager*>(app->extension(),"LiteApi.IEditorMarkManager");
324     }
325     return 0;
326 }
327 
328 class IHighlighterFactory : public QObject
329 {
330     Q_OBJECT
331 public:
IHighlighterFactory(QObject * parent)332     IHighlighterFactory(QObject *parent) : QObject(parent)
333     {}
334     virtual QStringList mimeTypes() const = 0;
335     virtual TextEditor::SyntaxHighlighter* create(ITextEditor *editor, QTextDocument *doc, const QString &mimeType) = 0;
336 };
337 
338 class IHighlighterManager :public IManager
339 {
340     Q_OBJECT
341 public:
IHighlighterManager(QObject * parent)342     IHighlighterManager(QObject *parent) : IManager(parent)
343     {}
344     virtual void addFactory(IHighlighterFactory *factroy) = 0;
345     virtual void removeFactory(IHighlighterFactory *factory) = 0;
346     virtual QList<IHighlighterFactory*> factoryList() const = 0;
347     virtual QStringList mimeTypeList() const = 0;
348     virtual IHighlighterFactory *findFactory(const QString &mimeType) const = 0;
349 };
350 
getHighlighterManager(LiteApi::IApplication * app)351 inline IHighlighterManager *getHighlighterManager(LiteApi::IApplication *app)
352 {
353     return static_cast<IHighlighterManager*>(app->extension()->findObject("LiteApi.IHighlighterManager"));
354 }
355 
356 inline QString wordUnderCursor(QTextCursor tc, bool *moveLeft = 0, int *selectStart = 0)
357 {
358     QString text = tc.block().text();
359     int pos = tc.positionInBlock();
360     if (pos > 0 && pos < text.length()) {
361         QChar ch = text.at(pos-1);
362         if (ch.isLetterOrNumber() || ch == '_') {
363             tc.movePosition(QTextCursor::Left);
364             if (moveLeft) {
365                 *moveLeft = true;
366             }
367         }
368     }
369     tc.select(QTextCursor::WordUnderCursor);
370     if (selectStart) {
371         *selectStart = tc.selectionStart();
372     }
373     return tc.selectedText();
374 }
375 
376 inline void selectWordUnderCursor(QTextCursor &tc, bool *moveLeft = 0)
377 {
378     QString text = tc.block().text();
379     int pos = tc.positionInBlock();
380     if (pos > 0 && pos < text.length()) {
381         QChar ch = text.at(pos-1);
382         if (ch.isLetterOrNumber() || ch == '_') {
383             tc.movePosition(QTextCursor::Left);
384             if (moveLeft) {
385                 *moveLeft = true;
386             }
387         }
388     }
389     tc.select(QTextCursor::WordUnderCursor);
390 }
391 
392 } //namespace LiteApi
393 
394 
395 #endif //LITEEDITORAPI_H
396 
397