int main (int argc, char *argv[]) { GCompletion *cmp; GList *items; gchar *prefix; #ifdef __SYMBIAN32__ g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL); g_set_print_handler(mrtPrintHandler); #endif /*__SYMBIAN32__*/ cmp = g_completion_new (NULL); items = NULL; items = g_list_append (items, "a\302\243"); items = g_list_append (items, "a\302\244"); items = g_list_append (items, "bb"); items = g_list_append (items, "bc"); g_completion_add_items (cmp, items); items = g_completion_complete (cmp, "a", &prefix); g_assert (!strcmp ("a\302", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "a", &prefix); g_assert (!strcmp ("a", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "a", NULL); g_assert (g_list_length (items) == 2); items = g_completion_complete_utf8 (cmp, "a", NULL); g_assert (g_list_length (items) == 2); g_completion_free (cmp); #if __SYMBIAN32__ testResultXml("completion-test"); #endif /* EMULATOR */ return 0; }
int main (int argc, char *argv[]) { GCompletion *cmp; GList *items; gchar *prefix; cmp = g_completion_new (NULL); items = NULL; items = g_list_append (items, "a\302\243"); items = g_list_append (items, "a\302\244"); items = g_list_append (items, "bb"); items = g_list_append (items, "bc"); g_completion_add_items (cmp, items); items = g_completion_complete (cmp, "a", &prefix); g_assert (!strcmp ("a\302", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "a", &prefix); g_assert (!strcmp ("a", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete_utf8 (cmp, "b", &prefix); g_assert (!strcmp ("b", prefix)); g_assert (g_list_length (items) == 2); g_free (prefix); items = g_completion_complete (cmp, "a", NULL); g_assert (g_list_length (items) == 2); items = g_completion_complete_utf8 (cmp, "a", NULL); g_assert (g_list_length (items) == 2); g_completion_free (cmp); return 0; }
static VALUE rg_complete(VALUE self, VALUE prefix) { gchar* new_prefix; VALUE ary = rb_ary_new(); #if GLIB_CHECK_VERSION(2,4,0) GList* list = g_completion_complete_utf8(_SELF(self), (const gchar*)RVAL2CSTR(prefix), &new_prefix); #else GList* list = g_completion_complete(_SELF(self), RVAL2CSTR(prefix), &new_prefix); #endif while (list) { rb_ary_push(ary, RARRAY_PTR((VALUE)list->data)[1]); list = list->next; } return rb_assoc_new(ary, new_prefix ? CSTR2RVAL(new_prefix) : Qnil); }
static int key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, struct session *sess) { int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, prefix_len, skip_len = 0; gboolean is_nick = FALSE, is_cmd = FALSE, found = FALSE, has_nick_prefix = FALSE; char ent[CHANLEN], *postfix = NULL, *result, *ch; GList *list = NULL, *tmp_list = NULL; const char *text; GCompletion *gcomp = NULL; GString *buf; /* force the IM Context to reset */ SPELL_ENTRY_SET_EDITABLE (t, FALSE); SPELL_ENTRY_SET_EDITABLE (t, TRUE); text = SPELL_ENTRY_GET_TEXT (t); if (text[0] == 0) return 1; len = g_utf8_strlen (text, -1); /* must be null terminated */ cursor_pos = SPELL_ENTRY_GET_POS (t); /* handle "nick: " or "nick " or "#channel "*/ ch = g_utf8_find_prev_char(text, g_utf8_offset_to_pointer(text,cursor_pos)); if (ch && ch[0] == ' ') { skip_len++; ch = g_utf8_find_prev_char(text, ch); if (!ch) return 2; cursor_pos = g_utf8_pointer_to_offset(text, ch); if (cursor_pos && (g_utf8_get_char_validated(ch, -1) == ':' || g_utf8_get_char_validated(ch, -1) == ',' || g_utf8_get_char_validated (ch, -1) == g_utf8_get_char_validated (prefs.hex_completion_suffix, -1))) { skip_len++; } else cursor_pos = g_utf8_pointer_to_offset(text, g_utf8_offset_to_pointer(ch, 1)); } comp = skip_len; /* store the text following the cursor for reinsertion later */ if ((cursor_pos + skip_len) < len) postfix = g_utf8_offset_to_pointer(text, cursor_pos + skip_len); for (ent_start = cursor_pos; ; --ent_start) { if (ent_start == 0) break; ch = g_utf8_offset_to_pointer(text, ent_start - 1); if (ch && ch[0] == ' ') break; } if (ent_start == 0 && text[0] == prefs.hex_input_command_char[0]) { ent_start++; is_cmd = TRUE; } else if (strchr (sess->server->chantypes, text[ent_start]) == NULL) { is_nick = TRUE; if (strchr (sess->server->nick_prefixes, text[ent_start]) != NULL) { if (ent_start == 0) has_nick_prefix = TRUE; ent_start++; } } prefix_len = ent_start; elen = cursor_pos - ent_start; g_utf8_strncpy (ent, g_utf8_offset_to_pointer (text, prefix_len), elen); if (sess->type == SESS_DIALOG && is_nick) { /* tab in a dialog completes the other person's name */ if (rfc_ncasecmp (sess->channel, ent, elen) == 0) { result = sess->channel; is_nick = FALSE; } else return 2; } else { if (is_nick) { gcomp = g_completion_new((GCompletionFunc)gcomp_nick_func); tmp_list = userlist_double_list(sess); /* create a temp list so we can free the memory */ if (prefs.hex_completion_sort == 1) /* sort in last-talk order? */ tmp_list = g_list_sort (tmp_list, (void *)talked_recent_cmp); } else { gcomp = g_completion_new (NULL); if (is_cmd) { tmp_list = cmdlist_double_list (command_list); for(i = 0; xc_cmds[i].name != NULL ; i++) { tmp_list = g_list_prepend (tmp_list, xc_cmds[i].name); } tmp_list = plugin_command_list(tmp_list); } else tmp_list = chanlist_double_list (sess_list); } tmp_list = g_list_reverse(tmp_list); /* make the comp entries turn up in the right order */ g_completion_set_compare (gcomp, (GCompletionStrncmpFunc)rfc_ncasecmp); if (tmp_list) { g_completion_add_items (gcomp, tmp_list); g_list_free (tmp_list); } if (comp && !(rfc_ncasecmp(old_gcomp.data, ent, old_gcomp.elen) == 0)) { key_action_tab_clean (); comp = 0; } list = g_completion_complete_utf8 (gcomp, comp ? old_gcomp.data : ent, &result); if (result == NULL) /* No matches found */ { g_completion_free(gcomp); return 2; } if (comp) /* existing completion */ { while(list) /* find the current entry */ { if(rfc_ncasecmp(list->data, ent, elen) == 0) { found = TRUE; break; } list = list->next; } if (found) { if (!(d1 && d1[0])) /* not holding down shift */ { if (g_list_next(list) == NULL) list = g_list_first(list); else list = g_list_next(list); } else { if (g_list_previous(list) == NULL) list = g_list_last(list); else list = g_list_previous(list); } g_free(result); result = (char*)list->data; } else { g_free(result); g_completion_free(gcomp); return 2; } } else { strcpy(old_gcomp.data, ent); old_gcomp.elen = elen; /* Get the first nick and put out the data for future nickcompletes */ if (prefs.hex_completion_amount > 0 && g_list_length (list) <= (guint) prefs.hex_completion_amount) { g_free(result); result = (char*)list->data; } else { /* bash style completion */ if (g_list_next(list) != NULL) { buf = g_string_sized_new (MAX(COMP_BUF, len + NICKLEN)); if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */ { if (prefix_len) g_string_append_len (buf, text, offset_to_len (text, prefix_len)); g_string_append (buf, result); cursor_pos = buf->len; g_free(result); if (postfix) { g_string_append_c (buf, ' '); g_string_append (buf, postfix); } SPELL_ENTRY_SET_TEXT (t, buf->str); SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos)); g_string_erase (buf, 0, -1); } else g_free(result); while (list) { len = buf->len; elen = strlen (list->data); /* next item to add */ if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */ { PrintText (sess, buf->str); g_string_erase (buf, 0, -1); } g_string_append (buf, (char*)list->data); g_string_append_c (buf, ' '); list = list->next; } PrintText (sess, buf->str); g_completion_free(gcomp); g_string_free (buf, TRUE); return 2; } /* Only one matching entry */ g_free(result); result = list->data; } } } if(result) { buf = g_string_sized_new (len + NICKLEN); if (prefix_len) g_string_append_len (buf, text, offset_to_len (text, prefix_len)); g_string_append (buf, result); if((!prefix_len || has_nick_prefix) && is_nick && prefs.hex_completion_suffix[0] != '\0') g_string_append_unichar (buf, g_utf8_get_char_validated (prefs.hex_completion_suffix, -1)); g_string_append_c (buf, ' '); cursor_pos = buf->len; if (postfix) g_string_append (buf, postfix); SPELL_ENTRY_SET_TEXT (t, buf->str); SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos)); g_string_free (buf, TRUE); } if (gcomp) g_completion_free(gcomp); return 2; }
static int key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, struct session *sess) { int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, found = 0, prefix_len, skip_len = 0, is_nick, is_cmd = 0; char buf[COMP_BUF], ent[CHANLEN], *postfix = NULL, *result, *ch; GList *list = NULL, *tmp_list = NULL; const char *text; GCompletion *gcomp = NULL; /* force the IM Context to reset */ SPELL_ENTRY_SET_EDITABLE (t, FALSE); SPELL_ENTRY_SET_EDITABLE (t, TRUE); text = SPELL_ENTRY_GET_TEXT (t); if (text[0] == 0) return 1; len = g_utf8_strlen (text, -1); /* must be null terminated */ cursor_pos = SPELL_ENTRY_GET_POS (t); buf[0] = 0; /* make sure we don't get garbage in the buffer */ /* handle "nick: " or "nick " or "#channel "*/ ch = g_utf8_find_prev_char(text, g_utf8_offset_to_pointer(text,cursor_pos)); if (ch && ch[0] == ' ') { skip_len++; ch = g_utf8_find_prev_char(text, ch); if (!ch) return 2; cursor_pos = g_utf8_pointer_to_offset(text, ch); if (cursor_pos && (g_utf8_get_char_validated(ch, -1) == ':' || g_utf8_get_char_validated(ch, -1) == ',' || g_utf8_get_char_validated(ch, -1) == prefs.nick_suffix[0])) { skip_len++; } else cursor_pos = g_utf8_pointer_to_offset(text, g_utf8_offset_to_pointer(ch, 1)); } comp = skip_len; /* store the text following the cursor for reinsertion later */ if ((cursor_pos + skip_len) < len) postfix = g_utf8_offset_to_pointer(text, cursor_pos + skip_len); for (ent_start = cursor_pos; ; --ent_start) { if (ent_start == 0) break; ch = g_utf8_offset_to_pointer(text, ent_start - 1); if (ch && ch[0] == ' ') break; } if (ent_start == 0 && text[0] == prefs.cmdchar[0]) { ent_start++; is_cmd = 1; } prefix_len = ent_start; elen = cursor_pos - ent_start; g_utf8_strncpy (ent, g_utf8_offset_to_pointer (text, prefix_len), elen); is_nick = (ent[0] == '#' || ent[0] == '&' || is_cmd) ? 0 : 1; if (sess->type == SESS_DIALOG && is_nick) { /* tab in a dialog completes the other person's name */ if (rfc_ncasecmp (sess->channel, ent, elen) == 0) { result = sess->channel; is_nick = 0; } else return 2; } else { if (is_nick) { gcomp = g_completion_new((GCompletionFunc)gcomp_nick_func); tmp_list = userlist_double_list(sess); /* create a temp list so we can free the memory */ if (prefs.completion_sort == 1) /* sort in last-talk order? */ tmp_list = g_list_sort (tmp_list, (void *)talked_recent_cmp); } else { gcomp = g_completion_new (NULL); if (is_cmd) { tmp_list = cmdlist_double_list (command_list); for(i = 0; xc_cmds[i].name != NULL ; i++) { tmp_list = g_list_prepend (tmp_list, xc_cmds[i].name); } tmp_list = plugin_command_list(tmp_list); } else tmp_list = chanlist_double_list (sess_list); } tmp_list = g_list_reverse(tmp_list); /* make the comp entries turn up in the right order */ g_completion_set_compare (gcomp, (GCompletionStrncmpFunc)rfc_ncasecmp); if (tmp_list) { g_completion_add_items (gcomp, tmp_list); g_list_free (tmp_list); } if (comp && !(rfc_ncasecmp(old_gcomp.data, ent, old_gcomp.elen) == 0)) { key_action_tab_clean (); comp = 0; } #if GLIB_CHECK_VERSION(2,4,0) list = g_completion_complete_utf8 (gcomp, comp ? old_gcomp.data : ent, &result); #else list = g_completion_complete (gcomp, comp ? old_gcomp.data : ent, &result); #endif if (result == NULL) /* No matches found */ { g_completion_free(gcomp); return 2; } if (comp) /* existing completion */ { while(list) /* find the current entry */ { if(rfc_ncasecmp(list->data, ent, elen) == 0) { found = 1; break; } list = list->next; } if (found) { if (!(d1 && d1[0])) /* not holding down shift */ { if (g_list_next(list) == NULL) list = g_list_first(list); else list = g_list_next(list); } else { if (g_list_previous(list) == NULL) list = g_list_last(list); else list = g_list_previous(list); } g_free(result); result = (char*)list->data; } else { g_free(result); g_completion_free(gcomp); return 2; } } else { strcpy(old_gcomp.data, ent); old_gcomp.elen = elen; /* Get the first nick and put out the data for future nickcompletes */ if (prefs.completion_amount && g_list_length (list) <= prefs.completion_amount) { g_free(result); result = (char*)list->data; } else { /* bash style completion */ if (g_list_next(list) != NULL) { if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */ { if (prefix_len) g_utf8_strncpy (buf, text, prefix_len); strncat (buf, result, COMP_BUF - prefix_len); cursor_pos = strlen (buf); g_free(result); #if !GLIB_CHECK_VERSION(2,4,0) g_utf8_validate (buf, -1, (const gchar **)&result); (*result) = 0; #endif if (postfix) { strcat (buf, " "); strncat (buf, postfix, COMP_BUF - cursor_pos -1); } SPELL_ENTRY_SET_TEXT (t, buf); SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos)); buf[0] = 0; } else g_free(result); while (list) { len = strlen (buf); /* current buffer */ elen = strlen (list->data); /* next item to add */ if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */ { PrintText (sess, buf); buf[0] = 0; len = 0; } strcpy (buf + len, (char *) list->data); strcpy (buf + len + elen, " "); list = list->next; } PrintText (sess, buf); g_completion_free(gcomp); return 2; } /* Only one matching entry */ g_free(result); result = list->data; } } } if(result) { if (prefix_len) g_utf8_strncpy(buf, text, prefix_len); strncat (buf, result, COMP_BUF - (prefix_len + 3)); /* make sure nicksuffix and space fits */ if(!prefix_len && is_nick) strcat (buf, &prefs.nick_suffix[0]); strcat (buf, " "); cursor_pos = strlen (buf); if (postfix) strncat (buf, postfix, COMP_BUF - cursor_pos - 2); SPELL_ENTRY_SET_TEXT (t, buf); SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos)); } if (gcomp) g_completion_free(gcomp); return 2; }
static gboolean entry_event (GtkEditable *entry, GdkEventKey *event, PanelRunDialog *dialog) { GtkTreeSelection *selection; char *prefix; char *nospace_prefix; char *nprefix; char *temp; int pos, tmp; if (event->type != GDK_KEY_PRESS) return FALSE; /* if user typed something we're not using the list anymore */ dialog->use_program_list = FALSE; selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->program_list)); gtk_tree_selection_unselect_all (selection); if (!panel_profile_get_enable_autocompletion ()) return FALSE; /* tab completion */ if (event->keyval == GDK_KEY_Tab) { gtk_editable_get_selection_bounds (entry, &pos, &tmp); if (dialog->completion_started && pos != tmp && pos != 1 && tmp == strlen (gtk_entry_get_text (GTK_ENTRY (entry)))) { gtk_editable_select_region (entry, 0, 0); gtk_editable_set_position (entry, -1); return TRUE; } } else if (event->length > 0) { gtk_editable_get_selection_bounds (entry, &pos, &tmp); if (dialog->completion_started && pos != tmp && pos != 0 && tmp == strlen (gtk_entry_get_text (GTK_ENTRY (entry)))) { temp = gtk_editable_get_chars (entry, 0, pos); prefix = g_strconcat (temp, event->string, NULL); g_free (temp); } else if (pos == tmp && tmp == strlen (gtk_entry_get_text (GTK_ENTRY (entry)))) { prefix = g_strconcat (gtk_entry_get_text (GTK_ENTRY (entry)), event->string, NULL); } else { return FALSE; } nospace_prefix = prefix; while (*nospace_prefix != '\0' && g_ascii_isspace (*nospace_prefix)) nospace_prefix++; if (*nospace_prefix == '\0') return FALSE; panel_run_dialog_update_completion (dialog, nospace_prefix); if (!dialog->completion) { g_free (prefix); return FALSE; } pos = strlen (prefix); nprefix = NULL; g_completion_complete_utf8 (dialog->completion, nospace_prefix, &nprefix); if (nprefix) { int insertpos; insertpos = 0; temp = g_strndup (prefix, nospace_prefix - prefix); g_free (prefix); prefix = g_strconcat (temp, nprefix, NULL); g_signal_handler_block (dialog->combobox, dialog->changed_id); gtk_editable_delete_text (entry, 0, -1); g_signal_handler_unblock (dialog->combobox, dialog->changed_id); gtk_editable_insert_text (entry, prefix, strlen (prefix), &insertpos); gtk_editable_set_position (entry, pos); gtk_editable_select_region (entry, pos, -1); dialog->completion_started = TRUE; g_free (temp); g_free (nprefix); g_free (prefix); return TRUE; } g_free (prefix); } return FALSE; }