r955@localhost: muntyan | 2005-11-24 02:14:16 -0600

Started rewrite of variables stuff
This commit is contained in:
Yevgen Muntyan 2005-11-24 14:14:48 +00:00
parent b32583592e
commit e2805c4056
13 changed files with 890 additions and 454 deletions

View File

@ -104,6 +104,7 @@ mooedit_include_headers = \
mooedit_noinst_headers = \
$(mooedit)/gtksourceiter.h \
$(mooedit)/mooedit-private.h \
$(mooedit)/mooedit-vars.h \
$(mooedit)/mooeditcolorsprefs-glade.h \
$(mooedit)/mooeditdialogs.h \
$(mooedit)/mooeditfileops.h \

View File

@ -35,6 +35,12 @@ void _moo_edit_settings_changed (const char *key,
const GValue *newval,
MooEdit *edit);
void _moo_edit_freeze_var_notify (MooEdit *edit);
void _moo_edit_thaw_var_notify (MooEdit *edit);
void _moo_edit_var_notify (MooEdit *edit,
const char *name);
/***********************************************************************/
/* File operations
/*/
@ -57,6 +63,10 @@ typedef enum {
} MooEditLineEndType;
typedef struct _VarTable VarTable;
typedef struct _StringList StringList;
struct _MooEditPrivate {
MooEditor *editor;
@ -87,8 +97,9 @@ struct _MooEditPrivate {
/***********************************************************************/
/* Language and stuff
/*/
GHashTable *vars;
gboolean lang_custom;
VarTable *vars;
StringList *changed_vars;
guint freeze_var_notify;
/***********************************************************************/
/* Preferences

267
moo/mooedit/mooedit-vars.h Normal file
View File

@ -0,0 +1,267 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
*
* mooedit.h
*
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
*
* 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.
*/
#ifndef __MOO_EDIT_VARS_H__
#define __MOO_EDIT_VARS_H__
#include "mooedit/mooedit-private.h"
G_BEGIN_DECLS
typedef struct {
GHashTable *hash;
} VarPool;
struct _StringList {
GHashTable *hash;
};
struct _VarTable {
VarPool *pool;
GHashTable *hash;
};
typedef struct {
GValue value;
guint dep : 4;
} Var;
static VarPool *var_pool_new (void);
static GParamSpec *var_pool_get_pspec (VarPool *pool,
const char *name);
static const char *var_pool_find_name (VarPool *pool,
const char *alias);
static void var_pool_add (VarPool *pool,
GParamSpec *pspec);
static void var_pool_add_alias (VarPool *pool,
const char *name,
const char *alias);
static StringList *string_list_new (void);
static void string_list_free (StringList *list);
static void string_list_add (StringList *list,
const char *s);
static VarTable *var_table_new (VarPool *pool);
static void var_table_free (VarTable *table);
static Var *var_table_get (VarTable *table,
const char *name);
static void var_table_insert (VarTable *table,
const char *name,
Var *var);
static void var_table_remove (VarTable *table,
const char *name);
static void var_table_remove_by_dep (VarTable *table,
guint dep,
StringList *changed);
static Var *var_new (guint dep,
GType type);
static void var_free (Var *var);
static StringList *
string_list_new (void)
{
StringList *l = g_new0 (StringList, 1);
l->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
return l;
}
static void
string_list_free (StringList *list)
{
if (list)
{
g_hash_table_destroy (list->hash);
g_free (list);
}
}
static void
string_list_add (StringList *list,
const char *s)
{
g_return_if_fail (list != NULL);
g_return_if_fail (s != NULL);
g_hash_table_insert (list->hash, g_strdup (s), NULL);
}
static VarTable *
var_table_new (VarPool *pool)
{
VarTable *table = g_new0 (VarTable, 1);
table->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) var_free);
table->pool = pool;
return table;
}
static void
var_table_free (VarTable *table)
{
if (table)
{
g_hash_table_destroy (table->hash);
g_free (table);
}
}
static Var *
var_table_get (VarTable *table,
const char *name)
{
return g_hash_table_lookup (table->hash, name);
}
static void
var_table_insert (VarTable *table,
const char *name,
Var *var)
{
if (var)
g_hash_table_insert (table->hash, g_strdup (name), var);
else
g_hash_table_remove (table->hash, name);
}
static void
var_table_remove (VarTable *table,
const char *name)
{
g_hash_table_remove (table->hash, name);
}
static gboolean
remove_by_dep (const char *name,
Var *val,
gpointer user_data)
{
struct {
StringList *list;
guint dep;
} *data = user_data;
if (val->dep >= data->dep)
{
string_list_add (data->list, name);
return TRUE;
}
else
{
return FALSE;
}
}
static void
var_table_remove_by_dep (VarTable *table,
guint dep,
StringList *changed)
{
struct {
StringList *list;
guint dep;
} data = {changed, dep};
g_hash_table_foreach_remove (table->hash,
(GHRFunc) remove_by_dep,
&data);
}
static Var *
var_new (guint dep,
GType type)
{
Var *var = g_new0 (Var, 1);
g_value_init (&var->value, type);
var->dep = dep;
return var;
}
static void
var_free (Var *var)
{
if (var)
{
g_value_unset (&var->value);
g_free (var);
}
}
static VarPool *
var_pool_new (void)
{
VarPool *pool = g_new0 (VarPool, 1);
pool->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) g_param_spec_unref);
return pool;
}
static GParamSpec *
var_pool_get_pspec (VarPool *pool,
const char *name)
{
return g_hash_table_lookup (pool->hash, name);
}
static const char *
var_pool_find_name (VarPool *pool,
const char *alias)
{
GParamSpec *pspec = var_pool_get_pspec (pool, alias);
return pspec ? g_param_spec_get_name (pspec) : NULL;
}
static void
var_pool_add (VarPool *pool,
GParamSpec *pspec)
{
const char *name = g_param_spec_get_name (pspec);
g_param_spec_ref (pspec);
g_param_spec_sink (pspec);
g_hash_table_insert (pool->hash, g_strdup (name), pspec);
}
static void
var_pool_add_alias (VarPool *pool,
const char *name,
const char *alias)
{
GParamSpec *pspec = var_pool_get_pspec (pool, name);
g_return_if_fail (pspec != NULL);
g_param_spec_ref (pspec);
g_hash_table_insert (pool->hash, g_strdup (alias), pspec);
}
G_END_DECLS
#endif /* __MOO_EDIT_VARS_H__ */

View File

@ -23,24 +23,15 @@
#include "mooedit/mooeditdialogs.h"
#include "mooedit/mooeditprefs.h"
#include "mooedit/mootextbuffer.h"
#include "mooedit/mooedit-vars.h"
#include "mooutils/moomarshals.h"
#include "mooutils/moocompat.h"
#include "mooutils/mooutils-gobject.h"
#include <string.h>
typedef struct {
char *str;
MooEditVarDep dep : 1;
} Value;
static Value *value_new (const char *str,
MooEditVarDep dep);
static void value_set (Value *value,
const char *str,
MooEditVarDep dep);
static void value_free (Value *value);
static VarPool *moo_edit_var_pool = NULL;
static void moo_edit_init_var_pool (void);
static GObject *moo_edit_constructor (GType type,
guint n_construct_properties,
@ -57,8 +48,7 @@ static void moo_edit_get_property (GObject *object,
GParamSpec *pspec);
static void moo_edit_variable_changed (MooEdit *edit,
const char *name,
const char *value);
const char *name);
static void moo_edit_filename_changed (MooEdit *edit,
const char *new_filename);
@ -68,9 +58,6 @@ static MooTextBuffer *get_moo_buffer (MooEdit *edit);
static void modified_changed_cb (GtkTextBuffer *buffer,
MooEdit *edit);
static void moo_edit_comment (MooEdit *edit);
static void moo_edit_uncomment (MooEdit *edit);
enum {
DOC_STATUS_CHANGED,
@ -101,6 +88,13 @@ moo_edit_class_init (MooEditClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
moo_edit_register_var (g_param_spec_string (MOO_EDIT_VAR_LANG, MOO_EDIT_VAR_LANG,
MOO_EDIT_VAR_LANG, NULL, 0));
moo_edit_register_var (g_param_spec_string (MOO_EDIT_VAR_INDENT, MOO_EDIT_VAR_INDENT,
MOO_EDIT_VAR_INDENT, NULL, 0));
moo_edit_register_var (g_param_spec_boolean (MOO_EDIT_VAR_STRIP, MOO_EDIT_VAR_STRIP,
MOO_EDIT_VAR_STRIP, FALSE, 0));
gobject_class->set_property = moo_edit_set_property;
gobject_class->get_property = moo_edit_get_property;
gobject_class->constructor = moo_edit_constructor;
@ -123,9 +117,8 @@ moo_edit_class_init (MooEditClass *klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (MooEditClass, variable_changed),
NULL, NULL,
_moo_marshal_VOID__STRING_STRING,
G_TYPE_NONE, 2,
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
_moo_marshal_VOID__STRING,
G_TYPE_NONE, 1,
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
signals[DOC_STATUS_CHANGED] =
@ -151,7 +144,7 @@ moo_edit_class_init (MooEditClass *klass)
moo_signal_new_cb ("comment",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_CALLBACK (moo_edit_comment),
NULL, /* G_CALLBACK (moo_edit_comment), */
NULL, NULL,
_moo_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@ -160,7 +153,7 @@ moo_edit_class_init (MooEditClass *klass)
moo_signal_new_cb ("uncomment",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_CALLBACK (moo_edit_uncomment),
NULL, /* G_CALLBACK (moo_edit_uncomment), */
NULL, NULL,
_moo_marshal_VOID__VOID,
G_TYPE_NONE, 0);
@ -191,11 +184,16 @@ moo_edit_class_init (MooEditClass *klass)
static void
moo_edit_init (MooEdit *edit)
{
MooIndenter *indent;
edit->priv = g_new0 (MooEditPrivate, 1);
edit->priv->file_watch_policy = MOO_EDIT_RELOAD_IF_SAFE;
edit->priv->enable_indentation = TRUE;
indent = moo_indenter_new (edit, NULL);
moo_text_view_set_indenter (MOO_TEXT_VIEW (edit), indent);
g_object_unref (indent);
/* XXX this is stupid */
#if defined(__WIN32__)
@ -206,8 +204,7 @@ moo_edit_init (MooEdit *edit)
edit->priv->line_end_type = MOO_EDIT_LINE_END_UNIX;
#endif
edit->priv->vars = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) value_free);
edit->priv->vars = var_table_new (moo_edit_var_pool);
g_object_set (edit, "draw-tabs", TRUE, "draw-trailing-spaces", TRUE, NULL);
}
@ -264,7 +261,7 @@ moo_edit_finalize (GObject *object)
g_free (edit->priv->display_basename);
g_free (edit->priv->encoding);
g_hash_table_destroy (edit->priv->vars);
var_table_free (edit->priv->vars);
g_free (edit->priv);
edit->priv = NULL;
@ -524,6 +521,7 @@ moo_edit_var_dep_get_type (void)
static const GEnumValue values[] = {
{ MOO_EDIT_VAR_DEP_NONE, (char*)"MOO_EDIT_VAR_DEP_NONE", (char*)"none" },
{ MOO_EDIT_VAR_DEP_FILENAME, (char*)"MOO_EDIT_VAR_DEP_FILENAME", (char*)"filename" },
{ MOO_EDIT_VAR_DEP_AUTO, (char*)"MOO_EDIT_VAR_DEP_AUTO", (char*)"auto" },
{ 0, NULL, NULL }
};
type = g_enum_register_static ("MooEditVarDep", values);
@ -604,14 +602,6 @@ moo_edit_set_lang (MooEdit *edit,
}
static MooLang*
moo_edit_get_lang (MooEdit *edit)
{
g_return_val_if_fail (MOO_IS_EDIT (edit), NULL);
return moo_text_buffer_get_lang (get_moo_buffer (edit));
}
void
moo_edit_set_highlight (MooEdit *edit,
gboolean highlight)
@ -629,101 +619,151 @@ moo_edit_get_highlight (MooEdit *edit)
}
static gboolean
is_ascii (const char *string)
{
while (*string++)
if ((guint8) *string > 127)
return FALSE;
return TRUE;
}
// static gboolean
// is_ascii (const char *string)
// {
// while (*string++)
// if ((guint8) *string > 127)
// return FALSE;
// return TRUE;
// }
//
//
// static void
// try_mode_string (MooEdit *edit,
// const char *text,
// const char *mode_string_start,
// const char *var_val_separator)
// {
// char *start, *mode_string;
// char **vars, **p;
//
// mode_string = NULL;
// vars = NULL;
//
// start = strstr (text, mode_string_start);
//
// if (!start || !start[strlen (mode_string_start)])
// goto out;
//
// start += strlen (mode_string_start);
//
// mode_string = g_strdup (start);
// g_strstrip (mode_string);
//
// vars = g_strsplit (mode_string, ";", 0);
//
// if (!vars)
// goto out;
//
// for (p = vars; *p != NULL; p++)
// {
// char *sep, *var, *value;
//
// g_strstrip (*p);
// sep = strstr (*p, var_val_separator);
//
// if (!sep || sep == *p || !sep[1])
// goto out;
//
// var = g_strndup (*p, sep - *p);
// g_strstrip (var);
//
// if (!var[0])
// {
// g_free (var);
// goto out;
// }
//
// value = sep + 1;
// g_strstrip (value);
//
// if (!value)
// {
// g_free (var);
// goto out;
// }
//
// moo_edit_set_var (edit, var, value);
//
// g_free (var);
// }
//
// out:
// g_free (mode_string);
// g_strfreev (vars);
// }
static void
try_mode_string (MooEdit *edit,
const char *text,
const char *mode_string_start,
const char *var_val_separator)
parse_kate_mode_string (G_GNUC_UNUSED MooEdit *edit,
G_GNUC_UNUSED char *string)
{
char *start, *mode_string;
char **vars, **p;
}
mode_string = NULL;
vars = NULL;
static void
parse_emacs_mode_string (G_GNUC_UNUSED MooEdit *edit,
G_GNUC_UNUSED char *string)
{
}
start = strstr (text, mode_string_start);
if (!start || !start[strlen (mode_string_start)])
goto out;
start += strlen (mode_string_start);
mode_string = g_strdup (start);
g_strstrip (mode_string);
vars = g_strsplit (mode_string, ";", 0);
if (!vars)
goto out;
for (p = vars; *p != NULL; p++)
{
char *sep, *var, *value;
g_strstrip (*p);
sep = strstr (*p, var_val_separator);
if (!sep || sep == *p || !sep[1])
goto out;
var = g_strndup (*p, sep - *p);
g_strstrip (var);
if (!var[0])
{
g_free (var);
goto out;
}
value = sep + 1;
g_strstrip (value);
if (!value)
{
g_free (var);
goto out;
}
moo_edit_set_var (edit, var, value);
g_free (var);
}
out:
g_free (mode_string);
g_strfreev (vars);
static void
parse_moo_mode_string (G_GNUC_UNUSED MooEdit *edit,
G_GNUC_UNUSED char *string)
{
}
#define KATE_MODE_STRING "kate:"
#define KATE_VAR_VAL_SEPARATOR " "
#define EMACS_MODE_STRING "-*-"
#define EMACS_VAR_VAL_SEPARATOR ":"
#define MOO_MODE_STRING "=*="
static void
try_mode (MooEdit *edit)
try_mode_string (MooEdit *edit,
char *string)
{
char *start, *end;
if ((start = strstr (string, KATE_MODE_STRING)))
{
start += strlen (KATE_MODE_STRING);
return parse_kate_mode_string (edit, start);
}
if ((start = strstr (string, EMACS_MODE_STRING)))
{
start += strlen (EMACS_MODE_STRING);
if ((end = strstr (start, EMACS_MODE_STRING)))
{
end[0] = 0;
return parse_emacs_mode_string (edit, start);
}
}
if ((start = strstr (string, MOO_MODE_STRING)))
{
start += strlen (MOO_MODE_STRING);
if ((end = strstr (start, MOO_MODE_STRING)))
{
end[0] = 0;
return parse_moo_mode_string (edit, start);
}
}
}
static void
try_mode_strings (MooEdit *edit)
{
GtkTextBuffer *buffer = get_buffer (edit);
GtkTextIter start, end;
char *text;
char *first, *last;
gtk_text_buffer_get_start_iter (buffer, &start);
end = start;
gtk_text_iter_forward_to_line_end (&end);
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
try_mode_string (edit, text, KATE_MODE_STRING, KATE_VAR_VAL_SEPARATOR);
try_mode_string (edit, text, EMACS_MODE_STRING, EMACS_VAR_VAL_SEPARATOR);
g_free (text);
first = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_text_buffer_get_end_iter (buffer, &end);
@ -739,238 +779,56 @@ try_mode (MooEdit *edit)
gtk_text_iter_set_line_offset (&start, 0);
}
text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
try_mode_string (edit, text, KATE_MODE_STRING, KATE_VAR_VAL_SEPARATOR);
g_free (text);
last = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
try_mode_string (edit, first);
try_mode_string (edit, last);
g_free (first);
g_free (last);
}
static void
moo_edit_comment (MooEdit *edit)
moo_edit_variable_changed (MooEdit *edit,
const char *name)
{
MooLang *lang = moo_edit_get_lang (edit);
if (!lang || (!lang->single_line_comment && !lang->multi_line_comment_start))
return;
g_return_if_fail (!lang->multi_line_comment_start || lang->multi_line_comment_end);
g_message ("comment");
}
static void
moo_edit_uncomment (MooEdit *edit)
{
MooLang *lang = moo_edit_get_lang (edit);
if (!lang || (!lang->single_line_comment && !lang->multi_line_comment_start))
return;
g_return_if_fail (!lang->multi_line_comment_start || lang->multi_line_comment_end);
g_message ("uncomment");
}
static Value *
get_value (MooEdit *edit,
const char *name)
{
return g_hash_table_lookup (edit->priv->vars, name);
}
static void
insert_value (MooEdit *edit,
const char *name,
Value *value)
{
if (value)
g_hash_table_insert (edit->priv->vars, g_strdup (name), value);
else
g_hash_table_remove (edit->priv->vars, name);
}
static void
set_variable (MooEdit *edit,
const char *name,
const char *strval,
MooEditVarDep dep)
{
char *key = NULL;
Value *value;
if (is_ascii (name))
key = g_ascii_strdown (name, -1);
else
key = g_strdup (name);
g_strdelimit (key, "-_", '-');
value = get_value (edit, name);
if (strval)
if (!strcmp (name, MOO_EDIT_VAR_LANG))
{
if (value)
{
if (value->dep >= dep)
value_set (value, strval, dep);
}
else
{
value = value_new (strval, dep);
insert_value (edit, key, value);
}
}
else if (value && value->dep >= dep)
{
insert_value (edit, key, NULL);
}
strval = strval ? value->str : NULL;
g_signal_emit (edit, signals[VARIABLE_CHANGED], 0, key, strval);
g_free (key);
}
void
moo_edit_set_var (MooEdit *edit,
const char *name,
const char *value)
{
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (name && name[0]);
moo_edit_set_var_full (edit, name, value,
MOO_EDIT_VAR_DEP_FILENAME);
}
void
moo_edit_set_var_full (MooEdit *edit,
const char *name,
const char *value,
MooEditVarDep dep)
{
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (name && name[0]);
set_variable (edit, name, value, dep);
}
const char*
moo_edit_get_var (MooEdit *edit,
const char *name)
{
Value *value;
g_return_val_if_fail (MOO_IS_EDIT (edit), NULL);
g_return_val_if_fail (name && name[0], NULL);
value = get_value (edit, name);
return value ? value->str : NULL;
}
static Value*
value_new (const char *str,
MooEditVarDep dep)
{
Value *val = g_new0 (Value, 1);
val->str = g_strdup (str);
val->dep = dep;
return val;
}
static void
value_set (Value *value,
const char *str,
MooEditVarDep dep)
{
char *tmp = g_strdup (str);
g_free (value->str);
value->str = tmp;
value->dep = dep;
}
static void
value_free (Value *value)
{
if (value)
{
g_free (value->str);
char *value = moo_edit_get_string (edit, name);
MooLangMgr *mgr = moo_editor_get_lang_mgr (edit->priv->editor);
MooLang *lang = value ? moo_lang_mgr_get_lang (mgr, value) : NULL;
moo_edit_set_lang (edit, lang);
g_free (value);
}
}
static void
moo_edit_variable_changed (MooEdit *edit,
const char *name,
const char *value)
{
if (!strcmp (name, MOO_EDIT_VAR_LANG))
{
MooLangMgr *mgr = moo_editor_get_lang_mgr (edit->priv->editor);
MooLang *lang = value ? moo_lang_mgr_get_lang (mgr, value) : NULL;
moo_edit_set_lang (edit, lang);
}
}
static void
moo_edit_choose_indenter (MooEdit *edit)
{
MooIndenter *indenter;
const char *name;
name = moo_edit_get_var (edit, MOO_EDIT_VAR_INDENTER);
if (!edit->priv->enable_indentation)
return;
indenter = moo_indenter_new (edit, name);
moo_text_view_set_indenter (MOO_TEXT_VIEW (edit), indenter);
g_object_unref (indenter);
}
static gboolean
check_dep (G_GNUC_UNUSED const char *name,
Value *value)
{
return value->dep >= MOO_EDIT_VAR_DEP_FILENAME;
}
static void
moo_edit_filename_changed (MooEdit *edit,
const char *filename)
{
MooLang *lang = NULL;
Value *value;
g_hash_table_foreach_remove (edit->priv->vars, (GHRFunc) check_dep, NULL);
_moo_edit_freeze_var_notify (edit);
value = get_value (edit, MOO_EDIT_VAR_LANG);
var_table_remove_by_dep (edit->priv->vars,
MOO_EDIT_VAR_DEP_FILENAME,
edit->priv->changed_vars);
if (!value || value->dep >= MOO_EDIT_VAR_DEP_FILENAME)
if (filename)
{
if (filename)
{
MooLangMgr *mgr = moo_editor_get_lang_mgr (edit->priv->editor);
lang = moo_lang_mgr_get_lang_for_file (mgr, filename);
}
moo_edit_set_var (edit, MOO_EDIT_VAR_LANG, lang ? lang->id : NULL);
MooLangMgr *mgr = moo_editor_get_lang_mgr (edit->priv->editor);
lang = moo_lang_mgr_get_lang_for_file (mgr, filename);
}
try_mode (edit);
moo_edit_set_string (edit, MOO_EDIT_VAR_LANG, lang ? lang->id : NULL,
MOO_EDIT_VAR_DEP_FILENAME);
moo_edit_set_string (edit, MOO_EDIT_VAR_INDENT, NULL,
MOO_EDIT_VAR_DEP_FILENAME);
try_mode_strings (edit);
moo_edit_choose_indenter (edit);
_moo_edit_thaw_var_notify (edit);
}
@ -1002,3 +860,297 @@ moo_edit_save_copy (MooEdit *edit,
return moo_editor_save_copy (edit->priv->editor, edit,
filename, encoding, error);
}
/*********************************************************************/
/* Variables
*/
void
moo_edit_set_var (MooEdit *edit,
const char *name,
const GValue *value,
MooEditVarDep dep)
{
Var *v;
GParamSpec *pspec;
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (name != NULL);
g_return_if_fail (!value || G_IS_VALUE (value));
pspec = var_pool_get_pspec (moo_edit_var_pool, name);
g_return_if_fail (pspec != NULL);
g_return_if_fail (!value || G_PARAM_SPEC_VALUE_TYPE (pspec) == G_VALUE_TYPE (value));
name = g_param_spec_get_name (pspec);
v = var_table_get (edit->priv->vars, name);
if (v && v->dep < dep)
return;
if (value)
{
if (!v)
{
v = var_new (dep, G_VALUE_TYPE (value));
var_table_insert (edit->priv->vars, name, v);
}
v->dep = dep;
g_value_copy (value, &v->value);
}
else
{
var_table_remove (edit->priv->vars, name);
}
_moo_edit_var_notify (edit, name);
}
gboolean
moo_edit_get_var (MooEdit *edit,
const char *name,
GValue *value)
{
Var *v;
g_return_val_if_fail (MOO_IS_EDIT (edit), FALSE);
g_return_val_if_fail (name != NULL, FALSE);
g_return_val_if_fail (!value || G_IS_VALUE (value), FALSE);
name = var_pool_find_name (moo_edit_var_pool, name);
g_return_val_if_fail (name != NULL, FALSE);
v = var_table_get (edit->priv->vars, name);
if (v && value)
{
g_return_val_if_fail (G_VALUE_TYPE (&v->value) == G_VALUE_TYPE (value), FALSE);
g_value_copy (&v->value, value);
}
return v != NULL;
}
char*
moo_edit_get_string (MooEdit *edit,
const char *name)
{
GValue val;
char *strval;
g_return_val_if_fail (MOO_IS_EDIT (edit), NULL);
g_return_val_if_fail (name != NULL, NULL);
val.g_type = 0;
g_value_init (&val, G_TYPE_STRING);
if (!moo_edit_get_var (edit, name, &val))
return NULL;
strval = g_value_dup_string (&val);
g_value_unset (&val);
return strval;
}
gboolean
moo_edit_get_bool (MooEdit *edit,
const char *name,
gboolean default_val)
{
GValue val;
g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
g_return_val_if_fail (name != NULL, default_val);
val.g_type = 0;
g_value_init (&val, G_TYPE_BOOLEAN);
if (!moo_edit_get_var (edit, name, &val))
return default_val;
return g_value_get_boolean (&val);
}
int
moo_edit_get_int (MooEdit *edit,
const char *name,
int default_val)
{
GValue val;
g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
g_return_val_if_fail (name != NULL, default_val);
val.g_type = 0;
g_value_init (&val, G_TYPE_INT);
if (!moo_edit_get_var (edit, name, &val))
return default_val;
return g_value_get_int (&val);
}
guint
moo_edit_get_uint (MooEdit *edit,
const char *name,
guint default_val)
{
GValue val;
g_return_val_if_fail (MOO_IS_EDIT (edit), default_val);
g_return_val_if_fail (name != NULL, default_val);
val.g_type = 0;
g_value_init (&val, G_TYPE_UINT);
if (!moo_edit_get_var (edit, name, &val))
return default_val;
return g_value_get_uint (&val);
}
void
moo_edit_set_string (MooEdit *edit,
const char *name,
const char *value,
MooEditVarDep dep)
{
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (name != NULL);
if (value)
{
GValue gval;
gval.g_type = 0;
g_value_init (&gval, G_TYPE_STRING);
g_value_set_static_string (&gval, value);
moo_edit_set_var (edit, name, &gval, dep);
g_value_unset (&gval);
}
else
{
moo_edit_set_var (edit, name, NULL, dep);
}
}
static void
emit_var_notify (MooEdit *edit,
const char *name)
{
g_signal_emit (edit, signals[VARIABLE_CHANGED], 0, name);
}
void
_moo_edit_var_notify (MooEdit *edit,
const char *name)
{
g_return_if_fail (MOO_IS_EDIT (edit));
if (edit->priv->freeze_var_notify)
{
if (!edit->priv->changed_vars)
edit->priv->changed_vars = string_list_new ();
string_list_add (edit->priv->changed_vars, name);
}
else
{
emit_var_notify (edit, name);
}
}
void
_moo_edit_freeze_var_notify (MooEdit *edit)
{
g_return_if_fail (MOO_IS_EDIT (edit));
edit->priv->freeze_var_notify++;
}
static void
emit_var_notify_cb (const char *varname,
G_GNUC_UNUSED gpointer dummy,
MooEdit *edit)
{
emit_var_notify (edit, varname);
}
void
_moo_edit_thaw_var_notify (MooEdit *edit)
{
g_return_if_fail (MOO_IS_EDIT (edit));
g_return_if_fail (edit->priv->freeze_var_notify > 0);
if (!--edit->priv->freeze_var_notify && edit->priv->changed_vars)
{
StringList *vars = edit->priv->changed_vars;
edit->priv->changed_vars = NULL;
g_object_ref (edit);
g_hash_table_foreach (vars->hash, (GHFunc) emit_var_notify_cb, edit);
g_object_unref (edit);
string_list_free (vars);
}
}
void
moo_edit_register_var (GParamSpec *pspec)
{
g_return_if_fail (G_IS_PARAM_SPEC (pspec));
moo_edit_init_var_pool ();
if (var_pool_get_pspec (moo_edit_var_pool, g_param_spec_get_name (pspec)))
{
g_critical ("%s: variable '%s' already registered",
G_STRLOC, g_param_spec_get_name (pspec));
return;
}
var_pool_add (moo_edit_var_pool, pspec);
}
void
moo_edit_register_var_alias (const char *name,
const char *alias)
{
g_return_if_fail (name != NULL);
g_return_if_fail (alias != NULL);
moo_edit_init_var_pool ();
if (!var_pool_get_pspec (moo_edit_var_pool, name))
{
g_critical ("%s: no variable '%s'", G_STRLOC, name);
return;
}
if (var_pool_get_pspec (moo_edit_var_pool, alias))
{
g_critical ("%s: variable '%s' already registered",
G_STRLOC, alias);
return;
}
var_pool_add_alias (moo_edit_var_pool, name, alias);
}
static void
moo_edit_init_var_pool (void)
{
if (!moo_edit_var_pool)
moo_edit_var_pool = var_pool_new ();
}

