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
15faf23e
Commit
15faf23e
authored
Jun 21, 2010
by
Leandro Melo
Browse files
Generic highlighter: Indentation based code folding.
parent
ec249304
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/plugins/texteditor/generichighlighter/highlightdefinition.cpp
View file @
15faf23e
...
...
@@ -42,7 +42,8 @@ using namespace Internal;
HighlightDefinition
::
HighlightDefinition
()
:
m_delimiters
(
QLatin1String
(
".():!+,-<=>%&/;?[]^{|}~
\\
*,
\t
"
)),
m_singleLineCommentAfterWhiteSpaces
(
false
),
m_keywordCaseSensitivity
(
Qt
::
CaseSensitive
)
m_keywordCaseSensitivity
(
Qt
::
CaseSensitive
),
m_indentationBasedFolding
(
false
)
{}
HighlightDefinition
::~
HighlightDefinition
()
...
...
@@ -165,3 +166,9 @@ void HighlightDefinition::setKeywordsSensitive(const QString &sensitivity)
Qt
::
CaseSensitivity
HighlightDefinition
::
keywordsSensitive
()
const
{
return
m_keywordCaseSensitivity
;
}
void
HighlightDefinition
::
setIndentationBasedFolding
(
const
QString
&
indentationBasedFolding
)
{
m_indentationBasedFolding
=
toBool
(
indentationBasedFolding
);
}
bool
HighlightDefinition
::
isIndentationBasedFolding
()
const
{
return
m_indentationBasedFolding
;
}
src/plugins/texteditor/generichighlighter/highlightdefinition.h
View file @
15faf23e
...
...
@@ -80,6 +80,9 @@ public:
void
setMultiLineCommentRegion
(
const
QString
&
region
);
const
QString
&
multiLineCommentRegion
()
const
;
void
setIndentationBasedFolding
(
const
QString
&
indentationBasedFolding
);
bool
isIndentationBasedFolding
()
const
;
private:
Q_DISABLE_COPY
(
HighlightDefinition
)
...
...
@@ -109,6 +112,8 @@ private:
QString
m_multiLineCommentRegion
;
Qt
::
CaseSensitivity
m_keywordCaseSensitivity
;
bool
m_indentationBasedFolding
;
};
}
// namespace Internal
...
...
src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.cpp
View file @
15faf23e
...
...
@@ -103,6 +103,8 @@ namespace {
static
const
QLatin1String
kLanguage
(
"language"
);
static
const
QLatin1String
kExtensions
(
"extensions"
);
static
const
QLatin1String
kIncludeAttrib
(
"includeAttrib"
);
static
const
QLatin1String
kFolding
(
"folding"
);
static
const
QLatin1String
kIndentationSensitive
(
"indentationsensitive"
);
static
const
QLatin1String
kHash
(
"#"
);
static
const
QLatin1String
kDoubleHash
(
"##"
);
}
...
...
@@ -145,6 +147,8 @@ bool HighlightDefinitionHandler::startElement(const QString &,
commentElementStarted
(
atts
);
}
else
if
(
qName
==
kKeywords
)
{
keywordsElementStarted
(
atts
);
}
else
if
(
qName
==
kFolding
)
{
foldingElementStarted
(
atts
);
}
else
if
(
qName
==
kDetectChar
)
{
detectCharStarted
(
atts
);
}
else
if
(
qName
==
kDetect2Chars
)
{
...
...
@@ -290,6 +294,11 @@ void HighlightDefinitionHandler::keywordsElementStarted(const QXmlAttributes &at
//@todo: wordWrapDelimiters?
}
void
HighlightDefinitionHandler
::
foldingElementStarted
(
const
QXmlAttributes
&
atts
)
const
{
m_definition
->
setIndentationBasedFolding
(
atts
.
value
(
kIndentationSensitive
));
}
void
HighlightDefinitionHandler
::
detectCharStarted
(
const
QXmlAttributes
&
atts
)
{
DetectCharRule
*
rule
=
new
DetectCharRule
;
...
...
src/plugins/texteditor/generichighlighter/highlightdefinitionhandler.h
View file @
15faf23e
...
...
@@ -65,6 +65,7 @@ private:
void
itemDataElementStarted
(
const
QXmlAttributes
&
atts
)
const
;
void
commentElementStarted
(
const
QXmlAttributes
&
atts
)
const
;
void
keywordsElementStarted
(
const
QXmlAttributes
&
atts
)
const
;
void
foldingElementStarted
(
const
QXmlAttributes
&
atts
)
const
;
void
ruleElementStarted
(
const
QXmlAttributes
&
atts
,
const
QSharedPointer
<
Rule
>
&
rule
);
// Specific rules.
...
...
src/plugins/texteditor/generichighlighter/highlighter.cpp
View file @
15faf23e
...
...
@@ -35,6 +35,7 @@
#include
"highlighterexception.h"
#include
"progressdata.h"
#include
"reuse.h"
#include
"tabsettings.h"
#include
<QtCore/QLatin1String>
#include
<QtCore/QLatin1Char>
...
...
@@ -54,6 +55,8 @@ const Highlighter::KateFormatMap Highlighter::m_kateFormats;
Highlighter
::
Highlighter
(
QTextDocument
*
parent
)
:
QSyntaxHighlighter
(
parent
),
m_regionDepth
(
0
),
m_indentationBasedFolding
(
false
),
m_tabSettings
(
0
),
m_persistentObservableStatesCounter
(
PersistentsStart
),
m_dynamicContextsCounter
(
0
),
m_isBroken
(
false
)
...
...
@@ -95,6 +98,12 @@ void Highlighter::setDefaultContext(const QSharedPointer<Context> &defaultConte
{
m_defaultContext
=
defaultContext
;
m_persistentObservableStates
.
insert
(
m_defaultContext
->
name
(),
Default
);
m_indentationBasedFolding
=
defaultContext
->
definition
()
->
isIndentationBasedFolding
();
}
void
Highlighter
::
setTabSettings
(
const
TabSettings
&
ts
)
{
m_tabSettings
=
&
ts
;
}
void
Highlighter
::
highlightBlock
(
const
QString
&
text
)
...
...
@@ -118,11 +127,14 @@ void Highlighter::highlightBlock(const QString &text)
false
);
m_contexts
.
clear
();
applyFolding
();
if
(
m_indentationBasedFolding
)
{
applyIndentationBasedFolding
(
text
);
}
else
{
applyRegionBasedFolding
();
// Takes into the account any change that might have affected the region depth since
// the last time the state was set.
setCurrentBlockState
(
computeState
(
extractObservableState
(
currentBlockState
())));
// In the case region depth has changed since the last time the state was set.
setCurrentBlockState
(
computeState
(
extractObservableState
(
currentBlockState
())));
}
}
catch
(
const
HighlighterException
&
)
{
m_isBroken
=
true
;
}
...
...
@@ -220,24 +232,25 @@ void Highlighter::iterateThroughRules(const QString &text,
if
(
rule
->
matchSucceed
(
text
,
length
,
progress
))
{
atLeastOneMatch
=
true
;
// Code folding.
if
(
!
rule
->
beginRegion
().
isEmpty
())
{
blockData
(
currentBlockUserData
())
->
m_foldingRegions
.
push
(
rule
->
beginRegion
());
++
m_regionDepth
;
if
(
progress
->
isOpeningBraceMatchAtFirstNonSpace
())
++
blockData
(
currentBlockUserData
())
->
m_foldingIndentDelta
;
}
if
(
!
rule
->
endRegion
().
isEmpty
())
{
QStack
<
QString
>
*
currentRegions
=
&
blockData
(
currentBlockUserData
())
->
m_foldingRegions
;
if
(
!
currentRegions
->
isEmpty
()
&&
rule
->
endRegion
()
==
currentRegions
->
top
())
{
currentRegions
->
pop
();
--
m_regionDepth
;
if
(
progress
->
isClosingBraceMatchAtNonEnd
())
--
blockData
(
currentBlockUserData
())
->
m_foldingIndentDelta
;
if
(
!
m_indentationBasedFolding
)
{
if
(
!
rule
->
beginRegion
().
isEmpty
())
{
blockData
(
currentBlockUserData
())
->
m_foldingRegions
.
push
(
rule
->
beginRegion
());
++
m_regionDepth
;
if
(
progress
->
isOpeningBraceMatchAtFirstNonSpace
())
++
blockData
(
currentBlockUserData
())
->
m_foldingIndentDelta
;
}
if
(
!
rule
->
endRegion
().
isEmpty
())
{
QStack
<
QString
>
*
currentRegions
=
&
blockData
(
currentBlockUserData
())
->
m_foldingRegions
;
if
(
!
currentRegions
->
isEmpty
()
&&
rule
->
endRegion
()
==
currentRegions
->
top
())
{
currentRegions
->
pop
();
--
m_regionDepth
;
if
(
progress
->
isClosingBraceMatchAtNonEnd
())
--
blockData
(
currentBlockUserData
())
->
m_foldingIndentDelta
;
}
}
progress
->
clearBracesMatches
();
}
progress
->
clearBracesMatches
();
if
(
progress
->
isWillContinueLine
())
{
createWillContinueBlock
();
...
...
@@ -524,7 +537,7 @@ int Highlighter::computeState(const int observableState) const
return
m_regionDepth
<<
12
|
observableState
;
}
void
Highlighter
::
applyFolding
()
const
void
Highlighter
::
apply
RegionBased
Folding
()
const
{
int
folding
=
0
;
BlockData
*
data
=
blockData
(
currentBlockUserData
());
...
...
@@ -543,3 +556,38 @@ void Highlighter::applyFolding() const
data
->
setFoldingEndIncluded
(
true
);
data
->
setFoldingIndent
(
folding
);
}
void
Highlighter
::
applyIndentationBasedFolding
(
const
QString
&
text
)
const
{
BlockData
*
data
=
blockData
(
currentBlockUserData
());
data
->
setFoldingEndIncluded
(
true
);
// If this line is empty, check its neighbours. They all might be part of the same block.
if
(
text
.
trimmed
().
isEmpty
())
{
data
->
setFoldingIndent
(
0
);
const
int
previousIndent
=
neighbouringNonEmptyBlockIndent
(
currentBlock
().
previous
(),
true
);
if
(
previousIndent
>
0
)
{
const
int
nextIndent
=
neighbouringNonEmptyBlockIndent
(
currentBlock
().
next
(),
false
);
if
(
previousIndent
==
nextIndent
)
data
->
setFoldingIndent
(
previousIndent
);
}
}
else
{
data
->
setFoldingIndent
(
m_tabSettings
->
indentationColumn
(
text
));
}
}
int
Highlighter
::
neighbouringNonEmptyBlockIndent
(
QTextBlock
block
,
const
bool
previous
)
const
{
while
(
true
)
{
if
(
!
block
.
isValid
())
return
0
;
if
(
block
.
text
().
trimmed
().
isEmpty
())
{
if
(
previous
)
block
=
block
.
previous
();
else
block
=
block
.
next
();
}
else
{
return
m_tabSettings
->
indentationColumn
(
block
.
text
());
}
}
}
src/plugins/texteditor/generichighlighter/highlighter.h
View file @
15faf23e
...
...
@@ -42,6 +42,9 @@
#include
<QtGui/QTextCharFormat>
namespace
TextEditor
{
struct
TabSettings
;
namespace
Internal
{
class
Rule
;
...
...
@@ -72,8 +75,9 @@ public:
RegionMarker
,
Others
};
void
configureFormat
(
TextFormatId
id
,
const
QTextCharFormat
&
format
);
void
configureFormat
(
TextFormatId
id
,
const
QTextCharFormat
&
format
);
void
setTabSettings
(
const
TabSettings
&
ts
);
void
setDefaultContext
(
const
QSharedPointer
<
Context
>
&
defaultContext
);
protected:
...
...
@@ -118,7 +122,9 @@ private:
const
QSharedPointer
<
HighlightDefinition
>
&
definition
);
void
applyVisualWhitespaceFormat
(
const
QString
&
text
);
void
applyFolding
()
const
;
void
applyRegionBasedFolding
()
const
;
void
applyIndentationBasedFolding
(
const
QString
&
text
)
const
;
int
neighbouringNonEmptyBlockIndent
(
QTextBlock
block
,
const
bool
previous
)
const
;
// Mapping from Kate format strings to format ids.
struct
KateFormatMap
...
...
@@ -166,6 +172,8 @@ private:
static
int
extractObservableState
(
const
int
state
);
int
m_regionDepth
;
bool
m_indentationBasedFolding
;
const
TabSettings
*
m_tabSettings
;
int
m_persistentObservableStatesCounter
;
int
m_dynamicContextsCounter
;
...
...
src/plugins/texteditor/plaintexteditor.cpp
View file @
15faf23e
...
...
@@ -153,6 +153,17 @@ void PlainTextEditor::setFontSettings(const FontSettings &fs)
}
}
void
PlainTextEditor
::
setTabSettings
(
const
TextEditor
::
TabSettings
&
ts
)
{
BaseTextEditor
::
setTabSettings
(
ts
);
if
(
baseTextDocument
()
->
syntaxHighlighter
())
{
Highlighter
*
highlighter
=
static_cast
<
Highlighter
*>
(
baseTextDocument
()
->
syntaxHighlighter
());
highlighter
->
setTabSettings
(
ts
);
}
}
void
PlainTextEditor
::
fileChanged
()
{
configure
(
Core
::
ICore
::
instance
()
->
mimeDatabase
()
->
findByFile
(
file
()
->
fileName
()));
...
...
src/plugins/texteditor/plaintexteditor.h
View file @
15faf23e
...
...
@@ -76,6 +76,7 @@ public:
public
slots
:
virtual
void
unCommentSelection
();
virtual
void
setFontSettings
(
const
FontSettings
&
fs
);
virtual
void
setTabSettings
(
const
TextEditor
::
TabSettings
&
);
private
slots
:
void
fileChanged
();
...
...
tests/auto/generichighlighter/highlighterengine/basetextdocumentlayout.h
View file @
15faf23e
...
...
@@ -30,14 +30,10 @@
#ifndef BASETEXTDOCUMENTLAYOUT_H
#define BASETEXTDOCUMENTLAYOUT_H
/*
Since the text editor plugin directory is not included in the search list of the pro file, this
file replaces the "real" basetextdocumentlayout.h file. The objective is to provide a simple
TextBlockUserData and avoid "external" dependencies or intrusive defines.
*/
#include
<QtGui/QTextBlockUserData>
// Replaces the "real" basetextdocumentlayout.h file.
struct
TextBlockUserData
:
QTextBlockUserData
{
virtual
~
TextBlockUserData
(){}
...
...
tests/auto/generichighlighter/highlighterengine/highlighterengine.pro
View file @
15faf23e
...
...
@@ -18,7 +18,8 @@ SOURCES += tst_highlighterengine.cpp \
HEADERS
+=
\
highlightermock
.
h
\
basetextdocumentlayout
.
h
\
formats
.
h
formats
.
h
\
tabsettings
.
h
INCLUDEPATH
+=
$$
GENERICHIGHLIGHTERDIR
...
...
tests/auto/generichighlighter/highlighterengine/tabsettings.h
0 → 100644
View file @
15faf23e
/**************************************************************************
**
** 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 TABSETTINGS_H
#define TABSETTINGS_H
#include
<QString>
// Replaces the "real" tabsettings.h file.
namespace
TextEditor
{
struct
TabSettings
{
int
indentationColumn
(
const
QString
&
)
const
{
return
0
;
}
};
}
#endif // TABSETTINGS_H
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment