Parse also sections in configuration files.
Allow whitespace in keys and section names. Remove unused LexConf.cxx. Highlight also space separated key value pairs. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1656 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
parent
7cdacb9ef4
commit
f651b49c18
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
2007-07-02 Enrico Tröger <enrico.troeger@uvena.de>
|
||||
|
||||
* src/symbols.c, tagmanager/conf.c:
|
||||
Parse also sections in configuration files.
|
||||
Allow whitespace in keys and section names.
|
||||
* scintilla/makefile.win32, scintilla/KeyWords.cxx,
|
||||
scintilla/LexConf.cxx, scintilla/Makefile.am:
|
||||
Remove unused LexConf.cxx.
|
||||
* scintilla/LexOthers.cxx:
|
||||
Highlight also space separated key value pairs.
|
||||
|
||||
|
||||
2007-06-29 Enrico Tröger <enrico.troeger@uvena.de>
|
||||
|
||||
* src/dialogs.c:
|
||||
|
@ -147,7 +147,6 @@ int Scintilla_LinkLexers() {
|
||||
LINK_LEXER(lmFreeBasic);
|
||||
LINK_LEXER(lmBatch);
|
||||
LINK_LEXER(lmCaml);
|
||||
LINK_LEXER(lmConf);
|
||||
LINK_LEXER(lmCPP);
|
||||
LINK_LEXER(lmCPPNoCase);
|
||||
LINK_LEXER(lmCss);
|
||||
|
@ -1,188 +0,0 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file LexConf.cxx
|
||||
** Lexer for Apache Configuration Files.
|
||||
**
|
||||
** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000.
|
||||
** i created this lexer because i needed something pretty when dealing
|
||||
** when Apache Configuration files...
|
||||
**/
|
||||
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "PropSet.h"
|
||||
#include "Accessor.h"
|
||||
#include "KeyWords.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#ifdef SCI_NAMESPACE
|
||||
using namespace Scintilla;
|
||||
#endif
|
||||
|
||||
static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
|
||||
{
|
||||
int state = SCE_CONF_DEFAULT;
|
||||
char chNext = styler[startPos];
|
||||
int lengthDoc = startPos + length;
|
||||
// create a buffer large enough to take the largest chunk...
|
||||
char *buffer = new char[length];
|
||||
int bufferCount = 0;
|
||||
|
||||
// this assumes that we have 2 keyword list in conf.properties
|
||||
WordList &directives = *keywordLists[0];
|
||||
WordList ¶ms = *keywordLists[1];
|
||||
|
||||
// go through all provided text segment
|
||||
// using the hand-written state machine shown below
|
||||
styler.StartAt(startPos);
|
||||
styler.StartSegment(startPos);
|
||||
for (int i = startPos; i < lengthDoc; i++) {
|
||||
char ch = chNext;
|
||||
chNext = styler.SafeGetCharAt(i + 1);
|
||||
|
||||
if (styler.IsLeadByte(ch)) {
|
||||
chNext = styler.SafeGetCharAt(i + 2);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
switch(state) {
|
||||
case SCE_CONF_DEFAULT:
|
||||
if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
|
||||
// whitespace is simply ignored here...
|
||||
styler.ColourTo(i,SCE_CONF_DEFAULT);
|
||||
break;
|
||||
} else if( ch == '#' ) {
|
||||
// signals the start of a comment...
|
||||
state = SCE_CONF_COMMENT;
|
||||
styler.ColourTo(i,SCE_CONF_COMMENT);
|
||||
} else if( ch == '.' /*|| ch == '/'*/) {
|
||||
// signals the start of a file...
|
||||
state = SCE_CONF_EXTENSION;
|
||||
styler.ColourTo(i,SCE_CONF_EXTENSION);
|
||||
} else if( ch == '"') {
|
||||
state = SCE_CONF_STRING;
|
||||
styler.ColourTo(i,SCE_CONF_STRING);
|
||||
} else if( ispunct(ch) ) {
|
||||
// signals an operator...
|
||||
// no state jump necessary for this
|
||||
// simple case...
|
||||
styler.ColourTo(i,SCE_CONF_OPERATOR);
|
||||
} else if( isalpha(ch) ) {
|
||||
// signals the start of an identifier
|
||||
bufferCount = 0;
|
||||
buffer[bufferCount++] = static_cast<char>(tolower(ch));
|
||||
state = SCE_CONF_IDENTIFIER;
|
||||
} else if( isdigit(ch) ) {
|
||||
// signals the start of a number
|
||||
bufferCount = 0;
|
||||
buffer[bufferCount++] = ch;
|
||||
//styler.ColourTo(i,SCE_CONF_NUMBER);
|
||||
state = SCE_CONF_NUMBER;
|
||||
} else {
|
||||
// style it the default style..
|
||||
styler.ColourTo(i,SCE_CONF_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_CONF_COMMENT:
|
||||
// if we find a newline here,
|
||||
// we simply go to default state
|
||||
// else continue to work on it...
|
||||
if( ch == '\n' || ch == '\r' ) {
|
||||
state = SCE_CONF_DEFAULT;
|
||||
} else {
|
||||
styler.ColourTo(i,SCE_CONF_COMMENT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_CONF_EXTENSION:
|
||||
// if we find a non-alphanumeric char,
|
||||
// we simply go to default state
|
||||
// else we're still dealing with an extension...
|
||||
if( isalnum(ch) || (ch == '_') ||
|
||||
(ch == '-') || (ch == '$') ||
|
||||
(ch == '/') || (ch == '.') || (ch == '*') )
|
||||
{
|
||||
styler.ColourTo(i,SCE_CONF_EXTENSION);
|
||||
} else {
|
||||
state = SCE_CONF_DEFAULT;
|
||||
chNext = styler[i--];
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_CONF_STRING:
|
||||
// if we find the end of a string char, we simply go to default state
|
||||
// else we're still dealing with an string...
|
||||
if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
|
||||
state = SCE_CONF_DEFAULT;
|
||||
}
|
||||
styler.ColourTo(i,SCE_CONF_STRING);
|
||||
break;
|
||||
|
||||
case SCE_CONF_IDENTIFIER:
|
||||
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
|
||||
if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
|
||||
buffer[bufferCount++] = static_cast<char>(tolower(ch));
|
||||
} else {
|
||||
state = SCE_CONF_DEFAULT;
|
||||
buffer[bufferCount] = '\0';
|
||||
|
||||
// check if the buffer contains a keyword, and highlight it if it is a keyword...
|
||||
if(directives.InList(buffer)) {
|
||||
styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
|
||||
} else if(params.InList(buffer)) {
|
||||
styler.ColourTo(i-1,SCE_CONF_PARAMETER );
|
||||
} else if(strchr(buffer,'/') || strchr(buffer,'.')) {
|
||||
styler.ColourTo(i-1,SCE_CONF_EXTENSION);
|
||||
} else {
|
||||
styler.ColourTo(i-1,SCE_CONF_DEFAULT);
|
||||
}
|
||||
|
||||
// push back the faulty character
|
||||
chNext = styler[i--];
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_CONF_NUMBER:
|
||||
// stay in CONF_NUMBER state until we find a non-numeric
|
||||
if( isdigit(ch) || ch == '.') {
|
||||
buffer[bufferCount++] = ch;
|
||||
} else {
|
||||
state = SCE_CONF_DEFAULT;
|
||||
buffer[bufferCount] = '\0';
|
||||
|
||||
// Colourize here...
|
||||
if( strchr(buffer,'.') ) {
|
||||
// it is an IP address...
|
||||
styler.ColourTo(i-1,SCE_CONF_IP);
|
||||
} else {
|
||||
// normal number
|
||||
styler.ColourTo(i-1,SCE_CONF_NUMBER);
|
||||
}
|
||||
|
||||
// push back a character
|
||||
chNext = styler[i--];
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
delete []buffer;
|
||||
}
|
||||
|
||||
static const char * const confWordListDesc[] = {
|
||||
"Directives",
|
||||
"Parameters",
|
||||
0
|
||||
};
|
||||
|
||||
LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);
|
@ -594,7 +594,8 @@ static void ColourisePropsLine(
|
||||
while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
|
||||
i++;
|
||||
if (i < lengthLine) {
|
||||
if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';') {
|
||||
if (lineBuffer[i] == '#' || lineBuffer[i] == '!' || lineBuffer[i] == ';' ||
|
||||
(i < (lengthLine - 1) && lineBuffer[i] == '/' && lineBuffer[i+1] == '/')) {
|
||||
styler.ColourTo(endPos, SCE_PROPS_COMMENT);
|
||||
} else if (lineBuffer[i] == '[') {
|
||||
styler.ColourTo(endPos, SCE_PROPS_SECTION);
|
||||
@ -605,9 +606,9 @@ static void ColourisePropsLine(
|
||||
styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
|
||||
} else {
|
||||
// Search for the '=' character
|
||||
while ((i < lengthLine) && (lineBuffer[i] != '='))
|
||||
while ((i < lengthLine) && ! (lineBuffer[i] == '=' || isspacechar(lineBuffer[i])))
|
||||
i++;
|
||||
if ((i < lengthLine) && (lineBuffer[i] == '=')) {
|
||||
if ((i < lengthLine) && (lineBuffer[i] == '=' || isspacechar(lineBuffer[i]))) {
|
||||
styler.ColourTo(startLine + i - 1, SCE_PROPS_KEY);
|
||||
styler.ColourTo(startLine + i, SCE_PROPS_ASSIGNMENT);
|
||||
styler.ColourTo(endPos, SCE_PROPS_DEFAULT);
|
||||
|
@ -14,7 +14,6 @@ LexBash.cxx \
|
||||
LexOMS.cxx \
|
||||
LexCPP.cxx \
|
||||
LexCaml.cxx \
|
||||
LexConf.cxx \
|
||||
LexCrontab.cxx \
|
||||
LexCSS.cxx \
|
||||
LexD.cxx \
|
||||
|
@ -60,7 +60,7 @@ MARSHALLER=scintilla-marshal.o
|
||||
#++Autogenerated -- run src/LexGen.py to regenerate
|
||||
#**LEXOBJS=\\\n\(\*.o \)
|
||||
LEXOBJS=\
|
||||
LexBash.o LexAsm.o LexCSS.o LexConf.o LexCPP.o LexCrontab.o LexHTML.o LexOthers.o LexPascal.o \
|
||||
LexBash.o LexAsm.o LexCSS.o LexCPP.o LexCrontab.o LexHTML.o LexOthers.o LexPascal.o \
|
||||
LexPerl.o LexPython.o LexSQL.o LexCaml.o LexOMS.o LexTCL.o LexRuby.o LexFortran.o LexVHDL.o \
|
||||
LexD.o LexLua.o LexHaskell.o LexBasic.o
|
||||
#--Autogenerated -- end of automatically generated section
|
||||
|
@ -470,6 +470,12 @@ static void init_tag_list(gint idx)
|
||||
&tv_iters.tag_function, _("Functions"),
|
||||
NULL);
|
||||
break;
|
||||
case GEANY_FILETYPES_CONF:
|
||||
tag_list_add_groups(tag_store,
|
||||
&tv_iters.tag_namespace, _("Sections"),
|
||||
&tv_iters.tag_macro, _("Keys"),
|
||||
NULL);
|
||||
break;
|
||||
case GEANY_FILETYPES_LATEX:
|
||||
{
|
||||
tag_list_add_groups(tag_store,
|
||||
|
@ -23,11 +23,13 @@
|
||||
* DATA DEFINITIONS
|
||||
*/
|
||||
typedef enum {
|
||||
K_NAMESPACE,
|
||||
K_MACRO
|
||||
} shKind;
|
||||
} confKind;
|
||||
|
||||
static kindOption ConfKinds [] = {
|
||||
{ TRUE, 'm', "macro", "macros"}
|
||||
{ TRUE, 'n', "namespace", "sections"},
|
||||
{ TRUE, 'm', "macro", "keys"}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -36,7 +38,8 @@ static kindOption ConfKinds [] = {
|
||||
|
||||
static boolean isIdentifier (int c)
|
||||
{
|
||||
return (boolean)(isalnum (c) || c == '_');
|
||||
// allow whitespace within keys and sections
|
||||
return (boolean)(isalnum (c) || isspace (c) || c == '_');
|
||||
}
|
||||
|
||||
static void findConfTags (void)
|
||||
@ -46,42 +49,54 @@ static void findConfTags (void)
|
||||
|
||||
while ((line = fileReadLine ()) != NULL)
|
||||
{
|
||||
const unsigned char* cp = line;
|
||||
boolean possible = TRUE;
|
||||
const unsigned char* cp = line;
|
||||
boolean possible = TRUE;
|
||||
|
||||
while (isspace ((int) *cp))
|
||||
++cp;
|
||||
if (*cp == '#')
|
||||
continue;
|
||||
|
||||
while (*cp != '\0')
|
||||
{
|
||||
/* We look for any sequence of identifier characters following
|
||||
* either a white space or a colon and followed by either = or :=
|
||||
*/
|
||||
if (possible && isIdentifier ((int) *cp))
|
||||
{
|
||||
while (isIdentifier ((int) *cp))
|
||||
{
|
||||
vStringPut (name, (int) *cp);
|
||||
++cp;
|
||||
}
|
||||
vStringTerminate (name);
|
||||
while (isspace ((int) *cp))
|
||||
++cp;
|
||||
if ( *cp == ':')
|
||||
++cp;
|
||||
if ( *cp == '=')
|
||||
makeSimpleTag (name, ConfKinds, K_MACRO);
|
||||
vStringClear (name);
|
||||
}
|
||||
else if (isspace ((int) *cp) || *cp == ':')
|
||||
possible = TRUE;
|
||||
else
|
||||
possible = FALSE;
|
||||
if (*cp != '\0')
|
||||
++cp;
|
||||
}
|
||||
++cp;
|
||||
if (*cp == '#' || (*cp != '\0' && *cp == '/' && *(cp+1) == '/'))
|
||||
continue;
|
||||
|
||||
/* look for a section */
|
||||
if (*cp != '\0' && *cp == '[')
|
||||
{
|
||||
++cp;
|
||||
while (*cp != '\0' && *cp != ']')
|
||||
{
|
||||
vStringPut (name, (int) *cp);
|
||||
++cp;
|
||||
}
|
||||
vStringTerminate (name);
|
||||
makeSimpleTag (name, ConfKinds, K_NAMESPACE);
|
||||
vStringClear (name);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (*cp != '\0')
|
||||
{
|
||||
/* We look for any sequence of identifier characters following a white space */
|
||||
if (possible && isIdentifier ((int) *cp))
|
||||
{
|
||||
while (isIdentifier ((int) *cp))
|
||||
{
|
||||
vStringPut (name, (int) *cp);
|
||||
++cp;
|
||||
}
|
||||
vStringTerminate (name);
|
||||
while (isspace ((int) *cp))
|
||||
++cp;
|
||||
if (*cp == '=')
|
||||
makeSimpleTag (name, ConfKinds, K_MACRO);
|
||||
vStringClear (name);
|
||||
}
|
||||
else if (isspace ((int) *cp))
|
||||
possible = TRUE;
|
||||
else
|
||||
possible = FALSE;
|
||||
|
||||
if (*cp != '\0')
|
||||
++cp;
|
||||
}
|
||||
}
|
||||
vStringDelete (name);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user