Kaydet (Commit) 9facea26 authored tarafından Nick Treleaven's avatar Nick Treleaven

Merge unstable branch:

Add reStructuredText scope information for tags (for symbol list
grouping).
Read custom system global tags files from $prefix/share/geany/tags;
Closes #2778923.
Show the number of tags in a user global tags file (instead of the
running total) in the debug message.
Also print debug messages when loading a tag file manually or for
default global tags files e.g. python.tags.
- code:
Move NestingLevel tags code into a separate file, add functions.
- docs:
Add 'Installation prefix' section instead of quoting '/usr/local'
each time.
Update for custom system global tags files.



git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3788 ea778897-0a13-0410-b9d1-a72fbfd435f5
2009-05-12 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/symbols.c, doc/geany.txt, doc/geany.html,
tagmanager/makefile.win32, tagmanager/nestlevel.c,
tagmanager/nestlevel.h, tagmanager/python.c, tagmanager/rest.c,
tagmanager/Makefile.am, wscript:
Merge unstable branch:
Add reStructuredText scope information for tags (for symbol list
grouping).
Read custom system global tags files from $prefix/share/geany/tags;
Closes #2778923.
Show the number of tags in a user global tags file (instead of the
running total) in the debug message.
Also print debug messages when loading a tag file manually or for
default global tags files e.g. python.tags.
- code:
Move NestingLevel tags code into a separate file, add functions.
- docs:
Add 'Installation prefix' section instead of quoting '/usr/local'
each time.
Update for custom system global tags files.
2009-05-11 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* src/highlighting.c:
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -231,6 +231,18 @@ list or one the authors. Sometimes you might need to ask for specific
help from your distro.
Installation prefix
-------------------
If you want to edit any of Geany's system configuration files after
installation you will need to know the installation prefix. Usually this
is not necessary as you can just use user configuration files.
Use the ``--print-prefix`` option to check - see `Command line
options`_. The first path is the prefix.
This is commonly ``/usr`` if you installed from a binary package, or
``/usr/local`` if you build from source.
Usage
......@@ -830,7 +842,7 @@ called ``snippets.conf`` at startup.
The system-wide configuration file can be found in
``$prefix/share/geany``, where ``$prefix`` is the path where Geany is
installed (commonly ``/usr/local``). It is not recommended to edit the
installed (see `Installation prefix`_). It is not recommended to edit the
system-wide file, because it will be overridden when Geany is updated.
To change the settings, copy the file from ``$prefix/share/geany``
......@@ -1217,8 +1229,7 @@ Tags
Geany has built-in functionality for generating tag information (aka
"workspace tags") for supported filetypes when you open a file. You
can also have Geany automatically load external tag files (aka "global
tags files") from its ``~/.config/geany/tags`` directory upon startup, or
manually using *Tools --> Load Tags*.
tags files") upon startup, or manually using *Tools --> Load Tags*.
Geany uses its own tag file format, similar to what ``ctags`` uses
(but is incompatible with ctags). You use Geany to generate global
......@@ -1250,6 +1261,9 @@ You can load a custom global tags file in two ways:
* Using the *Load Tags* command in the Tools menu.
* By creating a directory ``~/.config/geany/tags``, and moving or symlinking
the tags files there before starting Geany.
* By creating a directory ``$prefix/share/geany/tags``, and moving
or symlinking the tags files there before starting Geany.
``$prefix`` is the installation prefix (see `Installation prefix`_).
You can either download these files or generate your own. They have
the format::
......@@ -2432,8 +2446,7 @@ general preference is set. There is also a command-line option,
``-p``, which prevents plugins being loaded. Plugins are scanned in
the following directories:
* ``$prefix/lib/geany`` (``$prefix`` is usually ``/usr/local`` or
``/usr``)
* ``$prefix/lib/geany`` (see `Installation prefix`_)
* ``~/.config/geany/plugins``
Most plugins add menu items to the *Tools* menu when they are loaded.
......@@ -2845,10 +2858,10 @@ file to use default values.
The global configuration file is read from
``$prefix/share/geany/geany.conf`` (where ``$prefix`` is the path where
Geany is installed) when starting Geany and an user configuration
file does not exist. It can contain any settings which are found in
the usual configuration file created by Geany but does not have to
contain all settings.
Geany is installed, see `Installation prefix`_) when starting Geany and
an user configuration file does not exist. It can contain any settings
which are found in the usual configuration file created by Geany but
does not have to contain all settings.
.. note::
This feature is mainly intended for package maintainers or system
......@@ -2868,8 +2881,8 @@ word delimiter characters as well as compiler and linker settings.
The system-wide configuration files can be found in
``$prefix/share/geany`` and are called ``filetypes.$ext``,
where ``$prefix`` is the path where Geany is installed (commonly
``/usr/local``) and $ext is the name of the filetype. For every
where ``$prefix`` is the path where Geany is installed (see
`Installation prefix`_) and $ext is the name of the filetype. For every
filetype there is a corresponding definition file. There is one
exception: ``filetypes.common`` -- this file is for general settings,
which are not specific to a certain filetype. It is not recommended
......@@ -3249,7 +3262,7 @@ filetype using the ``filetype_extensions.conf`` file.
To override the system-wide configuration file, copy it from
``$prefix/share/geany`` to your configuration directory, usually
``~/.config/geany/``. ``$prefix`` is the path where Geany is installed
(commonly ``/usr/local``).
(see `Installation prefix`_).
For example::
......@@ -3444,7 +3457,7 @@ the file ``ui_toolbar.xml``.
To override the system-wide configuration file, copy it from
``$prefix/share/geany`` to your configuration directory, usually
``~/.config/geany/``. ``$prefix`` is the path where Geany is installed
(commonly ``/usr/local``).
(see `Installation prefix`_).
For example::
......
......@@ -87,8 +87,6 @@ static TagFileInfo tag_file_info[GTF_MAX] =
{FALSE, "python.tags"}
};
static gchar *user_tags_dir;
static GPtrArray *top_level_iter_names = NULL;
static struct
......@@ -130,6 +128,33 @@ void symbols_reload_config_files(void)
}
static gsize get_tag_count()
{
GPtrArray *tags = tm_get_workspace()->global_tags;
gsize count = tags ? tags->len : 0;
return count;
}
/* wrapper for tm_workspace_load_global_tags().
* note that the tag count only counts new global tags added - if a tag has the same name,
* currently it replaces the existing tag, so loading a file twice will say 0 tags the 2nd time. */
static gboolean symbols_load_global_tags(const gchar *tags_file, GeanyFiletype *ft)
{
gboolean result;
gsize old_tag_count = get_tag_count();
result = tm_workspace_load_global_tags(tags_file, ft->lang);
if (result)
{
geany_debug("Loaded %s (%s), %u tag(s).", tags_file, ft->name,
get_tag_count() - old_tag_count);
}
return result;
}
/* Ensure that the global tags file(s) for the file_type_idx filetype is loaded.
* This provides autocompletion, calltips, etc. */
void symbols_global_tags_loaded(gint file_type_idx)
......@@ -174,10 +199,8 @@ void symbols_global_tags_loaded(gint file_type_idx)
if (! tfi->tags_loaded)
{
gchar *fname = g_strconcat(app->datadir, G_DIR_SEPARATOR_S, tfi->tag_file, NULL);
gint tm_lang;
tm_lang = filetypes[file_type_idx]->lang;
tm_workspace_load_global_tags(fname, tm_lang);
symbols_load_global_tags(fname, filetypes[file_type_idx]);
tfi->tags_loaded = TRUE;
g_free(fname);
}
......@@ -1376,7 +1399,7 @@ void symbols_show_load_tags_dialog(void)
utf8_fname = utils_get_utf8_from_locale(fname);
ft = detect_global_tags_filetype(utf8_fname);
if (ft != NULL && tm_workspace_load_global_tags(fname, ft->lang))
if (ft != NULL && symbols_load_global_tags(fname, ft))
/* For translators: the first wildcard is the filetype, the second the filename */
ui_set_statusbar(TRUE, _("Loaded %s tags file '%s'."), ft->name, utf8_fname);
else
......@@ -1419,23 +1442,42 @@ static GHashTable *get_tagfile_hash(const GSList *file_list)
}
static void utils_slist_add_path(GSList *list, const gchar *path)
{
GSList *node;
for (node = list; node != NULL; node = g_slist_next(node))
{
setptr(node->data,
g_build_path(G_DIR_SEPARATOR_S, path, node->data, NULL));
}
}
static GHashTable *init_user_tags(void)
{
GSList *file_list;
GSList *file_list = NULL, *list = NULL;
GHashTable *lang_hash;
const gchar *dir;
user_tags_dir = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "tags", NULL);
file_list = utils_get_file_list(user_tags_dir, NULL, NULL);
lang_hash = get_tagfile_hash(file_list);
dir = utils_build_path(app->configdir, "tags", NULL);
/* create the user tags dir for next time if it doesn't exist */
if (! g_file_test(dir, G_FILE_TEST_IS_DIR))
{
utils_mkdir(dir, FALSE);
}
file_list = utils_get_file_list(dir, NULL, NULL);
utils_slist_add_path(file_list, dir);
dir = utils_build_path(app->datadir, "tags", NULL);
list = utils_get_file_list(dir, NULL, NULL);
utils_slist_add_path(list, dir);
file_list = g_slist_concat(file_list, list);
lang_hash = get_tagfile_hash(file_list);
/* don't need to delete list contents because they are now used for hash contents */
g_slist_free(file_list);
/* create the tags dir for next time if it doesn't exist */
if (! g_file_test(user_tags_dir, G_FILE_TEST_IS_DIR))
{
utils_mkdir(user_tags_dir, FALSE);
}
return lang_hash;
}
......@@ -1446,7 +1488,7 @@ static void load_user_tags(filetype_id ft_id)
static GHashTable *lang_hash = NULL;
GList *fnames;
const GList *node;
const GeanyFiletype *ft = filetypes[ft_id];
GeanyFiletype *ft = filetypes[ft_id];
g_return_if_fail(ft_id > 0);
g_return_if_fail(ft_id < GEANY_MAX_BUILT_IN_FILETYPES);
......@@ -1462,16 +1504,9 @@ static void load_user_tags(filetype_id ft_id)
for (node = fnames; node != NULL; node = g_list_next(node))
{
const gint tm_lang = ft->lang;
gchar *fname;
const gchar *fname = node->data;
fname = g_strconcat(user_tags_dir, G_DIR_SEPARATOR_S, node->data, NULL);
if (tm_workspace_load_global_tags(fname, tm_lang))
{
geany_debug("Loaded %s (%s), total tags: %u.", fname, ft->name,
tm_get_workspace()->global_tags->len);
}
g_free(fname);
symbols_load_global_tags(fname, ft);
}
g_list_foreach(fnames, (GFunc) g_free, NULL);
g_list_free(fnames);
......
......@@ -28,6 +28,7 @@ libtagmanager_a_SOURCES =\
entry.h\
get.h\
main.h\
nestlevel.h\
read.h\
parse.h\
strlist.h\
......@@ -66,6 +67,7 @@ libtagmanager_a_SOURCES =\
entry.c\
get.c\
keyword.c\
nestlevel.c\
options.h\
options.c\
parse.c\
......
......@@ -41,7 +41,8 @@ clean:
$(COMPLIB): args.o c.o fortran.o make.o conf.o pascal.o perl.o php.o diff.o vhdl.o lua.o js.o \
actionscript.o nsis.o \
haskell.o haxe.o html.o python.o lregex.o rest.o sh.o ctags.o entry.o get.o keyword.o options.o \
haskell.o haxe.o html.o python.o lregex.o rest.o sh.o ctags.o entry.o get.o keyword.o nestlevel.o \
options.o \
parse.o basic.o read.o sort.o strlist.o latex.o matlab.o docbook.o tcl.o ruby.o asm.o sql.o css.o \
vstring.o regex.o tm_workspace.o tm_work_object.o tm_source_file.o tm_project.o tm_tag.o \
tm_symbol.o tm_file_entry.o tm_tagmanager.o
......
/*
* $Id$
*
* Copyright (c) 1999-2002, Darren Hiebert
* Copyright 2009 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
*
* This source code is released for free distribution under the terms of the
* GNU General Public License.
*
* Defines external interface to scope nesting levels for tags.
*/
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include "main.h"
#include "nestlevel.h"
/*
* FUNCTION DEFINITIONS
*/
extern NestingLevels *nestingLevelsNew(void)
{
NestingLevels *nls = xCalloc (1, NestingLevels);
return nls;
}
extern void nestingLevelsFree(NestingLevels *nls)
{
int i;
for (i = 0; i < nls->allocated; i++)
vStringDelete(nls->levels[i].name);
if (nls->levels) eFree(nls->levels);
eFree(nls);
}
extern void nestingLevelsPush(NestingLevels *nls,
const vString *name, int type)
{
NestingLevel *nl = NULL;
if (nls->n >= nls->allocated)
{
nls->allocated++;
nls->levels = xRealloc(nls->levels,
nls->allocated, NestingLevel);
nls->levels[nls->n].name = vStringNew();
}
nl = &nls->levels[nls->n];
nls->n++;
vStringCopy(nl->name, name);
nl->type = type;
}
extern void nestingLevelsPop(NestingLevels *nls)
{
const NestingLevel *nl = nestingLevelsGetCurrent(nls);
Assert (nl != NULL);
vStringClear(nl->name);
nls->n--;
}
extern NestingLevel *nestingLevelsGetCurrent(NestingLevels *nls)
{
Assert (nls != NULL);
if (nls->n < 1)
return NULL;
return &nls->levels[nls->n - 1];
}
/* vi:set tabstop=4 shiftwidth=4: */
/*
* $Id$
*
* Copyright (c) 1999-2002, Darren Hiebert
* Copyright 2009 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
*
* This source code is released for free distribution under the terms of the
* GNU General Public License.
*
* Defines external interface to scope nesting levels for tags.
*/
#ifndef _NESTLEVEL_H
#define _NESTLEVEL_H
/*
* INCLUDE FILES
*/
#include "general.h" /* must always come first */
#include "vstring.h"
/*
* DATA DECLARATIONS
*/
typedef struct NestingLevel NestingLevel;
typedef struct NestingLevels NestingLevels;
struct NestingLevel
{
int indentation;
vString *name;
int type;
};
struct NestingLevels
{
NestingLevel *levels;
int n; /* number of levels in use */
int allocated;
};
/*
* FUNCTION PROTOTYPES
*/
extern NestingLevels *nestingLevelsNew(void);
extern void nestingLevelsFree(NestingLevels *nls);
extern void nestingLevelsPush(NestingLevels *nls,
const vString *name, int type);
extern void nestingLevelsPop(NestingLevels *nls);
extern NestingLevel *nestingLevelsGetCurrent(NestingLevels *nls);
#endif /* _NESTLEVEL_H */
/* vi:set tabstop=4 shiftwidth=4: */
......@@ -21,6 +21,7 @@
#include "read.h"
#include "main.h"
#include "vstring.h"
#include "nestlevel.h"
/*
* DATA DEFINITIONS
......@@ -36,23 +37,6 @@ static kindOption PythonKinds[] = {
{TRUE, 'v', "variable", "variables"}
};
typedef struct NestingLevel NestingLevel;
typedef struct NestingLevels NestingLevels;
struct NestingLevel
{
int indentation;
vString *name;
boolean is_class;
};
struct NestingLevels
{
NestingLevel *levels;
int n;
int allocated;
};
static char const * const singletriple = "'''";
static char const * const doubletriple = "\"\"\"";
......@@ -294,13 +278,13 @@ static boolean constructParentString(NestingLevels *nls, int indent,
break;
if (prev)
{
if (prev->is_class)
if (prev->type == K_CLASS)
vStringCatS(result, ".");
else
vStringCatS(result, "/");
}
vStringCat(result, nl->name);
is_class = nl->is_class;
is_class = (nl->type == K_CLASS);
prev = nl;
}
return is_class;
......@@ -330,27 +314,8 @@ static void checkParent(NestingLevels *nls, int indent, vString *parent)
}
}
static NestingLevels *newNestingLevels(void)
{
NestingLevels *nls = xCalloc (1, NestingLevels);
return nls;
}
static void freeNestingLevels(NestingLevels *nls)
{
int i;
for (i = 0; i < nls->allocated; i++)
vStringDelete(nls->levels[i].name);
if (nls->levels) eFree(nls->levels);
eFree(nls);
}
/* TODO: This is totally out of place in python.c, but strlist.h is not usable.
* Maybe should just move these three functions to a separate file, even if no
* other parser uses them.
*/
static void addNestingLevel(NestingLevels *nls, int indentation,
vString *name, boolean is_class)
const vString *name, boolean is_class)
{
int i;
NestingLevel *nl = NULL;
......@@ -362,20 +327,16 @@ static void addNestingLevel(NestingLevels *nls, int indentation,
}
if (i == nls->n)
{
if (i >= nls->allocated)
{
nls->allocated++;
nls->levels = xRealloc(nls->levels,
nls->allocated, NestingLevel);
nls->levels[i].name = vStringNew();
}
nestingLevelsPush(nls, name, 0);
nl = nls->levels + i;
}
nls->n = i + 1;
vStringCopy(nl->name, name);
else
{ /* reuse existing slot */
nls->n = i + 1;
vStringCopy(nl->name, name);
}
nl->indentation = indentation;
nl->is_class = is_class;
nl->type = is_class ? K_CLASS : !K_CLASS;
}
/* Return a pointer to the start of the next triple string, or NULL. Store
......@@ -471,7 +432,7 @@ static void findPythonTags (void)
vString *const name = vStringNew ();
vString *const parent = vStringNew();
NestingLevels *const nesting_levels = newNestingLevels();
NestingLevels *const nesting_levels = nestingLevelsNew();
const char *line;
int line_skip = 0;
......@@ -588,7 +549,7 @@ static void findPythonTags (void)
vStringDelete (parent);
vStringDelete (name);
vStringDelete (continuation);
freeNestingLevels (nesting_levels);
nestingLevelsFree (nesting_levels);
}
extern parserDefinition *PythonParser (void)
......
......@@ -19,6 +19,7 @@
#include "parse.h"
#include "read.h"
#include "vstring.h"
#include "nestlevel.h"
/*
* DATA DEFINITIONS
......@@ -40,24 +41,48 @@ static kindOption RestKinds[] = {
static char kindchars[SECTION_COUNT];
static NestingLevels *nestingLevels = NULL;
/*
* FUNCTION DEFINITIONS
*/
static void makeRestTag (const vString* const name,
kindOption* const kinds, const int kind)
static NestingLevel *getNestingLevel(const int kind)
{
NestingLevel *nl;
while (1)
{
nl = nestingLevelsGetCurrent(nestingLevels);
if (nl && nl->type >= kind)
nestingLevelsPop(nestingLevels);
else
break;
}
return nl;
}
static void makeRestTag (const vString* const name, const int kind)
{
if (name != NULL && vStringLength (name) > 0)
const NestingLevel *const nl = getNestingLevel(kind);
if (vStringLength (name) > 0)
{
tagEntryInfo e;
initTagEntry (&e, vStringValue (name));
e.lineNumber--; /* we want the line before the '---' underline chars */
e.kindName = kinds [kind].name;
e.kind = kinds [kind].letter;
e.kindName = RestKinds [kind].name;
e.kind = RestKinds [kind].letter;
if (nl && nl->type < kind)
{
e.extensionFields.scope [0] = RestKinds [nl->type].name;
e.extensionFields.scope [1] = vStringValue (nl->name);
}
makeTagEntry (&e);
}
nestingLevelsPush(nestingLevels, name, kind);
}
......@@ -105,6 +130,7 @@ static void findRestTags (void)
const unsigned char *line;
memset(kindchars, 0, sizeof kindchars);
nestingLevels = nestingLevelsNew();
while ((line = fileReadLine ()) != NULL)
{
......@@ -120,7 +146,7 @@ static void findRestTags (void)
if (kind >= 0)
{
makeRestTag(name, RestKinds, kind);
makeRestTag(name, kind);
continue;
}
}
......@@ -130,6 +156,7 @@ static void findRestTags (void)
vStringTerminate(name);
}
vStringDelete (name);
nestingLevelsFree(nestingLevels);
}
extern parserDefinition* RestParser (void)
......
......@@ -58,7 +58,8 @@ tagmanager_sources = [
'tagmanager/docbook.c', 'tagmanager/entry.c', 'tagmanager/fortran.c', 'tagmanager/get.c',
'tagmanager/haskell.c', 'tagmanager/haxe.c', 'tagmanager/html.c', 'tagmanager/js.c',
'tagmanager/keyword.c', 'tagmanager/latex.c', 'tagmanager/lregex.c', 'tagmanager/lua.c',
'tagmanager/make.c', 'tagmanager/matlab.c', 'tagmanager/nsis.c', 'tagmanager/options.c',
'tagmanager/make.c', 'tagmanager/matlab.c', 'tagmanager/nsis.c',
'tagmanager/nestlevel.c', 'tagmanager/options.c',
'tagmanager/parse.c', 'tagmanager/pascal.c',
'tagmanager/perl.c', 'tagmanager/php.c', 'tagmanager/python.c', 'tagmanager/read.c',
'tagmanager/rest.c', 'tagmanager/ruby.c', 'tagmanager/sh.c', 'tagmanager/sort.c',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment