completion prototype with GtkEntryCompletion
This commit is contained in:
parent
6c341024d7
commit
3f0911676f
70
termite.c
70
termite.c
|
@ -1,6 +1,7 @@
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
@ -23,11 +24,18 @@ typedef struct search_panel_info {
|
||||||
bool reverse;
|
bool reverse;
|
||||||
} search_panel_info;
|
} search_panel_info;
|
||||||
|
|
||||||
static gboolean always_selected(VteTerminal *vte, glong column, glong row) {
|
static gboolean always_selected(__attribute__((unused)) VteTerminal *vte,
|
||||||
|
__attribute__((unused)) glong column,
|
||||||
|
__attribute__((unused)) glong row) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete(VteTerminal *vte) {
|
static GtkTreeModel *create_completion_model(VteTerminal *vte) {
|
||||||
|
GtkListStore *store;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
store = gtk_list_store_new(1, G_TYPE_STRING);
|
||||||
|
|
||||||
// TODO: get the full buffer
|
// TODO: get the full buffer
|
||||||
gchar *content = vte_terminal_get_text(vte,
|
gchar *content = vte_terminal_get_text(vte,
|
||||||
(VteSelectionFunc)always_selected,
|
(VteSelectionFunc)always_selected,
|
||||||
|
@ -36,22 +44,70 @@ static void complete(VteTerminal *vte) {
|
||||||
|
|
||||||
if (!content) {
|
if (!content) {
|
||||||
fputs("no content", stderr);
|
fputs("no content", stderr);
|
||||||
return;
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *s_ptr = content, *saveptr;
|
char *s_ptr = content, *saveptr;
|
||||||
|
|
||||||
|
// TODO: remove duplicates
|
||||||
for (int j = 1; ; j++, s_ptr = NULL) {
|
for (int j = 1; ; j++, s_ptr = NULL) {
|
||||||
char *token = strtok_r(s_ptr, " \n", &saveptr);
|
char *token = strtok_r(s_ptr, " \n", &saveptr);
|
||||||
if (!token) {
|
if (!token) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf("token %d: %s\n", j, token);
|
gtk_list_store_append(store, &iter);
|
||||||
|
gtk_list_store_set(store, &iter, 0, token, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: GtkEntryCompletion widget
|
|
||||||
|
|
||||||
g_free(content);
|
g_free(content);
|
||||||
|
|
||||||
|
return GTK_TREE_MODEL(store);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkWidget *test_window = NULL;
|
||||||
|
|
||||||
|
static GtkWidget *do_entry_completion(VteTerminal *do_widget) {
|
||||||
|
GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(do_widget));
|
||||||
|
|
||||||
|
if (!test_window) {
|
||||||
|
test_window = gtk_dialog_new_with_buttons("GtkEntryCompletion",
|
||||||
|
GTK_WINDOW(window),
|
||||||
|
(GtkDialogFlags)0,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
gtk_window_set_resizable(GTK_WINDOW(test_window), FALSE);
|
||||||
|
|
||||||
|
g_signal_connect(test_window, "response", G_CALLBACK(gtk_widget_destroy), NULL);
|
||||||
|
g_signal_connect(test_window, "destroy", G_CALLBACK(gtk_widget_destroyed), &test_window);
|
||||||
|
|
||||||
|
GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(test_window));
|
||||||
|
|
||||||
|
// Create our entry
|
||||||
|
GtkWidget *entry = gtk_entry_new();
|
||||||
|
gtk_container_add(GTK_CONTAINER(content_area), entry);
|
||||||
|
|
||||||
|
// Create the completion object
|
||||||
|
GtkEntryCompletion *completion = gtk_entry_completion_new();
|
||||||
|
|
||||||
|
// Assign the completion to the entry
|
||||||
|
gtk_entry_set_completion(GTK_ENTRY(entry), completion);
|
||||||
|
g_object_unref(completion);
|
||||||
|
|
||||||
|
// Create a tree model and use it as the completion model
|
||||||
|
GtkTreeModel *completion_model = create_completion_model(do_widget);
|
||||||
|
gtk_entry_completion_set_model(completion, completion_model);
|
||||||
|
g_object_unref(completion_model);
|
||||||
|
|
||||||
|
// Use model column 0 as the text column
|
||||||
|
gtk_entry_completion_set_text_column(completion, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gtk_widget_get_visible(test_window))
|
||||||
|
gtk_widget_show_all(test_window);
|
||||||
|
else
|
||||||
|
gtk_widget_destroy(test_window);
|
||||||
|
|
||||||
|
return test_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void search(VteTerminal *vte, const char *pattern, bool reverse) {
|
static void search(VteTerminal *vte, const char *pattern, bool reverse) {
|
||||||
|
@ -122,7 +178,7 @@ static gboolean key_press_cb(VteTerminal *vte, GdkEventKey *event, search_panel_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modifiers == GDK_CONTROL_MASK && event->keyval == GDK_KEY_Tab) {
|
if (modifiers == GDK_CONTROL_MASK && event->keyval == GDK_KEY_Tab) {
|
||||||
complete(vte);
|
do_entry_completion(vte);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in New Issue