diff options
Diffstat (limited to 'lexers/LexPerl.cxx')
| -rw-r--r-- | lexers/LexPerl.cxx | 57 | 
1 files changed, 43 insertions, 14 deletions
| diff --git a/lexers/LexPerl.cxx b/lexers/LexPerl.cxx index e5b66eebb..ad9e77294 100644 --- a/lexers/LexPerl.cxx +++ b/lexers/LexPerl.cxx @@ -1184,6 +1184,26 @@ static bool IsCommentLine(int line, Accessor &styler) {  	return false;  } +static bool IsPackageLine(int line, Accessor &styler) { +	int pos = styler.LineStart(line); +	int style = styler.StyleAt(pos); +	if (style == SCE_PL_WORD && styler.Match(pos, "package")) { +		return true; +	} +	return false; +} + +static int PodHeadingLevel(int pos, Accessor &styler) { +	int lvl = static_cast<unsigned char>(styler.SafeGetCharAt(pos + 5)); +	if (lvl >= '1' && lvl <= '4') { +		return lvl - '0'; +	} +	return 0; +} + +#define PERL_HEADFOLD_SHIFT		4 +#define PERL_HEADFOLD_MASK		0xF0 +  static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],                          Accessor &styler) {  	bool foldComment = styler.GetPropertyInt("fold.comment") != 0; @@ -1210,7 +1230,7 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],  	int styleNext = styler.StyleAt(startPos);  	// Used at end of line to determine if the line was a package definition  	bool isPackageLine = false; -	bool isPodHeading = false; +	int podHeading = 0;  	for (unsigned int i = startPos; i < endPos; i++) {  		char ch = chNext;  		chNext = styler.SafeGetCharAt(i + 1); @@ -1225,52 +1245,61 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],  				&& IsCommentLine(lineCurrent + 1, styler))  				levelCurrent++;  			else if (IsCommentLine(lineCurrent - 1, styler) -					 && !IsCommentLine(lineCurrent+1, styler)) +					 && !IsCommentLine(lineCurrent + 1, styler))  				levelCurrent--;  		} +		// {} [] block folding  		if (style == SCE_PL_OPERATOR) {  			if (ch == '{') {  				levelCurrent++;  			} else if (ch == '}') {  				levelCurrent--;  			} +			if (ch == '[') { +				levelCurrent++; +			} else if (ch == ']') { +				levelCurrent--; +			}  		} -		// Custom POD folding +		// POD folding  		if (foldPOD && atLineStart) {  			int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;  			if (style == SCE_PL_POD) {  				if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)  					levelCurrent++;  				else if (styler.Match(i, "=cut")) -					levelCurrent--; +					levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;  				else if (styler.Match(i, "=head")) -					isPodHeading = true; +					podHeading = PodHeadingLevel(i, styler);  			} else if (style == SCE_PL_DATASECTION) {  				if (ch == '=' && isascii(chNext) && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)  					levelCurrent++;  				else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE) -					levelCurrent--; +					levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;  				else if (styler.Match(i, "=head")) -					isPodHeading = true; +					podHeading = PodHeadingLevel(i, styler);  				// if package used or unclosed brace, level > SC_FOLDLEVELBASE!  				// reset needed as level test is vs. SC_FOLDLEVELBASE -				else if (styler.Match(i, "__END__")) +				else if (stylePrevCh != SCE_PL_DATASECTION)  					levelCurrent = SC_FOLDLEVELBASE;  			}  		} -		// Custom package folding +		// package folding  		if (foldPackage && atLineStart) { -			if (style == SCE_PL_WORD && styler.Match(i, "package")) { +			if (IsPackageLine(lineCurrent, styler) +				&& !IsPackageLine(lineCurrent + 1, styler))  				isPackageLine = true; -			}  		}  		if (atEOL) {  			int lev = levelPrev; -			if (isPodHeading) { -				lev = levelPrev - 1; +			// POD headings occupy bits 7-4, leaving some breathing room for +			// non-standard practice -- POD sections stuck in blocks, etc. +			if (podHeading > 0) { +				levelCurrent = (lev & ~PERL_HEADFOLD_MASK) | (podHeading << PERL_HEADFOLD_SHIFT); +				lev = levelCurrent - 1;  				lev |= SC_FOLDLEVELHEADERFLAG; -				isPodHeading = false; +				podHeading = 0;  			}  			// Check if line was a package declaration  			// because packages need "special" treatment | 
