Add new filetype 'Gettext translation file' (closes #2131985).

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3018 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2008-09-28 16:32:49 +00:00
parent 22cde627fe
commit 087872260f
13 changed files with 212 additions and 6 deletions

View File

@ -3,6 +3,12 @@
* geany.glade, src/interface.c, src/notebook.c:
Revert previous notebook focus changes as this disables the tab
scroll arrows.
* scintilla/include/SciLexer.h, scintilla/include/Scintilla.iface,
scintilla/KeyWords.cxx, scintilla/LexOthers.cxx, src/templates.c,
src/highlighting.c, src/plugindata.h, src/filetypes.c,
src/filetypes.h, src/editor.c, data/filetype_extensions.conf,
data/filetypes.po:
Add new filetype 'Gettext translation file' (closes #2131985).
2008-09-27 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>

View File

@ -13,7 +13,7 @@ D=*.d;*.di;
F77=*.f;*.for;*.ftn;*.f77;
Fortran=*.f90;*.f95;*.f03;
FreeBasic=*.bas;*.bi;
GLSL=*.glsl;*.frag;*.vert
GLSL=*.glsl;*.frag;*.vert;
Haskell=*.hs;*.lhs;
Haxe=*.hx;
Java=*.java;*.jsp;
@ -40,4 +40,5 @@ Diff=*.diff;*.patch;*.rej;
LaTeX=*.tex;*.sty;*.idx;*.ltx;
reStructuredText=*.rest;*.reST;*.rst;
SQL=*.sql;
Po=*.po;*.pot;
None=*;

45
data/filetypes.po Normal file
View File

@ -0,0 +1,45 @@
# For complete documentation of this file, please see Geany's main documentation
[styling]
# foreground;background;bold;italic
default=0x7f0000;0xffffff;false;false
comment=0x808080;0xffffff;false;false
msgid=0x00007f;0xffffff;true;false
msgid_text=0x00007f;0xffffff;false;false
msgstr=0x7f0000;0xffffff;true;false
msgstr_text=0x7f0000;0xffffff;false;false
msgctxt=0x007f00;0xffffff;true;false
msgctxt_text=0x007f00;0xffffff;false;false
fuzzy=0xffa500;0xffffff;true;false
# the lexer don't support keywords
[settings]
# default extension used when saving files
#extension=po
# 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=
# 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=true
# context action command (please see Geany's main documentation for details)
context_action_cmd=
[build_settings]
# %f will be replaced by the complete filename
# %e will be replaced by the filename without extension
# (use only one of it at one time)
compiler=msgfmt --check --check-accelerators=_ "%f"

View File

@ -167,6 +167,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmPerl);
LINK_LEXER(lmPHP);
LINK_LEXER(lmPHPSCRIPT);
LINK_LEXER(lmPo);
LINK_LEXER(lmProps);
LINK_LEXER(lmPython);
LINK_LEXER(lmR);

View File

@ -24,6 +24,10 @@
using namespace Scintilla;
#endif
static bool strstart(const char *haystack, const char *needle) {
return strncmp(haystack, needle, strlen(needle)) == 0;
}
static bool Is0To9(char ch) {
return (ch >= '0') && (ch <= '9');
}
@ -582,6 +586,77 @@ static void FoldDiffDoc(unsigned int startPos, int length, int, WordList*[], Acc
} while (static_cast<int>(startPos) + length > curLineStart);
}
static void ColourisePoLine(
char *lineBuffer,
unsigned int lengthLine,
unsigned int startLine,
unsigned int endPos,
Accessor &styler) {
unsigned int i = 0;
static unsigned int state = SCE_PO_DEFAULT;
unsigned int state_start = SCE_PO_DEFAULT;
while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
i++;
if (i < lengthLine) {
if (lineBuffer[i] == '#') {
// check if the comment contains any flags ("#, ") and
// then whether the flags contain "fuzzy"
if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
styler.ColourTo(endPos, SCE_PO_FUZZY);
else
styler.ColourTo(endPos, SCE_PO_COMMENT);
} else {
if (lineBuffer[0] == '"') {
// line continuation, use previous style
styler.ColourTo(endPos, state);
return;
// this implicitly also matches "msgid_plural"
} else if (strstart(lineBuffer, "msgid")) {
state_start = SCE_PO_MSGID;
state = SCE_PO_MSGID_TEXT;
} else if (strstart(lineBuffer, "msgstr")) {
state_start = SCE_PO_MSGSTR;
state = SCE_PO_MSGSTR_TEXT;
} else if (strstart(lineBuffer, "msgctxt")) {
state_start = SCE_PO_MSGCTXT;
state = SCE_PO_MSGCTXT_TEXT;
}
if (state_start != SCE_PO_DEFAULT) {
// find the next space
while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
i++;
styler.ColourTo(startLine + i - 1, state_start);
styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
styler.ColourTo(endPos, state);
}
}
} else {
styler.ColourTo(endPos, SCE_PO_DEFAULT);
}
}
static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
char lineBuffer[1024];
styler.StartAt(startPos);
styler.StartSegment(startPos);
unsigned int linePos = 0;
unsigned int startLine = startPos;
for (unsigned int i = startPos; i < startPos + length; i++) {
lineBuffer[linePos++] = styler[i];
if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
// End of line (or of line buffer) met, colourise it
lineBuffer[linePos] = '\0';
ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
linePos = 0;
startLine = i + 1;
}
}
if (linePos > 0) { // Last line does not have ending characters
ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
}
}
static void ColourisePropsLine(
char *lineBuffer,
@ -815,10 +890,6 @@ static void ColouriseMakeDoc(unsigned int startPos, int length, int, WordList *[
}
}
static bool strstart(const char *haystack, const char *needle) {
return strncmp(haystack, needle, strlen(needle)) == 0;
}
static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLine, int &startValue) {
if (lineBuffer[0] == '>') {
// Command or return status
@ -1170,6 +1241,7 @@ 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);

View File

@ -102,6 +102,7 @@
#define SCLEX_MAGIK 87
#define SCLEX_POWERSHELL 88
#define SCLEX_OMS 89
#define SCLEX_PO 90
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1
@ -1234,6 +1235,15 @@
#define SCE_POWERSHELL_KEYWORD 8
#define SCE_POWERSHELL_CMDLET 9
#define SCE_POWERSHELL_ALIAS 10
#define SCE_PO_DEFAULT 0
#define SCE_PO_COMMENT 1
#define SCE_PO_MSGID 2
#define SCE_PO_MSGID_TEXT 3
#define SCE_PO_MSGSTR 4
#define SCE_PO_MSGSTR_TEXT 5
#define SCE_PO_MSGCTXT 6
#define SCE_PO_MSGCTXT_TEXT 7
#define SCE_PO_FUZZY 8
#define SCLEX_ASP 29
#define SCLEX_PHP 30
/*--Autogenerated -- end of section automatically generated from Scintilla.iface*/

View File

@ -1997,6 +1997,7 @@ val SCLEX_ASYMPTOTE=85
val SCLEX_R=86
val SCLEX_MAGIK=87
val SCLEX_POWERSHELL=88
val SCLEX_PO=90
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
# value assigned in sequence from SCLEX_AUTOMATIC+1.
@ -3294,6 +3295,17 @@ val SCE_POWERSHELL_IDENTIFIER=7
val SCE_POWERSHELL_KEYWORD=8
val SCE_POWERSHELL_CMDLET=9
val SCE_POWERSHELL_ALIAS=10
# Lexical state for SCLEX_PO
lex Po=SCLEX_PO SCE_PO_
val SCE_PO_DEFAULT=0
val SCE_PO_COMMENT=1
val SCE_PO_MSGID=2
val SCE_PO_MSGID_TEXT=3
val SCE_PO_MSGSTR=4
val SCE_PO_MSGSTR_TEXT=5
val SCE_PO_MSGCTXT=6
val SCE_PO_MSGCTXT_TEXT=7
val SCE_PO_FUZZY=8
# Events

View File

@ -2793,6 +2793,9 @@ static gboolean is_comment_style(gint lexer, gint style)
case SCLEX_PROPERTIES:
return (style == SCE_PROPS_COMMENT);
case SCLEX_PO:
return (style == SCE_PO_COMMENT);
case SCLEX_LATEX:
return (style == SCE_L_COMMENT);

View File

@ -450,6 +450,17 @@ static void init_builtin_filetypes(void)
ft->comment_close = NULL;
ft->group = GEANY_FILETYPE_GROUP_MISC;
#define PO
ft = filetypes[GEANY_FILETYPES_PO];
ft->lang = -2;
ft->name = g_strdup("Po");
ft->title = g_strdup(_("Gettext translation file"));
ft->extension = g_strdup("po");
ft->pattern = utils_strv_new("*.po", "*.pot", NULL);
ft->comment_open = g_strdup("#");
ft->comment_close = NULL;
ft->group = GEANY_FILETYPE_GROUP_MISC;
#define HAXE
ft = filetypes[GEANY_FILETYPES_HAXE];
ft->lang = 27;

View File

@ -78,6 +78,7 @@ typedef enum
GEANY_FILETYPES_LATEX,
GEANY_FILETYPES_REST,
GEANY_FILETYPES_SQL,
GEANY_FILETYPES_PO,
GEANY_FILETYPES_NONE, /* must be last filetype */
GEANY_MAX_BUILT_IN_FILETYPES /* Use filetypes_array->len instead */

View File

@ -2027,6 +2027,47 @@ static void styleset_css(ScintillaObject *sci)
}
static void styleset_po_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{
new_style_array(GEANY_FILETYPES_PO, 9);
get_keyfile_hex(config, config_home, "styling", "default", "0x7f0000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_PO].styling[0]);
get_keyfile_hex(config, config_home, "styling", "comment", "0x808080", "0xffffff", "false", &style_sets[GEANY_FILETYPES_PO].styling[1]);
get_keyfile_hex(config, config_home, "styling", "msgid", "0x00007f", "0xffffff", "true", &style_sets[GEANY_FILETYPES_PO].styling[2]);
get_keyfile_hex(config, config_home, "styling", "msgid_text", "0x00007f", "0xffffff", "false", &style_sets[GEANY_FILETYPES_PO].styling[3]);
get_keyfile_hex(config, config_home, "styling", "msgstr", "0x7f0000", "0xffffff", "true", &style_sets[GEANY_FILETYPES_PO].styling[4]);
get_keyfile_hex(config, config_home, "styling", "msgstr_text", "0x7f0000", "0xffffff", "false", &style_sets[GEANY_FILETYPES_PO].styling[5]);
get_keyfile_hex(config, config_home, "styling", "msgctxt", "0x007f00", "0xffffff", "true", &style_sets[GEANY_FILETYPES_PO].styling[6]);
get_keyfile_hex(config, config_home, "styling", "msgctxt_text", "0x007f00", "0xffffff", "false", &style_sets[GEANY_FILETYPES_PO].styling[7]);
get_keyfile_hex(config, config_home, "styling", "fuzzy", "0xffa500", "0xffffff", "true", &style_sets[GEANY_FILETYPES_PO].styling[8]);
style_sets[GEANY_FILETYPES_PO].keywords = NULL;
get_keyfile_wordchars(config, config_home,
&style_sets[GEANY_FILETYPES_PO].wordchars);
}
static void styleset_po(ScintillaObject *sci)
{
const filetype_id ft_id = GEANY_FILETYPES_PO;
styleset_common(sci, 5, ft_id);
apply_filetype_properties(sci, SCLEX_PO, ft_id);
set_sci_style(sci, STYLE_DEFAULT, GEANY_FILETYPES_PO, 0);
set_sci_style(sci, SCE_PO_DEFAULT, GEANY_FILETYPES_PO, 0);
set_sci_style(sci, SCE_PO_COMMENT, GEANY_FILETYPES_PO, 1);
set_sci_style(sci, SCE_PO_MSGID, GEANY_FILETYPES_PO, 2);
set_sci_style(sci, SCE_PO_MSGID_TEXT, GEANY_FILETYPES_PO, 3);
set_sci_style(sci, SCE_PO_MSGSTR, GEANY_FILETYPES_PO, 4);
set_sci_style(sci, SCE_PO_MSGSTR_TEXT, GEANY_FILETYPES_PO, 5);
set_sci_style(sci, SCE_PO_MSGCTXT, GEANY_FILETYPES_PO, 6);
set_sci_style(sci, SCE_PO_MSGCTXT_TEXT, GEANY_FILETYPES_PO, 7);
set_sci_style(sci, SCE_PO_FUZZY, GEANY_FILETYPES_PO, 8);
}
static void styleset_conf_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{
new_style_array(GEANY_FILETYPES_CONF, 6);
@ -3102,6 +3143,7 @@ void highlighting_init_styles(gint filetype_idx, GKeyFile *config, GKeyFile *con
init_styleset_case(GEANY_FILETYPES_PASCAL, pascal);
init_styleset_case(GEANY_FILETYPES_PERL, perl);
init_styleset_case(GEANY_FILETYPES_PHP, php);
init_styleset_case(GEANY_FILETYPES_PO, po);
init_styleset_case(GEANY_FILETYPES_PYTHON, python);
init_styleset_case(GEANY_FILETYPES_R, r);
init_styleset_case(GEANY_FILETYPES_RUBY, ruby);
@ -3157,6 +3199,7 @@ void highlighting_set_styles(ScintillaObject *sci, gint filetype_idx)
styleset_case(GEANY_FILETYPES_PASCAL, pascal);
styleset_case(GEANY_FILETYPES_PERL, perl);
styleset_case(GEANY_FILETYPES_PHP, php);
styleset_case(GEANY_FILETYPES_PO, po);
styleset_case(GEANY_FILETYPES_PYTHON, python);
styleset_case(GEANY_FILETYPES_R, r);
styleset_case(GEANY_FILETYPES_RUBY, ruby);

View File

@ -41,7 +41,7 @@
enum {
/** The Application Programming Interface (API) version, incremented
* whenever any plugin data types are modified or appended to. */
GEANY_API_VERSION = 97,
GEANY_API_VERSION = 98,
/** The Application Binary Interface (ABI) version, incremented whenever
* existing fields in the plugin data types have to be changed or reordered. */

View File

@ -534,6 +534,7 @@ static gchar *make_comment_block(const gchar *comment_text, gint filetype_idx, g
case GEANY_FILETYPES_TCL:
case GEANY_FILETYPES_OMS:
case GEANY_FILETYPES_CONF:
case GEANY_FILETYPES_PO:
{
line_prefix = "#";
break;