mirror of
https://github.com/notepad-plus-plus/notepad-plus-plus.git
synced 2025-08-14 06:18:27 +02:00
Release 5.5.2 ( https://www.scintilla.org/scintilla552.zip ) Released 21 August 2024. Add SCI_SETCOPYSEPARATOR for separator between parts of a multiple selection when copied to the clipboard. Feature #1530. Add SCI_GETUNDOSEQUENCE to determine whether an undo sequence is active and its nesting depth. Add SCI_STYLESETSTRETCH to support condensed and expanded text styles. Add SCI_LINEINDENT and SCI_LINEDEDENT. Feature #1524. Fix bug on Cocoa where double-click stopped working when system had been running for a long time. On Cocoa implement more values of font weight and stretch. Release 5.4.0 ( https://www.scintilla.org/lexilla540.zip ) Released 21 August 2024. Inside Lexilla, LexerModule instances are now const. This will require changes to applications that modify Lexilla.cxx, which may be done to add custom lexers. Lexer added for TOML "toml". Bash: Handle backslash in heredoc delimiter. Issue #257. Progress: Fix lexing of nested comments. Pull request #258. Force lower-casing of case-insensitive keyword lists so keywords match in some lexers. Issue #259. Close #15564
607 lines
19 KiB
C++
607 lines
19 KiB
C++
// Scintilla source code edit control
|
|
/** @file LexAbaqus.cxx
|
|
** Lexer for ABAQUS. Based on the lexer for APDL by Hadar Raz.
|
|
** By Sergio Lucato.
|
|
** Sort of completely rewritten by Gertjan Kloosterman
|
|
**/
|
|
// The License.txt file describes the conditions under which this software may be distributed.
|
|
|
|
// Code folding copyied and modified from LexBasic.cxx
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
|
|
#include <string>
|
|
#include <string_view>
|
|
|
|
#include "ILexer.h"
|
|
#include "Scintilla.h"
|
|
#include "SciLexer.h"
|
|
|
|
#include "WordList.h"
|
|
#include "LexAccessor.h"
|
|
#include "Accessor.h"
|
|
#include "StyleContext.h"
|
|
#include "CharacterSet.h"
|
|
#include "LexerModule.h"
|
|
|
|
using namespace Lexilla;
|
|
|
|
static inline bool IsAKeywordChar(const int ch) {
|
|
return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == ' ')));
|
|
}
|
|
|
|
static inline bool IsASetChar(const int ch) {
|
|
return (ch < 0x80 && (isalnum(ch) || (ch == '_') || (ch == '.') || (ch == '-')));
|
|
}
|
|
|
|
static void ColouriseABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList*[] /* *keywordlists[] */,
|
|
Accessor &styler) {
|
|
enum localState { KW_LINE_KW, KW_LINE_COMMA, KW_LINE_PAR, KW_LINE_EQ, KW_LINE_VAL, \
|
|
DAT_LINE_VAL, DAT_LINE_COMMA,\
|
|
COMMENT_LINE,\
|
|
ST_ERROR, LINE_END } state ;
|
|
|
|
// Do not leak onto next line
|
|
state = LINE_END ;
|
|
initStyle = SCE_ABAQUS_DEFAULT;
|
|
StyleContext sc(startPos, length, initStyle, styler);
|
|
|
|
// Things are actually quite simple
|
|
// we have commentlines
|
|
// keywordlines and datalines
|
|
// On a data line there will only be colouring of numbers
|
|
// a keyword line is constructed as
|
|
// *word,[ paramname[=paramvalue]]*
|
|
// if the line ends with a , the keyword line continues onto the new line
|
|
|
|
for (; sc.More(); sc.Forward()) {
|
|
switch ( state ) {
|
|
case KW_LINE_KW :
|
|
if ( sc.atLineEnd ) {
|
|
// finished the line in keyword state, switch to LINE_END
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = LINE_END ;
|
|
} else if ( IsAKeywordChar(sc.ch) ) {
|
|
// nothing changes
|
|
state = KW_LINE_KW ;
|
|
} else if ( sc.ch == ',' ) {
|
|
// Well well we say a comma, arguments *MUST* follow
|
|
sc.SetState(SCE_ABAQUS_OPERATOR) ;
|
|
state = KW_LINE_COMMA ;
|
|
} else {
|
|
// Flag an error
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
// Done with processing
|
|
break ;
|
|
case KW_LINE_COMMA :
|
|
// acomma on a keywordline was seen
|
|
if ( IsAKeywordChar(sc.ch)) {
|
|
sc.SetState(SCE_ABAQUS_ARGUMENT) ;
|
|
state = KW_LINE_PAR ;
|
|
} else if ( sc.atLineEnd || (sc.ch == ',') ) {
|
|
// we remain in keyword mode
|
|
state = KW_LINE_COMMA ;
|
|
} else if ( sc.ch == ' ' ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = KW_LINE_COMMA ;
|
|
} else {
|
|
// Anything else constitutes an error
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
break ;
|
|
case KW_LINE_PAR :
|
|
if ( sc.atLineEnd ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = LINE_END ;
|
|
} else if ( IsAKeywordChar(sc.ch) || (sc.ch == '-') ) {
|
|
// remain in this state
|
|
state = KW_LINE_PAR ;
|
|
} else if ( sc.ch == ',' ) {
|
|
sc.SetState(SCE_ABAQUS_OPERATOR) ;
|
|
state = KW_LINE_COMMA ;
|
|
} else if ( sc.ch == '=' ) {
|
|
sc.SetState(SCE_ABAQUS_OPERATOR) ;
|
|
state = KW_LINE_EQ ;
|
|
} else {
|
|
// Anything else constitutes an error
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
break ;
|
|
case KW_LINE_EQ :
|
|
if ( sc.ch == ' ' ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
// remain in this state
|
|
state = KW_LINE_EQ ;
|
|
} else if ( IsADigit(sc.ch) || (sc.ch == '-') || (sc.ch == '.' && IsADigit(sc.chNext)) ) {
|
|
sc.SetState(SCE_ABAQUS_NUMBER) ;
|
|
state = KW_LINE_VAL ;
|
|
} else if ( IsAKeywordChar(sc.ch) ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = KW_LINE_VAL ;
|
|
} else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
|
|
sc.SetState(SCE_ABAQUS_STRING) ;
|
|
state = KW_LINE_VAL ;
|
|
} else {
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
break ;
|
|
case KW_LINE_VAL :
|
|
if ( sc.atLineEnd ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = LINE_END ;
|
|
} else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
|
|
// nothing changes
|
|
state = KW_LINE_VAL ;
|
|
} else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
|
|
((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
|
|
(sc.state == SCE_ABAQUS_NUMBER)) {
|
|
// remain in number mode
|
|
state = KW_LINE_VAL ;
|
|
} else if (sc.state == SCE_ABAQUS_STRING) {
|
|
// accept everything until a closing quote
|
|
if ( sc.ch == '\'' || sc.ch == '\"' ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = KW_LINE_VAL ;
|
|
}
|
|
} else if ( sc.ch == ',' ) {
|
|
sc.SetState(SCE_ABAQUS_OPERATOR) ;
|
|
state = KW_LINE_COMMA ;
|
|
} else {
|
|
// anything else is an error
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
break ;
|
|
case DAT_LINE_VAL :
|
|
if ( sc.atLineEnd ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = LINE_END ;
|
|
} else if ( IsASetChar(sc.ch) && (sc.state == SCE_ABAQUS_DEFAULT) ) {
|
|
// nothing changes
|
|
state = DAT_LINE_VAL ;
|
|
} else if (( (IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
|
|
((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) &&
|
|
(sc.state == SCE_ABAQUS_NUMBER)) {
|
|
// remain in number mode
|
|
state = DAT_LINE_VAL ;
|
|
} else if (sc.state == SCE_ABAQUS_STRING) {
|
|
// accept everything until a closing quote
|
|
if ( sc.ch == '\'' || sc.ch == '\"' ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = DAT_LINE_VAL ;
|
|
}
|
|
} else if ( sc.ch == ',' ) {
|
|
sc.SetState(SCE_ABAQUS_OPERATOR) ;
|
|
state = DAT_LINE_COMMA ;
|
|
} else {
|
|
// anything else is an error
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
break ;
|
|
case DAT_LINE_COMMA :
|
|
// a comma on a data line was seen
|
|
if ( sc.atLineEnd ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = LINE_END ;
|
|
} else if ( sc.ch == ' ' ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = DAT_LINE_COMMA ;
|
|
} else if (sc.ch == ',') {
|
|
sc.SetState(SCE_ABAQUS_OPERATOR) ;
|
|
state = DAT_LINE_COMMA ;
|
|
} else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
|
|
sc.SetState(SCE_ABAQUS_NUMBER) ;
|
|
state = DAT_LINE_VAL ;
|
|
} else if ( IsAKeywordChar(sc.ch) ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = DAT_LINE_VAL ;
|
|
} else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
|
|
sc.SetState(SCE_ABAQUS_STRING) ;
|
|
state = DAT_LINE_VAL ;
|
|
} else {
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
break ;
|
|
case COMMENT_LINE :
|
|
if ( sc.atLineEnd ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = LINE_END ;
|
|
}
|
|
break ;
|
|
case ST_ERROR :
|
|
if ( sc.atLineEnd ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = LINE_END ;
|
|
}
|
|
break ;
|
|
case LINE_END :
|
|
if ( sc.atLineEnd || sc.ch == ' ' ) {
|
|
// nothing changes
|
|
state = LINE_END ;
|
|
} else if ( sc.ch == '*' ) {
|
|
if ( sc.chNext == '*' ) {
|
|
state = COMMENT_LINE ;
|
|
sc.SetState(SCE_ABAQUS_COMMENT) ;
|
|
} else {
|
|
state = KW_LINE_KW ;
|
|
sc.SetState(SCE_ABAQUS_STARCOMMAND) ;
|
|
}
|
|
} else {
|
|
// it must be a data line, things are as if we are in DAT_LINE_COMMA
|
|
if ( sc.ch == ',' ) {
|
|
sc.SetState(SCE_ABAQUS_OPERATOR) ;
|
|
state = DAT_LINE_COMMA ;
|
|
} else if ( IsADigit(sc.ch) || (sc.ch == '-')|| (sc.ch == '.' && IsADigit(sc.chNext)) ) {
|
|
sc.SetState(SCE_ABAQUS_NUMBER) ;
|
|
state = DAT_LINE_VAL ;
|
|
} else if ( IsAKeywordChar(sc.ch) ) {
|
|
sc.SetState(SCE_ABAQUS_DEFAULT) ;
|
|
state = DAT_LINE_VAL ;
|
|
} else if ( (sc.ch == '\'') || (sc.ch == '\"') ) {
|
|
sc.SetState(SCE_ABAQUS_STRING) ;
|
|
state = DAT_LINE_VAL ;
|
|
} else {
|
|
sc.SetState(SCE_ABAQUS_PROCESSOR) ;
|
|
state = ST_ERROR ;
|
|
}
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
sc.Complete();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// This copyied and modified from LexBasic.cxx
|
|
//------------------------------------------------------------------------------
|
|
|
|
/* Bits:
|
|
* 1 - whitespace
|
|
* 2 - operator
|
|
* 4 - identifier
|
|
* 8 - decimal digit
|
|
* 16 - hex digit
|
|
* 32 - bin digit
|
|
*/
|
|
static int character_classification[128] =
|
|
{
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
|
|
60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
|
|
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
|
|
2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
|
|
};
|
|
|
|
static bool IsSpace(int c) {
|
|
return c < 128 && (character_classification[c] & 1);
|
|
}
|
|
|
|
static bool IsIdentifier(int c) {
|
|
return c < 128 && (character_classification[c] & 4);
|
|
}
|
|
|
|
static int LowerCase(int c)
|
|
{
|
|
if (c >= 'A' && c <= 'Z')
|
|
return 'a' + c - 'A';
|
|
return c;
|
|
}
|
|
|
|
static Sci_Position LineEnd(Sci_Position line, Accessor &styler)
|
|
{
|
|
const Sci_Position docLines = styler.GetLine(styler.Length() - 1); // Available last line
|
|
Sci_Position eol_pos ;
|
|
// if the line is the last line, the eol_pos is styler.Length()
|
|
// eol will contain a new line, or a virtual new line
|
|
if ( docLines == line )
|
|
eol_pos = styler.Length() ;
|
|
else
|
|
eol_pos = styler.LineStart(line + 1) - 1;
|
|
return eol_pos ;
|
|
}
|
|
|
|
static Sci_Position LineStart(Sci_Position line, Accessor &styler)
|
|
{
|
|
return styler.LineStart(line) ;
|
|
}
|
|
|
|
// LineType
|
|
//
|
|
// bits determines the line type
|
|
// 1 : data line
|
|
// 2 : only whitespace
|
|
// 3 : data line with only whitespace
|
|
// 4 : keyword line
|
|
// 5 : block open keyword line
|
|
// 6 : block close keyword line
|
|
// 7 : keyword line in error
|
|
// 8 : comment line
|
|
static int LineType(Sci_Position line, Accessor &styler) {
|
|
Sci_Position pos = LineStart(line, styler) ;
|
|
Sci_Position eol_pos = LineEnd(line, styler) ;
|
|
|
|
int c ;
|
|
char ch = ' ';
|
|
|
|
Sci_Position i = pos ;
|
|
while ( i < eol_pos ) {
|
|
c = styler.SafeGetCharAt(i);
|
|
ch = static_cast<char>(LowerCase(c));
|
|
// We can say something as soon as no whitespace
|
|
// was encountered
|
|
if ( !IsSpace(c) )
|
|
break ;
|
|
i++ ;
|
|
}
|
|
|
|
if ( i >= eol_pos ) {
|
|
// This is a whitespace line, currently
|
|
// classifies as data line
|
|
return 3 ;
|
|
}
|
|
|
|
if ( ch != '*' ) {
|
|
// This is a data line
|
|
return 1 ;
|
|
}
|
|
|
|
if ( i == eol_pos - 1 ) {
|
|
// Only a single *, error but make keyword line
|
|
return 4+3 ;
|
|
}
|
|
|
|
// This means we can have a second character
|
|
// if that is also a * this means a comment
|
|
// otherwise it is a keyword.
|
|
c = styler.SafeGetCharAt(i+1);
|
|
ch = static_cast<char>(LowerCase(c));
|
|
if ( ch == '*' ) {
|
|
return 8 ;
|
|
}
|
|
|
|
// At this point we know this is a keyword line
|
|
// the character at position i is a *
|
|
// it is not a comment line
|
|
char word[256] ;
|
|
int wlen = 0;
|
|
|
|
word[wlen] = '*' ;
|
|
wlen++ ;
|
|
|
|
i++ ;
|
|
while ( (i < eol_pos) && (wlen < 255) ) {
|
|
c = styler.SafeGetCharAt(i);
|
|
ch = static_cast<char>(LowerCase(c));
|
|
|
|
if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
|
|
break ;
|
|
|
|
if ( IsIdentifier(c) ) {
|
|
word[wlen] = ch ;
|
|
wlen++ ;
|
|
}
|
|
|
|
i++ ;
|
|
}
|
|
|
|
word[wlen] = 0 ;
|
|
|
|
// Make a comparison
|
|
if ( !strcmp(word, "*step") ||
|
|
!strcmp(word, "*part") ||
|
|
!strcmp(word, "*instance") ||
|
|
!strcmp(word, "*assembly")) {
|
|
return 4+1 ;
|
|
}
|
|
|
|
if ( !strcmp(word, "*endstep") ||
|
|
!strcmp(word, "*endpart") ||
|
|
!strcmp(word, "*endinstance") ||
|
|
!strcmp(word, "*endassembly")) {
|
|
return 4+2 ;
|
|
}
|
|
|
|
return 4 ;
|
|
}
|
|
|
|
static void SafeSetLevel(Sci_Position line, int level, Accessor &styler)
|
|
{
|
|
if ( line < 0 )
|
|
return ;
|
|
|
|
int mask = ((~SC_FOLDLEVELHEADERFLAG) | (~SC_FOLDLEVELWHITEFLAG));
|
|
|
|
if ( (level & mask) < 0 )
|
|
return ;
|
|
|
|
if ( styler.LevelAt(line) != level )
|
|
styler.SetLevel(line, level) ;
|
|
}
|
|
|
|
static void FoldABAQUSDoc(Sci_PositionU startPos, Sci_Position length, int,
|
|
WordList *[], Accessor &styler) {
|
|
Sci_Position startLine = styler.GetLine(startPos) ;
|
|
Sci_Position endLine = styler.GetLine(startPos+length-1) ;
|
|
|
|
// bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
|
|
// We want to deal with all the cases
|
|
// To know the correct indentlevel, we need to look back to the
|
|
// previous command line indentation level
|
|
// order of formatting keyline datalines commentlines
|
|
Sci_Position beginData = -1 ;
|
|
Sci_Position beginComment = -1 ;
|
|
Sci_Position prvKeyLine = startLine ;
|
|
Sci_Position prvKeyLineTp = 0 ;
|
|
|
|
// Scan until we find the previous keyword line
|
|
// this will give us the level reference that we need
|
|
while ( prvKeyLine > 0 ) {
|
|
prvKeyLine-- ;
|
|
prvKeyLineTp = LineType(prvKeyLine, styler) ;
|
|
if ( prvKeyLineTp & 4 )
|
|
break ;
|
|
}
|
|
|
|
// Determine the base line level of all lines following
|
|
// the previous keyword
|
|
// new keyword lines are placed on this level
|
|
//if ( prvKeyLineTp & 4 ) {
|
|
int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
|
|
//}
|
|
|
|
// uncomment line below if weird behaviour continues
|
|
prvKeyLine = -1 ;
|
|
|
|
// Now start scanning over the lines.
|
|
for ( Sci_Position line = startLine; line <= endLine; line++ ) {
|
|
int lineType = LineType(line, styler) ;
|
|
|
|
// Check for comment line
|
|
if ( lineType == 8 ) {
|
|
if ( beginComment < 0 ) {
|
|
beginComment = line ;
|
|
}
|
|
}
|
|
|
|
// Check for data line
|
|
if ( (lineType == 1) || (lineType == 3) ) {
|
|
if ( beginData < 0 ) {
|
|
if ( beginComment >= 0 ) {
|
|
beginData = beginComment ;
|
|
} else {
|
|
beginData = line ;
|
|
}
|
|
}
|
|
beginComment = -1 ;
|
|
}
|
|
|
|
// Check for keywordline.
|
|
// As soon as a keyword line is encountered, we can set the
|
|
// levels of everything from the previous keyword line to this one
|
|
if ( lineType & 4 ) {
|
|
// this is a keyword, we can now place the previous keyword
|
|
// all its data lines and the remainder
|
|
|
|
// Write comments and data line
|
|
if ( beginComment < 0 ) {
|
|
beginComment = line ;
|
|
}
|
|
|
|
if ( beginData < 0 ) {
|
|
beginData = beginComment ;
|
|
if ( prvKeyLineTp != 5 )
|
|
SafeSetLevel(prvKeyLine, level, styler) ;
|
|
else
|
|
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
|
|
} else {
|
|
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
|
|
}
|
|
|
|
int datLevel = level + 1 ;
|
|
if ( !(prvKeyLineTp & 4) ) {
|
|
datLevel = level ;
|
|
}
|
|
|
|
for ( Sci_Position ll = beginData; ll < beginComment; ll++ )
|
|
SafeSetLevel(ll, datLevel, styler) ;
|
|
|
|
// The keyword we just found is going to be written at another level
|
|
// if we have a type 5 and type 6
|
|
if ( prvKeyLineTp == 5 ) {
|
|
level += 1 ;
|
|
}
|
|
|
|
if ( prvKeyLineTp == 6 ) {
|
|
level -= 1 ;
|
|
if ( level < 0 ) {
|
|
level = 0 ;
|
|
}
|
|
}
|
|
|
|
for ( Sci_Position lll = beginComment; lll < line; lll++ )
|
|
SafeSetLevel(lll, level, styler) ;
|
|
|
|
// wrap and reset
|
|
beginComment = -1 ;
|
|
beginData = -1 ;
|
|
prvKeyLine = line ;
|
|
prvKeyLineTp = lineType ;
|
|
}
|
|
|
|
}
|
|
|
|
if ( beginComment < 0 ) {
|
|
beginComment = endLine + 1 ;
|
|
} else {
|
|
// We need to find out whether this comment block is followed by
|
|
// a data line or a keyword line
|
|
const Sci_Position docLines = styler.GetLine(styler.Length() - 1);
|
|
|
|
for ( Sci_Position line = endLine + 1; line <= docLines; line++ ) {
|
|
Sci_Position lineType = LineType(line, styler) ;
|
|
|
|
if ( lineType != 8 ) {
|
|
if ( !(lineType & 4) ) {
|
|
beginComment = endLine + 1 ;
|
|
}
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( beginData < 0 ) {
|
|
beginData = beginComment ;
|
|
if ( prvKeyLineTp != 5 )
|
|
SafeSetLevel(prvKeyLine, level, styler) ;
|
|
else
|
|
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
|
|
} else {
|
|
SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
|
|
}
|
|
|
|
int datLevel = level + 1 ;
|
|
if ( !(prvKeyLineTp & 4) ) {
|
|
datLevel = level ;
|
|
}
|
|
|
|
for ( Sci_Position ll = beginData; ll < beginComment; ll++ )
|
|
SafeSetLevel(ll, datLevel, styler) ;
|
|
|
|
if ( prvKeyLineTp == 5 ) {
|
|
level += 1 ;
|
|
}
|
|
|
|
if ( prvKeyLineTp == 6 ) {
|
|
level -= 1 ;
|
|
}
|
|
for ( Sci_Position m = beginComment; m <= endLine; m++ )
|
|
SafeSetLevel(m, level, styler) ;
|
|
}
|
|
|
|
static const char * const abaqusWordListDesc[] = {
|
|
"processors",
|
|
"commands",
|
|
"slashommands",
|
|
"starcommands",
|
|
"arguments",
|
|
"functions",
|
|
0
|
|
};
|
|
|
|
extern const LexerModule lmAbaqus(SCLEX_ABAQUS, ColouriseABAQUSDoc, "abaqus", FoldABAQUSDoc, abaqusWordListDesc);
|