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