Submitted By: Andrew Rowland Date: 2008-09-19 Initial Package Version: 0.14 Origin: Self Description: Adds syntax highlighting support for R (and S-Plus) scripts. Upstream Status: Submitted and pending. diff -Naur geany-0.14-orig/data/filetype_extensions.conf geany-0.14/data/filetype_extensions.conf --- geany-0.14-orig/data/filetype_extensions.conf 2008-03-18 12:38:01.000000000 -0400 +++ geany-0.14/data/filetype_extensions.conf 2008-09-19 19:32:36.000000000 -0400 @@ -25,6 +25,7 @@ Perl=*.pl;*.perl;*.pm;*.agi;*.pod; PHP=*.php;*.php3;*.php4;*.php5;*.phtml; Python=*.py;*.pyw; +R=*.R;*.r; Ruby=*.rb;*.rhtml;*.ruby; Sh=*.sh;configure;configure.in;configure.in.in;configure.ac;*.ksh;*.zsh;*.ash;*.bash; Tcl=*.tcl;*.tk;*.wish; diff -Naur geany-0.14-orig/data/filetypes.r geany-0.14/data/filetypes.r --- geany-0.14-orig/data/filetypes.r 1969-12-31 19:00:00.000000000 -0500 +++ geany-0.14/data/filetypes.r 2008-09-19 19:37:57.000000000 -0400 @@ -0,0 +1,46 @@ +# For complete documentation of this file, please see Geany's main documentation +[styling] +# foreground;background;bold;italic +default=0x000000;0xffffff;false;false +#comment=0x000fff;0xffffff;true;false +#kword=0x66ff33;0xffffff;true;false +#operator=0x660000;0xffffff;false;false +#basekword=0x66ff33;0xffffff;false;false +#otherkword=0x66ff33;0xffffff;false;false +#number=0xcc00ff;0xffffff;false;false +#string=0xcc00ff;0xffffff;false;false +#string2=0xcc00ff;0xffffff;false;false +#identifier=0x6600ff;0xffffff;false;false +#infix=0xcc00ff;0xffffff;false;false +#infixeol=0xcc00ff;0xffffff;false;false + +[keywords] +# all items must be in one line +#primary=source if else for cbind rbind break array matrix +#secondary= + +[settings] +# default extension used when saving files +extension=R + +# the following characters are these which a "word" can contains, see documentation +#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 + +# if only single comment char is supported like # in this file, leave comment_close blank +comment_open=# +comment_close= +# this is an alternative way, so multiline comments are used +#comment_open=/* +#comment_close=*/ + +# set to false if a comment character/string should start at column 0 of a line, true uses any +# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d + #command_example(); +# setting to false would generate this +# command_example(); +# This setting works only for single line comments +comment_use_indent=false + +# context action command (please see Geany's main documentation for details) +context_action_cmd= + diff -Naur geany-0.14-orig/scintilla/include/SciLexer.h geany-0.14/scintilla/include/SciLexer.h --- geany-0.14-orig/scintilla/include/SciLexer.h 2008-03-26 12:42:50.000000000 -0400 +++ geany-0.14/scintilla/include/SciLexer.h 2008-09-17 23:10:36.000000000 -0400 @@ -1197,12 +1197,12 @@ #define SCE_R_DEFAULT 0 #define SCE_R_COMMENT 1 #define SCE_R_KWORD 2 -#define SCE_R_BASEKWORD 3 -#define SCE_R_OTHERKWORD 4 -#define SCE_R_NUMBER 5 -#define SCE_R_STRING 6 -#define SCE_R_STRING2 7 -#define SCE_R_OPERATOR 8 +#define SCE_R_OPERATOR 3 +#define SCE_R_BASEKWORD 4 +#define SCE_R_OTHERKWORD 5 +#define SCE_R_NUMBER 6 +#define SCE_R_STRING 7 +#define SCE_R_STRING2 8 #define SCE_R_IDENTIFIER 9 #define SCE_R_INFIX 10 #define SCE_R_INFIXEOL 11 diff -Naur geany-0.14-orig/scintilla/KeyWords.cxx geany-0.14/scintilla/KeyWords.cxx --- geany-0.14-orig/scintilla/KeyWords.cxx 2007-07-02 13:09:48.000000000 -0400 +++ geany-0.14/scintilla/KeyWords.cxx 2008-09-19 18:19:04.000000000 -0400 @@ -173,7 +173,8 @@ LINK_LEXER(lmTCL); LINK_LEXER(lmVHDL); LINK_LEXER(lmXML); - + LINK_LEXER(lmR); + //--Autogenerated -- end of automatically generated section return 1; diff -Naur geany-0.14-orig/scintilla/LexR.cxx geany-0.14/scintilla/LexR.cxx --- geany-0.14-orig/scintilla/LexR.cxx 1969-12-31 19:00:00.000000000 -0500 +++ geany-0.14/scintilla/LexR.cxx 2007-11-15 05:24:41.000000000 -0500 @@ -0,0 +1,213 @@ +// Scintilla source code edit control +/** @file Lexr.cxx + ** Lexer for R, S, SPlus Statistics Program (Heavily derived from CPP Lexer). + ** + **/ +// Copyright 1998-2002 by Neil Hodgson +// The License.txt file describes the conditions under which this software may be distributed. + +#include +#include +#include +#include +#include + +#include "Platform.h" + +#include "PropSet.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "KeyWords.h" +#include "Scintilla.h" +#include "SciLexer.h" + +#ifdef SCI_NAMESPACE +using namespace Scintilla; +#endif + +static inline bool IsAWordChar(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); +} + +static inline bool IsAWordStart(const int ch) { + return (ch < 0x80) && (isalnum(ch) || ch == '_'); +} + +static inline bool IsAnOperator(const int ch) { + if (isascii(ch) && isalnum(ch)) + return false; + // '.' left out as it is used to make up numbers + if (ch == '-' || ch == '+' || ch == '!' || ch == '~' || + ch == '?' || ch == ':' || ch == '*' || ch == '/' || + ch == '^' || ch == '<' || ch == '>' || ch == '=' || + ch == '&' || ch == '|' || ch == '$' || ch == '(' || + ch == ')' || ch == '}' || ch == '{' || ch == '[' || + ch == ']') + return true; + return false; +} + +static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], + Accessor &styler) { + + WordList &keywords = *keywordlists[0]; + WordList &keywords2 = *keywordlists[1]; + WordList &keywords3 = *keywordlists[2]; + + + // Do not leak onto next line + if (initStyle == SCE_R_INFIXEOL) + initStyle = SCE_R_DEFAULT; + + + StyleContext sc(startPos, length, initStyle, styler); + + for (; sc.More(); sc.Forward()) { + + if (sc.atLineStart && (sc.state == SCE_R_STRING)) { + // Prevent SCE_R_STRINGEOL from leaking back to previous line + sc.SetState(SCE_R_STRING); + } + + // Determine if the current state should terminate. + if (sc.state == SCE_R_OPERATOR) { + sc.SetState(SCE_R_DEFAULT); + } else if (sc.state == SCE_R_NUMBER) { + if (!IsADigit(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_R_DEFAULT); + } + } else if (sc.state == SCE_R_IDENTIFIER) { + if (!IsAWordChar(sc.ch) || (sc.ch == '.')) { + char s[100]; + sc.GetCurrentLowered(s, sizeof(s)); + if (keywords.InList(s)) { + sc.ChangeState(SCE_R_KWORD); + } else if (keywords2.InList(s)) { + sc.ChangeState(SCE_R_BASEKWORD); + } else if (keywords3.InList(s)) { + sc.ChangeState(SCE_R_OTHERKWORD); + } + sc.SetState(SCE_R_DEFAULT); + } + } else if (sc.state == SCE_R_COMMENT) { + if (sc.ch == '\r' || sc.ch == '\n') { + sc.SetState(SCE_R_DEFAULT); + } + } else if (sc.state == SCE_R_STRING) { + if (sc.ch == '\\') { + if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { + sc.Forward(); + } + } else if (sc.ch == '\"') { + sc.ForwardSetState(SCE_R_DEFAULT); + } + } else if (sc.state == SCE_R_INFIX) { + if (sc.ch == '%') { + sc.ForwardSetState(SCE_R_DEFAULT); + } else if (sc.atLineEnd) { + sc.ChangeState(SCE_R_INFIXEOL); + sc.ForwardSetState(SCE_R_DEFAULT); + } + }else if (sc.state == SCE_R_STRING2) { + if (sc.ch == '\\') { + if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { + sc.Forward(); + } + } else if (sc.ch == '\'') { + sc.ForwardSetState(SCE_R_DEFAULT); + } + } + + // Determine if a new state should be entered. + if (sc.state == SCE_R_DEFAULT) { + if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_R_NUMBER); + } else if (IsAWordStart(sc.ch) ) { + sc.SetState(SCE_R_IDENTIFIER); + } else if (sc.Match('#')) { + sc.SetState(SCE_R_COMMENT); + } else if (sc.ch == '\"') { + sc.SetState(SCE_R_STRING); + } else if (sc.ch == '%') { + sc.SetState(SCE_R_INFIX); + } else if (sc.ch == '\'') { + sc.SetState(SCE_R_STRING2); + } else if (IsAnOperator(sc.ch)) { + sc.SetState(SCE_R_OPERATOR); + } + } + } + sc.Complete(); +} + +// Store both the current line's fold level and the next lines in the +// level store to make it easy to pick up with each increment +// and to make it possible to fiddle the current level for "} else {". +static void FoldRDoc(unsigned int startPos, int length, int, WordList *[], + Accessor &styler) { + bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; + bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0; + unsigned int endPos = startPos + length; + int visibleChars = 0; + int lineCurrent = styler.GetLine(startPos); + int levelCurrent = SC_FOLDLEVELBASE; + if (lineCurrent > 0) + levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; + int levelMinCurrent = levelCurrent; + int levelNext = levelCurrent; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + for (unsigned int i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (style == SCE_R_OPERATOR) { + if (ch == '{') { + // Measure the minimum before a '{' to allow + // folding on "} else {" + if (levelMinCurrent > levelNext) { + levelMinCurrent = levelNext; + } + levelNext++; + } else if (ch == '}') { + levelNext--; + } + } + if (atEOL) { + int levelUse = levelCurrent; + if (foldAtElse) { + levelUse = levelMinCurrent; + } + int lev = levelUse | levelNext << 16; + if (visibleChars == 0 && foldCompact) + lev |= SC_FOLDLEVELWHITEFLAG; + if (levelUse < levelNext) + lev |= SC_FOLDLEVELHEADERFLAG; + if (lev != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, lev); + } + lineCurrent++; + levelCurrent = levelNext; + levelMinCurrent = levelCurrent; + visibleChars = 0; + } + if (!isspacechar(ch)) + visibleChars++; + } +} + + +static const char * const RWordLists[] = { + "Language Keywords", + "Base / Default package function", + "Other Package Functions", + "Unused", + "Unused", + 0, + }; + + + +LexerModule lmR(SCLEX_R, ColouriseRDoc, "r", FoldRDoc, RWordLists); diff -Naur geany-0.14-orig/scintilla/Makefile.am geany-0.14/scintilla/Makefile.am --- geany-0.14-orig/scintilla/Makefile.am 2008-02-22 04:56:31.000000000 -0500 +++ geany-0.14/scintilla/Makefile.am 2008-09-17 19:15:33.000000000 -0400 @@ -26,7 +26,8 @@ LexSQL.cxx \ LexTCL.cxx \ LexVHDL.cxx \ -LexHaskell.cxx +LexHaskell.cxx \ +LexR.cxx SRCS= \ CallTip.cxx \ diff -Naur geany-0.14-orig/src/editor.c geany-0.14/src/editor.c --- geany-0.14-orig/src/editor.c 2008-04-10 13:46:13.000000000 -0400 +++ geany-0.14/src/editor.c 2008-09-19 18:27:29.000000000 -0400 @@ -2299,6 +2299,13 @@ result = TRUE; break; } + case SCLEX_R: + { + if (prev_style == SCE_R_COMMENT || + style == SCE_R_STRING) + result = TRUE; + break; + } case SCLEX_SQL: { if (style == SCE_SQL_COMMENT || diff -Naur geany-0.14-orig/src/filetypes.c geany-0.14/src/filetypes.c --- geany-0.14-orig/src/filetypes.c 2008-04-11 11:39:44.000000000 -0400 +++ geany-0.14/src/filetypes.c 2008-09-17 22:47:58.000000000 -0400 @@ -79,7 +79,8 @@ FILETYPE_UID_CS, /* 30 */ FILETYPE_UID_BASIC, /* 31 */ FILETYPE_UID_HAXE, /* 32 */ - FILETYPE_UID_REST /* 33 */ + FILETYPE_UID_REST, /* 33 */ + FILETYPE_UID_R /* 34 */ }; @@ -484,6 +485,18 @@ filetypes[GEANY_FILETYPES_ALL]->pattern = utils_strv_new("*", NULL); filetypes[GEANY_FILETYPES_ALL]->comment_open = NULL; filetypes[GEANY_FILETYPES_ALL]->comment_close = NULL; + +#define R + filetypes[GEANY_FILETYPES_R]->id = GEANY_FILETYPES_R; + filetypes[GEANY_FILETYPES_R]->uid = FILETYPE_UID_R; + filetypes[GEANY_FILETYPES_R]->lang = 34; + filetypes[GEANY_FILETYPES_R]->name = g_strdup("R"); + filetypes[GEANY_FILETYPES_R]->title = g_strdup_printf(_("%s script file"), "R"); + filetypes[GEANY_FILETYPES_R]->extension = g_strdup("R"); + filetypes[GEANY_FILETYPES_R]->pattern = utils_strv_new("*.R", "*.r", NULL); + filetypes[GEANY_FILETYPES_R]->comment_open = g_strdup("#"); + filetypes[GEANY_FILETYPES_R]->comment_close = NULL; + } diff -Naur geany-0.14-orig/src/filetypes.h geany-0.14/src/filetypes.h --- geany-0.14-orig/src/filetypes.h 2008-03-05 12:09:57.000000000 -0500 +++ geany-0.14/src/filetypes.h 2008-09-17 19:05:13.000000000 -0400 @@ -58,6 +58,7 @@ GEANY_FILETYPES_PERL, GEANY_FILETYPES_PHP, GEANY_FILETYPES_PYTHON, + GEANY_FILETYPES_R, GEANY_FILETYPES_RUBY, GEANY_FILETYPES_SH, GEANY_FILETYPES_TCL, diff -Naur geany-0.14-orig/src/highlighting.c geany-0.14/src/highlighting.c --- geany-0.14-orig/src/highlighting.c 2008-04-11 11:59:44.000000000 -0400 +++ geany-0.14/src/highlighting.c 2008-09-19 19:16:52.000000000 -0400 @@ -1700,6 +1700,58 @@ } +static void styleset_r_init(gint ft_id, GKeyFile *config, GKeyFile *config_home) +{ + new_style_array(GEANY_FILETYPES_R, 12); + + get_keyfile_hex(config, config_home, "styling", "default", "0x000000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[0]); + get_keyfile_hex(config, config_home, "styling", "comment", "0x0066ff", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[1]); + get_keyfile_hex(config, config_home, "styling", "kword", "0x66ff33", "0xffffff", "true", &style_sets[GEANY_FILETYPES_R].styling[2]); + get_keyfile_hex(config, config_home, "styling", "operator", "0x660000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[3]); + get_keyfile_hex(config, config_home, "styling", "basekword", "0x66ff33", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[4]); + get_keyfile_hex(config, config_home, "styling", "otherkword", "0x66ff33", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[5]); + get_keyfile_hex(config, config_home, "styling", "number", "0xcc00ff", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[6]); + get_keyfile_hex(config, config_home, "styling", "string", "0xcc00ff", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[7]); + get_keyfile_hex(config, config_home, "styling", "string2", "0xcc00ff", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[8]); + get_keyfile_hex(config, config_home, "styling", "identifier", "0x6600ff", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[9]); + get_keyfile_hex(config, config_home, "styling", "infix", "0xcc00ff", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[10]); + get_keyfile_hex(config, config_home, "styling", "infixeol", "0xcc00ff", "0xffffff", "false", &style_sets[GEANY_FILETYPES_R].styling[11]); + + style_sets[GEANY_FILETYPES_R].keywords = g_new(gchar*, 2); + get_keyfile_keywords(config, config_home, "keywords", "primary", GEANY_FILETYPES_R, 0, "require if source array matrix diag solve for data.frame read.table NROW NCOL abs sqrt sum print while function"); + style_sets[GEANY_FILETYPES_R].keywords[1] = NULL; + + get_keyfile_wordchars(config, config_home, + &style_sets[GEANY_FILETYPES_R].wordchars); +} + + +static void styleset_r(ScintillaObject *sci) +{ + const filetype_id ft_id = GEANY_FILETYPES_R; + + styleset_common(sci, 5, ft_id); + + apply_filetype_properties(sci, SCLEX_R, ft_id); + + SSM(sci, SCI_SETKEYWORDS, 0, (sptr_t) style_sets[GEANY_FILETYPES_R].keywords[0]); + + set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_R, 0); + set_sci_style(sci, SCE_R_DEFAULT, GEANY_FILETYPES_R, 0); + set_sci_style(sci, SCE_R_COMMENT, GEANY_FILETYPES_R, 1); + set_sci_style(sci, SCE_R_KWORD, GEANY_FILETYPES_R, 2); + set_sci_style(sci, SCE_R_OPERATOR, GEANY_FILETYPES_R, 3); + set_sci_style(sci, SCE_R_BASEKWORD, GEANY_FILETYPES_R, 4); + set_sci_style(sci, SCE_R_OTHERKWORD, GEANY_FILETYPES_R, 5); + set_sci_style(sci, SCE_R_NUMBER, GEANY_FILETYPES_R, 6); + set_sci_style(sci, SCE_R_STRING, GEANY_FILETYPES_R, 7); + set_sci_style(sci, SCE_R_STRING2, GEANY_FILETYPES_R, 8); + set_sci_style(sci, SCE_R_IDENTIFIER, GEANY_FILETYPES_R, 9); + set_sci_style(sci, SCE_R_INFIX, GEANY_FILETYPES_R, 10); + set_sci_style(sci, SCE_R_INFIXEOL, GEANY_FILETYPES_R, 11); +} + + static void styleset_xml(ScintillaObject *sci) { const filetype_id ft_id = GEANY_FILETYPES_XML; @@ -2975,6 +3027,7 @@ init_styleset_case(GEANY_FILETYPES_TCL, tcl); init_styleset_case(GEANY_FILETYPES_VHDL, vhdl); init_styleset_case(GEANY_FILETYPES_XML, markup); + init_styleset_case(GEANY_FILETYPES_R, r); } } @@ -3027,6 +3080,7 @@ styleset_case(GEANY_FILETYPES_TCL, tcl); styleset_case(GEANY_FILETYPES_VHDL, vhdl); styleset_case(GEANY_FILETYPES_XML, xml); + styleset_case(GEANY_FILETYPES_R, r); default: styleset_case(GEANY_FILETYPES_ALL, none); } diff -Naur geany-0.14-orig/src/templates.c geany-0.14/src/templates.c --- geany-0.14-orig/src/templates.c 2008-02-27 08:17:29.000000000 -0500 +++ geany-0.14/src/templates.c 2008-09-19 18:28:46.000000000 -0400 @@ -408,6 +408,7 @@ case GEANY_FILETYPES_PYTHON: case GEANY_FILETYPES_RUBY: case GEANY_FILETYPES_SH: + case GEANY_FILETYPES_R: case GEANY_FILETYPES_MAKE: case GEANY_FILETYPES_PERL: case GEANY_FILETYPES_DIFF: