Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Marco Bubke
flatpak-qt-creator
Commits
36fa1de4
Commit
36fa1de4
authored
Nov 08, 2010
by
Leandro Melo
Browse files
Editors: Refactor auto-complete code out of the editors for better reusability.
Reviewed-by: Thorbjorn Lindeijer
parent
11f0208c
Changes
16
Hide whitespace changes
Inline
Side-by-side
src/plugins/cppeditor/cppautocompleter.cpp
0 → 100644
View file @
36fa1de4
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include
"cppautocompleter.h"
#include
<Token.h>
#include
<cplusplus/SimpleLexer.h>
#include
<cplusplus/MatchingText.h>
#include
<cplusplus/BackwardsScanner.h>
#include
<QtCore/QLatin1Char>
#include
<QtGui/QTextCursor>
using
namespace
CppEditor
;
using
namespace
Internal
;
using
namespace
CPlusPlus
;
CppAutoCompleter
::
CppAutoCompleter
()
{}
CppAutoCompleter
::~
CppAutoCompleter
()
{}
bool
CppAutoCompleter
::
doContextAllowsAutoParentheses
(
const
QTextCursor
&
cursor
,
const
QString
&
textToInsert
)
const
{
QChar
ch
;
if
(
!
textToInsert
.
isEmpty
())
ch
=
textToInsert
.
at
(
0
);
if
(
!
(
MatchingText
::
shouldInsertMatchingText
(
cursor
)
||
ch
==
QLatin1Char
(
'\''
)
||
ch
==
QLatin1Char
(
'"'
)))
return
false
;
else
if
(
isInComment
(
cursor
))
return
false
;
return
true
;
}
bool
CppAutoCompleter
::
doContextAllowsElectricCharacters
(
const
QTextCursor
&
cursor
)
const
{
const
Token
tk
=
SimpleLexer
::
tokenAt
(
cursor
.
block
().
text
(),
cursor
.
positionInBlock
(),
BackwardsScanner
::
previousBlockState
(
cursor
.
block
()));
// XXX Duplicated from CPPEditor::isInComment to avoid tokenizing twice
if
(
tk
.
isComment
())
{
const
unsigned
pos
=
cursor
.
selectionEnd
()
-
cursor
.
block
().
position
();
if
(
pos
==
tk
.
end
())
{
if
(
tk
.
is
(
T_CPP_COMMENT
)
||
tk
.
is
(
T_CPP_DOXY_COMMENT
))
return
false
;
const
int
state
=
cursor
.
block
().
userState
()
&
0xFF
;
if
(
state
>
0
)
return
false
;
}
if
(
pos
<
tk
.
end
())
return
false
;
}
else
if
(
tk
.
is
(
T_STRING_LITERAL
)
||
tk
.
is
(
T_WIDE_STRING_LITERAL
)
||
tk
.
is
(
T_CHAR_LITERAL
)
||
tk
.
is
(
T_WIDE_CHAR_LITERAL
))
{
const
unsigned
pos
=
cursor
.
selectionEnd
()
-
cursor
.
block
().
position
();
if
(
pos
<=
tk
.
end
())
return
false
;
}
return
true
;
}
bool
CppAutoCompleter
::
doIsInComment
(
const
QTextCursor
&
cursor
)
const
{
const
Token
tk
=
SimpleLexer
::
tokenAt
(
cursor
.
block
().
text
(),
cursor
.
positionInBlock
(),
BackwardsScanner
::
previousBlockState
(
cursor
.
block
()));
if
(
tk
.
isComment
())
{
const
unsigned
pos
=
cursor
.
selectionEnd
()
-
cursor
.
block
().
position
();
if
(
pos
==
tk
.
end
())
{
if
(
tk
.
is
(
T_CPP_COMMENT
)
||
tk
.
is
(
T_CPP_DOXY_COMMENT
))
return
true
;
const
int
state
=
cursor
.
block
().
userState
()
&
0xFF
;
if
(
state
>
0
)
return
true
;
}
if
(
pos
<
tk
.
end
())
return
true
;
}
return
false
;
}
QString
CppAutoCompleter
::
doInsertMatchingBrace
(
const
QTextCursor
&
cursor
,
const
QString
&
text
,
QChar
la
,
int
*
skippedChars
)
const
{
MatchingText
m
;
return
m
.
insertMatchingBrace
(
cursor
,
text
,
la
,
skippedChars
);
}
QString
CppAutoCompleter
::
doInsertParagraphSeparator
(
const
QTextCursor
&
cursor
)
const
{
MatchingText
m
;
return
m
.
insertParagraphSeparator
(
cursor
);
}
src/plugins/cppeditor/cppautocompleter.h
0 → 100644
View file @
36fa1de4
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef CPPAUTOCOMPLETER_H
#define CPPAUTOCOMPLETER_H
#include
<texteditor/autocompleter.h>
namespace
CppEditor
{
namespace
Internal
{
class
CppAutoCompleter
:
public
TextEditor
::
AutoCompleter
{
public:
CppAutoCompleter
();
virtual
~
CppAutoCompleter
();
private:
virtual
bool
doContextAllowsAutoParentheses
(
const
QTextCursor
&
cursor
,
const
QString
&
textToInsert
=
QString
())
const
;
virtual
bool
doContextAllowsElectricCharacters
(
const
QTextCursor
&
cursor
)
const
;
virtual
bool
doIsInComment
(
const
QTextCursor
&
cursor
)
const
;
virtual
QString
doInsertMatchingBrace
(
const
QTextCursor
&
cursor
,
const
QString
&
text
,
QChar
la
,
int
*
skippedChars
)
const
;
virtual
QString
doInsertParagraphSeparator
(
const
QTextCursor
&
cursor
)
const
;
};
}
// Internal
}
// CppEditor
#endif // CPPAUTOCOMPLETER_H
src/plugins/cppeditor/cppeditor.cpp
View file @
36fa1de4
...
...
@@ -36,6 +36,7 @@
#include
"cpplocalsymbols.h"
#include
"cppquickfixcollector.h"
#include
"cppqtstyleindenter.h"
#include
"cppautocompleter.h"
#include
<AST.h>
#include
<Control.h>
...
...
@@ -416,6 +417,7 @@ CPPEditor::CPPEditor(QWidget *parent)
setCodeFoldingSupported
(
true
);
setCodeFoldingVisible
(
true
);
setIndenter
(
new
CppQtStyleIndenter
);
setAutoCompleter
(
new
CppAutoCompleter
);
baseTextDocument
()
->
setSyntaxHighlighter
(
new
CppHighlighter
);
m_modelManager
=
CppTools
::
CppModelManagerInterface
::
instance
();
...
...
@@ -1407,90 +1409,6 @@ QModelIndex CPPEditor::outlineModelIndex()
return
m_outlineModelIndex
;
}
QString
CPPEditor
::
insertMatchingBrace
(
const
QTextCursor
&
tc
,
const
QString
&
text
,
QChar
la
,
int
*
skippedChars
)
const
{
MatchingText
m
;
return
m
.
insertMatchingBrace
(
tc
,
text
,
la
,
skippedChars
);
}
QString
CPPEditor
::
insertParagraphSeparator
(
const
QTextCursor
&
tc
)
const
{
MatchingText
m
;
return
m
.
insertParagraphSeparator
(
tc
);
}
bool
CPPEditor
::
contextAllowsAutoParentheses
(
const
QTextCursor
&
cursor
,
const
QString
&
textToInsert
)
const
{
QChar
ch
;
if
(
!
textToInsert
.
isEmpty
())
ch
=
textToInsert
.
at
(
0
);
if
(
!
(
MatchingText
::
shouldInsertMatchingText
(
cursor
)
||
ch
==
QLatin1Char
(
'\''
)
||
ch
==
QLatin1Char
(
'"'
)))
return
false
;
else
if
(
isInComment
(
cursor
))
return
false
;
return
true
;
}
bool
CPPEditor
::
contextAllowsElectricCharacters
(
const
QTextCursor
&
cursor
)
const
{
const
Token
tk
=
SimpleLexer
::
tokenAt
(
cursor
.
block
().
text
(),
cursor
.
positionInBlock
(),
BackwardsScanner
::
previousBlockState
(
cursor
.
block
()));
// XXX Duplicated from CPPEditor::isInComment to avoid tokenizing twice
if
(
tk
.
isComment
())
{
const
unsigned
pos
=
cursor
.
selectionEnd
()
-
cursor
.
block
().
position
();
if
(
pos
==
tk
.
end
())
{
if
(
tk
.
is
(
T_CPP_COMMENT
)
||
tk
.
is
(
T_CPP_DOXY_COMMENT
))
return
false
;
const
int
state
=
cursor
.
block
().
userState
()
&
0xFF
;
if
(
state
>
0
)
return
false
;
}
if
(
pos
<
tk
.
end
())
return
false
;
}
else
if
(
tk
.
is
(
T_STRING_LITERAL
)
||
tk
.
is
(
T_WIDE_STRING_LITERAL
)
||
tk
.
is
(
T_CHAR_LITERAL
)
||
tk
.
is
(
T_WIDE_CHAR_LITERAL
))
{
const
unsigned
pos
=
cursor
.
selectionEnd
()
-
cursor
.
block
().
position
();
if
(
pos
<=
tk
.
end
())
return
false
;
}
return
true
;
}
bool
CPPEditor
::
isInComment
(
const
QTextCursor
&
cursor
)
const
{
const
Token
tk
=
SimpleLexer
::
tokenAt
(
cursor
.
block
().
text
(),
cursor
.
positionInBlock
(),
BackwardsScanner
::
previousBlockState
(
cursor
.
block
()));
if
(
tk
.
isComment
())
{
const
unsigned
pos
=
cursor
.
selectionEnd
()
-
cursor
.
block
().
position
();
if
(
pos
==
tk
.
end
())
{
if
(
tk
.
is
(
T_CPP_COMMENT
)
||
tk
.
is
(
T_CPP_DOXY_COMMENT
))
return
true
;
const
int
state
=
cursor
.
block
().
userState
()
&
0xFF
;
if
(
state
>
0
)
return
true
;
}
if
(
pos
<
tk
.
end
())
return
true
;
}
return
false
;
}
bool
CPPEditor
::
event
(
QEvent
*
e
)
{
switch
(
e
->
type
())
{
...
...
src/plugins/cppeditor/cppeditor.h
View file @
36fa1de4
...
...
@@ -207,17 +207,6 @@ protected:
TextEditor
::
BaseTextEditorEditable
*
createEditableInterface
();
virtual
QString
insertMatchingBrace
(
const
QTextCursor
&
tc
,
const
QString
&
text
,
QChar
la
,
int
*
skippedChars
)
const
;
virtual
QString
insertParagraphSeparator
(
const
QTextCursor
&
tc
)
const
;
virtual
bool
contextAllowsAutoParentheses
(
const
QTextCursor
&
cursor
,
const
QString
&
textToInsert
=
QString
())
const
;
virtual
bool
contextAllowsElectricCharacters
(
const
QTextCursor
&
cursor
)
const
;
virtual
bool
isInComment
(
const
QTextCursor
&
cursor
)
const
;
const
CPlusPlus
::
Macro
*
findCanonicalMacro
(
const
QTextCursor
&
cursor
,
CPlusPlus
::
Document
::
Ptr
doc
)
const
;
...
...
src/plugins/cppeditor/cppeditor.pro
View file @
36fa1de4
...
...
@@ -23,7 +23,8 @@ HEADERS += cppplugin.h \
cpptypehierarchy
.
h
\
cppelementevaluator
.
h
\
cppquickfixcollector
.
h
\
cppqtstyleindenter
.
h
cppqtstyleindenter
.
h
\
cppautocompleter
.
h
SOURCES
+=
cppplugin
.
cpp
\
cppeditor
.
cpp
\
cpphighlighter
.
cpp
\
...
...
@@ -40,6 +41,7 @@ SOURCES += cppplugin.cpp \
cpptypehierarchy
.
cpp
\
cppelementevaluator
.
cpp
\
cppquickfixcollector
.
cpp
\
cppqtstyleindenter
.
cpp
cppqtstyleindenter
.
cpp
\
cppautocompleter
.
cpp
RESOURCES
+=
cppeditor
.
qrc
OTHER_FILES
+=
CppEditor
.
mimetypes
.
xml
src/plugins/qmljseditor/qmljsautocompleter.cpp
0 → 100644
View file @
36fa1de4
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include
"qmljsautocompleter.h"
#include
<qmljs/qmljsscanner.h>
#include
<QtCore/QChar>
#include
<QtCore/QLatin1Char>
#include
<QtGui/QTextDocument>
#include
<QtGui/QTextCursor>
#include
<QtGui/QTextBlock>
using
namespace
QmlJSEditor
;
using
namespace
Internal
;
using
namespace
QmlJS
;
static
int
blockStartState
(
const
QTextBlock
&
block
)
{
int
state
=
block
.
userState
();
if
(
state
==
-
1
)
return
0
;
else
return
state
&
0xff
;
}
static
Token
tokenUnderCursor
(
const
QTextCursor
&
cursor
)
{
const
QString
blockText
=
cursor
.
block
().
text
();
const
int
blockState
=
blockStartState
(
cursor
.
block
());
Scanner
tokenize
;
const
QList
<
Token
>
tokens
=
tokenize
(
blockText
,
blockState
);
const
int
pos
=
cursor
.
positionInBlock
();
int
tokenIndex
=
0
;
for
(;
tokenIndex
<
tokens
.
size
();
++
tokenIndex
)
{
const
Token
&
token
=
tokens
.
at
(
tokenIndex
);
if
(
token
.
is
(
Token
::
Comment
)
||
token
.
is
(
Token
::
String
))
{
if
(
pos
>
token
.
begin
()
&&
pos
<=
token
.
end
())
break
;
}
else
{
if
(
pos
>=
token
.
begin
()
&&
pos
<
token
.
end
())
break
;
}
}
if
(
tokenIndex
!=
tokens
.
size
())
return
tokens
.
at
(
tokenIndex
);
return
Token
();
}
static
bool
shouldInsertMatchingText
(
QChar
lookAhead
)
{
switch
(
lookAhead
.
unicode
())
{
case
'{'
:
case
'}'
:
case
']'
:
case
')'
:
case
';'
:
case
','
:
case
'"'
:
case
'\''
:
return
true
;
default:
if
(
lookAhead
.
isSpace
())
return
true
;
return
false
;
}
// switch
}
static
bool
shouldInsertMatchingText
(
const
QTextCursor
&
tc
)
{
QTextDocument
*
doc
=
tc
.
document
();
return
shouldInsertMatchingText
(
doc
->
characterAt
(
tc
.
selectionEnd
()));
}
static
bool
shouldInsertNewline
(
const
QTextCursor
&
tc
)
{
QTextDocument
*
doc
=
tc
.
document
();
int
pos
=
tc
.
selectionEnd
();
// count the number of empty lines.
int
newlines
=
0
;
for
(
int
e
=
doc
->
characterCount
();
pos
!=
e
;
++
pos
)
{
const
QChar
ch
=
doc
->
characterAt
(
pos
);
if
(
!
ch
.
isSpace
())
break
;
else
if
(
ch
==
QChar
::
ParagraphSeparator
)
++
newlines
;
}
if
(
newlines
<=
1
&&
doc
->
characterAt
(
pos
)
!=
QLatin1Char
(
'}'
))
return
true
;
return
false
;
}
static
bool
isCompleteStringLiteral
(
const
QStringRef
&
text
)
{
if
(
text
.
length
()
<
2
)
return
false
;
const
QChar
quote
=
text
.
at
(
0
);
if
(
text
.
at
(
text
.
length
()
-
1
)
==
quote
)
return
text
.
at
(
text
.
length
()
-
2
)
!=
QLatin1Char
(
'\\'
);
// ### not exactly.
return
false
;
}
AutoCompleter
::
AutoCompleter
()
{}
AutoCompleter
::~
AutoCompleter
()
{}
bool
AutoCompleter
::
doContextAllowsAutoParentheses
(
const
QTextCursor
&
cursor
,
const
QString
&
textToInsert
)
const
{
QChar
ch
;
if
(
!
textToInsert
.
isEmpty
())
ch
=
textToInsert
.
at
(
0
);
switch
(
ch
.
unicode
())
{
case
'\''
:
case
'"'
:
case
'('
:
case
'['
:
case
'{'
:
case
')'
:
case
']'
:
case
'}'
:
case
';'
:
break
;
default:
if
(
ch
.
isNull
())
break
;
return
false
;
}
// end of switch
const
Token
token
=
tokenUnderCursor
(
cursor
);
switch
(
token
.
kind
)
{
case
Token
::
Comment
:
return
false
;
case
Token
::
String
:
{
const
QString
blockText
=
cursor
.
block
().
text
();
const
QStringRef
tokenText
=
blockText
.
midRef
(
token
.
offset
,
token
.
length
);
const
QChar
quote
=
tokenText
.
at
(
0
);
if
(
ch
!=
quote
||
isCompleteStringLiteral
(
tokenText
))
break
;
return
false
;
}
default:
break
;
}
// end of switch
return
true
;
}
bool
AutoCompleter
::
doContextAllowsElectricCharacters
(
const
QTextCursor
&
cursor
)
const
{
Token
token
=
tokenUnderCursor
(
cursor
);
switch
(
token
.
kind
)
{
case
Token
::
Comment
:
case
Token
::
String
:
return
false
;
default:
return
true
;
}
}
bool
AutoCompleter
::
doIsInComment
(
const
QTextCursor
&
cursor
)
const
{
return
tokenUnderCursor
(
cursor
).
is
(
Token
::
Comment
);
}
QString
AutoCompleter
::
doInsertMatchingBrace
(
const
QTextCursor
&
cursor
,
const
QString
&
text
,
QChar
,
int
*
skippedChars
)
const
{
if
(
text
.
length
()
!=
1
)
return
QString
();
if
(
!
shouldInsertMatchingText
(
cursor
))
return
QString
();
const
QChar
la
=
cursor
.
document
()
->
characterAt
(
cursor
.
position
());
const
QChar
ch
=
text
.
at
(
0
);
switch
(
ch
.
unicode
())
{
case
'\''
:
if
(
la
!=
ch
)
return
QString
(
ch
);
++*
skippedChars
;
break
;
case
'"'
:
if
(
la
!=
ch
)
return
QString
(
ch
);
++*
skippedChars
;
break
;
case
'('
:
return
QString
(
QLatin1Char
(
')'
));
case
'['
:
return
QString
(
QLatin1Char
(
']'
));
case
'{'
:
return
QString
();
// nothing to do.
case
')'
:
case
']'
:
case
'}'
:
case
';'
:
if
(
la
==
ch
)
++*
skippedChars
;
break
;