2006-05-21 18:11:05 -05:00
|
|
|
/*
|
2005-10-17 05:23:40 +00:00
|
|
|
* moolangmgr.c
|
|
|
|
*
|
2006-02-23 14:03:17 +00:00
|
|
|
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
2005-10-17 05:23:40 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* See COPYING file that comes with this distribution.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define MOOEDIT_COMPILATION
|
|
|
|
#include "mooedit/moolangmgr.h"
|
|
|
|
#include "mooedit/moolang-strings.h"
|
|
|
|
#include "mooedit/moolang-parser.h"
|
|
|
|
#include "mooedit/mooeditprefs.h"
|
|
|
|
#include "mooutils/xdgmime/xdgmime.h"
|
|
|
|
#include "mooutils/mooprefs.h"
|
|
|
|
#include "mooutils/moomarshals.h"
|
2006-04-06 01:16:29 -05:00
|
|
|
#include "mooutils/mooutils-misc.h"
|
2005-11-30 16:46:02 +00:00
|
|
|
#include "mooutils/moocompat.h"
|
2005-10-17 05:23:40 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define LANG_FILE_SUFFIX ".lang"
|
|
|
|
#define LANG_FILE_SUFFIX_LEN 5
|
|
|
|
#define STYLES_FILE_SUFFIX ".styles"
|
|
|
|
#define STYLES_FILE_SUFFIX_LEN 7
|
|
|
|
#define EXTENSION_SEPARATOR ";"
|
|
|
|
|
|
|
|
|
|
|
|
static void moo_lang_mgr_finalize (GObject *object);
|
|
|
|
|
|
|
|
|
|
|
|
/* MOO_TYPE_LANG_MGR */
|
|
|
|
G_DEFINE_TYPE (MooLangMgr, moo_lang_mgr, G_TYPE_OBJECT)
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_lang_mgr_class_init (MooLangMgrClass *klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
2006-06-26 05:47:38 -05:00
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
gobject_class->finalize = moo_lang_mgr_finalize;
|
2006-06-26 05:47:38 -05:00
|
|
|
|
2006-08-15 03:21:44 -05:00
|
|
|
_moo_signal_new_cb ("loaded",
|
|
|
|
G_OBJECT_CLASS_TYPE (klass),
|
|
|
|
G_SIGNAL_RUN_LAST,
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
_moo_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
2006-05-04 01:40:54 -05:00
|
|
|
}
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
static void
|
|
|
|
string_list_free (gpointer list)
|
|
|
|
{
|
|
|
|
g_slist_foreach (list, (GFunc) g_free, NULL);
|
|
|
|
g_slist_free (list);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_lang_mgr_init (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
mgr->lang_names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
mgr->schemes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
|
|
|
mgr->active_scheme = moo_text_style_scheme_new_default ();
|
|
|
|
g_hash_table_insert (mgr->schemes, g_strdup (mgr->active_scheme->name),
|
|
|
|
mgr->active_scheme);
|
|
|
|
mgr->langs = NULL;
|
|
|
|
mgr->dirs_read = FALSE;
|
2006-05-04 01:40:54 -05:00
|
|
|
|
|
|
|
mgr->extensions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
|
|
g_free, string_list_free);
|
|
|
|
mgr->mime_types = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
|
|
g_free, string_list_free);
|
|
|
|
|
|
|
|
mgr->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
|
|
|
_moo_lang_mgr_load_config (mgr);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooLangMgr*
|
|
|
|
moo_lang_mgr_new (void)
|
|
|
|
{
|
|
|
|
return g_object_new (MOO_TYPE_LANG_MGR, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_lang_mgr_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
MooLangMgr *mgr = MOO_LANG_MGR (object);
|
|
|
|
|
|
|
|
g_slist_foreach (mgr->lang_dirs, (GFunc) g_free, NULL);
|
|
|
|
g_slist_free (mgr->lang_dirs);
|
|
|
|
|
|
|
|
g_slist_foreach (mgr->langs, (GFunc) _moo_lang_free, NULL);
|
|
|
|
g_slist_free (mgr->langs);
|
|
|
|
|
|
|
|
g_hash_table_destroy (mgr->lang_names);
|
|
|
|
g_hash_table_destroy (mgr->schemes);
|
|
|
|
mgr->active_scheme = NULL;
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
g_hash_table_destroy (mgr->mime_types);
|
|
|
|
g_hash_table_destroy (mgr->extensions);
|
|
|
|
|
|
|
|
g_hash_table_destroy (mgr->config);
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
G_OBJECT_CLASS(moo_lang_mgr_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-06 01:16:29 -05:00
|
|
|
static void
|
2005-10-17 05:23:40 +00:00
|
|
|
moo_lang_mgr_add_dir (MooLangMgr *mgr,
|
|
|
|
const char *dir)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
g_return_if_fail (dir != NULL);
|
|
|
|
g_return_if_fail (!mgr->dirs_read);
|
|
|
|
mgr->lang_dirs = g_slist_append (mgr->lang_dirs, g_strdup (dir));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
parse_bool (const char *string,
|
|
|
|
gboolean *val)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (string != NULL && val != NULL, FALSE);
|
|
|
|
if (!g_ascii_strcasecmp (string, "true") ||
|
|
|
|
!g_ascii_strcasecmp (string, "yes") ||
|
|
|
|
!strcmp (string, "1"))
|
|
|
|
{
|
|
|
|
*val = TRUE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else if (!g_ascii_strcasecmp (string, "false") ||
|
|
|
|
!g_ascii_strcasecmp (string, "no") ||
|
|
|
|
!strcmp (string, "0"))
|
|
|
|
{
|
|
|
|
*val = FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_warning ("%s: could not get boolean value from '%s'",
|
|
|
|
G_STRLOC, string);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
parse_color (const char *string,
|
|
|
|
GdkColor *val)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (string != NULL && val != NULL, FALSE);
|
|
|
|
|
|
|
|
if (gdk_color_parse (string, val))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
g_warning ("%s: could not get color value from '%s'",
|
|
|
|
G_STRLOC, string);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static MooTextStyle*
|
|
|
|
style_new_from_markup (MooMarkupNode *node,
|
|
|
|
gboolean modified)
|
|
|
|
{
|
|
|
|
GdkColor foreground, background;
|
|
|
|
gboolean bold, italic, underline, strikethrough;
|
|
|
|
const char *fg_prop, *bg_prop, *bold_prop, *italic_prop;
|
|
|
|
const char *underline_prop, *strikethrough_prop;
|
|
|
|
MooTextStyleMask mask = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail (node != NULL, NULL);
|
|
|
|
|
|
|
|
fg_prop = moo_markup_get_prop (node, STYLE_FOREGROUND_PROP);
|
|
|
|
bg_prop = moo_markup_get_prop (node, STYLE_BACKGROUND_PROP);
|
|
|
|
bold_prop = moo_markup_get_prop (node, STYLE_BOLD_PROP);
|
|
|
|
italic_prop = moo_markup_get_prop (node, STYLE_ITALIC_PROP);
|
|
|
|
underline_prop = moo_markup_get_prop (node, STYLE_UNDERLINE_PROP);
|
|
|
|
strikethrough_prop = moo_markup_get_prop (node, STYLE_STRIKETHROUGH_PROP);
|
|
|
|
|
|
|
|
if (bold_prop && parse_bool (bold_prop, &bold))
|
|
|
|
mask |= MOO_TEXT_STYLE_BOLD;
|
|
|
|
if (italic_prop && parse_bool (italic_prop, &italic))
|
|
|
|
mask |= MOO_TEXT_STYLE_ITALIC;
|
|
|
|
if (underline_prop && parse_bool (underline_prop, &underline))
|
|
|
|
mask |= MOO_TEXT_STYLE_UNDERLINE;
|
|
|
|
if (strikethrough_prop && parse_bool (strikethrough_prop, &strikethrough))
|
|
|
|
mask |= MOO_TEXT_STYLE_STRIKETHROUGH;
|
|
|
|
if (fg_prop && parse_color (fg_prop, &foreground))
|
|
|
|
mask |= MOO_TEXT_STYLE_FOREGROUND;
|
|
|
|
if (bg_prop && parse_color (bg_prop, &background))
|
|
|
|
mask |= MOO_TEXT_STYLE_BACKGROUND;
|
|
|
|
|
|
|
|
return moo_text_style_new (NULL,
|
|
|
|
&foreground, &background,
|
|
|
|
bold, italic, underline,
|
|
|
|
strikethrough, mask, modified);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
load_language_node (MooTextStyleScheme *scheme,
|
|
|
|
MooMarkupNode *node)
|
|
|
|
{
|
|
|
|
MooMarkupNode *child;
|
|
|
|
const char *lang_name;
|
|
|
|
|
|
|
|
g_return_if_fail (node != NULL && node->name != NULL && !strcmp (node->name, LANGUAGE_ELM));
|
|
|
|
g_return_if_fail (scheme != NULL);
|
|
|
|
|
|
|
|
lang_name = moo_markup_get_prop (node, LANG_NAME_PROP);
|
|
|
|
g_return_if_fail (lang_name && lang_name[0]);
|
|
|
|
|
|
|
|
for (child = node->children; child != NULL; child = child->next)
|
|
|
|
{
|
|
|
|
MooTextStyle *style;
|
|
|
|
const char *style_name;
|
|
|
|
|
|
|
|
if (!MOO_MARKUP_IS_ELEMENT (child))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp (child->name, STYLE_ELM))
|
|
|
|
{
|
|
|
|
g_warning ("%s: invalid element '%s'", G_STRLOC, child->name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
style_name = moo_markup_get_prop (child, STYLE_NAME_PROP);
|
|
|
|
|
|
|
|
if (!style_name || !style_name[0])
|
|
|
|
{
|
|
|
|
g_warning ("%s: style name absent", G_STRLOC);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
style = style_new_from_markup (child, TRUE);
|
|
|
|
|
|
|
|
if (!style)
|
|
|
|
{
|
|
|
|
g_critical ("%s: could not parse style node", G_STRLOC);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
moo_text_style_scheme_compose (scheme, lang_name, style_name, style);
|
|
|
|
moo_text_style_free (style);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-08 22:46:03 +00:00
|
|
|
void
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_lang_mgr_set_active_scheme (MooLangMgr *mgr,
|
|
|
|
const char *name)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
MooTextStyleScheme *scheme;
|
|
|
|
|
2005-12-08 22:46:03 +00:00
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
if (!name)
|
|
|
|
name = SCHEME_DEFAULT;
|
|
|
|
|
|
|
|
scheme = g_hash_table_lookup (mgr->schemes, name);
|
|
|
|
|
|
|
|
if (!scheme)
|
|
|
|
scheme = g_hash_table_lookup (mgr->schemes, SCHEME_DEFAULT);
|
|
|
|
|
|
|
|
g_return_if_fail (scheme != NULL);
|
|
|
|
mgr->active_scheme = scheme;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-08 22:46:03 +00:00
|
|
|
static void
|
|
|
|
moo_lang_mgr_choose_scheme (MooLangMgr *mgr,
|
|
|
|
MooMarkupNode *node)
|
|
|
|
{
|
|
|
|
const char *name = moo_markup_get_prop (node, DEFAULT_SCHEME_PROP);
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_lang_mgr_set_active_scheme (mgr, name);
|
2005-12-08 22:46:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
static void
|
|
|
|
moo_lang_mgr_load_styles (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
MooMarkupDoc *xml;
|
|
|
|
MooMarkupNode *root, *child;
|
|
|
|
|
|
|
|
xml = moo_prefs_get_markup ();
|
|
|
|
g_return_if_fail (xml != NULL);
|
|
|
|
|
|
|
|
root = moo_markup_get_element (MOO_MARKUP_NODE (xml),
|
|
|
|
MOO_STYLES_PREFS_PREFIX);
|
|
|
|
|
|
|
|
if (!root)
|
|
|
|
return;
|
|
|
|
|
|
|
|
moo_lang_mgr_choose_scheme (mgr, root);
|
|
|
|
|
|
|
|
for (child = root->children; child != NULL; child = child->next)
|
|
|
|
{
|
|
|
|
MooMarkupNode *grand_child;
|
|
|
|
MooTextStyleScheme *scheme;
|
|
|
|
const char *scheme_name;
|
|
|
|
|
|
|
|
if (!MOO_MARKUP_IS_ELEMENT (child))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp (child->name, SCHEME_ELM))
|
|
|
|
{
|
|
|
|
g_warning ("%s: invalid element '%s'", G_STRLOC, child->name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
scheme_name = moo_markup_get_prop (child, SCHEME_NAME_PROP);
|
|
|
|
|
|
|
|
if (!scheme_name || !scheme_name[0])
|
|
|
|
{
|
|
|
|
g_warning ("%s: scheme name missing", G_STRLOC);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
scheme = g_hash_table_lookup (mgr->schemes, scheme_name);
|
|
|
|
|
|
|
|
if (!scheme)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (grand_child = child->children; grand_child != NULL; grand_child = grand_child->next)
|
|
|
|
{
|
|
|
|
if (!MOO_MARKUP_IS_ELEMENT (grand_child))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!strcmp (grand_child->name, LANGUAGE_ELM))
|
|
|
|
{
|
|
|
|
load_language_node (scheme, grand_child);
|
|
|
|
}
|
|
|
|
else if (!strcmp (grand_child->name, DEFAULT_STYLE_ELM))
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
MooTextStyle *style;
|
|
|
|
|
|
|
|
name = moo_markup_get_prop (grand_child, STYLE_NAME_PROP);
|
|
|
|
|
|
|
|
if (!name || !name[0])
|
|
|
|
{
|
|
|
|
g_warning ("%s: style name absent", G_STRLOC);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
style = style_new_from_markup (grand_child, TRUE);
|
|
|
|
|
|
|
|
if (!style)
|
|
|
|
{
|
|
|
|
g_critical ("%s: could not parse style node", G_STRLOC);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
moo_text_style_scheme_compose (scheme, NULL, name, style);
|
|
|
|
moo_text_style_free (style);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_warning ("%s: invalid element '%s'", G_STRLOC, grand_child->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static GSList*
|
|
|
|
read_files (MooLangMgr *mgr,
|
|
|
|
GHashTable *lang_xml_names)
|
|
|
|
{
|
|
|
|
GSList *l;
|
|
|
|
GSList *lang_xml_list = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (mgr != NULL, NULL);
|
|
|
|
g_return_val_if_fail (lang_xml_names != NULL, NULL);
|
|
|
|
|
|
|
|
if (!mgr->lang_dirs)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (l = mgr->lang_dirs; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
const char *dirname = l->data, *entry;
|
|
|
|
GDir *dir;
|
|
|
|
|
|
|
|
dir = g_dir_open (dirname, 0, NULL);
|
|
|
|
|
|
|
|
if (!dir)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
while ((entry = g_dir_read_name (dir)))
|
|
|
|
{
|
|
|
|
guint entry_len = strlen (entry);
|
|
|
|
|
|
|
|
if (entry_len > LANG_FILE_SUFFIX_LEN &&
|
|
|
|
!strcmp (entry + (entry_len - LANG_FILE_SUFFIX_LEN), LANG_FILE_SUFFIX))
|
|
|
|
{
|
|
|
|
char *filename;
|
|
|
|
LangXML *lang, *old_lang;
|
|
|
|
|
|
|
|
filename = g_build_filename (dirname, entry, NULL);
|
2006-04-28 20:22:03 -05:00
|
|
|
lang = _moo_lang_parse_file (filename);
|
2005-10-17 05:23:40 +00:00
|
|
|
g_free (filename);
|
|
|
|
|
|
|
|
if (!lang)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
old_lang = g_hash_table_lookup (lang_xml_names, lang->name);
|
|
|
|
|
|
|
|
if (old_lang)
|
|
|
|
{
|
|
|
|
g_message ("%s: loading another instance of lang '%s'",
|
|
|
|
G_STRLOC, lang->name);
|
|
|
|
lang_xml_list = g_slist_remove (lang_xml_list, old_lang);
|
2006-04-28 20:22:03 -05:00
|
|
|
_moo_lang_xml_free (old_lang);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
lang_xml_list = g_slist_append (lang_xml_list, lang);
|
|
|
|
g_hash_table_insert (lang_xml_names, g_strdup (lang->name), lang);
|
|
|
|
}
|
|
|
|
else if (entry_len > STYLES_FILE_SUFFIX_LEN &&
|
|
|
|
!strcmp (entry + (entry_len - STYLES_FILE_SUFFIX_LEN), STYLES_FILE_SUFFIX))
|
|
|
|
{
|
|
|
|
char *filename;
|
|
|
|
MooTextStyleScheme *scheme;
|
|
|
|
|
|
|
|
filename = g_build_filename (dirname, entry, NULL);
|
2006-04-28 20:22:03 -05:00
|
|
|
scheme = _moo_text_style_scheme_parse_file (filename, NULL); /* XXX */
|
2005-10-17 05:23:40 +00:00
|
|
|
g_free (filename);
|
|
|
|
|
|
|
|
if (!scheme)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (g_hash_table_lookup (mgr->schemes, scheme->name))
|
|
|
|
{
|
|
|
|
g_message ("%s: loading another instance of scheme '%s'",
|
|
|
|
G_STRLOC, scheme->name);
|
|
|
|
if (!strcmp (mgr->active_scheme->name, scheme->name))
|
|
|
|
mgr->active_scheme = scheme;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX base scheme */
|
|
|
|
|
|
|
|
g_hash_table_insert (mgr->schemes, g_strdup (scheme->name), scheme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_dir_close (dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
return lang_xml_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static GSList*
|
|
|
|
check_external_refs (GSList *lang_xml_list,
|
|
|
|
GHashTable *lang_xml_names)
|
|
|
|
{
|
|
|
|
gboolean again = TRUE;
|
|
|
|
|
|
|
|
while (again)
|
|
|
|
{
|
|
|
|
GSList *l;
|
|
|
|
|
|
|
|
again = FALSE;
|
|
|
|
|
|
|
|
for (l = lang_xml_list; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
GSList *ref_link;
|
|
|
|
LangXML *xml = l->data;
|
|
|
|
gboolean valid = TRUE;
|
|
|
|
|
|
|
|
for (ref_link = xml->external_refs; ref_link != NULL; ref_link = ref_link->next)
|
|
|
|
{
|
|
|
|
CrossRef *ref = ref_link->data;
|
|
|
|
LangXML *ref_lang;
|
|
|
|
|
|
|
|
g_assert (ref->lang != NULL);
|
|
|
|
|
|
|
|
ref_lang = g_hash_table_lookup (lang_xml_names, ref->lang);
|
|
|
|
|
|
|
|
if (!ref_lang)
|
|
|
|
{
|
|
|
|
g_warning ("%s: invalid reference to lang '%s' in lang '%s'",
|
|
|
|
G_STRLOC, ref->lang, xml->name);
|
|
|
|
g_hash_table_remove (lang_xml_names, xml->name);
|
|
|
|
lang_xml_list = g_slist_remove (lang_xml_list, xml);
|
2006-04-28 20:22:03 -05:00
|
|
|
_moo_lang_xml_free (xml);
|
2005-10-17 05:23:40 +00:00
|
|
|
valid = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!g_hash_table_lookup (ref_lang->context_names, ref->name))
|
|
|
|
{
|
|
|
|
g_warning ("%s: lang '%s' does not contain context '%s', referenced from lang '%s'",
|
|
|
|
G_STRLOC, ref->lang, ref->name, xml->name);
|
|
|
|
g_hash_table_remove (lang_xml_names, xml->name);
|
|
|
|
lang_xml_list = g_slist_remove (lang_xml_list, xml);
|
2006-04-28 20:22:03 -05:00
|
|
|
_moo_lang_xml_free (xml);
|
2005-10-17 05:23:40 +00:00
|
|
|
valid = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!valid)
|
|
|
|
{
|
|
|
|
again = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return lang_xml_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_lang_build_contexts (MooLang *lang,
|
|
|
|
LangXML *xml)
|
|
|
|
{
|
|
|
|
GSList *l;
|
|
|
|
|
2005-11-17 07:04:35 +00:00
|
|
|
g_assert (!strcmp (lang->display_name, xml->name));
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
for (l = xml->syntax->contexts; l != NULL; l = l->next)
|
|
|
|
{
|
2006-06-17 05:38:44 -05:00
|
|
|
ContextXML *ctx_xml;
|
|
|
|
G_GNUC_UNUSED MooContext *ctx;
|
|
|
|
ctx_xml = l->data;
|
|
|
|
ctx = _moo_lang_add_context (lang, ctx_xml->name, ctx_xml->style);
|
2005-10-17 05:23:40 +00:00
|
|
|
g_assert (ctx != NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static MooTextStyle*
|
|
|
|
style_new_from_xml (StyleXML *xml)
|
|
|
|
{
|
|
|
|
GdkColor foreground, background;
|
|
|
|
gboolean bold, italic, underline, strikethrough;
|
|
|
|
MooTextStyleMask mask = 0;
|
|
|
|
|
|
|
|
g_return_val_if_fail (xml != NULL, NULL);
|
|
|
|
|
|
|
|
if (xml->bold && parse_bool (xml->bold, &bold))
|
|
|
|
mask |= MOO_TEXT_STYLE_BOLD;
|
|
|
|
if (xml->italic && parse_bool (xml->italic, &italic))
|
|
|
|
mask |= MOO_TEXT_STYLE_ITALIC;
|
|
|
|
if (xml->underline && parse_bool (xml->underline, &underline))
|
|
|
|
mask |= MOO_TEXT_STYLE_UNDERLINE;
|
|
|
|
if (xml->strikethrough && parse_bool (xml->strikethrough, &strikethrough))
|
|
|
|
mask |= MOO_TEXT_STYLE_STRIKETHROUGH;
|
|
|
|
if (xml->foreground && parse_color (xml->foreground, &foreground))
|
|
|
|
mask |= MOO_TEXT_STYLE_FOREGROUND;
|
|
|
|
if (xml->background && parse_color (xml->background, &background))
|
|
|
|
mask |= MOO_TEXT_STYLE_BACKGROUND;
|
|
|
|
|
|
|
|
return moo_text_style_new (xml->default_style,
|
|
|
|
&foreground, &background,
|
|
|
|
bold, italic, underline,
|
|
|
|
strikethrough, mask, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
static GSList *
|
|
|
|
parse_mime_types (const char *mimetypes)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
2006-05-04 01:40:54 -05:00
|
|
|
char *copy;
|
|
|
|
GSList *list = NULL;
|
2005-10-17 05:23:40 +00:00
|
|
|
char **pieces, **p;
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
if (!mimetypes || !mimetypes[0])
|
|
|
|
return NULL;
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
copy = g_strstrip (g_strdup (mimetypes));
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
pieces = g_strsplit (copy, EXTENSION_SEPARATOR, 0);
|
|
|
|
g_return_val_if_fail (pieces != NULL, NULL);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
for (p = pieces; *p; p++)
|
2006-05-04 01:40:54 -05:00
|
|
|
if (**p)
|
|
|
|
list = g_slist_prepend (list, g_strdup (*p));
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
g_strfreev (pieces);
|
2006-05-04 01:40:54 -05:00
|
|
|
g_free (copy);
|
|
|
|
|
|
|
|
return g_slist_reverse (list);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
static GSList *
|
|
|
|
parse_extensions (const char *extensions)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
2006-05-04 01:40:54 -05:00
|
|
|
char *copy;
|
|
|
|
GSList *list = NULL;
|
2005-10-17 05:23:40 +00:00
|
|
|
char **pieces, **p;
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
if (!extensions || !extensions[0])
|
|
|
|
return NULL;
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
copy = g_strstrip (g_strdup (extensions));
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
pieces = g_strsplit (copy, EXTENSION_SEPARATOR, 0);
|
|
|
|
g_return_val_if_fail (pieces != NULL, NULL);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
for (p = pieces; *p; p++)
|
|
|
|
if (**p)
|
2006-05-04 01:40:54 -05:00
|
|
|
list = g_slist_prepend (list, g_strdup (*p));
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
g_strfreev (pieces);
|
2006-05-04 01:40:54 -05:00
|
|
|
g_free (copy);
|
|
|
|
|
|
|
|
return g_slist_reverse (list);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_lang_finish_build (MooLang *lang,
|
|
|
|
LangXML *xml)
|
|
|
|
{
|
|
|
|
GSList *l;
|
|
|
|
|
2005-11-17 07:04:35 +00:00
|
|
|
g_assert (!strcmp (lang->display_name, xml->name));
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
if (xml->style_list)
|
|
|
|
{
|
|
|
|
for (l = xml->style_list->styles; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
StyleXML *style_xml = l->data;
|
|
|
|
MooTextStyle *style = style_new_from_xml (style_xml);
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_lang_add_style (lang, style_xml->name, style);
|
2005-10-17 05:23:40 +00:00
|
|
|
moo_text_style_free (style);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xml->mimetypes)
|
2006-05-04 01:40:54 -05:00
|
|
|
lang->mime_types = parse_mime_types (xml->mimetypes);
|
2005-10-17 05:23:40 +00:00
|
|
|
if (xml->extensions)
|
2006-05-04 01:40:54 -05:00
|
|
|
lang->extensions = parse_extensions (xml->extensions);
|
2005-12-16 16:51:31 +00:00
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
if (xml->general)
|
2005-12-16 16:51:31 +00:00
|
|
|
{
|
2005-10-17 05:23:40 +00:00
|
|
|
lang->brackets = g_strdup (xml->general->brackets);
|
2005-12-16 16:51:31 +00:00
|
|
|
lang->line_comment = g_strdup (xml->general->single_line_start);
|
|
|
|
lang->block_comment_start = g_strdup (xml->general->multi_line_start);
|
|
|
|
lang->block_comment_end = g_strdup (xml->general->multi_line_end);
|
|
|
|
}
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
lang->sample = g_strdup (xml->sample);
|
|
|
|
|
|
|
|
for (l = xml->syntax->contexts; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
GSList *rule_link;
|
|
|
|
ContextXML *ctx_xml;
|
|
|
|
MooContext *ctx, *switch_to;
|
|
|
|
|
|
|
|
ctx_xml = l->data;
|
2006-05-04 01:40:54 -05:00
|
|
|
ctx = _moo_lang_get_context (lang, ctx_xml->name);
|
2005-10-17 05:23:40 +00:00
|
|
|
g_assert (ctx != NULL);
|
|
|
|
|
|
|
|
for (rule_link = ctx_xml->rules; rule_link != NULL; rule_link = rule_link->next)
|
|
|
|
{
|
|
|
|
RuleXML *rule_xml = rule_link->data;
|
2006-04-28 20:22:03 -05:00
|
|
|
MooRule *rule = _moo_rule_new_from_xml (rule_xml, xml, lang);
|
2005-10-17 05:23:40 +00:00
|
|
|
if (rule)
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_context_add_rule (ctx, rule);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (ctx_xml->eol_switch_info.type)
|
|
|
|
{
|
|
|
|
case MOO_CONTEXT_STAY:
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_context_set_eol_stay (ctx);
|
2005-10-17 05:23:40 +00:00
|
|
|
break;
|
|
|
|
case MOO_CONTEXT_POP:
|
2006-07-08 09:59:35 -05:00
|
|
|
_moo_context_set_eol_pop (ctx, ctx_xml->eol_switch_info.u.num);
|
2005-10-17 05:23:40 +00:00
|
|
|
break;
|
|
|
|
case MOO_CONTEXT_SWITCH:
|
2006-07-08 09:59:35 -05:00
|
|
|
if (ctx_xml->eol_switch_info.u.ref.lang)
|
2006-05-04 01:40:54 -05:00
|
|
|
switch_to = _moo_lang_mgr_get_context (lang->mgr,
|
2006-07-08 09:59:35 -05:00
|
|
|
ctx_xml->eol_switch_info.u.ref.lang,
|
|
|
|
ctx_xml->eol_switch_info.u.ref.name);
|
2005-10-17 05:23:40 +00:00
|
|
|
else
|
2006-07-08 09:59:35 -05:00
|
|
|
switch_to = _moo_lang_get_context (lang, ctx_xml->eol_switch_info.u.ref.name);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
if (!switch_to)
|
|
|
|
g_critical ("%s: oops", G_STRLOC);
|
|
|
|
else
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_context_set_eol_switch (ctx, switch_to);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
moo_lang_mgr_read_dirs (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
GHashTable *lang_xml_names;
|
|
|
|
GSList *lang_xml_list, *l;
|
2006-04-06 01:16:29 -05:00
|
|
|
char **dirs;
|
|
|
|
guint n_dirs, i;
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
2006-04-06 01:16:29 -05:00
|
|
|
|
|
|
|
if (mgr->dirs_read)
|
|
|
|
return;
|
|
|
|
|
|
|
|
dirs = moo_get_data_subdirs (MOO_LANG_DIR_BASENAME,
|
|
|
|
MOO_DATA_SHARE, &n_dirs);
|
|
|
|
for (i = 0; i < n_dirs; ++i)
|
|
|
|
moo_lang_mgr_add_dir (mgr, dirs[i]);
|
|
|
|
g_strfreev (dirs);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
if (!mgr->lang_dirs)
|
|
|
|
return;
|
|
|
|
|
|
|
|
lang_xml_names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
|
|
|
|
|
|
|
lang_xml_list = read_files (mgr, lang_xml_names);
|
|
|
|
|
|
|
|
if (!lang_xml_list)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
lang_xml_list = check_external_refs (lang_xml_list, lang_xml_names);
|
|
|
|
|
|
|
|
if (!lang_xml_list)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
mgr->dirs_read = TRUE;
|
|
|
|
|
|
|
|
for (l = lang_xml_list; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
LangXML *xml = l->data;
|
2006-05-04 01:40:54 -05:00
|
|
|
MooLang *lang = _moo_lang_new (mgr, xml->name,
|
|
|
|
xml->section, xml->version,
|
|
|
|
xml->author);
|
2005-10-17 05:23:40 +00:00
|
|
|
lang->hidden = xml->hidden;
|
|
|
|
moo_lang_build_contexts (lang, xml);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (l = lang_xml_list; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
LangXML *xml = l->data;
|
|
|
|
MooLang *lang = moo_lang_mgr_get_lang (mgr, xml->name);
|
|
|
|
g_assert (lang != NULL);
|
|
|
|
moo_lang_finish_build (lang, xml);
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
g_hash_table_destroy (lang_xml_names);
|
2006-04-28 20:22:03 -05:00
|
|
|
g_slist_foreach (lang_xml_list, (GFunc) _moo_lang_xml_free, NULL);
|
2005-10-17 05:23:40 +00:00
|
|
|
g_slist_free (lang_xml_list);
|
|
|
|
|
|
|
|
moo_lang_mgr_load_styles (mgr);
|
2006-06-26 05:47:38 -05:00
|
|
|
g_signal_emit_by_name (mgr, "loaded");
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooContext*
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_lang_mgr_get_context (MooLangMgr *mgr,
|
|
|
|
const char *lang_name,
|
|
|
|
const char *ctx_name)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
MooLang *lang;
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_return_val_if_fail (lang_name && ctx_name, NULL);
|
|
|
|
lang = moo_lang_mgr_get_lang (mgr, lang_name);
|
|
|
|
g_return_val_if_fail (lang != NULL, NULL);
|
2006-05-04 01:40:54 -05:00
|
|
|
return _moo_lang_get_context (lang, ctx_name);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooLang*
|
|
|
|
moo_lang_mgr_get_lang (MooLangMgr *mgr,
|
|
|
|
const char *name)
|
|
|
|
{
|
2005-11-17 07:04:35 +00:00
|
|
|
char *id;
|
|
|
|
MooLang *lang;
|
2005-10-17 05:23:40 +00:00
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_return_val_if_fail (name != NULL, NULL);
|
2006-04-10 02:55:51 -05:00
|
|
|
id = moo_lang_id_from_name (name);
|
2005-11-17 07:04:35 +00:00
|
|
|
lang = g_hash_table_lookup (mgr->lang_names, id);
|
|
|
|
g_free (id);
|
|
|
|
return lang;
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GSList*
|
|
|
|
moo_lang_mgr_get_available_langs (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
return g_slist_copy (mgr->langs);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
maybe_add_section (MooLang *lang,
|
|
|
|
GSList **list)
|
|
|
|
{
|
|
|
|
if (!g_slist_find_custom (*list, lang->section, (GCompareFunc) strcmp))
|
|
|
|
*list = g_slist_prepend (*list, g_strdup (lang->section));
|
|
|
|
}
|
|
|
|
|
|
|
|
GSList*
|
|
|
|
moo_lang_mgr_get_sections (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
GSList *list = NULL;
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_slist_foreach (mgr->langs, (GFunc) maybe_add_section, &list);
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
static MooLang *
|
|
|
|
lang_mgr_get_lang_by_extension (MooLangMgr *mgr,
|
|
|
|
const char *filename)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
MooLang *lang = NULL;
|
|
|
|
char *basename, *utf8_basename;
|
|
|
|
GSList *l;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
|
|
|
|
g_return_val_if_fail (filename != NULL, NULL);
|
|
|
|
|
|
|
|
/* TODO: is this right? */
|
|
|
|
basename = g_path_get_basename (filename);
|
|
|
|
g_return_val_if_fail (basename != NULL, NULL);
|
|
|
|
utf8_basename = g_filename_display_name (basename);
|
|
|
|
g_return_val_if_fail (utf8_basename != NULL, NULL);
|
|
|
|
|
|
|
|
for (l = mgr->langs; !found && l != NULL; l = l->next)
|
|
|
|
{
|
2006-05-04 01:40:54 -05:00
|
|
|
GSList *g, *extensions;
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
lang = l->data;
|
2006-05-04 01:40:54 -05:00
|
|
|
extensions = moo_lang_get_extensions (lang);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
for (g = extensions; !found && g != NULL; g = g->next)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
if (g_pattern_match_simple ((char*) g->data, utf8_basename))
|
|
|
|
{
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found)
|
|
|
|
lang = NULL;
|
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
g_free (utf8_basename);
|
|
|
|
g_free (basename);
|
|
|
|
return lang;
|
|
|
|
}
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
static MooLang *
|
|
|
|
lang_mgr_get_lang_for_bak_filename (MooLangMgr *mgr,
|
|
|
|
const char *filename)
|
|
|
|
{
|
|
|
|
MooLang *lang = NULL;
|
2006-04-09 03:25:57 -05:00
|
|
|
char *utf8_name, *utf8_base = NULL;
|
2005-11-21 07:59:22 +00:00
|
|
|
int len;
|
|
|
|
guint i;
|
|
|
|
|
2006-06-14 10:01:59 -05:00
|
|
|
static const char *bak_globs[] = {"*~", "*.bak", "*.in", "*.orig"};
|
2005-11-21 07:59:22 +00:00
|
|
|
|
|
|
|
utf8_name = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
|
|
|
|
g_return_val_if_fail (utf8_name != NULL, NULL);
|
|
|
|
|
|
|
|
len = strlen (utf8_name);
|
|
|
|
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (bak_globs); ++i)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
2005-11-21 07:59:22 +00:00
|
|
|
int ext_len = strlen (bak_globs[i]) - 1;
|
|
|
|
|
|
|
|
if (len > ext_len && g_pattern_match_simple (bak_globs[i], utf8_name))
|
|
|
|
{
|
2006-04-09 03:25:57 -05:00
|
|
|
utf8_base = g_strndup (utf8_name, len - ext_len);
|
2005-11-21 07:59:22 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
2006-04-09 03:25:57 -05:00
|
|
|
if (utf8_base)
|
2005-11-21 07:59:22 +00:00
|
|
|
{
|
2006-04-09 03:25:57 -05:00
|
|
|
char *base = g_filename_from_utf8 (utf8_base, -1, NULL, NULL, NULL);
|
2005-11-21 07:59:22 +00:00
|
|
|
|
2006-04-09 03:25:57 -05:00
|
|
|
if (base)
|
|
|
|
lang = moo_lang_mgr_get_lang_for_filename (mgr, base);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
g_free (base);
|
2006-04-09 03:25:57 -05:00
|
|
|
g_free (utf8_base);
|
2005-11-21 07:59:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_free (utf8_name);
|
2005-10-17 05:23:40 +00:00
|
|
|
return lang;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-08-23 20:33:03 -05:00
|
|
|
static gboolean
|
|
|
|
filename_blacklisted (MooLangMgr *mgr,
|
|
|
|
const char *filename)
|
|
|
|
{
|
|
|
|
/* bak files */
|
|
|
|
char *basename, *utf8_basename;
|
|
|
|
gboolean result = FALSE;
|
|
|
|
GSList *extensions;
|
|
|
|
|
|
|
|
basename = g_path_get_basename (filename);
|
|
|
|
g_return_val_if_fail (basename != NULL, FALSE);
|
|
|
|
utf8_basename = g_filename_display_name (basename);
|
|
|
|
g_return_val_if_fail (utf8_basename != NULL, FALSE);
|
|
|
|
|
|
|
|
extensions = g_hash_table_lookup (mgr->extensions, MOO_LANG_NONE);
|
|
|
|
|
|
|
|
while (extensions)
|
|
|
|
{
|
|
|
|
if (g_pattern_match_simple ((char*) extensions->data, utf8_basename))
|
|
|
|
{
|
|
|
|
result = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
extensions = extensions->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (utf8_basename);
|
|
|
|
g_free (basename);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
file_blacklisted (MooLangMgr *mgr,
|
|
|
|
const char *filename)
|
|
|
|
{
|
|
|
|
/* XXX mime type */
|
|
|
|
return filename_blacklisted (mgr, filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-10-17 05:23:40 +00:00
|
|
|
MooLang*
|
2005-11-21 07:59:22 +00:00
|
|
|
moo_lang_mgr_get_lang_for_file (MooLangMgr *mgr,
|
|
|
|
const char *filename)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
MooLang *lang = NULL;
|
2005-11-21 07:59:22 +00:00
|
|
|
const char *mime_type;
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_return_val_if_fail (filename != NULL, NULL);
|
|
|
|
|
2006-08-23 20:33:03 -05:00
|
|
|
if (file_blacklisted (mgr, filename))
|
|
|
|
return NULL;
|
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
lang = lang_mgr_get_lang_by_extension (mgr, filename);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
if (lang)
|
|
|
|
return lang;
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
#ifdef MOO_USE_XDGMIME
|
|
|
|
/* XXX: xdgmime wants utf8-encoded filename here. is it a problem? */
|
2005-12-04 16:26:18 +00:00
|
|
|
/* It's a big problem! */
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-12-02 17:52:27 +00:00
|
|
|
mime_type = xdg_mime_get_mime_type_for_file (filename, NULL);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-06-17 05:50:03 -05:00
|
|
|
if (mime_type != XDG_MIME_TYPE_UNKNOWN)
|
2005-11-21 07:59:22 +00:00
|
|
|
lang = moo_lang_mgr_get_lang_for_mime_type (mgr, mime_type);
|
|
|
|
|
|
|
|
if (lang)
|
|
|
|
return lang;
|
2006-06-13 00:59:42 -05:00
|
|
|
#else
|
|
|
|
#ifdef __GNUC__
|
2006-08-20 22:47:28 -05:00
|
|
|
#warning "Implement moo_lang_mgr_get_lang_for_file()"
|
2006-06-13 00:59:42 -05:00
|
|
|
#endif
|
2005-11-21 07:59:22 +00:00
|
|
|
#endif /* MOO_USE_XDGMIME */
|
|
|
|
|
|
|
|
lang = lang_mgr_get_lang_for_bak_filename (mgr, filename);
|
|
|
|
|
|
|
|
if (lang)
|
|
|
|
return lang;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooLang*
|
|
|
|
moo_lang_mgr_get_lang_for_filename (MooLangMgr *mgr,
|
|
|
|
const char *filename)
|
|
|
|
{
|
|
|
|
MooLang *lang = NULL;
|
|
|
|
const char *mime_type;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_return_val_if_fail (filename != NULL, NULL);
|
|
|
|
|
2006-08-23 20:33:03 -05:00
|
|
|
if (filename_blacklisted (mgr, filename))
|
|
|
|
return NULL;
|
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
lang = lang_mgr_get_lang_by_extension (mgr, filename);
|
|
|
|
|
|
|
|
if (lang)
|
|
|
|
return lang;
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
#ifdef MOO_USE_XDGMIME
|
|
|
|
/* XXX: xdgmime wants utf8-encoded filename here. is it a problem? */
|
2005-12-04 16:26:18 +00:00
|
|
|
/* It's a big problem! */
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
mime_type = xdg_mime_get_mime_type_from_file_name (filename);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2006-06-17 05:50:03 -05:00
|
|
|
if (mime_type != XDG_MIME_TYPE_UNKNOWN)
|
2005-11-21 07:59:22 +00:00
|
|
|
lang = moo_lang_mgr_get_lang_for_mime_type (mgr, mime_type);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
if (lang)
|
|
|
|
return lang;
|
2006-06-13 00:59:42 -05:00
|
|
|
#else
|
|
|
|
#ifdef __GNUC__
|
2006-08-20 22:47:28 -05:00
|
|
|
#warning "Implement moo_lang_mgr_get_lang_for_filename()"
|
2006-06-13 00:59:42 -05:00
|
|
|
#endif
|
2005-11-21 07:59:22 +00:00
|
|
|
#endif /* MOO_USE_XDGMIME */
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
lang = lang_mgr_get_lang_for_bak_filename (mgr, filename);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
if (lang)
|
|
|
|
return lang;
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
|
2005-12-02 17:48:10 +00:00
|
|
|
#ifdef MOO_USE_XDGMIME
|
2005-11-21 07:59:22 +00:00
|
|
|
static int
|
|
|
|
check_mime_subclass (const char *base,
|
|
|
|
const char *mime)
|
|
|
|
{
|
|
|
|
return !xdg_mime_mime_type_subclass (mime, base);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooLang*
|
2005-11-21 07:59:22 +00:00
|
|
|
moo_lang_mgr_get_lang_for_mime_type (MooLangMgr *mgr,
|
|
|
|
const char *mime)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
GSList *l;
|
|
|
|
MooLang *lang = NULL;
|
|
|
|
gboolean found = FALSE;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
2005-11-21 07:59:22 +00:00
|
|
|
g_return_val_if_fail (mime != NULL, NULL);
|
2005-10-17 05:23:40 +00:00
|
|
|
|
2005-11-21 07:59:22 +00:00
|
|
|
for (l = mgr->langs; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
lang = l->data;
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
if (g_slist_find_custom (moo_lang_get_mime_types (lang), mime,
|
|
|
|
(GCompareFunc) strcmp))
|
2005-11-21 07:59:22 +00:00
|
|
|
{
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (found)
|
|
|
|
return lang;
|
|
|
|
|
|
|
|
for (l = mgr->langs; l != NULL; l = l->next)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
lang = l->data;
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
if (g_slist_find_custom (moo_lang_get_mime_types (lang), mime,
|
|
|
|
(GCompareFunc) check_mime_subclass))
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return found ? lang : NULL;
|
|
|
|
}
|
2005-12-21 13:04:46 +00:00
|
|
|
#else /* MOO_USE_XDGMIME */
|
|
|
|
MooLang*
|
|
|
|
moo_lang_mgr_get_lang_for_mime_type (MooLangMgr *mgr,
|
|
|
|
const char *mime)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_return_val_if_fail (mime != NULL, NULL);
|
|
|
|
g_warning ("%s: implement me?", G_STRLOC);
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-12-02 17:48:10 +00:00
|
|
|
#endif /* MOO_USE_XDGMIME */
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
static MooTextStyle*
|
|
|
|
moo_lang_get_style (MooLang *lang,
|
|
|
|
const char *style_name)
|
|
|
|
{
|
|
|
|
MooTextStyle *style;
|
|
|
|
g_return_val_if_fail (lang != NULL && style_name != NULL, NULL);
|
|
|
|
style = g_hash_table_lookup (lang->style_names, style_name);
|
|
|
|
return moo_text_style_copy (style);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooTextStyle*
|
2006-05-04 01:40:54 -05:00
|
|
|
_moo_lang_mgr_get_style (MooLangMgr *mgr,
|
|
|
|
const char *lang_name,
|
|
|
|
const char *style_name,
|
|
|
|
MooTextStyleScheme *scheme)
|
2005-10-17 05:23:40 +00:00
|
|
|
{
|
|
|
|
const MooTextStyle *scheme_style = NULL;
|
|
|
|
MooTextStyle *lang_style = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_return_val_if_fail (style_name != NULL, NULL);
|
|
|
|
g_return_val_if_fail (mgr->active_scheme != NULL, NULL);
|
|
|
|
|
|
|
|
if (!scheme)
|
|
|
|
scheme = mgr->active_scheme;
|
|
|
|
|
|
|
|
if (lang_name)
|
|
|
|
{
|
|
|
|
MooLang *lang = moo_lang_mgr_get_lang (mgr, lang_name);
|
|
|
|
g_return_val_if_fail (lang != NULL, NULL);
|
|
|
|
lang_style = moo_lang_get_style (lang, style_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
scheme_style = moo_text_style_scheme_get (scheme, lang_name, style_name);
|
|
|
|
|
|
|
|
if (lang_style)
|
|
|
|
{
|
|
|
|
if (scheme_style)
|
|
|
|
moo_text_style_compose (lang_style, scheme_style);
|
|
|
|
return lang_style;
|
|
|
|
}
|
|
|
|
else if (scheme_style)
|
|
|
|
{
|
|
|
|
return moo_text_style_copy (scheme_style);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MooTextStyleScheme*
|
|
|
|
moo_lang_mgr_get_active_scheme (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_return_val_if_fail (mgr->active_scheme != NULL, NULL);
|
|
|
|
return mgr->active_scheme;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_lang_mgr_add_lang (MooLangMgr *mgr,
|
|
|
|
MooLang *lang)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
g_return_if_fail (lang != NULL);
|
2005-11-17 07:04:35 +00:00
|
|
|
g_return_if_fail (lang->id != NULL);
|
|
|
|
g_return_if_fail (!g_hash_table_lookup (mgr->lang_names, lang->id));
|
2005-10-17 05:23:40 +00:00
|
|
|
|
|
|
|
mgr->langs = g_slist_append (mgr->langs, lang);
|
2005-11-17 07:04:35 +00:00
|
|
|
g_hash_table_insert (mgr->lang_names, g_strdup (lang->id), lang);
|
2005-10-17 05:23:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
prepend_scheme (G_GNUC_UNUSED const char *scheme_name,
|
|
|
|
gpointer scheme,
|
|
|
|
GSList **list)
|
|
|
|
{
|
|
|
|
*list = g_slist_prepend (*list, scheme);
|
|
|
|
}
|
|
|
|
|
|
|
|
GSList*
|
|
|
|
moo_lang_mgr_list_schemes (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
GSList *list = NULL;
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
g_hash_table_foreach (mgr->schemes, (GHFunc) prepend_scheme, &list);
|
|
|
|
return list;
|
|
|
|
}
|
2006-05-04 01:40:54 -05:00
|
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
string_list_equal (GSList *list1,
|
|
|
|
GSList *list2)
|
|
|
|
{
|
|
|
|
while (list1 && list2)
|
|
|
|
{
|
|
|
|
if (strcmp (list1->data, list2->data))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
list1 = list1->next;
|
|
|
|
list2 = list2->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !list1 && !list2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_lang_set_string (MooLang *lang,
|
|
|
|
GSList *original,
|
|
|
|
GSList *new,
|
|
|
|
GHashTable *hash)
|
|
|
|
{
|
|
|
|
g_return_if_fail (lang != NULL);
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (lang->mgr));
|
|
|
|
|
|
|
|
if (string_list_equal (original, new))
|
|
|
|
{
|
|
|
|
g_hash_table_remove (hash, lang->id);
|
|
|
|
string_list_free (new);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_hash_table_insert (hash, g_strdup (lang->id), new);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_lang_set_mime_types (MooLang *lang,
|
|
|
|
const char *string)
|
|
|
|
{
|
|
|
|
g_return_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr));
|
|
|
|
moo_lang_set_string (lang, lang->mime_types,
|
|
|
|
parse_mime_types (string),
|
|
|
|
lang->mgr->mime_types);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_lang_set_extensions (MooLang *lang,
|
|
|
|
const char *string)
|
|
|
|
{
|
|
|
|
g_return_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr));
|
|
|
|
moo_lang_set_string (lang, lang->extensions,
|
|
|
|
parse_extensions (string),
|
|
|
|
lang->mgr->extensions);
|
|
|
|
}
|
|
|
|
|
2006-08-23 20:33:03 -05:00
|
|
|
void
|
|
|
|
_moo_lang_mgr_set_mime_types (MooLangMgr *mgr,
|
|
|
|
const char *lang_id,
|
|
|
|
const char *mime)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
|
|
|
|
if (lang_id && strcmp (lang_id, MOO_LANG_NONE) != 0)
|
|
|
|
{
|
|
|
|
MooLang *lang = moo_lang_mgr_get_lang (mgr, lang_id);
|
|
|
|
g_return_if_fail (lang != NULL);
|
|
|
|
return _moo_lang_set_mime_types (lang, mime);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_insert (mgr->mime_types,
|
|
|
|
g_strdup (MOO_LANG_NONE),
|
|
|
|
parse_mime_types (mime));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_lang_mgr_set_extensions (MooLangMgr *mgr,
|
|
|
|
const char *lang_id,
|
|
|
|
const char *extensions)
|
|
|
|
{
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
|
|
|
|
if (lang_id && strcmp (lang_id, MOO_LANG_NONE) != 0)
|
|
|
|
{
|
|
|
|
MooLang *lang = moo_lang_mgr_get_lang (mgr, lang_id);
|
|
|
|
g_return_if_fail (lang != NULL);
|
|
|
|
return _moo_lang_set_extensions (lang, extensions);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_hash_table_insert (mgr->extensions,
|
|
|
|
g_strdup (MOO_LANG_NONE),
|
|
|
|
parse_extensions (extensions));
|
|
|
|
}
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
|
|
|
|
GSList *
|
|
|
|
moo_lang_get_extensions (MooLang *lang)
|
|
|
|
{
|
|
|
|
gpointer orig_key, value;
|
|
|
|
|
|
|
|
g_return_val_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr), NULL);
|
|
|
|
|
|
|
|
if (g_hash_table_lookup_extended (lang->mgr->extensions, lang->id, &orig_key, &value))
|
|
|
|
return value;
|
|
|
|
else
|
|
|
|
return lang->extensions;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GSList *
|
|
|
|
moo_lang_get_mime_types (MooLang *lang)
|
|
|
|
{
|
|
|
|
gpointer orig_key, value;
|
|
|
|
|
|
|
|
g_return_val_if_fail (lang != NULL && MOO_IS_LANG_MGR (lang->mgr), NULL);
|
|
|
|
|
|
|
|
if (g_hash_table_lookup_extended (lang->mgr->mime_types, lang->id, &orig_key, &value))
|
|
|
|
return value;
|
|
|
|
else
|
|
|
|
return lang->mime_types;
|
|
|
|
}
|
|
|
|
|
2006-08-23 20:33:03 -05:00
|
|
|
GSList *
|
|
|
|
_moo_lang_mgr_get_extensions (MooLangMgr *mgr,
|
|
|
|
const char *lang_id)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
|
|
|
|
if (lang_id && strcmp (lang_id, MOO_LANG_NONE) != 0)
|
|
|
|
{
|
|
|
|
MooLang *lang = moo_lang_mgr_get_lang (mgr, lang_id);
|
|
|
|
g_return_val_if_fail (lang != NULL, NULL);
|
|
|
|
return moo_lang_get_extensions (lang);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_hash_table_lookup (mgr->extensions, MOO_LANG_NONE);
|
|
|
|
}
|
|
|
|
|
|
|
|
GSList *
|
|
|
|
_moo_lang_mgr_get_mime_types (MooLangMgr *mgr,
|
|
|
|
const char *lang_id)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
|
|
|
|
if (lang_id && strcmp (lang_id, MOO_LANG_NONE) != 0)
|
|
|
|
{
|
|
|
|
MooLang *lang = moo_lang_mgr_get_lang (mgr, lang_id);
|
|
|
|
g_return_val_if_fail (lang != NULL, NULL);
|
|
|
|
return moo_lang_get_mime_types (lang);
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_hash_table_lookup (mgr->mime_types, MOO_LANG_NONE);
|
|
|
|
}
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
|
|
|
|
const char *
|
|
|
|
_moo_lang_mgr_get_config (MooLangMgr *mgr,
|
|
|
|
const char *lang_id)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (MOO_IS_LANG_MGR (mgr), NULL);
|
|
|
|
|
|
|
|
if (!lang_id)
|
|
|
|
lang_id = MOO_LANG_NONE;
|
|
|
|
|
|
|
|
return g_hash_table_lookup (mgr->config, lang_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_lang_mgr_update_config (MooLangMgr *mgr,
|
|
|
|
MooEditConfig *config,
|
|
|
|
const char *lang_id)
|
|
|
|
{
|
|
|
|
const char *lang_config;
|
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
g_return_if_fail (MOO_IS_EDIT_CONFIG (config));
|
|
|
|
|
|
|
|
g_object_freeze_notify (G_OBJECT (config));
|
|
|
|
|
|
|
|
moo_edit_config_unset_by_source (config, MOO_EDIT_CONFIG_SOURCE_LANG);
|
|
|
|
|
|
|
|
lang_config = _moo_lang_mgr_get_config (mgr, lang_id);
|
|
|
|
|
|
|
|
if (lang_config)
|
|
|
|
moo_edit_config_parse (config, lang_config,
|
|
|
|
MOO_EDIT_CONFIG_SOURCE_LANG);
|
|
|
|
|
|
|
|
g_object_thaw_notify (G_OBJECT (config));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_lang_mgr_set_config (MooLangMgr *mgr,
|
|
|
|
const char *lang_id,
|
|
|
|
const char *config)
|
|
|
|
{
|
|
|
|
const char *old;
|
|
|
|
char *norm = NULL;
|
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
|
|
|
|
lang_id = lang_id ? lang_id : MOO_LANG_NONE;
|
|
|
|
old = g_hash_table_lookup (mgr->config, lang_id);
|
|
|
|
|
|
|
|
if (config)
|
|
|
|
{
|
|
|
|
norm = g_strstrip (g_strdup (config));
|
|
|
|
|
|
|
|
if (!norm[0])
|
|
|
|
{
|
|
|
|
g_free (norm);
|
|
|
|
norm = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!norm)
|
|
|
|
g_hash_table_remove (mgr->config, lang_id);
|
|
|
|
else
|
|
|
|
g_hash_table_insert (mgr->config, g_strdup (lang_id), norm);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************************************************/
|
|
|
|
/* Loading and saving
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define ELEMENT_LANG_CONFIG MOO_EDIT_PREFS_PREFIX "/langs"
|
|
|
|
#define ELEMENT_LANG "lang"
|
|
|
|
#define ELEMENT_EXTENSIONS "extensions"
|
|
|
|
#define ELEMENT_MIME_TYPES "mime-types"
|
|
|
|
#define ELEMENT_CONFIG "config"
|
|
|
|
#define PROP_LANG_ID "id"
|
|
|
|
|
|
|
|
static void
|
|
|
|
load_lang_node (MooLangMgr *mgr,
|
|
|
|
MooMarkupNode *lang_node)
|
|
|
|
{
|
|
|
|
const char *lang_id;
|
|
|
|
MooMarkupNode *node;
|
|
|
|
|
|
|
|
lang_id = moo_markup_get_prop (lang_node, PROP_LANG_ID);
|
|
|
|
g_return_if_fail (lang_id != NULL);
|
|
|
|
|
|
|
|
for (node = lang_node->children; node != NULL; node = node->next)
|
|
|
|
{
|
|
|
|
if (!MOO_MARKUP_IS_ELEMENT (node))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!strcmp (node->name, ELEMENT_EXTENSIONS))
|
|
|
|
{
|
|
|
|
const char *string = moo_markup_get_content (node);
|
|
|
|
GSList *list = parse_extensions (string);
|
|
|
|
g_hash_table_insert (mgr->extensions, g_strdup (lang_id), list);
|
|
|
|
}
|
|
|
|
else if (!strcmp (node->name, ELEMENT_MIME_TYPES))
|
|
|
|
{
|
|
|
|
const char *string = moo_markup_get_content (node);
|
|
|
|
GSList *list = parse_mime_types (string);
|
|
|
|
g_hash_table_insert (mgr->mime_types, g_strdup (lang_id), list);
|
|
|
|
}
|
|
|
|
else if (!strcmp (node->name, ELEMENT_CONFIG))
|
|
|
|
{
|
|
|
|
const char *string = moo_markup_get_content (node);
|
|
|
|
g_hash_table_insert (mgr->config, g_strdup (lang_id), g_strdup (string));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_warning ("%s: invalid node '%s'", G_STRLOC, node->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
moo_lang_mgr_set_default_config (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
_moo_lang_mgr_set_config (mgr, "makefile", "use-tabs: true");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_moo_lang_mgr_load_config (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
MooMarkupDoc *xml;
|
|
|
|
MooMarkupNode *root, *node;
|
|
|
|
|
|
|
|
moo_lang_mgr_set_default_config (mgr);
|
|
|
|
|
|
|
|
xml = moo_prefs_get_markup ();
|
|
|
|
g_return_if_fail (xml != NULL);
|
|
|
|
|
|
|
|
root = moo_markup_get_element (MOO_MARKUP_NODE (xml),
|
|
|
|
ELEMENT_LANG_CONFIG);
|
|
|
|
|
|
|
|
if (!root)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (node = root->children; node != NULL; node = node->next)
|
|
|
|
{
|
|
|
|
if (!MOO_MARKUP_IS_ELEMENT (node))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp (node->name, ELEMENT_LANG))
|
|
|
|
{
|
|
|
|
g_warning ("%s: invalid '%s' element", G_STRLOC, node->name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
load_lang_node (mgr, node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static MooMarkupNode *
|
|
|
|
create_lang_node (MooMarkupNode *root,
|
|
|
|
MooMarkupNode *lang_node,
|
|
|
|
const char *lang_id)
|
|
|
|
{
|
|
|
|
if (!lang_node)
|
|
|
|
{
|
|
|
|
lang_node = moo_markup_create_element (root, ELEMENT_LANG);
|
|
|
|
moo_markup_set_prop (lang_node, PROP_LANG_ID, lang_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return lang_node;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
list_to_string (GSList *list)
|
|
|
|
{
|
|
|
|
GString *string = g_string_new (NULL);
|
|
|
|
|
|
|
|
while (list)
|
|
|
|
{
|
|
|
|
g_string_append (string, list->data);
|
|
|
|
|
|
|
|
if ((list = list->next))
|
|
|
|
g_string_append_c (string, ';');
|
|
|
|
}
|
|
|
|
|
|
|
|
return g_string_free (string, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
save_one_lang (MooMarkupNode *root,
|
|
|
|
const char *lang_id,
|
|
|
|
const char *config,
|
|
|
|
GSList *extensions,
|
|
|
|
gboolean save_extensions,
|
|
|
|
GSList *mimetypes,
|
|
|
|
gboolean save_mimetypes)
|
|
|
|
{
|
|
|
|
MooMarkupNode *lang_node = NULL;
|
|
|
|
|
|
|
|
if (save_extensions)
|
|
|
|
{
|
|
|
|
char *string = list_to_string (extensions);
|
|
|
|
lang_node = create_lang_node (root, lang_node, lang_id);
|
|
|
|
moo_markup_create_text_element (lang_node, ELEMENT_EXTENSIONS, string);
|
|
|
|
g_free (string);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (save_mimetypes)
|
|
|
|
{
|
|
|
|
char *string = list_to_string (mimetypes);
|
|
|
|
lang_node = create_lang_node (root, lang_node, lang_id);
|
|
|
|
moo_markup_create_text_element (lang_node, ELEMENT_MIME_TYPES, string);
|
|
|
|
g_free (string);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config)
|
|
|
|
{
|
|
|
|
lang_node = create_lang_node (root, lang_node, lang_id);
|
|
|
|
moo_markup_create_text_element (lang_node, ELEMENT_CONFIG, config);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-23 20:33:03 -05:00
|
|
|
static void
|
|
|
|
save_one (MooLangMgr *mgr,
|
|
|
|
MooLang *lang,
|
|
|
|
const char *id,
|
|
|
|
MooMarkupDoc *xml,
|
|
|
|
MooMarkupNode **root)
|
|
|
|
{
|
|
|
|
const char *config;
|
|
|
|
GSList *extensions, *mimetypes;
|
|
|
|
|
|
|
|
id = lang ? lang->id : id;
|
|
|
|
g_return_if_fail (id != NULL);
|
|
|
|
|
|
|
|
config = g_hash_table_lookup (mgr->config, id);
|
|
|
|
extensions = _moo_lang_mgr_get_extensions (mgr, id);
|
|
|
|
mimetypes = _moo_lang_mgr_get_mime_types (mgr, id);
|
|
|
|
|
|
|
|
if (!config && lang && extensions == lang->extensions && mimetypes == lang->mime_types)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!*root)
|
|
|
|
*root = moo_markup_create_element (MOO_MARKUP_NODE (xml), ELEMENT_LANG_CONFIG);
|
|
|
|
|
|
|
|
g_return_if_fail (*root != NULL);
|
|
|
|
|
|
|
|
save_one_lang (*root, id, config,
|
|
|
|
extensions, !lang || extensions != lang->extensions,
|
|
|
|
mimetypes, !lang || mimetypes != lang->mime_types);
|
|
|
|
}
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
void
|
|
|
|
_moo_lang_mgr_save_config (MooLangMgr *mgr)
|
|
|
|
{
|
|
|
|
MooMarkupDoc *xml;
|
|
|
|
MooMarkupNode *root;
|
|
|
|
GSList *l;
|
|
|
|
|
|
|
|
g_return_if_fail (MOO_IS_LANG_MGR (mgr));
|
|
|
|
|
|
|
|
xml = moo_prefs_get_markup ();
|
|
|
|
g_return_if_fail (xml != NULL);
|
|
|
|
|
|
|
|
root = moo_markup_get_element (MOO_MARKUP_NODE (xml), ELEMENT_LANG_CONFIG);
|
|
|
|
|
|
|
|
if (root)
|
|
|
|
moo_markup_delete_node (root);
|
|
|
|
|
|
|
|
root = NULL;
|
|
|
|
|
2006-08-23 20:33:03 -05:00
|
|
|
save_one (mgr, NULL, MOO_LANG_NONE, xml, &root);
|
|
|
|
|
2006-05-04 01:40:54 -05:00
|
|
|
for (l = mgr->langs; l != NULL; l = l->next)
|
|
|
|
{
|
|
|
|
MooLang *lang = l->data;
|
2006-08-23 20:33:03 -05:00
|
|
|
save_one (mgr, lang, lang->id, xml, &root);
|
2006-05-04 01:40:54 -05:00
|
|
|
}
|
|
|
|
}
|