MooCompletion tries all groups now; groups may have a suffix to insert after completion
This commit is contained in:
parent
1176fcbb8f
commit
5812b8897b
@ -20,35 +20,41 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
COLUMN_DATA,
|
||||||
|
COLUMN_GROUP
|
||||||
|
};
|
||||||
|
|
||||||
struct _MooCompletionPrivate {
|
struct _MooCompletionPrivate {
|
||||||
GtkListStore *store;
|
GtkListStore *store;
|
||||||
GSList *groups;
|
GSList *groups;
|
||||||
MooCompletionGroup *active_group;
|
GSList *active_groups;
|
||||||
|
GList *data;
|
||||||
|
|
||||||
GtkTextView *doc;
|
GtkTextView *doc;
|
||||||
GtkTextBuffer *buffer;
|
GtkTextBuffer *buffer;
|
||||||
GtkTextMark *start;
|
GtkTextMark *start;
|
||||||
GtkTextMark *end;
|
GtkTextMark *end;
|
||||||
|
|
||||||
|
MooCompletionStringFunc string_func;
|
||||||
|
MooCompletionFreeFunc free_func;
|
||||||
|
MooCompletionCmpFunc cmp_func;
|
||||||
|
|
||||||
MooTextPopup *popup;
|
MooTextPopup *popup;
|
||||||
guint working : 1;
|
guint working : 1;
|
||||||
guint in_update : 1;
|
guint in_update : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MooCompletionGroup {
|
struct _MooCompletionGroup {
|
||||||
guint ref_count;
|
|
||||||
|
|
||||||
EggRegex *regex;
|
EggRegex *regex;
|
||||||
guint *parens;
|
guint *parens;
|
||||||
guint n_parens;
|
guint n_parens;
|
||||||
|
|
||||||
GCompletion *cmpl;
|
GCompletion *cmpl;
|
||||||
GList *data;
|
GList *data;
|
||||||
GList *tmp;
|
char *suffix;
|
||||||
|
|
||||||
MooCompletionStringFunc string_func;
|
|
||||||
MooCompletionFreeFunc free_func;
|
MooCompletionFreeFunc free_func;
|
||||||
MooCompletionCmpFunc cmp_func;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -56,11 +62,11 @@ static void moo_completion_dispose (GObject *object);
|
|||||||
|
|
||||||
static void moo_completion_update (MooCompletion *cmpl);
|
static void moo_completion_update (MooCompletion *cmpl);
|
||||||
static void moo_completion_populate (MooCompletion *cmpl,
|
static void moo_completion_populate (MooCompletion *cmpl,
|
||||||
MooCompletionGroup *group,
|
|
||||||
const char *text,
|
const char *text,
|
||||||
char **prefix);
|
char **prefix);
|
||||||
static void moo_completion_complete (MooCompletion *cmpl,
|
static void moo_completion_complete (MooCompletion *cmpl,
|
||||||
gpointer data);
|
GtkTreeModel *model,
|
||||||
|
GtkTreeIter *iter);
|
||||||
|
|
||||||
static void moo_completion_connect_popup (MooCompletion *cmpl);
|
static void moo_completion_connect_popup (MooCompletion *cmpl);
|
||||||
static void moo_completion_disconnect_popup (MooCompletion *cmpl);
|
static void moo_completion_disconnect_popup (MooCompletion *cmpl);
|
||||||
@ -68,8 +74,15 @@ static void moo_completion_disconnect_popup (MooCompletion *cmpl);
|
|||||||
static gboolean moo_completion_empty (MooCompletion *cmpl);
|
static gboolean moo_completion_empty (MooCompletion *cmpl);
|
||||||
static gboolean moo_completion_unique (MooCompletion *cmpl,
|
static gboolean moo_completion_unique (MooCompletion *cmpl,
|
||||||
GtkTreeIter *iter);
|
GtkTreeIter *iter);
|
||||||
static gpointer moo_completion_get_data (MooCompletion *cmpl,
|
static int list_sort_func (GtkTreeModel *model,
|
||||||
GtkTreeIter *iter);
|
GtkTreeIter *a,
|
||||||
|
GtkTreeIter *b,
|
||||||
|
MooCompletion *cmpl);
|
||||||
|
|
||||||
|
static MooCompletionGroup *moo_completion_group_new
|
||||||
|
(MooCompletionStringFunc string_func,
|
||||||
|
MooCompletionFreeFunc free_func);
|
||||||
|
static void moo_completion_group_free (MooCompletionGroup *group);
|
||||||
|
|
||||||
static gboolean moo_completion_group_find (MooCompletionGroup *group,
|
static gboolean moo_completion_group_find (MooCompletionGroup *group,
|
||||||
const char *line,
|
const char *line,
|
||||||
@ -93,8 +106,9 @@ moo_completion_dispose (GObject *object)
|
|||||||
moo_completion_set_doc (cmpl, NULL);
|
moo_completion_set_doc (cmpl, NULL);
|
||||||
|
|
||||||
g_object_unref (cmpl->priv->store);
|
g_object_unref (cmpl->priv->store);
|
||||||
g_slist_foreach (cmpl->priv->groups, (GFunc) moo_completion_group_unref, NULL);
|
g_slist_foreach (cmpl->priv->groups, (GFunc) moo_completion_group_free, NULL);
|
||||||
g_slist_free (cmpl->priv->groups);
|
g_slist_free (cmpl->priv->groups);
|
||||||
|
g_slist_free (cmpl->priv->active_groups);
|
||||||
|
|
||||||
if (cmpl->priv->popup)
|
if (cmpl->priv->popup)
|
||||||
{
|
{
|
||||||
@ -121,7 +135,12 @@ static void
|
|||||||
moo_completion_init (MooCompletion *cmpl)
|
moo_completion_init (MooCompletion *cmpl)
|
||||||
{
|
{
|
||||||
cmpl->priv = g_new0 (MooCompletionPrivate, 1);
|
cmpl->priv = g_new0 (MooCompletionPrivate, 1);
|
||||||
cmpl->priv->store = gtk_list_store_new (1, G_TYPE_POINTER);
|
cmpl->priv->store = gtk_list_store_new (2, G_TYPE_POINTER,
|
||||||
|
G_TYPE_POINTER);
|
||||||
|
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (cmpl->priv->store),
|
||||||
|
COLUMN_DATA,
|
||||||
|
(GtkTreeIterCompareFunc) list_sort_func,
|
||||||
|
cmpl, NULL);
|
||||||
cmpl->priv->popup = moo_text_popup_new (NULL);
|
cmpl->priv->popup = moo_text_popup_new (NULL);
|
||||||
moo_completion_connect_popup (cmpl);
|
moo_completion_connect_popup (cmpl);
|
||||||
}
|
}
|
||||||
@ -132,11 +151,10 @@ moo_completion_try_complete (MooCompletion *cmpl,
|
|||||||
gboolean insert_unique)
|
gboolean insert_unique)
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
MooCompletionGroup *group;
|
|
||||||
GtkTextIter start, end;
|
GtkTextIter start, end;
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
gboolean found = FALSE;
|
gboolean found = FALSE;
|
||||||
int start_pos, end_pos;
|
int start_pos = -1, end_pos = -1;
|
||||||
char *prefix = NULL, *text = NULL, *line;
|
char *prefix = NULL, *text = NULL, *line;
|
||||||
|
|
||||||
g_return_if_fail (MOO_IS_COMPLETION (cmpl));
|
g_return_if_fail (MOO_IS_COMPLETION (cmpl));
|
||||||
@ -154,35 +172,49 @@ moo_completion_try_complete (MooCompletion *cmpl,
|
|||||||
|
|
||||||
line = gtk_text_buffer_get_slice (cmpl->priv->buffer, &start, &end, TRUE);
|
line = gtk_text_buffer_get_slice (cmpl->priv->buffer, &start, &end, TRUE);
|
||||||
|
|
||||||
for (l = cmpl->priv->groups; !found && l != NULL; l = l->next)
|
for (l = cmpl->priv->groups; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
group = l->data;
|
int start_pos_here, end_pos_here;
|
||||||
found = moo_completion_group_find (group, line, &start_pos, &end_pos);
|
MooCompletionGroup *grp = l->data;
|
||||||
|
|
||||||
|
if (!moo_completion_group_find (grp, line, &start_pos_here, &end_pos_here))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
start_pos = start_pos_here;
|
||||||
|
end_pos = end_pos_here;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start_pos_here == start_pos && end_pos_here == end_pos)
|
||||||
|
cmpl->priv->active_groups =
|
||||||
|
g_slist_prepend (cmpl->priv->active_groups, grp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
cmpl->priv->active_group = group;
|
cmpl->priv->active_groups = g_slist_reverse (cmpl->priv->active_groups);
|
||||||
|
|
||||||
gtk_text_iter_set_line_index (&start, start_pos);
|
gtk_text_iter_set_line_index (&start, start_pos);
|
||||||
gtk_text_iter_set_line_index (&end, end_pos);
|
gtk_text_iter_set_line_index (&end, end_pos);
|
||||||
|
|
||||||
text = gtk_text_buffer_get_slice (cmpl->priv->buffer, &start, &end, TRUE);
|
text = gtk_text_buffer_get_slice (cmpl->priv->buffer, &start, &end, TRUE);
|
||||||
moo_completion_set_region (cmpl, &start, &end);
|
moo_completion_set_region (cmpl, &start, &end);
|
||||||
moo_completion_populate (cmpl, group, text, &prefix);
|
moo_completion_populate (cmpl, text, &prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found || moo_completion_empty (cmpl))
|
if (!found || moo_completion_empty (cmpl))
|
||||||
{
|
{
|
||||||
cmpl->priv->active_group = NULL;
|
g_slist_free (cmpl->priv->active_groups);
|
||||||
|
cmpl->priv->active_groups = NULL;
|
||||||
cmpl->priv->working = FALSE;
|
cmpl->priv->working = FALSE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insert_unique && moo_completion_unique (cmpl, &iter))
|
if (insert_unique && moo_completion_unique (cmpl, &iter))
|
||||||
{
|
{
|
||||||
gpointer data = moo_completion_get_data (cmpl, &iter);
|
moo_completion_complete (cmpl, GTK_TREE_MODEL (cmpl->priv->store), &iter);
|
||||||
moo_completion_complete (cmpl, data);
|
|
||||||
cmpl->priv->working = FALSE;
|
cmpl->priv->working = FALSE;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -209,61 +241,76 @@ static void
|
|||||||
moo_completion_update (MooCompletion *cmpl)
|
moo_completion_update (MooCompletion *cmpl)
|
||||||
{
|
{
|
||||||
GtkTextIter start, end;
|
GtkTextIter start, end;
|
||||||
GList *list;
|
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
g_return_if_fail (cmpl->priv->working);
|
g_return_if_fail (cmpl->priv->working);
|
||||||
g_return_if_fail (cmpl->priv->active_group != NULL);
|
g_return_if_fail (cmpl->priv->active_groups != NULL);
|
||||||
|
|
||||||
moo_completion_get_region (cmpl, &start, &end);
|
moo_completion_get_region (cmpl, &start, &end);
|
||||||
text = gtk_text_buffer_get_slice (cmpl->priv->buffer, &start, &end, TRUE);
|
text = gtk_text_buffer_get_slice (cmpl->priv->buffer, &start, &end, TRUE);
|
||||||
|
|
||||||
list = moo_completion_group_complete (cmpl->priv->active_group, text, NULL);
|
moo_completion_populate (cmpl, text, NULL);
|
||||||
gtk_list_store_clear (cmpl->priv->store);
|
|
||||||
|
|
||||||
if (list)
|
|
||||||
{
|
|
||||||
while (list)
|
|
||||||
{
|
|
||||||
GtkTreeIter iter;
|
|
||||||
gtk_list_store_append (cmpl->priv->store, &iter);
|
|
||||||
gtk_list_store_set (cmpl->priv->store, &iter, 0, list->data, -1);
|
|
||||||
list = list->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!moo_completion_empty (cmpl))
|
||||||
moo_text_popup_update (cmpl->priv->popup);
|
moo_text_popup_update (cmpl->priv->popup);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
moo_completion_hide (cmpl);
|
moo_completion_hide (cmpl);
|
||||||
}
|
|
||||||
|
|
||||||
g_free (text);
|
g_free (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
list_sort_func (GtkTreeModel *model,
|
||||||
|
GtkTreeIter *a,
|
||||||
|
GtkTreeIter *b,
|
||||||
|
MooCompletion *cmpl)
|
||||||
|
{
|
||||||
|
gpointer data1, data2;
|
||||||
|
|
||||||
|
g_assert (MOO_IS_COMPLETION (cmpl));
|
||||||
|
g_assert (model == GTK_TREE_MODEL (cmpl->priv->store));
|
||||||
|
g_assert (cmpl->priv->cmp_func != NULL);
|
||||||
|
|
||||||
|
gtk_tree_model_get (model, a, COLUMN_DATA, &data1, -1);
|
||||||
|
gtk_tree_model_get (model, b, COLUMN_DATA, &data2, -1);
|
||||||
|
|
||||||
|
return cmpl->priv->cmp_func (data1, data2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
moo_completion_complete (MooCompletion *cmpl,
|
moo_completion_complete (MooCompletion *cmpl,
|
||||||
gpointer data)
|
GtkTreeModel *model,
|
||||||
|
GtkTreeIter *iter)
|
||||||
{
|
{
|
||||||
char *text, *old_text;
|
char *text, *old_text;
|
||||||
GtkTextIter start, end;
|
GtkTextIter start, end;
|
||||||
|
gpointer data = NULL;
|
||||||
|
MooCompletionGroup *group = NULL;
|
||||||
|
|
||||||
g_return_if_fail (cmpl->priv->active_group != NULL);
|
g_return_if_fail (cmpl->priv->active_groups != NULL);
|
||||||
|
|
||||||
text = cmpl->priv->active_group->string_func ?
|
gtk_tree_model_get (model, iter, COLUMN_DATA, &data, COLUMN_GROUP, &group, -1);
|
||||||
cmpl->priv->active_group->string_func (data) : data;
|
g_assert (group != NULL);
|
||||||
|
|
||||||
|
text = cmpl->priv->string_func ? cmpl->priv->string_func (data) : data;
|
||||||
g_return_if_fail (text != NULL);
|
g_return_if_fail (text != NULL);
|
||||||
|
|
||||||
moo_completion_get_region (cmpl, &start, &end);
|
moo_completion_get_region (cmpl, &start, &end);
|
||||||
old_text = gtk_text_buffer_get_slice (cmpl->priv->buffer,
|
old_text = gtk_text_buffer_get_slice (cmpl->priv->buffer,
|
||||||
&start, &end, TRUE);
|
&start, &end, TRUE);
|
||||||
|
|
||||||
if (strcmp (text, old_text))
|
if (strcmp (text, old_text) || group->suffix)
|
||||||
{
|
{
|
||||||
gtk_text_buffer_begin_user_action (cmpl->priv->buffer);
|
gtk_text_buffer_begin_user_action (cmpl->priv->buffer);
|
||||||
|
|
||||||
gtk_text_buffer_delete (cmpl->priv->buffer, &start, &end);
|
gtk_text_buffer_delete (cmpl->priv->buffer, &start, &end);
|
||||||
gtk_text_buffer_insert (cmpl->priv->buffer, &start, text, -1);
|
gtk_text_buffer_insert (cmpl->priv->buffer, &start, text, -1);
|
||||||
|
|
||||||
|
if (group->suffix)
|
||||||
|
gtk_text_buffer_insert (cmpl->priv->buffer, &start, group->suffix, -1);
|
||||||
|
|
||||||
gtk_text_buffer_end_user_action (cmpl->priv->buffer);
|
gtk_text_buffer_end_user_action (cmpl->priv->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,22 +322,54 @@ moo_completion_complete (MooCompletion *cmpl,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
moo_completion_populate (MooCompletion *cmpl,
|
moo_completion_populate (MooCompletion *cmpl,
|
||||||
MooCompletionGroup *group,
|
|
||||||
const char *text,
|
const char *text,
|
||||||
char **prefix)
|
char **prefix)
|
||||||
{
|
{
|
||||||
GList *list;
|
GSList *l;
|
||||||
|
char *prefix_here = NULL;
|
||||||
|
|
||||||
gtk_list_store_clear (cmpl->priv->store);
|
gtk_list_store_clear (cmpl->priv->store);
|
||||||
list = moo_completion_group_complete (group, text, prefix);
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (cmpl->priv->store),
|
||||||
|
GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
|
||||||
|
GTK_SORT_ASCENDING);
|
||||||
|
|
||||||
while (list)
|
for (l = cmpl->priv->active_groups; l != NULL; l = l->next)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter;
|
char *new_prefix = NULL;
|
||||||
gtk_list_store_append (cmpl->priv->store, &iter);
|
MooCompletionGroup *group = l->data;
|
||||||
gtk_list_store_set (cmpl->priv->store, &iter, 0, list->data, -1);
|
GList *list = moo_completion_group_complete (group, text, &new_prefix);
|
||||||
list = list->next;
|
|
||||||
|
while (list)
|
||||||
|
{
|
||||||
|
GtkTreeIter iter;
|
||||||
|
gtk_list_store_append (cmpl->priv->store, &iter);
|
||||||
|
gtk_list_store_set (cmpl->priv->store, &iter,
|
||||||
|
COLUMN_DATA, list->data,
|
||||||
|
COLUMN_GROUP, group,
|
||||||
|
-1);
|
||||||
|
list = list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prefix_here ||
|
||||||
|
(prefix_here && new_prefix &&
|
||||||
|
strlen (prefix_here) < strlen (new_prefix)))
|
||||||
|
{
|
||||||
|
g_free (prefix_here);
|
||||||
|
prefix_here = new_prefix;
|
||||||
|
new_prefix = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (new_prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmpl->priv->cmp_func)
|
||||||
|
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (cmpl->priv->store),
|
||||||
|
COLUMN_DATA, GTK_SORT_ASCENDING);
|
||||||
|
|
||||||
|
if (prefix)
|
||||||
|
*prefix = prefix_here;
|
||||||
|
else
|
||||||
|
g_free (prefix_here);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -310,24 +389,12 @@ moo_completion_unique (MooCompletion *cmpl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpointer
|
|
||||||
moo_completion_get_data (MooCompletion *cmpl,
|
|
||||||
GtkTreeIter *iter)
|
|
||||||
{
|
|
||||||
gpointer data = NULL;
|
|
||||||
gtk_tree_model_get (GTK_TREE_MODEL (cmpl->priv->store), iter, 0, &data, -1);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_popup_activate (MooCompletion *cmpl,
|
on_popup_activate (MooCompletion *cmpl,
|
||||||
GtkTreeModel *model,
|
GtkTreeModel *model,
|
||||||
GtkTreeIter *iter)
|
GtkTreeIter *iter)
|
||||||
{
|
{
|
||||||
gpointer data = NULL;
|
moo_completion_complete (cmpl, model, iter);
|
||||||
gtk_tree_model_get (model, iter, 0, &data, -1);
|
|
||||||
moo_completion_complete (cmpl, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -371,6 +438,8 @@ moo_completion_hide (MooCompletion *cmpl)
|
|||||||
cmpl->priv->working = FALSE;
|
cmpl->priv->working = FALSE;
|
||||||
moo_text_popup_hide (cmpl->priv->popup);
|
moo_text_popup_hide (cmpl->priv->popup);
|
||||||
gtk_list_store_clear (cmpl->priv->store);
|
gtk_list_store_clear (cmpl->priv->store);
|
||||||
|
g_slist_free (cmpl->priv->active_groups);
|
||||||
|
cmpl->priv->active_groups = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,9 +545,17 @@ moo_completion_set_region (MooCompletion *cmpl,
|
|||||||
|
|
||||||
|
|
||||||
MooCompletion *
|
MooCompletion *
|
||||||
moo_completion_new (void)
|
moo_completion_new (MooCompletionStringFunc string_func,
|
||||||
|
MooCompletionFreeFunc free_func,
|
||||||
|
MooCompletionCmpFunc cmp_func)
|
||||||
{
|
{
|
||||||
return g_object_new (MOO_TYPE_COMPLETION, NULL);
|
MooCompletion *cmpl = g_object_new (MOO_TYPE_COMPLETION, NULL);
|
||||||
|
|
||||||
|
cmpl->priv->string_func = string_func;
|
||||||
|
cmpl->priv->free_func = free_func;
|
||||||
|
cmpl->priv->cmp_func = cmp_func;
|
||||||
|
|
||||||
|
return cmpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -487,15 +564,15 @@ text_cell_data_func (G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
|
|||||||
GtkCellRenderer *cell,
|
GtkCellRenderer *cell,
|
||||||
GtkTreeModel *tree_model,
|
GtkTreeModel *tree_model,
|
||||||
GtkTreeIter *iter,
|
GtkTreeIter *iter,
|
||||||
MooCompletionGroup *group)
|
MooCompletion *cmpl)
|
||||||
{
|
{
|
||||||
gpointer data = NULL;
|
gpointer data = NULL;
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
g_return_if_fail (group != NULL);
|
g_assert (MOO_IS_COMPLETION (cmpl));
|
||||||
|
|
||||||
gtk_tree_model_get (tree_model, iter, 0, &data, -1);
|
gtk_tree_model_get (tree_model, iter, 0, &data, -1);
|
||||||
text = group->string_func ? group->string_func (data) : data;
|
text = cmpl->priv->string_func ? cmpl->priv->string_func (data) : data;
|
||||||
g_return_if_fail (text != NULL);
|
g_return_if_fail (text != NULL);
|
||||||
|
|
||||||
g_object_set (cell, "text", text, NULL);
|
g_object_set (cell, "text", text, NULL);
|
||||||
@ -503,40 +580,43 @@ text_cell_data_func (G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
|
|||||||
|
|
||||||
|
|
||||||
MooCompletion *
|
MooCompletion *
|
||||||
moo_completion_new_text (GList *words,
|
moo_completion_new_text (GList *words)
|
||||||
gboolean sorted)
|
|
||||||
{
|
{
|
||||||
MooCompletion *cmpl;
|
MooCompletion *cmpl;
|
||||||
MooCompletionGroup *group;
|
|
||||||
GtkCellRenderer *cell;
|
GtkCellRenderer *cell;
|
||||||
|
|
||||||
cmpl = moo_completion_new ();
|
cmpl = moo_completion_new (NULL, g_free, (MooCompletionCmpFunc) strcmp);
|
||||||
group = moo_completion_group_new_text (sorted);
|
|
||||||
moo_completion_group_add_data (group, words);
|
if (words)
|
||||||
moo_completion_group_set_pattern (group, "\\w*", NULL, 0);
|
{
|
||||||
moo_completion_add_group (cmpl, group);
|
MooCompletionGroup *group = moo_completion_new_group (cmpl);
|
||||||
moo_completion_group_unref (group);
|
moo_completion_group_add_data (group, words);
|
||||||
|
moo_completion_group_set_pattern (group, "\\w*", NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
cell = gtk_cell_renderer_text_new ();
|
cell = gtk_cell_renderer_text_new ();
|
||||||
gtk_tree_view_column_pack_start (cmpl->priv->popup->column, cell, TRUE);
|
gtk_tree_view_column_pack_start (cmpl->priv->popup->column, cell, TRUE);
|
||||||
gtk_tree_view_column_set_cell_data_func (cmpl->priv->popup->column, cell,
|
gtk_tree_view_column_set_cell_data_func (cmpl->priv->popup->column, cell,
|
||||||
(GtkTreeCellDataFunc) text_cell_data_func,
|
(GtkTreeCellDataFunc) text_cell_data_func,
|
||||||
moo_completion_group_ref (group),
|
g_object_ref (cmpl),
|
||||||
(GtkDestroyNotify) moo_completion_group_unref);
|
g_object_unref);
|
||||||
|
|
||||||
return cmpl;
|
return cmpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
MooCompletionGroup *
|
||||||
moo_completion_add_group (MooCompletion *cmpl,
|
moo_completion_new_group (MooCompletion *cmpl)
|
||||||
MooCompletionGroup *group)
|
|
||||||
{
|
{
|
||||||
g_return_if_fail (MOO_IS_COMPLETION (cmpl));
|
MooCompletionGroup *group;
|
||||||
g_return_if_fail (group != NULL);
|
|
||||||
g_return_if_fail (g_slist_find (cmpl->priv->groups, group) == NULL);
|
g_return_val_if_fail (MOO_IS_COMPLETION (cmpl), NULL);
|
||||||
cmpl->priv->groups = g_slist_append (cmpl->priv->groups,
|
|
||||||
moo_completion_group_ref (group));
|
group = moo_completion_group_new (cmpl->priv->string_func,
|
||||||
|
cmpl->priv->free_func);
|
||||||
|
cmpl->priv->groups = g_slist_append (cmpl->priv->groups, group);
|
||||||
|
|
||||||
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -546,29 +626,15 @@ moo_completion_add_group (MooCompletion *cmpl,
|
|||||||
|
|
||||||
MooCompletionGroup *
|
MooCompletionGroup *
|
||||||
moo_completion_group_new (MooCompletionStringFunc string_func,
|
moo_completion_group_new (MooCompletionStringFunc string_func,
|
||||||
MooCompletionFreeFunc free_func,
|
MooCompletionFreeFunc free_func)
|
||||||
MooCompletionCmpFunc cmp_func)
|
|
||||||
{
|
{
|
||||||
MooCompletionGroup *group = g_new0 (MooCompletionGroup, 1);
|
MooCompletionGroup *group = g_new0 (MooCompletionGroup, 1);
|
||||||
|
|
||||||
group->ref_count = 1;
|
|
||||||
group->cmpl = g_completion_new (string_func);
|
group->cmpl = g_completion_new (string_func);
|
||||||
group->string_func = string_func;
|
|
||||||
group->free_func = free_func;
|
group->free_func = free_func;
|
||||||
group->cmp_func = cmp_func;
|
|
||||||
|
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MooCompletionGroup *
|
|
||||||
moo_completion_group_new_text (gboolean sorted)
|
|
||||||
{
|
|
||||||
return moo_completion_group_new (NULL, g_free,
|
|
||||||
sorted ? (MooCompletionCmpFunc) strcmp : NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
moo_completion_group_set_data (MooCompletionGroup *group,
|
moo_completion_group_set_data (MooCompletionGroup *group,
|
||||||
GList *data)
|
GList *data)
|
||||||
@ -650,16 +716,9 @@ moo_completion_group_complete (MooCompletionGroup *group,
|
|||||||
if (!prefix)
|
if (!prefix)
|
||||||
prefix = &dummy;
|
prefix = &dummy;
|
||||||
|
|
||||||
|
/* g_completion_complete_utf8 wants prefix != NULL */
|
||||||
list = g_completion_complete_utf8 (group->cmpl, text, prefix);
|
list = g_completion_complete_utf8 (group->cmpl, text, prefix);
|
||||||
|
|
||||||
if (group->cmp_func)
|
|
||||||
{
|
|
||||||
g_list_free (group->tmp);
|
|
||||||
group->tmp = g_list_sort (g_list_copy (list),
|
|
||||||
(GCompareFunc) group->cmp_func);
|
|
||||||
list = group->tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (dummy);
|
g_free (dummy);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@ -723,45 +782,45 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
moo_completion_group_set_suffix (MooCompletionGroup *group,
|
||||||
|
const char *suffix)
|
||||||
|
{
|
||||||
|
g_return_if_fail (group != NULL);
|
||||||
|
|
||||||
|
if (group->suffix != suffix)
|
||||||
|
{
|
||||||
|
g_free (group->suffix);
|
||||||
|
group->suffix = (suffix && suffix[0]) ? g_strdup (suffix) : NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GType
|
GType
|
||||||
moo_completion_group_get_type (void)
|
moo_completion_group_get_type (void)
|
||||||
{
|
{
|
||||||
static GType type;
|
static GType type;
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
type = g_boxed_type_register_static ("MooCompletionGroup",
|
type = g_pointer_type_register_static ("MooCompletionGroup");
|
||||||
(GBoxedCopyFunc) moo_completion_group_ref,
|
|
||||||
(GBoxedFreeFunc) moo_completion_group_unref);
|
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MooCompletionGroup *
|
static void
|
||||||
moo_completion_group_ref (MooCompletionGroup *group)
|
moo_completion_group_free (MooCompletionGroup *group)
|
||||||
{
|
|
||||||
g_return_val_if_fail (group != NULL, NULL);
|
|
||||||
group->ref_count++;
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
moo_completion_group_unref (MooCompletionGroup *group)
|
|
||||||
{
|
{
|
||||||
g_return_if_fail (group != NULL);
|
g_return_if_fail (group != NULL);
|
||||||
|
|
||||||
if (!(--group->ref_count))
|
egg_regex_unref (group->regex);
|
||||||
{
|
g_free (group->parens);
|
||||||
egg_regex_unref (group->regex);
|
g_completion_free (group->cmpl);
|
||||||
g_free (group->parens);
|
g_free (group->suffix);
|
||||||
g_completion_free (group->cmpl);
|
|
||||||
|
|
||||||
if (group->free_func)
|
if (group->free_func)
|
||||||
g_list_foreach (group->data, (GFunc) group->free_func, NULL);
|
g_list_foreach (group->data, (GFunc) group->free_func, NULL);
|
||||||
g_list_free (group->data);
|
g_list_free (group->data);
|
||||||
g_list_free (group->tmp);
|
|
||||||
|
|
||||||
g_free (group);
|
g_free (group);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,6 @@ typedef int (*MooCompletionCmpFunc) (gpointer data1,
|
|||||||
GType moo_completion_get_type (void) G_GNUC_CONST;
|
GType moo_completion_get_type (void) G_GNUC_CONST;
|
||||||
GType moo_completion_group_get_type (void) G_GNUC_CONST;
|
GType moo_completion_group_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
MooCompletionGroup *moo_completion_group_new_text (gboolean sorted);
|
|
||||||
MooCompletionGroup *moo_completion_group_new (MooCompletionStringFunc string_func,
|
|
||||||
MooCompletionFreeFunc free_func,
|
|
||||||
MooCompletionCmpFunc cmp_func);
|
|
||||||
/* these two steal data */
|
/* these two steal data */
|
||||||
void moo_completion_group_set_data (MooCompletionGroup *group,
|
void moo_completion_group_set_data (MooCompletionGroup *group,
|
||||||
GList *data);
|
GList *data);
|
||||||
@ -70,14 +66,16 @@ void moo_completion_group_set_pattern (MooCompletionGroup *group,
|
|||||||
const char *pattern,
|
const char *pattern,
|
||||||
const guint *parens,
|
const guint *parens,
|
||||||
guint n_parens);
|
guint n_parens);
|
||||||
|
void moo_completion_group_set_suffix (MooCompletionGroup *group,
|
||||||
|
const char *suffix);
|
||||||
|
|
||||||
MooCompletionGroup *moo_completion_group_ref (MooCompletionGroup *group);
|
MooCompletion *moo_completion_new (MooCompletionStringFunc string_func,
|
||||||
void moo_completion_group_unref (MooCompletionGroup *group);
|
MooCompletionFreeFunc free_func,
|
||||||
|
MooCompletionCmpFunc cmp_func);
|
||||||
MooCompletion *moo_completion_new (void);
|
|
||||||
/* steals words */
|
/* steals words */
|
||||||
MooCompletion *moo_completion_new_text (GList *words,
|
MooCompletion *moo_completion_new_text (GList *words);
|
||||||
gboolean sorted);
|
|
||||||
|
MooCompletionGroup *moo_completion_new_group (MooCompletion *cmpl);
|
||||||
|
|
||||||
void moo_completion_try_complete (MooCompletion *cmpl,
|
void moo_completion_try_complete (MooCompletion *cmpl,
|
||||||
gboolean insert_unique);
|
gboolean insert_unique);
|
||||||
@ -89,9 +87,6 @@ GtkTextView *moo_completion_get_doc (MooCompletion *cmpl);
|
|||||||
|
|
||||||
GtkListStore *moo_completion_get_store (MooCompletion *cmpl);
|
GtkListStore *moo_completion_get_store (MooCompletion *cmpl);
|
||||||
|
|
||||||
void moo_completion_add_group (MooCompletion *cmpl,
|
|
||||||
MooCompletionGroup *group);
|
|
||||||
|
|
||||||
MooTextPopup *moo_completion_get_popup (MooCompletion *cmpl);
|
MooTextPopup *moo_completion_get_popup (MooCompletion *cmpl);
|
||||||
|
|
||||||
gboolean moo_completion_get_region (MooCompletion *cmpl,
|
gboolean moo_completion_get_region (MooCompletion *cmpl,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
/*
|
||||||
*
|
|
||||||
* completion-plugin.c
|
* completion-plugin.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
* Copyright (C) 2004-2006 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||||
@ -12,9 +11,7 @@
|
|||||||
* See COPYING file that comes with this distribution.
|
* See COPYING file that comes with this distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mooedit/mooplugin-macro.h"
|
#include "mooedit/mooplugin-macro.h"
|
||||||
#include "mooedit/plugins/mooeditplugins.h"
|
#include "mooedit/plugins/mooeditplugins.h"
|
||||||
|
@ -116,26 +116,13 @@ cmpl_data_read_simple_file (CmplData *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list = parse_words (contents, NULL, data->path);
|
list = parse_words (contents, NULL, data->path);
|
||||||
data->cmpl = moo_completion_new_text (list, TRUE);
|
data->cmpl = moo_completion_new_text (list);
|
||||||
g_message ("read %d words from %s", g_list_length (list), data->path);
|
g_message ("read %d words from %s", g_list_length (list), data->path);
|
||||||
|
|
||||||
g_free (contents);
|
g_free (contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
text_cell_data_func (G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
|
|
||||||
GtkCellRenderer *cell,
|
|
||||||
GtkTreeModel *tree_model,
|
|
||||||
GtkTreeIter *iter)
|
|
||||||
{
|
|
||||||
gpointer data = NULL;
|
|
||||||
gtk_tree_model_get (tree_model, iter, 0, &data, -1);
|
|
||||||
g_return_if_fail (data != NULL);
|
|
||||||
g_object_set (cell, "text", data, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static guint *
|
static guint *
|
||||||
parse_numbers (const char *string,
|
parse_numbers (const char *string,
|
||||||
guint *n_numbers_p)
|
guint *n_numbers_p)
|
||||||
@ -199,9 +186,7 @@ cmpl_data_read_config_file (CmplData *data)
|
|||||||
{
|
{
|
||||||
MooConfig *config;
|
MooConfig *config;
|
||||||
guint i, n_items;
|
guint i, n_items;
|
||||||
GSList *completion_groups = NULL;
|
MooCompletionGroup *group = NULL;
|
||||||
GtkCellRenderer *cell;
|
|
||||||
MooTextPopup *popup;
|
|
||||||
|
|
||||||
g_return_if_fail (data->cmpl == NULL);
|
g_return_if_fail (data->cmpl == NULL);
|
||||||
g_return_if_fail (data->path != NULL);
|
g_return_if_fail (data->path != NULL);
|
||||||
@ -212,20 +197,23 @@ cmpl_data_read_config_file (CmplData *data)
|
|||||||
n_items = moo_config_n_items (config);
|
n_items = moo_config_n_items (config);
|
||||||
g_return_if_fail (n_items != 0);
|
g_return_if_fail (n_items != 0);
|
||||||
|
|
||||||
|
data->cmpl = moo_completion_new_text (NULL);
|
||||||
|
|
||||||
for (i = 0; i < n_items; ++i)
|
for (i = 0; i < n_items; ++i)
|
||||||
{
|
{
|
||||||
MooConfigItem *item;
|
MooConfigItem *item;
|
||||||
const char *pattern, *prefix;
|
const char *pattern, *prefix, *suffix;
|
||||||
const char *groups;
|
const char *groups;
|
||||||
guint *parens;
|
guint *parens;
|
||||||
guint n_parens;
|
guint n_parens;
|
||||||
GList *words;
|
GList *words;
|
||||||
MooCompletionGroup *group;
|
|
||||||
|
|
||||||
item = moo_config_nth_item (config, i);
|
item = moo_config_nth_item (config, i);
|
||||||
|
|
||||||
pattern = moo_config_item_get_value (item, "pattern");
|
pattern = moo_config_item_get_value (item, "pattern");
|
||||||
prefix = moo_config_item_get_value (item, "prefix");
|
prefix = moo_config_item_get_value (item, "prefix");
|
||||||
|
suffix = moo_config_item_get_value (item, "insert-suffix");
|
||||||
|
suffix = suffix ? suffix : moo_config_item_get_value (item, "insert_suffix");
|
||||||
|
|
||||||
groups = moo_config_item_get_value (item, "group");
|
groups = moo_config_item_get_value (item, "group");
|
||||||
groups = groups ? groups : moo_config_item_get_value (item, "groups");
|
groups = groups ? groups : moo_config_item_get_value (item, "groups");
|
||||||
@ -258,40 +246,23 @@ cmpl_data_read_config_file (CmplData *data)
|
|||||||
g_message ("read %d words for patttern '%s' from %s",
|
g_message ("read %d words for patttern '%s' from %s",
|
||||||
g_list_length (words), pattern, data->path);
|
g_list_length (words), pattern, data->path);
|
||||||
|
|
||||||
group = moo_completion_group_new_text (TRUE);
|
group = moo_completion_new_group (data->cmpl);
|
||||||
moo_completion_group_add_data (group, words);
|
moo_completion_group_add_data (group, words);
|
||||||
moo_completion_group_set_pattern (group, pattern, parens, n_parens);
|
moo_completion_group_set_pattern (group, pattern, parens, n_parens);
|
||||||
g_free (parens);
|
|
||||||
|
|
||||||
completion_groups = g_slist_prepend (completion_groups, group);
|
if (suffix && suffix[0])
|
||||||
|
moo_completion_group_set_suffix (group, suffix);
|
||||||
|
|
||||||
|
g_free (parens);
|
||||||
}
|
}
|
||||||
|
|
||||||
moo_config_free (config);
|
moo_config_free (config);
|
||||||
|
|
||||||
if (!completion_groups)
|
if (!group)
|
||||||
{
|
{
|
||||||
g_warning ("%s: no completions", G_STRLOC);
|
g_warning ("%s: no completions", G_STRLOC);
|
||||||
data->cmpl = moo_completion_new_text (NULL, TRUE);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
completion_groups = g_slist_reverse (completion_groups);
|
|
||||||
data->cmpl = moo_completion_new ();
|
|
||||||
|
|
||||||
while (completion_groups)
|
|
||||||
{
|
|
||||||
moo_completion_add_group (data->cmpl, completion_groups->data);
|
|
||||||
moo_completion_group_unref (completion_groups->data);
|
|
||||||
completion_groups = g_slist_delete_link (completion_groups,
|
|
||||||
completion_groups);
|
|
||||||
}
|
|
||||||
|
|
||||||
popup = moo_completion_get_popup (data->cmpl);
|
|
||||||
cell = gtk_cell_renderer_text_new ();
|
|
||||||
gtk_tree_view_column_pack_start (popup->column, cell, TRUE);
|
|
||||||
gtk_tree_view_column_set_cell_data_func (popup->column, cell,
|
|
||||||
(GtkTreeCellDataFunc) text_cell_data_func,
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,10 +11,7 @@
|
|||||||
* See COPYING file that comes with this distribution.
|
* See COPYING file that comes with this distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#include ""
|
#include ""
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user