Commit a976385b authored by Roberto Raggi's avatar Roberto Raggi

Code completion of doxygen tags.

parent 5205d86a
......@@ -49,6 +49,9 @@ TokenUnderCursor::~TokenUnderCursor()
SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor) const
{
SimpleLexer tokenize;
tokenize.setObjCEnabled(true);
tokenize.setSkipComments(false);
QTextBlock block = cursor.block();
int column = cursor.columnNumber();
......
......@@ -15,8 +15,7 @@ HEADERS += cppplugin.h \
cppeditorconstants.h \
cppeditorenums.h \
cppeditor_global.h \
cppclasswizard.h \
cppdoxygen.h
cppclasswizard.h
SOURCES += cppplugin.cpp \
cppeditoractionhandler.cpp \
......@@ -24,7 +23,6 @@ SOURCES += cppplugin.cpp \
cpphighlighter.cpp \
cpphoverhandler.cpp \
cppfilewizard.cpp \
cppclasswizard.cpp \
cppdoxygen.cpp
cppclasswizard.cpp
RESOURCES += cppeditor.qrc
......@@ -32,7 +32,7 @@
***************************************************************************/
#include "cpphighlighter.h"
#include "cppdoxygen.h"
#include <cpptools/cppdoxygen.h>
#include <Token.h>
#include <cplusplus/SimpleLexer.h>
......@@ -341,8 +341,8 @@ void CppHighlighter::highlightDoxygenComment(const QString &text, int position,
while (it->isLetterOrNumber() || it->unicode() == '_')
++it;
int k = classifyDoxygen(start, it - start);
if (k != T_DOXY_IDENTIFIER) {
int k = CppTools::classifyDoxygenTag(start, it - start);
if (k != CppTools::T_DOXY_IDENTIFIER) {
setFormat(initial, start - uc - initial, format);
setFormat(start - uc - 1, it - start + 1, kwFormat);
initial = it - uc;
......
......@@ -32,8 +32,8 @@
***************************************************************************/
#include "cppcodecompletion.h"
#include "cppmodelmanager.h"
#include "cppdoxygen.h"
#include <Control.h>
#include <AST.h>
......@@ -371,46 +371,54 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
const QChar ch3 = pos > 1 ? editor->characterAt(pos - 3) : QChar();
int start = pos;
int k = T_EOF_SYMBOL;
if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) {
if (kind)
*kind = T_DOT;
k = T_DOT;
--start;
} else if (wantFunctionCall && ch == QLatin1Char('(')) {
if (kind)
*kind = T_LPAREN;
k = T_LPAREN;
--start;
} else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
if (kind)
*kind = T_COLON_COLON;
k = T_COLON_COLON;
start -= 2;
} else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) {
if (kind)
*kind = T_ARROW;
k = T_ARROW;
start -= 2;
} else if (ch2 == QLatin1Char('.') && ch == QLatin1Char('*')) {
if (kind)
*kind = T_DOT_STAR;
k = T_DOT_STAR;
start -= 2;
} else if (ch3 == QLatin1Char('-') && ch2 == QLatin1Char('>') && ch == QLatin1Char('*')) {
if (kind)
*kind = T_ARROW_STAR;
k = T_ARROW_STAR;
start -= 3;
} else if (ch == QLatin1Char('@') || ch == QLatin1Char('\\')) {
k = T_DOXY_COMMENT;
--start;
}
if (start != pos) {
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
QTextCursor tc(edit->textCursor());
tc.setPosition(pos);
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
const SimpleToken tk = tokenUnderCursor(tc);
if (tk.isComment() || tk.isLiteral()) {
if (kind)
*kind = T_EOF_SYMBOL;
return pos;
}
if (start == pos)
return start;
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
QTextCursor tc(edit->textCursor());
tc.setPosition(pos);
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
const SimpleToken tk = tokenUnderCursor(tc);
if (k == T_DOXY_COMMENT && tk.isNot(T_DOXY_COMMENT)) {
k = T_EOF_SYMBOL;
start = pos;
}
else if (tk.is(T_COMMENT) || tk.isLiteral()) {
k = T_EOF_SYMBOL;
start = pos;
}
if (kind)
*kind = k;
return start;
}
......@@ -457,15 +465,31 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
ExpressionUnderCursor expressionUnderCursor;
QString expression;
if (m_completionOperator == T_DOXY_COMMENT) {
for (int i = 1; i < T_DOXY_LAST_TAG; ++i) {
TextEditor::CompletionItem item(this);
item.m_text.append(QString::fromLatin1(doxygenTagSpell(i)));
m_completions.append(item);
}
return m_startPosition;
}
if (m_completionOperator) {
QTextCursor tc(edit->document());
tc.setPosition(endOfExpression);
expression = expressionUnderCursor(tc);
if (m_completionOperator == T_LPAREN) {
if (expression.endsWith(QLatin1String("SIGNAL")))
m_completionOperator = T_SIGNAL;
else if (expression.endsWith(QLatin1String("SLOT")))
m_completionOperator = T_SLOT;
else if (editor->position() != endOfOperator) {
// We don't want a function completion when the cursor isn't at the opening brace
expression.clear();
......
......@@ -34,20 +34,138 @@
#include <QString>
#include "cppdoxygen.h"
using namespace CppEditor::Internal;
using namespace CppTools;
/*
TODO:
~
@
$
\
#
f[
f]
f$
*/
~
@
$
\
#
f[
f]
f$
static const char *doxy_token_spell[] = {
"identifier",
"arg",
"attention",
"author",
"callgraph",
"code",
"dot",
"else",
"endcode",
"endcond",
"enddot",
"endhtmlonly",
"endif",
"endlatexonly",
"endlink",
"endmanonly",
"endverbatim",
"endxmlonly",
"hideinitializer",
"htmlonly",
"interface",
"internal",
"invariant",
"latexonly",
"li",
"manonly",
"n",
"nosubgrouping",
"note",
"only",
"post",
"pre",
"remarks",
"return",
"returns",
"sa",
"see",
"showinitializer",
"since",
"test",
"todo",
"verbatim",
"warning",
"xmlonly",
"a",
"addtogroup",
"anchor",
"b",
"c",
"class",
"cond",
"copydoc",
"def",
"dontinclude",
"dotfile",
"e",
"elseif",
"em",
"enum",
"example",
"exception",
"exceptions",
"file",
"htmlinclude",
"if",
"ifnot",
"include",
"link",
"namespace",
"p",
"package",
"ref",
"relates",
"relatesalso",
"retval",
"throw",
"throws",
"verbinclude",
"version",
"xrefitem",
"param",
"image",
"defgroup",
"page",
"paragraph",
"section",
"struct",
"subsection",
"subsubsection",
"union",
"weakgroup",
"addindex",
"brief",
"bug",
"date",
"deprecated",
"fn",
"ingroup",
"line",
"mainpage",
"name",
"overload",
"par",
"short",
"skip",
"skipline",
"typedef",
"until",
"var"
};
*/
static inline int classify1(const QChar *s) {
if (s[0].unicode() == 'a') {
return T_DOXY_A;
......@@ -1490,7 +1608,10 @@ static inline int classify15(const QChar *s) {
return T_DOXY_IDENTIFIER;
}
int CppEditor::Internal::classifyDoxygen(const QChar *s, int n) {
const char *CppTools::doxygenTagSpell(int index)
{ return doxy_token_spell[index]; }
int CppTools::classifyDoxygenTag(const QChar *s, int n) {
switch (n) {
case 1: return classify1(s);
case 2: return classify2(s);
......
......@@ -30,8 +30,10 @@
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
namespace CppEditor {
namespace Internal {
#include "cpptools_global.h"
namespace CppTools {
enum DoxygenReservedWord {
T_DOXY_IDENTIFIER = 0,
......@@ -150,11 +152,12 @@ enum DoxygenReservedWord {
T_DOXY_UNTIL,
T_DOXY_VAR,
};
T_DOXY_LAST_TAG
int classifyDoxygen(const QChar *s, int n);
};
CPPTOOLS_EXPORT int classifyDoxygenTag(const QChar *s, int n);
CPPTOOLS_EXPORT const char *doxygenTagSpell(int index);
} // namespace Internal
} // namespace CppEditor::Internal
......@@ -19,7 +19,8 @@ HEADERS += completionsettingspage.h \
cpptoolsconstants.h \
cpptoolseditorsupport.h \
cpptoolsplugin.h \
searchsymbols.h
searchsymbols.h \
cppdoxygen.h
SOURCES += completionsettingspage.cpp \
cppclassesfilter.cpp \
......@@ -29,6 +30,7 @@ SOURCES += completionsettingspage.cpp \
cppquickopenfilter.cpp \
cpptoolseditorsupport.cpp \
cpptoolsplugin.cpp \
searchsymbols.cpp
searchsymbols.cpp \
cppdoxygen.cpp
FORMS += completionsettingspage.ui
......@@ -34,10 +34,12 @@
#ifndef CPPTOOLS_GLOBAL_H
#define CPPTOOLS_GLOBAL_H
#include <QtGlobal>
#if defined(CPPTOOLS_LIBRARY)
# define CPPTOOLS_EXPORT Q_DECL_EXPORT
#else
# define CPPTOOLS_EXPORT Q_DECL_IMPORT
#endif
#endif // CPPTOOLS_GLOBAL_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment