diff options
| -rw-r--r-- | lexers/LexOthers.cxx | 112 | ||||
| -rw-r--r-- | lexers/LexPO.cxx | 150 | ||||
| -rw-r--r-- | src/Catalogue.cxx | 2 | ||||
| -rw-r--r-- | win32/scintilla.mak | 3 | ||||
| -rw-r--r-- | win32/scintilla_vc6.mak | 3 | 
5 files changed, 157 insertions, 113 deletions
diff --git a/lexers/LexOthers.cxx b/lexers/LexOthers.cxx index fb8c97b31..d27c83545 100644 --- a/lexers/LexOthers.cxx +++ b/lexers/LexOthers.cxx @@ -614,117 +614,6 @@ static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Ac  	} while (static_cast<int>(startPos) + length > curLineStart);  } -// see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference -// some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines) -static void ColourisePoDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { -	StyleContext sc(startPos, length, initStyle, styler); -	bool escaped = false; -	int curLine = styler.GetLine(startPos); -	// the line state holds the last state on or before the line that isn't the default style -	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT; -	 -	for (; sc.More(); sc.Forward()) { -		// whether we should leave a state -		switch (sc.state) { -			case SCE_PO_COMMENT: -			case SCE_PO_PROGRAMMER_COMMENT: -			case SCE_PO_REFERENCE: -			case SCE_PO_FLAGS: -			case SCE_PO_FUZZY: -				if (sc.atLineEnd) -					sc.SetState(SCE_PO_DEFAULT); -				else if (sc.state == SCE_PO_FLAGS && sc.Match("fuzzy")) -					// here we behave like the previous parser, but this should probably be highlighted -					// on its own like a keyword rather than changing the whole flags style -					sc.ChangeState(SCE_PO_FUZZY); -				break; -			 -			case SCE_PO_MSGCTXT: -			case SCE_PO_MSGID: -			case SCE_PO_MSGSTR: -				if (isspacechar(sc.ch)) -					sc.SetState(SCE_PO_DEFAULT); -				break; -			 -			case SCE_PO_ERROR: -				if (sc.atLineEnd) -					sc.SetState(SCE_PO_DEFAULT); -				break; -			 -			case SCE_PO_MSGCTXT_TEXT: -			case SCE_PO_MSGID_TEXT: -			case SCE_PO_MSGSTR_TEXT: -				if (sc.atLineEnd) { // invalid inside a string -					if (sc.state == SCE_PO_MSGCTXT_TEXT) -						sc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL); -					else if (sc.state == SCE_PO_MSGID_TEXT) -						sc.ChangeState(SCE_PO_MSGID_TEXT_EOL); -					else if (sc.state == SCE_PO_MSGSTR_TEXT) -						sc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL); -					sc.SetState(SCE_PO_DEFAULT); -					escaped = false; -				} else { -					if (escaped) -						escaped = false; -					else if (sc.ch == '\\') -						escaped = true; -					else if (sc.ch == '"') -						sc.ForwardSetState(SCE_PO_DEFAULT); -				} -				break; -		} -		 -		// whether we should enter a new state -		if (sc.state == SCE_PO_DEFAULT) { -			// forward to the first non-white character on the line -			bool atLineStart = sc.atLineStart; -			if (atLineStart) { -				while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch)) -					sc.Forward(); -			} -			 -			if (atLineStart && sc.ch == '#') { -				if (sc.chNext == '.') -					sc.SetState(SCE_PO_PROGRAMMER_COMMENT); -				else if (sc.chNext == ':') -					sc.SetState(SCE_PO_REFERENCE); -				else if (sc.chNext == ',') -					sc.SetState(SCE_PO_FLAGS); -				else if (sc.chNext == '|') -					sc.SetState(SCE_PO_COMMENT); // previous untranslated string, no special style yet -				else -					sc.SetState(SCE_PO_COMMENT); -			} else if (atLineStart && sc.Match("msgid")) { // includes msgid_plural -				sc.SetState(SCE_PO_MSGID); -			} else if (atLineStart && sc.Match("msgstr")) { // includes [] suffixes -				sc.SetState(SCE_PO_MSGSTR); -			} else if (atLineStart && sc.Match("msgctxt")) { -				sc.SetState(SCE_PO_MSGCTXT); -			} else if (sc.ch == '"') { -				if (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT) -					sc.SetState(SCE_PO_MSGCTXT_TEXT); -				else if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT) -					sc.SetState(SCE_PO_MSGID_TEXT); -				else if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT) -					sc.SetState(SCE_PO_MSGSTR_TEXT); -				else -					sc.SetState(SCE_PO_ERROR); -			} else if (! isspacechar(sc.ch)) -				sc.SetState(SCE_PO_ERROR); -			 -			if (sc.state != SCE_PO_DEFAULT) -				curLineState = sc.state; -		} -		 -		if (sc.atLineEnd) { -			// Update the line state, so it can be seen by next line -			curLine = styler.GetLine(sc.currentPos); -			styler.SetLineState(curLine, curLineState); -		} -	} -	sc.Complete(); -} -  static inline bool isassignchar(unsigned char ch) {  	return (ch == '=') || (ch == ':');  } @@ -1537,7 +1426,6 @@ static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[  LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);  LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc); -LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);  LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);  LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);  LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc); diff --git a/lexers/LexPO.cxx b/lexers/LexPO.cxx new file mode 100644 index 000000000..d1ccda394 --- /dev/null +++ b/lexers/LexPO.cxx @@ -0,0 +1,150 @@ +// Scintilla source code edit control +/** @file LexPO.cxx + ** Lexer for GetText Translation (PO) files. + **/ +// Copyright 2012 by Colomban Wendling <ban@herbesfolles.org> +// The License.txt file describes the conditions under which this software may be distributed. + +// see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference +// some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines) + +// TODO: +// * add keywords for flags (fuzzy, c-format, ...) +// * highlight formats inside c-format strings (%s, %d, etc.) + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> +#include <assert.h> +#include <ctype.h> + +#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" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static void ColourisePODoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { +	StyleContext sc(startPos, length, initStyle, styler); +	bool escaped = false; +	int curLine = styler.GetLine(startPos); +	// the line state holds the last state on or before the line that isn't the default style +	int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT; +	 +	for (; sc.More(); sc.Forward()) { +		// whether we should leave a state +		switch (sc.state) { +			case SCE_PO_COMMENT: +			case SCE_PO_PROGRAMMER_COMMENT: +			case SCE_PO_REFERENCE: +			case SCE_PO_FLAGS: +			case SCE_PO_FUZZY: +				if (sc.atLineEnd) +					sc.SetState(SCE_PO_DEFAULT); +				else if (sc.state == SCE_PO_FLAGS && sc.Match("fuzzy")) +					// here we behave like the previous parser, but this should probably be highlighted +					// on its own like a keyword rather than changing the whole flags style +					sc.ChangeState(SCE_PO_FUZZY); +				break; +			 +			case SCE_PO_MSGCTXT: +			case SCE_PO_MSGID: +			case SCE_PO_MSGSTR: +				if (isspacechar(sc.ch)) +					sc.SetState(SCE_PO_DEFAULT); +				break; +			 +			case SCE_PO_ERROR: +				if (sc.atLineEnd) +					sc.SetState(SCE_PO_DEFAULT); +				break; +			 +			case SCE_PO_MSGCTXT_TEXT: +			case SCE_PO_MSGID_TEXT: +			case SCE_PO_MSGSTR_TEXT: +				if (sc.atLineEnd) { // invalid inside a string +					if (sc.state == SCE_PO_MSGCTXT_TEXT) +						sc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL); +					else if (sc.state == SCE_PO_MSGID_TEXT) +						sc.ChangeState(SCE_PO_MSGID_TEXT_EOL); +					else if (sc.state == SCE_PO_MSGSTR_TEXT) +						sc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL); +					sc.SetState(SCE_PO_DEFAULT); +					escaped = false; +				} else { +					if (escaped) +						escaped = false; +					else if (sc.ch == '\\') +						escaped = true; +					else if (sc.ch == '"') +						sc.ForwardSetState(SCE_PO_DEFAULT); +				} +				break; +		} +		 +		// whether we should enter a new state +		if (sc.state == SCE_PO_DEFAULT) { +			// forward to the first non-white character on the line +			bool atLineStart = sc.atLineStart; +			if (atLineStart) { +				while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch)) +					sc.Forward(); +			} +			 +			if (atLineStart && sc.ch == '#') { +				if (sc.chNext == '.') +					sc.SetState(SCE_PO_PROGRAMMER_COMMENT); +				else if (sc.chNext == ':') +					sc.SetState(SCE_PO_REFERENCE); +				else if (sc.chNext == ',') +					sc.SetState(SCE_PO_FLAGS); +				else if (sc.chNext == '|') +					sc.SetState(SCE_PO_COMMENT); // previous untranslated string, no special style yet +				else +					sc.SetState(SCE_PO_COMMENT); +			} else if (atLineStart && sc.Match("msgid")) { // includes msgid_plural +				sc.SetState(SCE_PO_MSGID); +			} else if (atLineStart && sc.Match("msgstr")) { // includes [] suffixes +				sc.SetState(SCE_PO_MSGSTR); +			} else if (atLineStart && sc.Match("msgctxt")) { +				sc.SetState(SCE_PO_MSGCTXT); +			} else if (sc.ch == '"') { +				if (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT) +					sc.SetState(SCE_PO_MSGCTXT_TEXT); +				else if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT) +					sc.SetState(SCE_PO_MSGID_TEXT); +				else if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT) +					sc.SetState(SCE_PO_MSGSTR_TEXT); +				else +					sc.SetState(SCE_PO_ERROR); +			} else if (! isspacechar(sc.ch)) +				sc.SetState(SCE_PO_ERROR); +			 +			if (sc.state != SCE_PO_DEFAULT) +				curLineState = sc.state; +		} +		 +		if (sc.atLineEnd) { +			// Update the line state, so it can be seen by next line +			curLine = styler.GetLine(sc.currentPos); +			styler.SetLineState(curLine, curLineState); +		} +	} +	sc.Complete(); +} + +static const char *const poWordListDesc[] = { +	0 +}; + +LexerModule lmPO(SCLEX_PO, ColourisePODoc, "po", 0, poWordListDesc); diff --git a/src/Catalogue.cxx b/src/Catalogue.cxx index 2f752472b..cd69d814b 100644 --- a/src/Catalogue.cxx +++ b/src/Catalogue.cxx @@ -152,7 +152,7 @@ int Scintilla_LinkLexers() {  	LINK_LEXER(lmPerl);  	LINK_LEXER(lmPHPSCRIPT);  	LINK_LEXER(lmPLM); -	LINK_LEXER(lmPo); +	LINK_LEXER(lmPO);  	LINK_LEXER(lmPOV);  	LINK_LEXER(lmPowerPro);  	LINK_LEXER(lmPowerShell); diff --git a/win32/scintilla.mak b/win32/scintilla.mak index e57da3c71..d7d8d3a30 100644 --- a/win32/scintilla.mak +++ b/win32/scintilla.mak @@ -146,6 +146,7 @@ LEXOBJS=\  	$(DIR_O)\LexPB.obj \  	$(DIR_O)\LexPerl.obj \  	$(DIR_O)\LexPLM.obj \ +	$(DIR_O)\LexPO.obj \  	$(DIR_O)\LexPOV.obj \  	$(DIR_O)\LexPowerPro.obj \  	$(DIR_O)\LexPowerShell.obj \ @@ -408,6 +409,8 @@ $(DIR_O)\LexPerl.obj: ..\lexers\LexPerl.cxx $(LEX_HEADERS)  $(DIR_O)\LexPLM.obj: ..\lexers\LexPLM.cxx $(LEX_HEADERS) +$(DIR_O)\LexPO.obj: ..\lexers\LexPO.cxx $(LEX_HEADERS) +  $(DIR_O)\LexPOV.obj: ..\lexers\LexPOV.cxx $(LEX_HEADERS)  $(DIR_O)\LexPowerPro.obj: ..\lexers\LexPowerPro.cxx $(LEX_HEADERS) diff --git a/win32/scintilla_vc6.mak b/win32/scintilla_vc6.mak index 2f900ab01..bfc9e6f18 100644 --- a/win32/scintilla_vc6.mak +++ b/win32/scintilla_vc6.mak @@ -143,6 +143,7 @@ LEXOBJS=\  	$(DIR_O)\LexPB.obj \  	$(DIR_O)\LexPerl.obj \  	$(DIR_O)\LexPLM.obj \ +	$(DIR_O)\LexPO.obj \  	$(DIR_O)\LexPOV.obj \  	$(DIR_O)\LexPowerPro.obj \  	$(DIR_O)\LexPowerShell.obj \ @@ -402,6 +403,8 @@ $(DIR_O)\LexPerl.obj: ..\lexers\LexPerl.cxx $(LEX_HEADERS)  $(DIR_O)\LexPLM.obj: ..\lexers\LexPLM.cxx $(LEX_HEADERS) +$(DIR_O)\LexPO.obj: ..\lexers\LexPO.cxx $(LEX_HEADERS) +  $(DIR_O)\LexPOV.obj: ..\lexers\LexPOV.cxx $(LEX_HEADERS)  $(DIR_O)\LexPowerPro.obj: ..\lexers\LexPowerPro.cxx $(LEX_HEADERS)  | 
