STORM-959 Syntax highlighting for LSL multi-line comments. (from Ima Mechanique)

Tank_Master 2011-10-29 21:45:15 -07:00
parent c74e29e3ae
commit 8dff6606ae
4 changed files with 96 additions and 25 deletions

View File

@ -480,6 +480,7 @@ Ima Mechanique
OPEN-50
OPEN-61
OPEN-76
STORM-959
STORM-1175
Imnotgoing Sideways
Inma Rau
@ -650,6 +651,8 @@ Lilly Zenovka
Lizzy Macarthur
Luban Yiyuan
Luc Starsider
Luminous Luminos
STORM-959
Lunita Savira
Maccus McCullough
maciek marksman

View File

@ -57,6 +57,22 @@ LLKeywords::LLKeywords() : mLoaded(FALSE)
{
}
inline BOOL LLKeywordToken::isTail(const llwchar* s) const
{
BOOL res = TRUE;
const llwchar* t = mDelimiter.c_str();
S32 len = mDelimiter.size();
for (S32 i=0; i<len; i++)
{
if (s[i] != t[i])
{
res = FALSE;
break;
}
}
return res;
}
LLKeywords::~LLKeywords()
{
std::for_each(mWordTokenMap.begin(), mWordTokenMap.end(), DeletePairedPointer());
@ -106,6 +122,7 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
std::string SOL_LINE("[line ");
std::string SOL_ONE_SIDED_DELIMITER("[one_sided_delimiter ");
std::string SOL_TWO_SIDED_DELIMITER("[two_sided_delimiter ");
std::string SOL_DOUBLE_QUOTATION_MARKS("[double_quotation_marks ");
LLColor3 cur_color( 1, 0, 0 );
LLKeywordToken::TOKEN_TYPE cur_type = LLKeywordToken::WORD;
@ -137,6 +154,12 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
cur_type = LLKeywordToken::TWO_SIDED_DELIMITER;
continue;
}
else if( line.find(SOL_DOUBLE_QUOTATION_MARKS) == 0 )
{
cur_color = readColor( line.substr(SOL_DOUBLE_QUOTATION_MARKS.size()) );
cur_type = LLKeywordToken::DOUBLE_QUOTATION_MARKS;
continue;
}
else if( line.find(SOL_ONE_SIDED_DELIMITER) == 0 )
{
cur_color = readColor( line.substr(SOL_ONE_SIDED_DELIMITER.size()) );
@ -154,10 +177,26 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
if( !token_buffer.empty() && token_word_iter != word_tokens.end() )
{
// first word is keyword
// first word is the keyword or a left delimiter
std::string keyword = (*token_word_iter);
LLStringUtil::trim(keyword);
// second word may be a right delimiter
std::string delimiter;
if (cur_type == LLKeywordToken::TWO_SIDED_DELIMITER)
{
while (delimiter.length() == 0 && ++token_word_iter != word_tokens.end())
{
delimiter = *token_word_iter;
LLStringUtil::trim(delimiter);
}
}
else if (cur_type == LLKeywordToken::DOUBLE_QUOTATION_MARKS)
{
// Closing delimiter is identical to the opening one.
delimiter = keyword;
}
// following words are tooltip
std::string tool_tip;
while (++token_word_iter != word_tokens.end())
@ -170,11 +209,11 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
{
// Replace : with \n for multi-line tool tips.
LLStringUtil::replaceChar( tool_tip, ':', '\n' );
addToken(cur_type, keyword, cur_color, tool_tip );
addToken(cur_type, keyword, cur_color, tool_tip, delimiter );
}
else
{
addToken(cur_type, keyword, cur_color, LLStringUtil::null );
addToken(cur_type, keyword, cur_color, LLStringUtil::null, delimiter );
}
}
}
@ -189,23 +228,26 @@ BOOL LLKeywords::loadFromFile( const std::string& filename )
void LLKeywords::addToken(LLKeywordToken::TOKEN_TYPE type,
const std::string& key_in,
const LLColor3& color,
const std::string& tool_tip_in )
const std::string& tool_tip_in,
const std::string& delimiter_in)
{
LLWString key = utf8str_to_wstring(key_in);
LLWString tool_tip = utf8str_to_wstring(tool_tip_in);
LLWString delimiter = utf8str_to_wstring(delimiter_in);
switch(type)
{
case LLKeywordToken::WORD:
mWordTokenMap[key] = new LLKeywordToken(type, color, key, tool_tip);
mWordTokenMap[key] = new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null);
break;
case LLKeywordToken::LINE:
mLineTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip));
mLineTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, LLWStringUtil::null));
break;
case LLKeywordToken::TWO_SIDED_DELIMITER:
case LLKeywordToken::DOUBLE_QUOTATION_MARKS:
case LLKeywordToken::ONE_SIDED_DELIMITER:
mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip));
mDelimiterTokenList.push_front(new LLKeywordToken(type, color, key, tool_tip, delimiter));
break;
default:
@ -357,7 +399,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
}
// cur is now at the first non-whitespace character of a new line
// Line start tokens
{
BOOL line_done = FALSE;
@ -418,14 +460,15 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
S32 seg_end = 0;
seg_start = cur - base;
cur += cur_delimiter->getLength();
cur += cur_delimiter->getLengthHead();
if( cur_delimiter->getType() == LLKeywordToken::TWO_SIDED_DELIMITER )
LLKeywordToken::TOKEN_TYPE type = cur_delimiter->getType();
if( type == LLKeywordToken::TWO_SIDED_DELIMITER || type == LLKeywordToken::DOUBLE_QUOTATION_MARKS )
{
while( *cur && !cur_delimiter->isHead(cur))
while( *cur && !cur_delimiter->isTail(cur))
{
// Check for an escape sequence.
if (*cur == '\\')
if (type == LLKeywordToken::DOUBLE_QUOTATION_MARKS && *cur == '\\')
{
// Count the number of backslashes.
S32 num_backslashes = 0;
@ -435,10 +478,10 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
between_delimiters++;
cur++;
}
// Is the next character the end delimiter?
if (cur_delimiter->isHead(cur))
// If the next character is the end delimiter?
if (cur_delimiter->isTail(cur))
{
// Is there was an odd number of backslashes, then this delimiter
// If there was an odd number of backslashes, then this delimiter
// does not end the sequence.
if (num_backslashes % 2 == 1)
{
@ -461,13 +504,13 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
if( *cur )
{
cur += cur_delimiter->getLength();
seg_end = seg_start + between_delimiters + 2 * cur_delimiter->getLength();
cur += cur_delimiter->getLengthHead();
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead() + cur_delimiter->getLengthTail();
}
else
{
// eof
seg_end = seg_start + between_delimiters + cur_delimiter->getLength();
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
}
}
else
@ -479,7 +522,7 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
between_delimiters++;
cur++;
}
seg_end = seg_start + between_delimiters + cur_delimiter->getLength();
seg_end = seg_start + between_delimiters + cur_delimiter->getLengthHead();
}
insertSegments(wtext, *seg_list,cur_delimiter, text_len, seg_start, seg_end, defaultColor, editor);

View File

@ -41,23 +41,44 @@ typedef LLPointer<LLTextSegment> LLTextSegmentPtr;
class LLKeywordToken
{
public:
enum TOKEN_TYPE { WORD, LINE, TWO_SIDED_DELIMITER, ONE_SIDED_DELIMITER };
/**
* @brief Types of tokens/delimters being parsed.
*
* @desc Tokens/delimiters that need to be identified/highlighted. All are terminated if an EOF is encountered.
* - WORD are keywords in the normal sense, i.e. constants, events, etc.
* - LINE are for entire lines (currently only flow control labels use this).
* - ONE_SIDED_DELIMITER are for open-ended delimiters which are terminated by EOL.
* - TWO_SIDED_DELIMITER are for delimiters that end with a different delimiter than they open with.
* - DOUBLE_QUOTATION_MARKS are for delimiting areas using the same delimiter to open and close.
*/
typedef enum TOKEN_TYPE
{
WORD,
LINE,
TWO_SIDED_DELIMITER,
ONE_SIDED_DELIMITER,
DOUBLE_QUOTATION_MARKS
};
LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip )
LLKeywordToken( TOKEN_TYPE type, const LLColor3& color, const LLWString& token, const LLWString& tool_tip, const LLWString& delimiter )
:
mType( type ),
mToken( token ),
mColor( color ),
mToolTip( tool_tip )
mToolTip( tool_tip ),
mDelimiter( delimiter ) // right delimiter
{
}
S32 getLength() const { return mToken.size(); }
S32 getLengthHead() const { return mToken.size(); }
S32 getLengthTail() const { return mDelimiter.size(); }
BOOL isHead(const llwchar* s) const;
BOOL isTail(const llwchar* s) const;
const LLWString& getToken() const { return mToken; }
const LLColor3& getColor() const { return mColor; }
TOKEN_TYPE getType() const { return mType; }
const LLWString& getToolTip() const { return mToolTip; }
const LLWString& getDelimiter() const { return mDelimiter; }
#ifdef _DEBUG
void dump();
@ -68,6 +89,7 @@ private:
LLWString mToken;
LLColor3 mColor;
LLWString mToolTip;
LLWString mDelimiter;
};
class LLKeywords
@ -85,7 +107,8 @@ public:
void addToken(LLKeywordToken::TOKEN_TYPE type,
const std::string& key,
const LLColor3& color,
const std::string& tool_tip = LLStringUtil::null);
const std::string& tool_tip = LLStringUtil::null,
const std::string& delimiter = LLStringUtil::null);
// This class is here as a performance optimization.
// The word token map used to be defined as std::map<LLWString, LLKeywordToken*>.

View File

@ -634,9 +634,11 @@ return Leave current function or event handler
# Comment
[one_sided_delimiter .8, .3, .15]
// Comment:Non-functional commentary or disabled code
[two_sided_delimiter .8, .3, .15]
/* */ Comment:Non-functional commentary or disabled code
# String literals
[two_sided_delimiter 0, .2, 0]
[double_quotation_marks 0, .2, 0]
" String literal
#functions are supplied by the program now.