View File

@ -37,12 +37,13 @@ G_BEGIN_DECLS
typedef enum {
MOO_EDIT_VAR_DEP_NONE = 0,
MOO_EDIT_VAR_DEP_FILENAME = 1
MOO_EDIT_VAR_DEP_FILENAME = 1,
MOO_EDIT_VAR_DEP_AUTO = 2
} MooEditVarDep;
#define MOO_EDIT_VAR_LANG "lang"
#define MOO_EDIT_VAR_INDENTER "indenter"
#define MOO_EDIT_VAR_STRIP "strip"
#define MOO_EDIT_VAR_LANG "lang"
#define MOO_EDIT_VAR_INDENT "indent"
#define MOO_EDIT_VAR_STRIP "strip"
typedef enum {
@ -95,8 +96,7 @@ struct _MooEditClass
void (* lang_changed) (MooEdit *edit);
void (* variable_changed) (MooEdit *edit,
const char *variable,
const char *value);
const char *name);
void (* save_before) (MooEdit *edit);
void (* save_after) (MooEdit *edit);
@ -140,13 +140,31 @@ gboolean moo_edit_get_highlight (MooEdit *edit);
void moo_edit_set_var (MooEdit *edit,
const char *name,
const char *value);
void moo_edit_set_var_full (MooEdit *edit,
const GValue *value,
MooEditVarDep dep);
gboolean moo_edit_get_var (MooEdit *edit,
const char *name,
GValue *value);
char *moo_edit_get_string (MooEdit *edit,
const char *name);
gboolean moo_edit_get_bool (MooEdit *edit,
const char *name,
gboolean default_val);
int moo_edit_get_int (MooEdit *edit,
const char *name,
int default_val);
guint moo_edit_get_uint (MooEdit *edit,
const char *name,
guint default_val);
void moo_edit_set_string (MooEdit *edit,
const char *name,
const char *value,
MooEditVarDep dep);
const char *moo_edit_get_var (MooEdit *edit,
const char *name);
void moo_edit_register_var (GParamSpec *pspec);
void moo_edit_register_var_alias (const char *name,
const char *alias);
gboolean moo_edit_save (MooEdit *edit);
gboolean moo_edit_save_as (MooEdit *edit,

View File

@ -1184,7 +1184,7 @@ handle_enter (MooTextView *view,
gtk_text_buffer_delete (buffer, &start, &end);
/* XXX insert "\r\n" on windows? */
gtk_text_buffer_insert (buffer, &start, "\n", 1);
moo_indenter_character (view->priv->indenter, buffer, '\n', &start);
moo_indenter_character (view->priv->indenter, '\n', &start);
gtk_text_buffer_end_user_action (buffer);

View File

@ -746,8 +746,13 @@ moo_editor_add_doc (MooEditor *editor,
g_hash_table_insert (editor->priv->savers, doc, moo_edit_saver_ref (saver));
if (!moo_edit_get_filename (doc) &&
!moo_edit_get_var (doc, MOO_EDIT_VAR_LANG) && editor->priv->default_lang)
moo_edit_set_var (doc, MOO_EDIT_VAR_LANG, editor->priv->default_lang);
!moo_edit_get_string (doc, MOO_EDIT_VAR_LANG) &&
editor->priv->default_lang)
{
moo_edit_set_string (doc, MOO_EDIT_VAR_LANG,
editor->priv->default_lang,
MOO_EDIT_VAR_DEP_AUTO);
}
}
@ -1377,18 +1382,11 @@ do_save (MooEditor *editor,
GError **error)
{
gboolean result;
gboolean strip_whitespace = FALSE;
const char *var;
gboolean strip;
var = moo_edit_get_var (doc, MOO_EDIT_VAR_STRIP);
strip = moo_edit_get_bool (doc, MOO_EDIT_VAR_STRIP, FALSE);
if (var) /* XXX */
strip_whitespace = !g_ascii_strcasecmp (var, "true") ||
!g_ascii_strcasecmp (var, "on");
else
strip_whitespace = editor->priv->strip_whitespace;
if (strip_whitespace)
if (strip)
moo_text_view_strip_whitespace (MOO_TEXT_VIEW (doc));
g_signal_emit_by_name (doc, "save-before");

View File

@ -1771,7 +1771,7 @@ lang_item_activated (MooEditWindow *window,
g_return_if_fail (doc != NULL);
g_return_if_fail (MOO_IS_EDIT_WINDOW (window));
old_val = moo_edit_get_var (doc, MOO_EDIT_VAR_LANG);
old_val = moo_edit_get_string (doc, MOO_EDIT_VAR_LANG);
if (old_val)
do_set = !lang_name || strcmp (old_val, lang_name);
@ -1779,8 +1779,8 @@ lang_item_activated (MooEditWindow *window,
do_set = !!lang_name;
if (do_set)
moo_edit_set_var_full (doc, MOO_EDIT_VAR_LANG, lang_name,
MOO_EDIT_VAR_DEP_NONE);
moo_edit_set_string (doc, MOO_EDIT_VAR_LANG, lang_name,
MOO_EDIT_VAR_DEP_NONE);
}

View File

@ -15,6 +15,7 @@
#define MOOINDENTER_COMPILATION
#include "mooedit/mooindenter.h"
#include "mooedit/mooedit.h"
#include "mooutils/moomarshals.h"
#include <string.h>
@ -34,22 +35,22 @@ static void moo_indenter_get_property (GObject *object,
GParamSpec *pspec);
static void character_default (MooIndenter *indenter,
GtkTextBuffer *buffer,
gunichar inserted_char,
GtkTextIter *where);
static void set_value_default (MooIndenter *indenter,
const char *var,
const char *value);
static void update_variable_default (MooIndenter *indenter,
const char *var);
static void variable_changed (MooIndenter *indenter,
const char *var,
const char *value);
const char *var);
enum {
UPDATE_VARIABLE,
CHARACTER,
LAST_SIGNAL
};
// static guint signals[LAST_SIGNAL];
static guint signals[LAST_SIGNAL];
enum {
PROP_0,
@ -75,7 +76,15 @@ moo_indenter_class_init (MooIndenterClass *klass)
gobject_class->get_property = moo_indenter_get_property;
klass->character = character_default;
klass->set_value = set_value_default;
klass->update_variable = update_variable_default;
moo_edit_register_var (g_param_spec_uint ("indent-tab-width", "indent-tab-width",
"indent-tab-width", 1, G_MAXUINT, 8, 0));
moo_edit_register_var (g_param_spec_boolean ("indent-use-tabs",
"indent-use-tabs", "indent-use-tabs", TRUE, 0));
moo_edit_register_var_alias ("indent-use-tabs", "use-tabs");
moo_edit_register_var (g_param_spec_uint ("indent-width", "indent-width",
"indent-width", 1, G_MAXUINT, 8, 0));
g_object_class_install_property (gobject_class,
PROP_DOC,
@ -112,6 +121,27 @@ moo_indenter_class_init (MooIndenterClass *klass)
G_MAXUINT,
8,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
signals[UPDATE_VARIABLE] =
g_signal_new ("update-variable",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (MooIndenterClass, update_variable),
NULL, NULL,
_moo_marshal_VOID__STRING,
G_TYPE_NONE, 1,
G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE);
signals[CHARACTER] =
g_signal_new ("character",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (MooIndenterClass, character),
NULL, NULL,
_moo_marshal_VOID__UINT_BOXED,
G_TYPE_NONE, 1,
G_TYPE_UINT,
GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE);
}
@ -135,24 +165,22 @@ moo_indenter_constructor (GType type,
if (indent->doc)
{
guint i;
static const char *known_vars[] = {
"tab-width", "indent-tabs-mode",
"space-indent", "indent-width",
"c-basic-offset"
static const char *vars[] = {
"indent-tab-width",
"indent-width",
"indent-use-tabs"
};
for (i = 0; i < G_N_ELEMENTS (known_vars); ++i)
moo_indenter_set_value (indent, known_vars[i], NULL);
for (i = 0; i < G_N_ELEMENTS (known_vars); ++i)
for (i = 0; i < G_N_ELEMENTS (vars); ++i)
{
const char *val = moo_edit_get_var (indent->doc, known_vars[i]);
if (val)
moo_indenter_set_value (indent, known_vars[i], val);
if (moo_edit_get_var (indent->doc, vars[i], NULL))
variable_changed (indent, vars[i]);
}
g_signal_connect_swapped (indent->doc, "variable-changed",
G_CALLBACK (variable_changed), indent);
G_CALLBACK (variable_changed),
indent);
}
return object;
@ -243,32 +271,19 @@ static void moo_indenter_get_property (GObject *object,
static void
variable_changed (MooIndenter *indenter,
const char *var,
const char *value)
const char *var)
{
moo_indenter_set_value (indenter, var, value);
g_signal_emit (indenter, signals[UPDATE_VARIABLE], 0, var);
}
void
moo_indenter_character (MooIndenter *indenter,
GtkTextBuffer *buffer,
gunichar inserted_char,
GtkTextIter *where)
{
g_return_if_fail (MOO_IS_INDENTER (indenter));
MOO_INDENTER_GET_CLASS(indenter)->character (indenter, buffer, inserted_char, where);
}
void
moo_indenter_set_value (MooIndenter *indenter,
const char *var,
const char *value)
{
g_return_if_fail (MOO_IS_INDENTER (indenter));
g_return_if_fail (var && var[0]);
MOO_INDENTER_GET_CLASS(indenter)->set_value (indenter, var, value);
MOO_INDENTER_GET_CLASS(indenter)->character (indenter, inserted_char, where);
}
@ -376,12 +391,12 @@ compute_line_offset (GtkTextIter *iter,
static void
character_default (MooIndenter *indenter,
GtkTextBuffer *buffer,
gunichar inserted_char,
GtkTextIter *where)
{
int i;
char *indent_string = NULL;
GtkTextBuffer *buffer = gtk_text_iter_get_buffer (where);
if (inserted_char != '\n')
return;
@ -676,31 +691,22 @@ moo_indenter_shift_lines (MooIndenter *indenter,
static void
set_value_default (MooIndenter *indenter,
const char *var,
const char *value)
update_variable_default (MooIndenter *indenter,
const char *var)
{
if (!g_ascii_strcasecmp (var, "tab-width"))
if (!strcmp (var, "indent-tab-width"))
{
guint64 tab_width = value ? g_ascii_strtoull (value, NULL, 10) : 8;
if (tab_width > 0 && tab_width < G_MAXUINT)
indenter->tab_width = tab_width;
guint tab_width = moo_edit_get_uint (indenter->doc, var, 8);
g_object_set (indenter, "tab-width", tab_width, NULL);
}
else if (!g_ascii_strcasecmp (var, "indent-tabs-mode"))
else if (!strcmp (var, "indent-use-tabs"))
{
indenter->use_tabs = value ? !g_ascii_strcasecmp (value, "t") : TRUE;
gboolean use_tabs = moo_edit_get_bool (indenter->doc, var, TRUE);
g_object_set (indenter, "use-tabs", use_tabs, NULL);
}
else if (!g_ascii_strcasecmp (var, "space-indent"))
else if (!strcmp (var, "indent-width"))
{
indenter->use_tabs = value ? !!g_ascii_strcasecmp (value, "on") : FALSE;
}
else if (!g_ascii_strcasecmp (var, "c-basic-offset") ||
!g_ascii_strcasecmp (var, "indent-width"))
{
guint64 indent = value ? g_ascii_strtoull (value, NULL, 10) : 8;
if (indent > 0 && indent < G_MAXUINT)
indenter->indent = indent;
guint width = moo_edit_get_uint (indenter->doc, var, 8);
g_object_set (indenter, "indent-width", width, NULL);
}
}

View File

@ -46,14 +46,11 @@ struct _MooIndenterClass
{
GObjectClass parent_class;
void (*set_value) (MooIndenter *indenter,
const char *var,
const char *value);
void (*character) (MooIndenter *indenter,
GtkTextBuffer *buffer,
gunichar inserted_char,
GtkTextIter *where);
void (*update_variable) (MooIndenter *indenter,
const char *varname);
void (*character) (MooIndenter *indenter,
gunichar inserted_char,
GtkTextIter *where);
};
@ -62,16 +59,11 @@ GType moo_indenter_get_type (void) G_GNUC_CONST;
MooIndenter *moo_indenter_new (gpointer doc,
const char *name);
void moo_indenter_set_value (MooIndenter *indenter,
const char *var,
const char *value);
char *moo_indenter_make_space (MooIndenter *indenter,
guint len,
guint start);
void moo_indenter_character (MooIndenter *indenter,
GtkTextBuffer *buffer,
gunichar inserted_char,
GtkTextIter *where);
void moo_indenter_tab (MooIndenter *indenter,

View File

@ -930,7 +930,7 @@ moo_text_view_char_inserted (MooTextView *view,
{
GtkTextBuffer *buffer = get_buffer (view);
gtk_text_buffer_begin_user_action (buffer);
moo_indenter_character (view->priv->indenter, buffer,
moo_indenter_character (view->priv->indenter,
character, where);
gtk_text_buffer_end_user_action (buffer);
return TRUE;

View File

@ -123,6 +123,7 @@
(values
'("none" "MOO_EDIT_VAR_DEP_NONE")
'("filename" "MOO_EDIT_VAR_DEP_FILENAME")
'("auto" "MOO_EDIT_VAR_DEP_AUTO")
)
)
@ -345,35 +346,35 @@
(return-type "gboolean")
)
(define-method set_var
(of-object "MooEdit")
(c-name "moo_edit_set_var")
(return-type "none")
(parameters
'("const-char*" "name")
'("const-char*" "value" (null-ok))
)
)
;; (define-method set_var
;; (of-object "MooEdit")
;; (c-name "moo_edit_set_var")
;; (return-type "none")
;; (parameters
;; '("const-char*" "name")
;; '("const-char*" "value" (null-ok))
;; )
;; )
(define-method set_var_full
(of-object "MooEdit")
(c-name "moo_edit_set_var_full")
(return-type "none")
(parameters
'("const-char*" "name")
'("const-char*" "value" (null-ok))
'("MooEditVarDep" "dep")
)
)
;; (define-method set_var_full
;; (of-object "MooEdit")
;; (c-name "moo_edit_set_var_full")
;; (return-type "none")
;; (parameters
;; '("const-char*" "name")
;; '("const-char*" "value" (null-ok))
;; '("MooEditVarDep" "dep")
;; )
;; )
(define-method get_var
(of-object "MooEdit")
(c-name "moo_edit_get_var")
(return-type "const-char*")
(parameters
'("const-char*" "name")
)
)
;; (define-method get_var
;; (of-object "MooEdit")
;; (c-name "moo_edit_get_var")
;; (return-type "const-char*")
;; (parameters
;; '("const-char*" "name")
;; )
;; )
(define-method save
(of-object "MooEdit")
@ -539,16 +540,6 @@
)
)
(define-method set_value
(of-object "MooIndenter")
(c-name "moo_indenter_set_value")
(return-type "none")
(parameters
'("const-char*" "var")
'("const-char*" "value")
)
)
(define-method make_space
(of-object "MooIndenter")
(c-name "moo_indenter_make_space")
@ -564,7 +555,6 @@
(c-name "moo_indenter_character")
(return-type "none")
(parameters
'("GtkTextBuffer*" "buffer")
'("gunichar" "inserted_char")
'("GtkTextIter*" "where")
)

View File

@ -30,4 +30,5 @@ VOID:STRING
VOID:STRING,INT
VOID:STRING,STRING
VOID:UINT
VOID:UINT,BOXED
VOID:VOID