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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user