diff options
Diffstat (limited to 'lexers/LexBasic.cxx')
| -rw-r--r-- | lexers/LexBasic.cxx | 63 | 
1 files changed, 56 insertions, 7 deletions
| diff --git a/lexers/LexBasic.cxx b/lexers/LexBasic.cxx index 057afed65..55641edc1 100644 --- a/lexers/LexBasic.cxx +++ b/lexers/LexBasic.cxx @@ -1,7 +1,7 @@  // Scintilla source code edit control  /** @file LexBasic.cxx   ** Lexer for BlitzBasic and PureBasic. - ** Converted to lexer object by "Udo Lechner" <dlchnr(at)gmx(dot)net> + ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>   **/  // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>  // The License.txt file describes the conditions under which this software may be distributed. @@ -22,6 +22,7 @@  #include <stdio.h>  #include <stdarg.h>  #include <assert.h> +#include <ctype.h>  #ifdef _MSC_VER  #pragma warning(disable: 4786) @@ -36,7 +37,6 @@  #include "WordList.h"  #include "LexAccessor.h" -#include "Accessor.h"  #include "StyleContext.h"  #include "CharacterSet.h"  #include "LexerModule.h" @@ -147,9 +147,19 @@ static int CheckFreeFoldPoint(char const *token, int &level) {  // Options used for LexerBasic  struct OptionsBasic {  	bool fold; +	bool foldSyntaxBased; +	bool foldCommentExplicit; +	std::string foldExplicitStart; +	std::string foldExplicitEnd; +	bool foldExplicitAnywhere;  	bool foldCompact;  	OptionsBasic() {  		fold = false; +		foldSyntaxBased = true; +		foldCommentExplicit = false; +		foldExplicitStart = ""; +		foldExplicitEnd   = ""; +		foldExplicitAnywhere = false;  		foldCompact = true;  	}  }; @@ -182,6 +192,23 @@ struct OptionSetBasic : public OptionSet<OptionsBasic> {  	OptionSetBasic(const char * const wordListDescriptions[]) {  		DefineProperty("fold", &OptionsBasic::fold); +		DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased, +			"Set this property to 0 to disable syntax based folding."); + +		DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit, +			"This option enables folding explicit fold points when using the Basic lexer. " +			"Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start " +			"and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded."); + +		DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart, +			"The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB)."); + +		DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd, +			"The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB)."); + +		DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere, +			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); +  		DefineProperty("fold.compact", &OptionsBasic::foldCompact);  		DefineWordListSets(wordListDescriptions); @@ -235,7 +262,7 @@ public:  		return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);  	}  	static ILexer *LexerFactoryFreeBasic() { -		return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc); +		return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );  	}  }; @@ -397,7 +424,6 @@ void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initS  	if (!options.fold)  		return; -  	LexAccessor styler(pAccess);  	int line = styler.GetLine(startPos); @@ -406,12 +432,16 @@ void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initS  	int endPos = startPos + length;  	char word[256];  	int wordlen = 0; +	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); +	int cNext = styler[startPos];  	// Scan for tokens at the start of the line (they may include  	// whitespace, for tokens like "End Function"  	for (int i = startPos; i < endPos; i++) { -		int c = styler.SafeGetCharAt(i); -		if (!done && !go) { +		int c = cNext; +		cNext = styler.SafeGetCharAt(i + 1); +		bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n'); +		if (options.foldSyntaxBased && !done && !go) {  			if (wordlen) { // are we scanning a token already?  				word[wordlen] = static_cast<char>(LowerCase(c));  				if (!IsIdentifier(c)) { // done with token @@ -441,7 +471,26 @@ void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initS  				}  			}  		} -		if (c == '\n') { // line end +		if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) { +			if (userDefinedFoldMarkers) { +				if (styler.Match(i, options.foldExplicitStart.c_str())) { + 					level |= SC_FOLDLEVELHEADERFLAG; +					go = 1; +				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) { + 					go = -1; + 				} +			} else { +				if (c == comment_char) { +					if (cNext == '{') { +						level |= SC_FOLDLEVELHEADERFLAG; +						go = 1; +					} else if (cNext == '}') { +						go = -1; +					} +				} + 			} + 		} +		if (atEOL) { // line end  			if (!done && wordlen == 0 && options.foldCompact) // line was only space  				level |= SC_FOLDLEVELWHITEFLAG;  			if (level != styler.LevelAt(line)) | 
