Notepad++ syntax coloring
Lately, my external editor of choice has been Notepad++. It’s flexible, highly configurable, and supports user-defined syntax coloring. Of course, it doesn’t ship with a syntax coloring file for VFP, so I came up with my own. After a while, I got tired of typing in commands as I got to them, and wrote a program to generate the whole thing.
I copied most of the XML out of my half-completed file, and only substituted in the keywords. I had to specify the folding keywords manually, since FoxCode.dbf doesn’t have any concept of folding. A couple of places the whole thing fell down were comments, since comments and multiplication share the asterisk, and quotes, since VFP uses so many different delimiters. I basically shrugged on these and went “Oh, well” — if you know a better way to handle it, please let me know. :-)
Once you have the file generated, either copy it into Notepad’s APPDATA directory, or copy the Fox-specific code out of the file and paste it in to the existing userdefinelang.xml. From there, you can tweak the fonts, sizes, and colors within N++, which automatically saves the UDL changes on exit.
#DEFINE USERNAME "gfitzgerald"
#DEFINE APPDATAPATH "C:\Documents and Settings\" + USERNAME + "\Application Data\Microsoft\Visual FoxPro 9\foxcode.dbf"
LOCAL loWordsUsed ;
, lcWords1, lcWords2, lcWords3 ;
, lcCurrWord ;
, lcUserDefLang
USE APPDATAPATH ;
AGAIN ;
SHARED ;
IN 0 ;
ALIAS MyFoxCode
SELECT abbrev, expanded ;
FROM MyFoxCode ;
INTO CURSOR crsrFoxFuncs ;
WHERE type = 'F' ;
AND RIGHT(UPPER(ALLTRIM(expanded)), 3) != "TIP" ;
AND VAL(RIGHT(ALLTRIM(expanded), 1)) = 0 ;
ORDER BY expanded
loWordsUsed = CREATEOBJECT("Collection")
STORE "" TO lcWords1, lcWords2, lcWords3
lcFolder1 = " IF TEXT PROCEDURE DEFINE FOR FUNCTION WITH TRY SCAN "
lcFolder2 = " ENDIF ENDTEXT ENDPROC ENDDEFINE ENDFOR ENDFUNC ENDWITH ENDTRY ENDSCAN "
lcWords4 = " AND OR NOT .T. .F. .NULL. "
SELECT crsrFoxFuncs
SCAN
lcAbbrev = UPPER(ALLTRIM(abbrev))
lcExpand = UPPER(ALLTRIM(expanded))
lcWords1 = lcWords1 ;
+ IIF(EMPTY(lcAbbrev), "", lcAbbrev + " ") ;
+ IIF(lcAbbrev == lcExpand, "", lcExpand + " ")
ENDSCAN
SELECT abbrev, expanded, tip ;
FROM myFoxCode ;
INTO CURSOR crsrFoxCmds ;
WHERE type = 'C' ;
AND VAL(RIGHT(ALLTRIM(expanded), 1)) = 0 ;
ORDER BY expanded
SELECT crsrFoxCmds
SCAN
lcCurrAbbrev = UPPER(ALLTRIM(abbrev))
IF NOT EMPTY(lcCurrAbbrev) ;
AND loWordsUsed.GetKey(lcCurrAbbrev) = 0 ;
AND NOT " " + lcCurrAbbrev + " " $ lcFolder1 ;
AND NOT " " + lcCurrAbbrev + " " $ lcFolder2 ;
AND NOT " " + lcCurrAbbrev + " " $ lcWords4
lcWords2 = lcWords2 + lcCurrAbbrev + " "
loWordsUsed.Add(.T., lcCurrAbbrev)
ENDIF
FOR i = 1 TO GETWORDCOUNT(expanded)
lcCurrWord = UPPER(ALLTRIM(GETWORDNUM(expanded, i)))
IF loWordsUsed.GetKey(lcCurrWord) = 0 ;
AND NOT " " + lcCurrWord + " " $ lcFolder1 ;
AND NOT " " + lcCurrWord + " " $ lcFolder2 ;
AND NOT " " + lcCurrWord + " " $ lcWords4
IF i = 1
lcWords2 = lcWords2 + lcCurrWord + " "
ELSE
lcWords3 = lcWords3 + lcCurrWord + " "
ENDIF
loWordsUsed.Add(.T., lcCurrWord)
ENDIF
ENDFOR
IF NOT EMPTY(tip)
FOR i = 1 TO GETWORDCOUNT(tip)
lcTipWord = ALLTRIM(CHRTRAN(GETWORDNUM(tip, i), "[]", " "))
IF NOT EMPTY(lcTipWord) ;
AND NOT " " + lcTipWord + " " $ lcFolder1 ;
AND NOT " " + lcTipWord + " " $ lcFolder2 ;
AND NOT " " + lcTipWord + " " $ lcWords4
llAllUpper = .T.
FOR j = 1 TO LEN(lcTipWord)
lcTipLetter = SUBSTR(lcTipWord, j, 1)
IF NOT(ISALPHA(lcTipLetter) AND ISUPPER(lcTipLetter))
llAllUpper = .F.
ENDIF
ENDFOR
IF llAllUpper AND loWordsUsed.GetKey(lcTipWord) = 0
lcWords3 = lcWords3 + lcTipWord + " "
loWordsUsed.Add(.T., lcTipWord)
ENDIF
ENDIF
ENDFOR
ENDIF
ENDSCAN
ALINES(laWords3, lcWords3, 1, " ")
ASORT(laWords3)
lcWords3 = ""
FOR i = 1 TO ALEN(laWords3, 1)
lcWords3 = lcWords3 + laWords3[i] + " "
ENDFOR
lcWords3 = RTRIM(lcWords3)
TEXT TO lcUserDefLang TEXTMERGE NOSHOW
<NotepadPlus>
<UserLang name="Visual FoxPro" ext="PRG prg">
<Settings>
<Global caseIgnored="yes" />
<TreatAsSymbol comment="no" commentLine="yes" />
<Prefix words1="no" words2="no" words3="no" words4="no" />
</Settings>
<KeywordLists>
<Keywords name="Delimiters">{00}00</Keywords>
<Keywords name="Folder+"><<ALLTRIM(lcFolder1)>></Keywords>
<Keywords name="Folder-"><<ALLTRIM(lcFolder2)>></Keywords>
<Keywords name="Operators">- ! $ ( ) * , / ; ? [ ] ^ + < = ></Keywords>
<Keywords name="Comment">1 2 0&& 0NOTE</Keywords>
<Keywords name="Words1"><<lcWords1>></Keywords>
<Keywords name="Words2"><<lcWords2>></Keywords>
<Keywords name="Words3"><<lcWords3>></Keywords>
<Keywords name="Words4"><<ALLTRIM(lcWords4)>></Keywords>
</KeywordLists>
<Styles>
<WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="FOLDEROPEN" styleID="12" fgColor="0000FF" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="0000FF" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="KEYWORD1" styleID="5" fgColor="0000FF" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="KEYWORD2" styleID="6" fgColor="0000FF" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="KEYWORD3" styleID="7" fgColor="0000FF" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="KEYWORD4" styleID="8" fgColor="FF0000" bgColor="FFFFFF" fontName="Consolas" fontStyle="1" fontSize="12" />
<WordsStyle name="COMMENT" styleID="1" fgColor="000840" bgColor="FFFFFF" fontName="Consolas" fontStyle="2" fontSize="10" />
<WordsStyle name="COMMENT LINE" styleID="2" fgColor="008040" bgColor="FFFFFF" fontName="Consolas" fontStyle="2" fontSize="10" />
<WordsStyle name="NUMBER" styleID="4" fgColor="008000" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="OPERATOR" styleID="10" fgColor="800000" bgColor="FFFFFF" fontName="Consolas" fontStyle="1" fontSize="12" />
<WordsStyle name="DELIMINER1" styleID="14" fgColor="FFFFFF" bgColor="804000" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="DELIMINER2" styleID="15" fgColor="FFFFFF" bgColor="804000" fontName="Consolas" fontStyle="0" fontSize="12" />
<WordsStyle name="DELIMINER3" styleID="16" fgColor="000000" bgColor="FFFFFF" fontName="Consolas" fontStyle="0" />
</Styles>
</UserLang>
</NotepadPlus>
ENDTEXT
STRTOFILE(lcUserDefLang, "userdefinelang.xml")
Posted by Garrett on October 28th, 2008 in Code Sample, Original, VFP | 3 Comments

I am too lazy to do it manually and not smart enough to do it your way…
What can I say – thank you! :-)
Comment by Andrzej — October 29, 2008 @ 5:16 am
Hey Garret,
Thanks for the code!
Comment by Cetin Basoz — June 16, 2009 @ 10:40 am
Hi, Garret!
Thank you for your code,
I have found VFP syntax for Notepad++ for long time, But I have not capablity to generate XML file with your code. Bother you can help me make a XML of this code and send it to my email (orphenmds#163.com) if you are convenience.
Your cooperation will be appreciated.
Comment by Oswald — June 27, 2009 @ 9:20 am