SF.net SVN: geany:[5271] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Fri Oct 1 15:08:43 UTC 2010


Revision: 5271
          http://geany.svn.sourceforge.net/geany/?rev=5271&view=rev
Author:   ntrel
Date:     2010-10-01 15:08:43 +0000 (Fri, 01 Oct 2010)

Log Message:
-----------
Add snippet keybinding support for keys in user snippets.conf (based
on patch by Eugene Arshinov, thanks). No docs yet.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/editor.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2010-10-01 14:28:05 UTC (rev 5270)
+++ trunk/ChangeLog	2010-10-01 15:08:43 UTC (rev 5271)
@@ -3,6 +3,9 @@
  * src/tools.c, doc/geany.txt, doc/geany.html:
    Fix passing quoted arguments when using 'Send Selection to'. This
    means sed 's/\./(dot)/g' now works.
+ * src/editor.c:
+   Add snippet keybinding support for keys in user snippets.conf (based
+   on patch by Eugene Arshinov, thanks). No docs yet.
 
 
 2010-09-30  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>

Modified: trunk/src/editor.c
===================================================================
--- trunk/src/editor.c	2010-10-01 14:28:05 UTC (rev 5270)
+++ trunk/src/editor.c	2010-10-01 15:08:43 UTC (rev 5271)
@@ -76,6 +76,7 @@
 static GHashTable *snippet_hash = NULL;
 static GQueue *snippet_offsets = NULL;
 static gint snippet_cursor_insert_pos;
+static GtkAccelGroup *snippet_accel_group = NULL;
 
 /* holds word under the mouse or keyboard cursor */
 static gchar current_word[GEANY_MAX_WORD_LENGTH];
@@ -111,12 +112,16 @@
 static void read_current_word(GeanyEditor *editor, gint pos, gchar *word, size_t wordlen,
 		const gchar *wc, gboolean stem);
 static gsize count_indent_size(GeanyEditor *editor, const gchar *base_indent);
+static const gchar *snippets_find_completion_by_name(const gchar *type, const gchar *name);
+static gssize snippets_make_replacements(GeanyEditor *editor, GString *pattern,
+		gsize indent_size);
 
 
 void editor_snippets_free(void)
 {
 	g_hash_table_destroy(snippet_hash);
 	g_queue_free(snippet_offsets);
+	gtk_window_remove_accel_group(GTK_WINDOW(main_widgets.window), snippet_accel_group);
 }
 
 
@@ -136,6 +141,8 @@
 	groups_sys = g_key_file_get_groups(sysconfig, &len);
 	for (i = 0; i < len; i++)
 	{
+		if (strcmp(groups_sys[i], "Keybindings") == 0)
+			continue;
 		keys_sys = g_key_file_get_keys(sysconfig, groups_sys[i], &len_keys, NULL);
 		/* create new hash table for the read section (=> filetype) */
 		tmp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -154,6 +161,8 @@
 	groups_user = g_key_file_get_groups(userconfig, &len);
 	for (i = 0; i < len; i++)
 	{
+		if (strcmp(groups_user[i], "Keybindings") == 0)
+			continue;
 		keys_user = g_key_file_get_keys(userconfig, groups_user[i], &len_keys, NULL);
 
 		tmp = g_hash_table_lookup(snippet_hash, groups_user[i]);
@@ -182,6 +191,74 @@
 }
 
 
+static void on_snippet_keybinding_activate(gchar *key)
+{
+	GeanyDocument *doc = document_get_current();
+	const gchar *s;
+	GHashTable *specials;
+	GString *pattern;
+	gint pos, line, indent_width, cursor_pos;
+
+	if (!doc || !GTK_WIDGET_HAS_FOCUS(doc->editor->sci))
+		return;
+
+	s = snippets_find_completion_by_name(doc->file_type->name, key);
+	if (!s) /* allow user to specify keybindings for "special" snippets */
+	{
+		specials = g_hash_table_lookup(snippet_hash, "Special");
+		if (G_LIKELY(specials != NULL))
+			s = g_hash_table_lookup(specials, key);
+	}
+	if (!s)
+	{
+		utils_beep();
+		return;
+	}
+
+	pos = sci_get_current_position(doc->editor->sci);
+	line = sci_get_line_from_position(doc->editor->sci, pos);
+	indent_width = sci_get_line_indentation(doc->editor->sci, line);
+
+	pattern = g_string_new(s);
+	cursor_pos = snippets_make_replacements(doc->editor, pattern, indent_width);
+
+	editor_insert_text_block(doc->editor, pattern->str, pos, cursor_pos, indent_width, FALSE);
+	sci_scroll_caret(doc->editor->sci);
+
+	g_string_free(pattern, TRUE);
+}
+
+
+static void load_kb(GKeyFile *userconfig)
+{
+	gchar group[] = "Keybindings";
+	gsize len, j;
+	gchar **keys = g_key_file_get_keys(userconfig, group, &len, NULL);
+
+	if (!keys)
+		return;
+	for (j = 0; j < len; j++)
+	{
+		guint key;
+		GdkModifierType mods;
+		gchar *accel_string = g_key_file_get_value(userconfig, group, keys[j], NULL);
+
+		gtk_accelerator_parse(accel_string, &key, &mods);
+		g_free(accel_string);
+
+		if (key == 0 && mods == 0)
+		{
+			g_warning("Can not parse accelerator \"%s\" from user snippets.conf", accel_string);
+			continue;
+		}
+		gtk_accel_group_connect(snippet_accel_group, key, mods, 0,
+			g_cclosure_new_swap((GCallback)on_snippet_keybinding_activate,
+				g_strdup(keys[j]), (GClosureNotify)g_free));
+	}
+	g_strfreev(keys);
+}
+
+
 void editor_snippets_init(void)
 {
 	gchar *sysconfigfile, *userconfigfile;
@@ -204,6 +281,11 @@
 
 	snippets_init(sysconfig, userconfig);
 
+	/* setup snippet keybindings */
+	snippet_accel_group = gtk_accel_group_new();
+	gtk_window_add_accel_group(GTK_WINDOW(main_widgets.window), snippet_accel_group);
+	load_kb(userconfig);
+
 	g_free(sysconfigfile);
 	g_free(userconfigfile);
 	g_key_file_free(sysconfig);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list