From c3f96340ca4c8d1febd73990b77708947a335515 Mon Sep 17 00:00:00 2001 From: "David C. Rankin" Date: Sat, 28 Jul 2018 02:29:58 -0500 Subject: [PATCH] Add/implement word completion with gtk_source_completion and add configurable setting to enable/disable word completion in settings->file load/save->word completion. Protect includes to insure building without gtksourceview. --- gtk_appdata.c | 8 ++++ gtk_appdata.h | 4 +- gtk_completionsv.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++ gtk_completionsv.h | 19 +++++++++ gtk_settings.c | 41 +++++++++++++++++++ gtk_settings.h | 1 + gtk_textview.c | 4 ++ gtk_textview.h | 1 + 8 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 gtk_completionsv.c create mode 100644 gtk_completionsv.h diff --git a/gtk_appdata.c b/gtk_appdata.c index dd020e5..50477ce 100644 --- a/gtk_appdata.c +++ b/gtk_appdata.c @@ -75,6 +75,8 @@ g_print ("app->exename : %s\n" app->langname = NULL; /* language name (owned by mgr, do not free) */ // app->schememgr = gtk_source_style_scheme_manager_get_default(); // app->schemeids = gtk_source_style_scheme_manager_get_scheme_ids (app->schememgr); + app->completion = NULL; /* completion provider object */ + app->enablecmplt = TRUE; /* enable word completion */ app->highlight = TRUE; /* show syntax highlight */ app->showmargin = TRUE; /* show margin at specific column */ app->marginwidth = 80; /* initial right margin to display */ @@ -318,6 +320,10 @@ static void context_read_keyfile (kwinst *app) "highlight", &err); if (chk_key_ok (&err)) app->highlight = bv; + bv = g_key_file_get_boolean (app->keyfile, "sourceview", + "enablecmplt", &err); + if (chk_key_ok (&err)) app->enablecmplt = bv; + bv = g_key_file_get_boolean (app->keyfile, "sourceview", "lineno", &err); if (chk_key_ok (&err)) app->lineno = bv; @@ -430,6 +436,8 @@ static void context_write_keyfile (kwinst *app) g_key_file_set_boolean (app->keyfile, "cleanup", "trimendws", app->trimendws); #ifdef HAVESOURCEVIEW g_key_file_set_boolean (app->keyfile, "sourceview", "highlight", app->highlight); + g_key_file_set_boolean (app->keyfile, "sourceview", "enablecmplt", + app->enablecmplt); g_key_file_set_boolean (app->keyfile, "sourceview", "lineno", app->lineno); g_key_file_set_boolean (app->keyfile, "sourceview", "linehghlt", app->linehghlt); g_key_file_set_boolean (app->keyfile, "sourceview", "showmargin", app->showmargin); diff --git a/gtk_appdata.h b/gtk_appdata.h index 5939d0b..7dd4183 100644 --- a/gtk_appdata.h +++ b/gtk_appdata.h @@ -48,7 +48,7 @@ #define HAVEMSWIN 1 #endif -#define VER "0.2.1" +#define VER "0.2.2" #define SITE "https://www.rankinlawfirm.com" #define LICENSE "gpl-2.0.txt" #define CFGDIR "gtkwrite" @@ -141,6 +141,8 @@ typedef struct { GtkSourceBuffer *buffer; GtkSourceLanguageManager *langmgr; GtkSourceLanguage *language; + GtkSourceCompletion *completion; + gboolean enablecmplt; /* enable word-completion */ const gchar *langname; /* name of language from sourceview guess */ // GtkSourceStyleSchemeManager *schememgr; // const gchar * const *schemeids; diff --git a/gtk_completionsv.c b/gtk_completionsv.c new file mode 100644 index 0000000..737e0c0 --- /dev/null +++ b/gtk_completionsv.c @@ -0,0 +1,99 @@ +static const int stub; + +#if defined (WGTKSOURCEVIEW2) || defined (WGTKSOURCEVIEW3) || defined (WGTKSOURCEVIEW4) + +#include "gtk_completionsv.h" + +typedef struct _cmplprovider cmplprovider; +typedef struct _cmplproviderClass cmplproviderClass; + +struct _cmplprovider +{ + GObject parent; + + GList *proposals; + gint priority; + gchar *name; + + GdkPixbuf *icon; +}; + +struct _cmplproviderClass +{ + GObjectClass parent_class; +}; + +static void cmpl_provider_iface_init (GtkSourceCompletionProviderIface *iface); + +G_DEFINE_TYPE_WITH_CODE (cmplprovider, cmpl_provider, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GTK_TYPE_SOURCE_COMPLETION_PROVIDER, + cmpl_provider_iface_init)) + +static gchar *cmpl_provider_get_name (GtkSourceCompletionProvider *provider) +{ + return g_strdup (((cmplprovider *)provider)->name); +} + +static gint cmpl_provider_get_priority (GtkSourceCompletionProvider *provider) +{ + return ((cmplprovider *)provider)->priority; +} + +static gboolean cmpl_provider_match (GtkSourceCompletionProvider *provider, + GtkSourceCompletionContext *context) +{ + return TRUE; + + if (provider || context) {} +} + +static void cmpl_provider_populate (GtkSourceCompletionProvider *provider, + GtkSourceCompletionContext *context) +{ + gtk_source_completion_context_add_proposals (context, provider, + ((cmplprovider *)provider)->proposals, + TRUE); +} + +static void cmpl_provider_iface_init (GtkSourceCompletionProviderIface *iface) +{ + iface->get_name = cmpl_provider_get_name; + + iface->populate = cmpl_provider_populate; + iface->match = cmpl_provider_match; + iface->get_priority = cmpl_provider_get_priority; + + // iface->get_icon = cmpl_provider_get_icon; + iface->get_icon = NULL; +} + +static void cmpl_provider_class_init (cmplproviderClass *klass) +{ + if (klass) {} +} + +static void cmpl_provider_init (cmplprovider *self) +{ + GList *proposals = NULL; + self->proposals = proposals; +} + +void create_completion (kwinst *app) +{ + GtkSourceCompletionWords *prov_words; + + app->completion = gtk_source_view_get_completion (GTK_SOURCE_VIEW (app->view)); + + prov_words = gtk_source_completion_words_new (NULL, NULL); + + gtk_source_completion_words_register (prov_words, + gtk_text_view_get_buffer (GTK_TEXT_VIEW (app->view))); + + gtk_source_completion_add_provider (app->completion, + GTK_SOURCE_COMPLETION_PROVIDER (prov_words), + NULL); + +// g_object_set (prov_words, "priority", 10, NULL); +} + +#endif diff --git a/gtk_completionsv.h b/gtk_completionsv.h new file mode 100644 index 0000000..f089a63 --- /dev/null +++ b/gtk_completionsv.h @@ -0,0 +1,19 @@ +#ifndef __completionsv_h__ +#define __completionsv_h__ 1 + +#if defined (WGTKSOURCEVIEW2) || defined (WGTKSOURCEVIEW3) || defined (WGTKSOURCEVIEW4) + +#include +#include +#include +#include +#include +#include + +#include "gtk_appdata.h" + +void create_completion (kwinst *app); + +#endif + +#endif diff --git a/gtk_settings.c b/gtk_settings.c index 691e4f5..d9c3865 100644 --- a/gtk_settings.c +++ b/gtk_settings.c @@ -56,6 +56,7 @@ GtkWidget *create_settings_dlg (kwinst *app) GtkWidget *chkshowmargin; /* checkbox - show right margin guide */ GtkObject *adjmarginwidth; /* adjustment - right marginwidth */ GtkWidget *spinmarginwidth; /* spinbutton - right marginwidth */ + GtkWidget *chkenablecmplt; /* checkbox - enable word completion */ #endif GtkObject *adjtab; /* adjustment - tab spinbutton */ @@ -552,6 +553,37 @@ GtkWidget *create_settings_dlg (kwinst *app) /* pack frame into notebook vboxnb */ gtk_box_pack_start (GTK_BOX (vboxnb), frame, FALSE, FALSE, 0); +#ifdef HAVESOURCEVIEW + /* frame within page - cursor positon on open */ + frame = gtk_frame_new (NULL); + gtk_frame_set_label (GTK_FRAME (frame), "Word Completion"); + gtk_frame_set_label_align (GTK_FRAME (frame), 0.0, 0.5); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_OUT); + gtk_container_set_border_width (GTK_CONTAINER (frame), 5); + gtk_widget_show (frame); + + /* table inside frame */ + table = gtk_table_new (1, 2, TRUE); + gtk_table_set_row_spacings (GTK_TABLE (table), 5); + gtk_table_set_col_spacings (GTK_TABLE (table), 3); + gtk_container_set_border_width (GTK_CONTAINER (table), 5); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + /* options checkboxs */ + chkenablecmplt = gtk_check_button_new_with_mnemonic ("Enable _Word Completion"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chkenablecmplt), + app->enablecmplt); + gtk_table_attach_defaults (GTK_TABLE (table), chkenablecmplt, 0, 1, 0, 1); + gtk_widget_show (chkenablecmplt); + label = gtk_label_new ("(enabled/disabled on next editor use)"); + gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1); + gtk_widget_show (label); + + /* pack frame into notebook vboxnb */ + gtk_box_pack_start (GTK_BOX (vboxnb), frame, FALSE, FALSE, 0); +#endif + /* frame within page */ frame = gtk_frame_new (NULL); gtk_frame_set_label (GTK_FRAME (frame), "End-of-Line Handling/Selection"); @@ -732,6 +764,9 @@ GtkWidget *create_settings_dlg (kwinst *app) g_signal_connect (spinmarginwidth, "value-changed", G_CALLBACK (spinmarginwidth_changed), app); + g_signal_connect (chkenablecmplt, "toggled", + G_CALLBACK (chkenablecmplt_toggled), app); + #endif g_signal_connect (chkwinrestore, "toggled", G_CALLBACK (chkwinrestore_toggled), app); @@ -893,6 +928,12 @@ void spinmarginwidth_changed (GtkWidget *widget, kwinst *app) app->marginwidth = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(widget)); } +void chkenablecmplt_toggled (GtkWidget *widget, kwinst *app) +{ + app->enablecmplt = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW(app->view), + app->enablecmplt); +} #endif void chkwinrestore_toggled (GtkWidget *widget, kwinst *app) diff --git a/gtk_settings.h b/gtk_settings.h index 765faa2..8caac49 100644 --- a/gtk_settings.h +++ b/gtk_settings.h @@ -40,6 +40,7 @@ void spinrecent_changed (GtkWidget *widget, kwinst *app); void chklinehghlt_toggled (GtkWidget *widget, kwinst *app); void chkshowmargin_toggled (GtkWidget *widget, kwinst *app); void spinmarginwidth_changed (GtkWidget *widget, kwinst *app); +void chkenablecmplt_toggled (GtkWidget *widget, kwinst *app); #endif // gboolean fov (GtkWidget *widget, GdkEvent *event, gpointer user_data); diff --git a/gtk_textview.c b/gtk_textview.c index 2881431..ce116e1 100644 --- a/gtk_textview.c +++ b/gtk_textview.c @@ -28,6 +28,10 @@ GtkWidget *create_textview_scrolledwindow (kwinst *app) // gtk_source_view_set_smart_backspace (GTK_SOURCE_VIEW(app->view), TRUE); gtk_source_view_set_smart_home_end (GTK_SOURCE_VIEW(app->view), GTK_SOURCE_SMART_HOME_END_BEFORE); + + /* create the sourceview completion object */ + if (app->enablecmplt) + create_completion (app); #else /* create buffer for text_view, init cursor and iter, line & col */ app->buffer = gtk_text_buffer_new (NULL); diff --git a/gtk_textview.h b/gtk_textview.h index 8d07201..2aed11f 100644 --- a/gtk_textview.h +++ b/gtk_textview.h @@ -4,6 +4,7 @@ #include #include "gtk_appdata.h" +#include "gtk_completionsv.h" GtkWidget *create_textview_scrolledwindow (kwinst *app); void set_tab_size (PangoFontDescription *font_desc, kwinst *app, gint sz);