SF.net SVN: geany: [2324] trunk
ntrel at users.sourceforge.net
ntrel at xxxxx
Wed Mar 12 17:07:51 UTC 2008
Revision: 2324
http://geany.svn.sourceforge.net/geany/?rev=2324&view=rev
Author: ntrel
Date: 2008-03-12 10:07:43 -0700 (Wed, 12 Mar 2008)
Log Message:
-----------
Merge plugin-keybindings branch:
Change keybindings code to use keybinding groups, each with a
separate enum set, which will make the plugin ABI more stable, and
lay the groundwork for plugin keybindings support.
Note: this breaks the plugin API.
Rename keybindings_cmd() to keybindings_send_command(), which now
takes a group_id argument.
Add keybindings_lookup_item().
Add documentation for keybindings structs.
Add support for plugin keybindings using the PLUGIN_KEY_GROUP()
macro.
Add a plugin keybinding for 'Insert Special HTML Characters'.
Rename KBCallback, cmd_id, cb_func with clearer names.
Add KeyBinding::menu_item field for setting accelerators (currently
does nothing).
Load keybindings keyfile after plugins have loaded at startup, so
their shortcuts are also loaded. Still to do: loading individual
plugin keybindings after startup.
Group most keybinding callbacks together according to keybinding
group.
Add keybindings_set_item() and add it to the plugin API.
Set main menu widget accels with keybindings_set_item() - they are
ignored for now. Popup menu accels are set separately.
Modified Paths:
--------------
trunk/ChangeLog
trunk/doc/plugins.dox
trunk/plugins/filebrowser.c
trunk/plugins/htmlchars.c
trunk/src/build.c
trunk/src/callbacks.c
trunk/src/keybindings.c
trunk/src/keybindings.h
trunk/src/main.c
trunk/src/plugindata.h
trunk/src/plugins.c
trunk/src/prefs.c
trunk/src/tools.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/ChangeLog 2008-03-12 17:07:43 UTC (rev 2324)
@@ -1,3 +1,34 @@
+2008-03-12 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/build.c, src/keybindings.c, src/keybindings.h,
+ src/tools.c, src/prefs.c, src/plugindata.h, src/callbacks.c,
+ src/plugins.c, src/main.c, doc/plugins.dox, plugins/filebrowser.c,
+ plugins/htmlchars.c:
+ Merge plugin-keybindings branch:
+ Change keybindings code to use keybinding groups, each with a
+ separate enum set, which will make the plugin ABI more stable, and
+ lay the groundwork for plugin keybindings support.
+ Note: this breaks the plugin API.
+ Rename keybindings_cmd() to keybindings_send_command(), which now
+ takes a group_id argument.
+ Add keybindings_lookup_item().
+ Add documentation for keybindings structs.
+ Add support for plugin keybindings using the PLUGIN_KEY_GROUP()
+ macro.
+ Add a plugin keybinding for 'Insert Special HTML Characters'.
+ Rename KBCallback, cmd_id, cb_func with clearer names.
+ Add KeyBinding::menu_item field for setting accelerators (currently
+ does nothing).
+ Load keybindings keyfile after plugins have loaded at startup, so
+ their shortcuts are also loaded. Still to do: loading individual
+ plugin keybindings after startup.
+ Group most keybinding callbacks together according to keybinding
+ group.
+ Add keybindings_set_item() and add it to the plugin API.
+ Set main menu widget accels with keybindings_set_item() - they are
+ ignored for now. Popup menu accels are set separately.
+
+
2008-03-09 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
* src/document.c:
Modified: trunk/doc/plugins.dox
===================================================================
--- trunk/doc/plugins.dox 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/doc/plugins.dox 2008-03-12 17:07:43 UTC (rev 2324)
@@ -49,10 +49,10 @@
* are optional, i.e. they can be omitted, others are required and must be defined.
*
* - @code version_check() @endcode
- * Use VERSION_CHECK() macro instead. Required by Geany.
+ * Use the VERSION_CHECK() macro instead. Required by Geany.
*
* - @code PluginInfo* info() @endcode
- * Use PLUGIN_INFO() macro to define it. Required by Geany.
+ * Use the PLUGIN_INFO() macro to define it. Required by Geany.
*
* - @code GeanyData* geany_data @endcode
* Geany owned fields and functions.
@@ -64,6 +64,9 @@
* An array for connecting GeanyObject events, which should be terminated with
* {NULL, NULL, FALSE, NULL}. See @link signals Signal documentation @endlink.
*
+ * - @code KeyBindingGroup plugin_key_group[1] @endcode
+ * Use the PLUGIN_KEY_GROUP() macro to define it.
+ *
* - @code void configure(GtkWidget *parent) @endcode
* Called when the plugin should show a configure dialog to let the user set some basic
* plugin configuration. Optionally, can be omitted when not needed.
@@ -84,7 +87,7 @@
*
* To use plugin signals in Geany, you simply create a GeanyCallback array, list the signals
* you want to listen to and create the appropiate signal callbacks for each signal.
- * @note The GeanyCallback array has be ended with a final NULL entry.
+ * @note The GeanyCallback array has to be ended with a final NULL entry.
*
* The following code demonstrates how to use signals in Geany plugins. The code can be inserted
* in your plugin code at any desired position.
@@ -193,7 +196,7 @@
* @section intro Introduction
*
* Since Geany 0.12 there is a plugin interface to extend Geany's functionality and
- * add new features. This %document gives a briefly overview about how to add new
+ * add new features. This %document gives a brief overview about how to add new
* plugins by writing a simple "Hello World" plugin in C.
*
*
Modified: trunk/plugins/filebrowser.c
===================================================================
--- trunk/plugins/filebrowser.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/plugins/filebrowser.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -495,6 +495,12 @@
}
+static void on_hide_sidebar(void)
+{
+ p_keybindings->send_command(GEANY_KEY_GROUP_VIEW, GEANY_KEYS_VIEW_SIDEBAR);
+}
+
+
static GtkWidget *create_popup_menu(void)
{
GtkWidget *item, *menu, *image;
@@ -545,9 +551,7 @@
gtk_image_new_from_stock("gtk-close", GTK_ICON_SIZE_MENU));
gtk_widget_show(item);
gtk_container_add(GTK_CONTAINER(menu), item);
- g_signal_connect_swapped((gpointer) item, "activate",
- G_CALLBACK(p_keybindings->send_command),
- GINT_TO_POINTER(GEANY_KEYS_MENU_SIDEBAR));
+ g_signal_connect((gpointer) item, "activate", G_CALLBACK(on_hide_sidebar), NULL);
return menu;
}
Modified: trunk/plugins/htmlchars.c
===================================================================
--- trunk/plugins/htmlchars.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/plugins/htmlchars.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -28,6 +28,7 @@
#include "support.h"
#include "plugindata.h"
#include "document.h"
+#include "keybindings.h"
#include "pluginmacros.h"
@@ -41,8 +42,18 @@
_("The Geany developer team"))
+/* Keybinding(s) */
enum
{
+ KB_INSERT_HTML_CHARS,
+ KB_COUNT
+};
+
+PLUGIN_KEY_GROUP(html_chars, KB_COUNT)
+
+
+enum
+{
COLUMN_CHARACTER,
COLUMN_HTML_NAME,
N_COLUMNS
@@ -503,13 +514,20 @@
}
+static void kb_activate(G_GNUC_UNUSED guint key_id)
+{
+ item_activate(NULL, NULL);
+}
+
+
/* Called by Geany to initialize the plugin */
void init(GeanyData *data)
{
GtkWidget *demo_item;
+ const gchar *menu_text = _("_Insert Special HTML Characters");
/* Add an item to the Tools menu */
- demo_item = gtk_menu_item_new_with_mnemonic(_("_Insert Special HTML Characters"));
+ demo_item = gtk_menu_item_new_with_mnemonic(menu_text);
gtk_widget_show(demo_item);
gtk_container_add(GTK_CONTAINER(geany_data->tools_menu), demo_item);
g_signal_connect(G_OBJECT(demo_item), "activate", G_CALLBACK(item_activate), NULL);
@@ -517,6 +535,10 @@
/* disable menu_item when there are no documents open */
plugin_fields->menu_item = demo_item;
plugin_fields->flags = PLUGIN_IS_DOCUMENT_SENSITIVE;
+
+ /* setup keybindings */
+ p_keybindings->set_item(plugin_key_group, KB_INSERT_HTML_CHARS, kb_activate,
+ 0, 0, "insert_html_chars", menu_text, demo_item);
}
Modified: trunk/src/build.c
===================================================================
--- trunk/src/build.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/build.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -1087,16 +1087,29 @@
}
-#define GEANY_ADD_WIDGET_ACCEL(gkey, menuitem) \
- if (keys[(gkey)]->key != 0) \
- gtk_widget_add_accelerator(menuitem, "activate", accel_group, \
- keys[(gkey)]->key, keys[(gkey)]->mods, GTK_ACCEL_VISIBLE)
+/* note: copied from keybindings.c.
+ * Perhaps the separate Tex menu could be merged with the default build menu?
+ * Then this could be done with Glade and set the accels in keybindings.c. */
+static void add_menu_accel(KeyBindingGroup *group, guint kb_id,
+ GtkAccelGroup *accel_group, GtkWidget *menuitem)
+{
+ KeyBinding *kb = &group->keys[kb_id];
+ if (kb->key != 0)
+ gtk_widget_add_accelerator(menuitem, "activate", accel_group,
+ kb->key, kb->mods, GTK_ACCEL_VISIBLE);
+}
+
+
+#define GEANY_ADD_WIDGET_ACCEL(kb_id, menuitem) \
+ add_menu_accel(group, kb_id, accel_group, menuitem)
+
static void create_build_menu_gen(BuildMenuItems *menu_items)
{
GtkWidget *menu, *item = NULL, *image, *separator;
GtkAccelGroup *accel_group = gtk_accel_group_new();
GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
+ KeyBindingGroup *group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_BUILD);
menu = gtk_menu_new();
@@ -1213,6 +1226,7 @@
GtkWidget *menu, *item, *image, *separator;
GtkAccelGroup *accel_group = gtk_accel_group_new();
GtkTooltips *tooltips = GTK_TOOLTIPS(lookup_widget(app->window, "tooltips"));
+ KeyBindingGroup *group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_BUILD);
menu = gtk_menu_new();
Modified: trunk/src/callbacks.c
===================================================================
--- trunk/src/callbacks.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/callbacks.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -654,7 +654,7 @@
{
if (event->keyval == GDK_Escape)
{
- keybindings_cmd(GEANY_KEYS_SWITCH_EDITOR);
+ keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR);
return TRUE;
}
return FALSE;
@@ -925,7 +925,7 @@
if (! sci_can_copy(sci))
{
- keybindings_cmd(GEANY_KEYS_EDIT_SELECTWORD);
+ keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_WORD);
keep_sel = FALSE;
}
@@ -1133,7 +1133,7 @@
on_compile_button_clicked (GtkToolButton *toolbutton,
gpointer user_data)
{
- keybindings_cmd(GEANY_KEYS_BUILD_COMPILE);
+ keybindings_send_command(GEANY_KEY_GROUP_BUILD, GEANY_KEYS_BUILD_COMPILE);
}
@@ -1581,7 +1581,7 @@
on_run_button_clicked (GtkToolButton *toolbutton,
gpointer user_data)
{
- keybindings_cmd(GEANY_KEYS_BUILD_RUN);
+ keybindings_send_command(GEANY_KEY_GROUP_BUILD, GEANY_KEYS_BUILD_RUN);
}
@@ -1737,7 +1737,7 @@
on_menu_duplicate_line1_activate (GtkMenuItem *menuitem,
gpointer user_data)
{
- keybindings_cmd(GEANY_KEYS_EDIT_DUPLICATELINE);
+ keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_DUPLICATELINE);
}
Modified: trunk/src/keybindings.c
===================================================================
--- trunk/src/keybindings.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/keybindings.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -46,28 +46,31 @@
#include "vte.h"
-KeyBinding *keys[GEANY_MAX_KEYS];
+GPtrArray *keybinding_groups; /* array of KeyBindingGroup pointers */
+/* keyfile group name for non-plugin KB groups */
+static const gchar default_group_name[] = "Bindings";
+
static const gboolean swap_alt_tab_order = FALSE;
-/* simple convenience function to allocate and fill the struct */
-static KeyBinding *fill(KBCallback func, guint key, GdkModifierType mod, const gchar *name,
- const gchar *label);
+static gboolean check_current_word(void);
static void cb_func_file_action(guint key_id);
-static void cb_func_menu_print(guint key_id);
+static void cb_func_project_action(guint key_id);
+static void cb_func_editor_action(guint key_id);
+static void cb_func_select_action(guint key_id);
+static void cb_func_format_action(guint key_id);
+static void cb_func_insert_action(guint key_id);
+static void cb_func_search_action(guint key_id);
+static void cb_func_goto_action(guint key_id);
+static void cb_func_clipboard(guint key_id);
+static void cb_func_build_action(guint key_id);
-static void cb_func_menu_undo(guint key_id);
-static void cb_func_menu_redo(guint key_id);
-static void cb_func_clipboard(guint key_id);
-static void cb_func_menu_selectall(guint key_id);
+/* TODO: refactor individual callbacks per group */
static void cb_func_menu_help(guint key_id);
static void cb_func_menu_preferences(guint key_id);
-static void cb_func_menu_insert_date(guint key_id);
-static void cb_func_menu_search(guint key_id);
-
static void cb_func_menu_toggle_all(guint key_id);
static void cb_func_menu_fullscreen(guint key_id);
static void cb_func_menu_messagewindow(guint key_id);
@@ -80,10 +83,7 @@
static void cb_func_reloadtaglist(guint key_id);
static void cb_func_menu_opencolorchooser(guint key_id);
-static void cb_func_menu_insert_specialchars(guint key_id);
-static void cb_func_build_action(guint key_id);
-
static void cb_func_switch_editor(guint key_id);
static void cb_func_switch_scribble(guint key_id);
static void cb_func_switch_vte(guint key_id);
@@ -92,270 +92,402 @@
static void cb_func_switch_tabright(guint key_id);
static void cb_func_switch_tablastused(guint key_id);
static void cb_func_move_tab(guint key_id);
-static void cb_func_nav_back(guint key_id);
-static void cb_func_nav_forward(guint key_id);
static void cb_func_toggle_sidebar(guint key_id);
-/* common function for editing keybindings, only valid when scintilla has focus. */
-static void cb_func_edit(guint key_id);
+static void add_popup_menu_accels(void);
-/* common function for global editing keybindings. */
-static void cb_func_edit_global(guint key_id);
-/* common function for keybindings using current word */
-static void cb_func_current_word(guint key_id);
+/** Simple convenience function to fill a KeyBinding struct item */
+void keybindings_set_item(KeyBindingGroup *group, gsize key_id,
+ KeyCallback callback, guint key, GdkModifierType mod,
+ const gchar *name, const gchar *label, GtkWidget *menu_item)
+{
+ KeyBinding *kb;
-static void add_menu_accels(void);
+ g_assert(key_id < group->count);
+ kb = &group->keys[key_id];
+ kb->name = name;
+ kb->label = label;
+ kb->key = key;
+ kb->mods = mod;
+ kb->callback = callback;
+ kb->menu_item = menu_item;
+}
+
+
+static KeyBindingGroup *add_kb_group(KeyBindingGroup *group,
+ const gchar *name, const gchar *label, gsize count, KeyBinding *keys)
+{
+ g_ptr_array_add(keybinding_groups, group);
+
+ group->name = name;
+ group->label = label;
+ group->count = count;
+ group->keys = keys;
+ return group;
+}
+
+
+/* Lookup a widget in the main window */
+#define LW(widget_name) \
+ lookup_widget(app->window, G_STRINGIFY(widget_name))
+
+/* Expansion for group_id = FILE:
+ * static KeyBinding FILE_keys[GEANY_KEYS_FILE_COUNT]; */
+#define DECLARE_KEYS(group_id) \
+ static KeyBinding group_id ## _keys[GEANY_KEYS_ ## group_id ## _COUNT]
+
+/* Expansion for group_id = FILE:
+ * add_kb_group(&groups[GEANY_KEY_GROUP_FILE], NULL, _("File menu"),
+ * GEANY_KEYS_FILE_COUNT, FILE_keys); */
+#define ADD_KB_GROUP(group_id, label) \
+ add_kb_group(&groups[GEANY_KEY_GROUP_ ## group_id], default_group_name, label, \
+ GEANY_KEYS_ ## group_id ## _COUNT, group_id ## _keys)
+
+/* Init all fields of keys with default values.
+ * The menu_item field is always the main menu item, popup menu accelerators are
+ * set in add_popup_menu_accels(). */
static void init_default_kb(void)
{
- /* init all fields of keys with default values */
- keys[GEANY_KEYS_MENU_NEW] = fill(cb_func_file_action,
- GDK_n, GDK_CONTROL_MASK, "menu_new", _("New"));
- keys[GEANY_KEYS_MENU_OPEN] = fill(cb_func_file_action,
- GDK_o, GDK_CONTROL_MASK, "menu_open", _("Open"));
- keys[GEANY_KEYS_MENU_OPENSELECTED] = fill(cb_func_file_action,
- GDK_o, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "menu_open_selected", _("Open selected file"));
- keys[GEANY_KEYS_MENU_SAVE] = fill(cb_func_file_action,
- GDK_s, GDK_CONTROL_MASK, "menu_save", _("Save"));
- keys[GEANY_KEYS_MENU_SAVEAS] = fill(cb_func_file_action,
- 0, 0, "menu_saveas", _("Save as"));
- keys[GEANY_KEYS_MENU_SAVEALL] = fill(cb_func_file_action,
- GDK_S, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "menu_saveall", _("Save all"));
- keys[GEANY_KEYS_MENU_PRINT] = fill(cb_func_menu_print,
- GDK_p, GDK_CONTROL_MASK, "menu_print", _("Print"));
- keys[GEANY_KEYS_MENU_CLOSE] = fill(cb_func_file_action,
- GDK_w, GDK_CONTROL_MASK, "menu_close", _("Close"));
- keys[GEANY_KEYS_MENU_CLOSEALL] = fill(cb_func_file_action,
- GDK_w, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "menu_closeall", _("Close all"));
- keys[GEANY_KEYS_MENU_RELOADFILE] = fill(cb_func_file_action,
- GDK_r, GDK_CONTROL_MASK, "menu_reloadfile", _("Reload file"));
- keys[GEANY_KEYS_MENU_PROJECTPROPERTIES] = fill(cb_func_file_action,
- 0, 0, "project_properties", _("Project properties"));
+ static KeyBindingGroup groups[GEANY_KEY_GROUP_COUNT];
+ KeyBindingGroup *group;
+ DECLARE_KEYS(FILE);
+ DECLARE_KEYS(PROJECT);
+ DECLARE_KEYS(EDITOR);
+ DECLARE_KEYS(CLIPBOARD);
+ DECLARE_KEYS(SELECT);
+ DECLARE_KEYS(FORMAT);
+ DECLARE_KEYS(INSERT);
+ DECLARE_KEYS(SETTINGS);
+ DECLARE_KEYS(SEARCH);
+ DECLARE_KEYS(GOTO);
+ DECLARE_KEYS(VIEW);
+ DECLARE_KEYS(FOCUS);
+ DECLARE_KEYS(NOTEBOOK);
+ DECLARE_KEYS(DOCUMENT);
+ DECLARE_KEYS(BUILD);
+ DECLARE_KEYS(TOOLS);
+ DECLARE_KEYS(HELP);
- keys[GEANY_KEYS_MENU_UNDO] = fill(cb_func_menu_undo,
- GDK_z, GDK_CONTROL_MASK, "menu_undo", _("Undo"));
- keys[GEANY_KEYS_MENU_REDO] = fill(cb_func_menu_redo,
- GDK_y, GDK_CONTROL_MASK, "menu_redo", _("Redo"));
- keys[GEANY_KEYS_MENU_CUT] = fill(cb_func_clipboard,
- GDK_x, GDK_CONTROL_MASK, "menu_cut", _("Cut"));
- keys[GEANY_KEYS_MENU_COPY] = fill(cb_func_clipboard,
- GDK_c, GDK_CONTROL_MASK, "menu_copy", _("Copy"));
- keys[GEANY_KEYS_MENU_PASTE] = fill(cb_func_clipboard,
- GDK_v, GDK_CONTROL_MASK, "menu_paste", _("Paste"));
- keys[GEANY_KEYS_MENU_SELECTALL] = fill(cb_func_menu_selectall,
- GDK_a, GDK_CONTROL_MASK, "menu_selectall", _("Select All"));
- keys[GEANY_KEYS_MENU_INSERTDATE] = fill(cb_func_menu_insert_date,
- GDK_d, GDK_SHIFT_MASK | GDK_MOD1_MASK, "menu_insert_date", _("Insert date"));
- keys[GEANY_KEYS_MENU_PREFERENCES] = fill(cb_func_menu_preferences,
- GDK_p, GDK_CONTROL_MASK | GDK_MOD1_MASK, "menu_preferences", _("Preferences"));
+ group = ADD_KB_GROUP(FILE, _("File"));
- /* search */
- keys[GEANY_KEYS_MENU_FIND] = fill(cb_func_menu_search,
- GDK_f, GDK_CONTROL_MASK, "menu_find", _("Find"));
- keys[GEANY_KEYS_MENU_FINDNEXT] = fill(cb_func_menu_search,
- GDK_g, GDK_CONTROL_MASK, "menu_findnext", _("Find Next"));
- keys[GEANY_KEYS_MENU_FINDPREVIOUS] = fill(cb_func_menu_search,
- GDK_g, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "menu_findprevious", _("Find Previous"));
- keys[GEANY_KEYS_MENU_FINDNEXTSEL] = fill(cb_func_menu_search,
- 0, 0, "menu_findnextsel", _("Find Next Selection"));
- keys[GEANY_KEYS_MENU_FINDPREVSEL] = fill(cb_func_menu_search,
- 0, 0, "menu_findprevsel", _("Find Previous Selection"));
- keys[GEANY_KEYS_MENU_REPLACE] = fill(cb_func_menu_search,
- GDK_h, GDK_CONTROL_MASK, "menu_replace", _("Replace"));
- keys[GEANY_KEYS_MENU_FINDINFILES] = fill(cb_func_menu_search, GDK_f,
- GDK_CONTROL_MASK | GDK_SHIFT_MASK, "menu_findinfiles", _("Find in Files"));
- keys[GEANY_KEYS_MENU_NEXTMESSAGE] = fill(cb_func_menu_search,
- 0, 0, "menu_nextmessage", _("Next Message"));
- keys[GEANY_KEYS_MENU_GOTOLINE] = fill(cb_func_menu_search,
- GDK_l, GDK_CONTROL_MASK, "menu_gotoline", _("Go to Line"));
+ keybindings_set_item(group, GEANY_KEYS_FILE_NEW, cb_func_file_action,
+ GDK_n, GDK_CONTROL_MASK, "menu_new", _("New"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FILE_OPEN, cb_func_file_action,
+ GDK_o, GDK_CONTROL_MASK, "menu_open", _("Open"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FILE_OPENSELECTED, cb_func_file_action,
+ GDK_o, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "menu_open_selected",
+ _("Open selected file"), LW(menu_open_selected_file1));
+ keybindings_set_item(group, GEANY_KEYS_FILE_SAVE, cb_func_file_action,
+ GDK_s, GDK_CONTROL_MASK, "menu_save", _("Save"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FILE_SAVEAS, cb_func_file_action,
+ 0, 0, "menu_saveas", _("Save as"), LW(menu_save_as1));
+ keybindings_set_item(group, GEANY_KEYS_FILE_SAVEALL, cb_func_file_action,
+ GDK_S, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "menu_saveall", _("Save all"),
+ LW(menu_save_all1));
+ keybindings_set_item(group, GEANY_KEYS_FILE_PRINT, cb_func_file_action,
+ GDK_p, GDK_CONTROL_MASK, "menu_print", _("Print"), LW(print1));
+ keybindings_set_item(group, GEANY_KEYS_FILE_CLOSE, cb_func_file_action,
+ GDK_w, GDK_CONTROL_MASK, "menu_close", _("Close"), LW(menu_close1));
+ keybindings_set_item(group, GEANY_KEYS_FILE_CLOSEALL, cb_func_file_action,
+ GDK_w, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "menu_closeall", _("Close all"),
+ LW(menu_close_all1));
+ keybindings_set_item(group, GEANY_KEYS_FILE_RELOAD, cb_func_file_action,
+ GDK_r, GDK_CONTROL_MASK, "menu_reloadfile", _("Reload file"), LW(menu_reload1));
- keys[GEANY_KEYS_MENU_TOGGLEALL] = fill(cb_func_menu_toggle_all,
- 0, 0, "menu_toggleall", _("Toggle All Additional Widgets"));
- keys[GEANY_KEYS_MENU_FULLSCREEN] = fill(cb_func_menu_fullscreen,
- GDK_F11, 0, "menu_fullscreen", _("Fullscreen"));
- keys[GEANY_KEYS_MENU_MESSAGEWINDOW] = fill(cb_func_menu_messagewindow,
- 0, 0, "menu_messagewindow", _("Toggle Messages Window"));
- keys[GEANY_KEYS_MENU_SIDEBAR] = fill(cb_func_toggle_sidebar,
- 0, 0, "toggle_sidebar", _("Toggle Sidebar"));
- keys[GEANY_KEYS_MENU_ZOOMIN] = fill(cb_func_menu_zoomin,
- GDK_plus, GDK_CONTROL_MASK, "menu_zoomin", _("Zoom In"));
- keys[GEANY_KEYS_MENU_ZOOMOUT] = fill(cb_func_menu_zoomout,
- GDK_minus, GDK_CONTROL_MASK, "menu_zoomout", _("Zoom Out"));
+ group = ADD_KB_GROUP(PROJECT, _("Project"));
- keys[GEANY_KEYS_MENU_OPENCOLORCHOOSER] = fill(cb_func_menu_opencolorchooser,
- 0, 0, "menu_opencolorchooser", _("Show Color Chooser"));
- keys[GEANY_KEYS_MENU_INSERTSPECIALCHARS] = fill(cb_func_menu_insert_specialchars,
- 0, 0, "menu_insert_specialchars", _("Insert Special HTML Characters"));
+ keybindings_set_item(group, GEANY_KEYS_PROJECT_PROPERTIES, cb_func_project_action,
+ 0, 0, "project_properties", _("Project properties"), LW(project_properties1));
- keys[GEANY_KEYS_MENU_REPLACETABS] = fill(cb_func_menu_replacetabs,
- 0, 0, "menu_replacetabs", _("Replace tabs by space"));
- keys[GEANY_KEYS_MENU_FOLDALL] = fill(cb_func_menu_foldall,
- 0, 0, "menu_foldall", _("Fold all"));
- keys[GEANY_KEYS_MENU_UNFOLDALL] = fill(cb_func_menu_unfoldall,
- 0, 0, "menu_unfoldall", _("Unfold all"));
- keys[GEANY_KEYS_RELOADTAGLIST] = fill(cb_func_reloadtaglist,
- GDK_r, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "reloadtaglist", _("Reload symbol list"));
+ group = ADD_KB_GROUP(EDITOR, _("Editor"));
- keys[GEANY_KEYS_BUILD_COMPILE] = fill(cb_func_build_action,
- GDK_F8, 0, "build_compile", _("Compile"));
- keys[GEANY_KEYS_BUILD_LINK] = fill(cb_func_build_action,
- GDK_F9, 0, "build_link", _("Build"));
- keys[GEANY_KEYS_BUILD_MAKE] = fill(cb_func_build_action,
- GDK_F9, GDK_SHIFT_MASK, "build_make", _("Make all"));
- keys[GEANY_KEYS_BUILD_MAKEOWNTARGET] = fill(cb_func_build_action,
- GDK_F9, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "build_makeowntarget",
- _("Make custom target"));
- keys[GEANY_KEYS_BUILD_MAKEOBJECT] = fill(cb_func_build_action,
- 0, 0, "build_makeobject", _("Make object"));
- keys[GEANY_KEYS_BUILD_NEXTERROR] = fill(cb_func_build_action,
- 0, 0, "build_nexterror", _("Next error"));
- keys[GEANY_KEYS_BUILD_RUN] = fill(cb_func_build_action,
- GDK_F5, 0, "build_run", _("Run"));
- keys[GEANY_KEYS_BUILD_RUN2] = fill(cb_func_build_action,
- 0, 0, "build_run2", _("Run (alternative command)"));
- keys[GEANY_KEYS_BUILD_OPTIONS] = fill(cb_func_build_action,
- 0, 0, "build_options", _("Build options"));
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_UNDO, cb_func_editor_action,
+ GDK_z, GDK_CONTROL_MASK, "menu_undo", _("Undo"), LW(menu_undo2));
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_REDO, cb_func_editor_action,
+ GDK_y, GDK_CONTROL_MASK, "menu_redo", _("Redo"), LW(menu_redo2));
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_DUPLICATELINE, cb_func_editor_action,
+ GDK_d, GDK_CONTROL_MASK, "edit_duplicateline", _("Duplicate line or selection"),
+ LW(menu_duplicate_line1));
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_DELETELINE, cb_func_editor_action,
+ GDK_k, GDK_CONTROL_MASK, "edit_deleteline", _("Delete current line(s)"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_TRANSPOSELINE, cb_func_editor_action,
+ GDK_t, GDK_CONTROL_MASK, "edit_transposeline", _("Transpose current line"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_SCROLLTOLINE, cb_func_editor_action,
+ GDK_l, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "edit_scrolltoline", _("Scroll to current line"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_SCROLLLINEUP, cb_func_editor_action,
+ GDK_Up, GDK_MOD1_MASK, "edit_scrolllineup", _("Scroll up the view by one line"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_SCROLLLINEDOWN, cb_func_editor_action,
+ GDK_Down, GDK_MOD1_MASK, "edit_scrolllinedown", _("Scroll down the view by one line"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_COMPLETESNIPPET, NULL, /* handled specially in check_snippet_completion() */
+ GDK_Tab, 0, "edit_completesnippet", _("Complete snippet"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_SUPPRESSSNIPPETCOMPLETION, cb_func_editor_action,
+ 0, 0, "edit_suppresssnippetcompletion", _("Suppress snippet completion"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_CONTEXTACTION, cb_func_editor_action,
+ 0, 0, "popup_contextaction", _("Context Action"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_AUTOCOMPLETE, cb_func_editor_action,
+ GDK_space, GDK_CONTROL_MASK, "edit_autocomplete", _("Complete word"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_CALLTIP, cb_func_editor_action,
+ GDK_space, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "edit_calltip", _("Show calltip"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_EDITOR_MACROLIST, cb_func_editor_action,
+ GDK_Return, GDK_CONTROL_MASK, "edit_macrolist", _("Show macro list"), NULL);
- keys[GEANY_KEYS_MENU_HELP] = fill(cb_func_menu_help,
- GDK_F1, 0, "menu_help", _("Help"));
+ group = ADD_KB_GROUP(CLIPBOARD, _("Clipboard"));
- keys[GEANY_KEYS_SWITCH_EDITOR] = fill(cb_func_switch_editor,
- GDK_F2, 0, "switch_editor", _("Switch to Editor"));
- keys[GEANY_KEYS_SWITCH_SCRIBBLE] = fill(cb_func_switch_scribble,
- GDK_F6, 0, "switch_scribble", _("Switch to Scribble"));
- keys[GEANY_KEYS_SWITCH_VTE] = fill(cb_func_switch_vte,
- GDK_F4, 0, "switch_vte", _("Switch to VTE"));
- keys[GEANY_KEYS_SWITCH_SEARCH_BAR] = fill(cb_func_switch_search_bar,
- GDK_F7, 0, "switch_search_bar", _("Switch to Search Bar"));
- keys[GEANY_KEYS_SWITCH_TABLEFT] = fill(cb_func_switch_tableft,
- GDK_Page_Up, GDK_CONTROL_MASK, "switch_tableft", _("Switch to left document"));
- keys[GEANY_KEYS_SWITCH_TABRIGHT] = fill(cb_func_switch_tabright,
- GDK_Page_Down, GDK_CONTROL_MASK, "switch_tabright", _("Switch to right document"));
- keys[GEANY_KEYS_SWITCH_TABLASTUSED] = fill(cb_func_switch_tablastused,
- GDK_Tab, GDK_CONTROL_MASK, "switch_tablastused", _("Switch to last used document"));
- keys[GEANY_KEYS_MOVE_TABLEFT] = fill(cb_func_move_tab,
- GDK_Page_Up, GDK_MOD1_MASK, "move_tableft", _("Move document left"));
- keys[GEANY_KEYS_MOVE_TABRIGHT] = fill(cb_func_move_tab,
- GDK_Page_Down, GDK_MOD1_MASK, "move_tabright", _("Move document right"));
- keys[GEANY_KEYS_MOVE_TABFIRST] = fill(cb_func_move_tab,
- 0, 0, "move_tabfirst", _("Move document first"));
- keys[GEANY_KEYS_MOVE_TABLAST] = fill(cb_func_move_tab,
- 0, 0, "move_tablast", _("Move document last"));
- keys[GEANY_KEYS_NAV_BACK] = fill(cb_func_nav_back,
- 0, 0, "nav_back", _("Navigate back a location"));
- keys[GEANY_KEYS_NAV_FORWARD] = fill(cb_func_nav_forward,
- 0, 0, "nav_forward", _("Navigate forward a location"));
+ keybindings_set_item(group, GEANY_KEYS_CLIPBOARD_CUT, cb_func_clipboard,
+ GDK_x, GDK_CONTROL_MASK, "menu_cut", _("Cut"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_CLIPBOARD_COPY, cb_func_clipboard,
+ GDK_c, GDK_CONTROL_MASK, "menu_copy", _("Copy"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_CLIPBOARD_PASTE, cb_func_clipboard,
+ GDK_v, GDK_CONTROL_MASK, "menu_paste", _("Paste"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_CLIPBOARD_COPYLINE, cb_func_clipboard,
+ GDK_c, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "edit_copyline", _("Copy current line(s)"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_CLIPBOARD_CUTLINE, cb_func_clipboard,
+ GDK_x, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "edit_cutline", _("Cut current line(s)"), NULL);
- keys[GEANY_KEYS_EDIT_DUPLICATELINE] = fill(cb_func_edit,
- GDK_d, GDK_CONTROL_MASK, "edit_duplicateline", _("Duplicate line or selection"));
- keys[GEANY_KEYS_EDIT_DELETELINE] = fill(cb_func_edit,
- GDK_k, GDK_CONTROL_MASK, "edit_deleteline", _("Delete current line(s)"));
- keys[GEANY_KEYS_EDIT_COPYLINE] = fill(cb_func_edit,
- GDK_c, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "edit_copyline", _("Copy current line(s)"));
- keys[GEANY_KEYS_EDIT_CUTLINE] = fill(cb_func_edit,
- GDK_x, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "edit_cutline", _("Cut current line(s)"));
- keys[GEANY_KEYS_EDIT_TRANSPOSELINE] = fill(cb_func_edit,
- GDK_t, GDK_CONTROL_MASK, "edit_transposeline", _("Transpose current line"));
- keys[GEANY_KEYS_EDIT_TOGGLECASE] = fill(cb_func_edit,
- GDK_u, GDK_CONTROL_MASK | GDK_MOD1_MASK, "edit_togglecase", _("Toggle Case of Selection"));
- keys[GEANY_KEYS_EDIT_COMMENTLINETOGGLE] = fill(cb_func_edit,
- GDK_e, GDK_CONTROL_MASK, "edit_commentlinetoggle", _("Toggle line commentation"));
- keys[GEANY_KEYS_EDIT_COMMENTLINE] = fill(cb_func_edit,
- 0, 0, "edit_commentline", _("Comment line(s)"));
- keys[GEANY_KEYS_EDIT_UNCOMMENTLINE] = fill(cb_func_edit,
- 0, 0, "edit_uncommentline", _("Uncomment line(s)"));
- keys[GEANY_KEYS_EDIT_INCREASEINDENT] = fill(cb_func_edit,
- GDK_i, GDK_CONTROL_MASK, "edit_increaseindent", _("Increase indent"));
- keys[GEANY_KEYS_EDIT_DECREASEINDENT] = fill(cb_func_edit,
- GDK_u, GDK_CONTROL_MASK, "edit_decreaseindent", _("Decrease indent"));
- keys[GEANY_KEYS_EDIT_INCREASEINDENTBYSPACE] = fill(cb_func_edit,
- 0, 0, "edit_increaseindentbyspace", _("Increase indent by one space"));
- keys[GEANY_KEYS_EDIT_DECREASEINDENTBYSPACE] = fill(cb_func_edit,
- 0, 0, "edit_decreaseindentbyspace", _("Decrease indent by one space"));
- keys[GEANY_KEYS_EDIT_AUTOINDENT] = fill(cb_func_edit,
- 0, 0, "edit_autoindent", _("Smart line indent"));
- keys[GEANY_KEYS_EDIT_SENDTOCMD1] = fill(cb_func_edit,
- GDK_1, GDK_CONTROL_MASK, "edit_sendtocmd1", _("Send to Custom Command 1"));
- keys[GEANY_KEYS_EDIT_SENDTOCMD2] = fill(cb_func_edit,
- GDK_2, GDK_CONTROL_MASK, "edit_sendtocmd2", _("Send to Custom Command 2"));
- keys[GEANY_KEYS_EDIT_SENDTOCMD3] = fill(cb_func_edit,
- GDK_3, GDK_CONTROL_MASK, "edit_sendtocmd3", _("Send to Custom Command 3"));
- keys[GEANY_KEYS_EDIT_GOTOMATCHINGBRACE] = fill(cb_func_edit_global,
+ group = ADD_KB_GROUP(SELECT, _("Select"));
+
+ keybindings_set_item(group, GEANY_KEYS_SELECT_ALL, cb_func_select_action,
+ GDK_a, GDK_CONTROL_MASK, "menu_selectall", _("Select All"), LW(menu_select_all1));
+ keybindings_set_item(group, GEANY_KEYS_SELECT_WORD, cb_func_select_action,
+ GDK_w, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectword", _("Select current word"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_SELECT_LINE, cb_func_select_action,
+ GDK_l, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectline", _("Select current line(s)"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_SELECT_PARAGRAPH, cb_func_select_action,
+ GDK_p, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectparagraph", _("Select current paragraph"), NULL);
+
+ group = ADD_KB_GROUP(FORMAT, _("Format"));
+
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_TOGGLECASE, cb_func_format_action,
+ GDK_u, GDK_CONTROL_MASK | GDK_MOD1_MASK, "edit_togglecase",
+ _("Toggle Case of Selection"), LW(menu_toggle_case2));
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_COMMENTLINETOGGLE, cb_func_format_action,
+ GDK_e, GDK_CONTROL_MASK, "edit_commentlinetoggle", _("Toggle line commentation"),
+ LW(menu_toggle_line_commentation1));
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_COMMENTLINE, cb_func_format_action,
+ 0, 0, "edit_commentline", _("Comment line(s)"), LW(menu_comment_line1));
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_UNCOMMENTLINE, cb_func_format_action,
+ 0, 0, "edit_uncommentline", _("Uncomment line(s)"), LW(menu_uncomment_line1));
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_INCREASEINDENT, cb_func_format_action,
+ GDK_i, GDK_CONTROL_MASK, "edit_increaseindent", _("Increase indent"),
+ LW(menu_increase_indent1));
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_DECREASEINDENT, cb_func_format_action,
+ GDK_u, GDK_CONTROL_MASK, "edit_decreaseindent", _("Decrease indent"),
+ LW(menu_decrease_indent1));
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_INCREASEINDENTBYSPACE, cb_func_format_action,
+ 0, 0, "edit_increaseindentbyspace", _("Increase indent by one space"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_DECREASEINDENTBYSPACE, cb_func_format_action,
+ 0, 0, "edit_decreaseindentbyspace", _("Decrease indent by one space"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_AUTOINDENT, cb_func_format_action,
+ 0, 0, "edit_autoindent", _("Smart line indent"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_SENDTOCMD1, cb_func_format_action,
+ GDK_1, GDK_CONTROL_MASK, "edit_sendtocmd1", _("Send to Custom Command 1"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_SENDTOCMD2, cb_func_format_action,
+ GDK_2, GDK_CONTROL_MASK, "edit_sendtocmd2", _("Send to Custom Command 2"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FORMAT_SENDTOCMD3, cb_func_format_action,
+ GDK_3, GDK_CONTROL_MASK, "edit_sendtocmd3", _("Send to Custom Command 3"), NULL);
+
+ group = ADD_KB_GROUP(INSERT, _("Insert"));
+
+ keybindings_set_item(group, GEANY_KEYS_INSERT_DATE, cb_func_insert_action,
+ GDK_d, GDK_SHIFT_MASK | GDK_MOD1_MASK, "menu_insert_date", _("Insert date"),
+ LW(insert_date_custom1));
+ keybindings_set_item(group, GEANY_KEYS_INSERT_ALTWHITESPACE, cb_func_insert_action,
+ 0, 0, "edit_insertwhitespace", _("Insert alternative whitespace"), NULL);
+
+ group = ADD_KB_GROUP(SETTINGS, _("Settings"));
+
+ keybindings_set_item(group, GEANY_KEYS_SETTINGS_PREFERENCES, cb_func_menu_preferences,
+ GDK_p, GDK_CONTROL_MASK | GDK_MOD1_MASK, "menu_preferences", _("Preferences"),
+ LW(preferences1));
+
+ group = ADD_KB_GROUP(SEARCH, _("Search"));
+
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_FIND, cb_func_search_action,
+ GDK_f, GDK_CONTROL_MASK, "menu_find", _("Find"), LW(find1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_FINDNEXT, cb_func_search_action,
+ GDK_g, GDK_CONTROL_MASK, "menu_findnext", _("Find Next"), LW(find_next1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_FINDPREVIOUS, cb_func_search_action,
+ GDK_g, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "menu_findprevious", _("Find Previous"),
+ LW(find_previous1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_FINDNEXTSEL, cb_func_search_action,
+ 0, 0, "menu_findnextsel", _("Find Next Selection"),LW(find_nextsel1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_FINDPREVSEL, cb_func_search_action,
+ 0, 0, "menu_findprevsel", _("Find Previous Selection"), LW(find_prevsel1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_REPLACE, cb_func_search_action,
+ GDK_h, GDK_CONTROL_MASK, "menu_replace", _("Replace"), LW(replace1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_FINDINFILES, cb_func_search_action, GDK_f,
+ GDK_CONTROL_MASK | GDK_SHIFT_MASK, "menu_findinfiles", _("Find in Files"),
+ LW(find_in_files1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_NEXTMESSAGE, cb_func_search_action,
+ 0, 0, "menu_nextmessage", _("Next Message"), LW(next_message1));
+ keybindings_set_item(group, GEANY_KEYS_SEARCH_FINDUSAGE, cb_func_search_action,
+ 0, 0, "popup_findusage", _("Find Usage"), NULL);
+
+ group = ADD_KB_GROUP(GOTO, _("Go to"));
+
+ keybindings_set_item(group, GEANY_KEYS_GOTO_BACK, cb_func_goto_action,
+ 0, 0, "nav_back", _("Navigate back a location"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_GOTO_FORWARD, cb_func_goto_action,
+ 0, 0, "nav_forward", _("Navigate forward a location"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_GOTO_LINE, cb_func_goto_action,
+ GDK_l, GDK_CONTROL_MASK, "menu_gotoline", _("Go to Line"), LW(go_to_line1));
+ keybindings_set_item(group, GEANY_KEYS_GOTO_MATCHINGBRACE, cb_func_goto_action,
GDK_b, GDK_CONTROL_MASK, "edit_gotomatchingbrace",
- _("Go to matching brace"));
- keys[GEANY_KEYS_EDIT_TOGGLEMARKER] = fill(cb_func_edit_global,
+ _("Go to matching brace"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_GOTO_TOGGLEMARKER, cb_func_goto_action,
GDK_m, GDK_CONTROL_MASK, "edit_togglemarker",
- _("Toggle marker"));
- keys[GEANY_KEYS_EDIT_GOTONEXTMARKER] = fill(cb_func_edit_global,
+ _("Toggle marker"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_GOTO_NEXTMARKER, cb_func_goto_action,
GDK_period, GDK_CONTROL_MASK, "edit_gotonextmarker",
- _("Go to next marker"));
- keys[GEANY_KEYS_EDIT_GOTOPREVIOUSMARKER] = fill(cb_func_edit_global,
+ _("Go to next marker"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_GOTO_PREVIOUSMARKER, cb_func_goto_action,
GDK_comma, GDK_CONTROL_MASK, "edit_gotopreviousmarker",
- _("Go to previous marker"));
+ _("Go to previous marker"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_GOTO_TAGDEFINITION, cb_func_goto_action,
+ 0, 0, "popup_gototagdefinition", _("Go to Tag Definition"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_GOTO_TAGDECLARATION, cb_func_goto_action,
+ 0, 0, "popup_gototagdeclaration", _("Go to Tag Declaration"), NULL);
- keys[GEANY_KEYS_EDIT_AUTOCOMPLETE] = fill(cb_func_edit,
- GDK_space, GDK_CONTROL_MASK, "edit_autocomplete", _("Complete word"));
- keys[GEANY_KEYS_EDIT_CALLTIP] = fill(cb_func_edit,
- GDK_space, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "edit_calltip", _("Show calltip"));
- keys[GEANY_KEYS_EDIT_MACROLIST] = fill(cb_func_edit,
- GDK_Return, GDK_CONTROL_MASK, "edit_macrolist", _("Show macro list"));
- keys[GEANY_KEYS_EDIT_COMPLETESNIPPET] = fill(NULL, /* has special callback */
- GDK_Tab, 0, "edit_completesnippet", _("Complete snippet"));
- keys[GEANY_KEYS_EDIT_SUPPRESSSNIPPETCOMPLETION] = fill(cb_func_edit,
- 0, 0, "edit_suppresssnippetcompletion", _("Suppress snippet completion"));
+ group = ADD_KB_GROUP(VIEW, _("View"));
- keys[GEANY_KEYS_EDIT_SELECTWORD] = fill(cb_func_edit,
- GDK_w, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectword", _("Select current word"));
- keys[GEANY_KEYS_EDIT_SELECTLINE] = fill(cb_func_edit,
- GDK_l, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectline", _("Select current line(s)"));
- keys[GEANY_KEYS_EDIT_SELECTPARAGRAPH] = fill(cb_func_edit,
- GDK_p, GDK_SHIFT_MASK | GDK_MOD1_MASK, "edit_selectparagraph", _("Select current paragraph"));
- keys[GEANY_KEYS_EDIT_SCROLLTOLINE] = fill(cb_func_edit,
- GDK_l, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "edit_scrolltoline", _("Scroll to current line"));
- keys[GEANY_KEYS_EDIT_SCROLLLINEUP] = fill(cb_func_edit,
- GDK_Up, GDK_MOD1_MASK, "edit_scrolllineup", _("Scroll up the view by one line"));
- keys[GEANY_KEYS_EDIT_SCROLLLINEDOWN] = fill(cb_func_edit,
- GDK_Down, GDK_MOD1_MASK, "edit_scrolllinedown", _("Scroll down the view by one line"));
+ keybindings_set_item(group, GEANY_KEYS_VIEW_TOGGLEALL, cb_func_menu_toggle_all,
+ 0, 0, "menu_toggleall", _("Toggle All Additional Widgets"),
+ LW(menu_toggle_all_additional_widgets1));
+ keybindings_set_item(group, GEANY_KEYS_VIEW_FULLSCREEN, cb_func_menu_fullscreen,
+ GDK_F11, 0, "menu_fullscreen", _("Fullscreen"), LW(menu_fullscreen1));
+ keybindings_set_item(group, GEANY_KEYS_VIEW_MESSAGEWINDOW, cb_func_menu_messagewindow,
+ 0, 0, "menu_messagewindow", _("Toggle Messages Window"),
+ LW(menu_show_messages_window1));
+ keybindings_set_item(group, GEANY_KEYS_VIEW_SIDEBAR, cb_func_toggle_sidebar,
+ 0, 0, "toggle_sidebar", _("Toggle Sidebar"), LW(menu_show_sidebar1));
+ keybindings_set_item(group, GEANY_KEYS_VIEW_ZOOMIN, cb_func_menu_zoomin,
+ GDK_plus, GDK_CONTROL_MASK, "menu_zoomin", _("Zoom In"), LW(menu_zoom_in1));
+ keybindings_set_item(group, GEANY_KEYS_VIEW_ZOOMOUT, cb_func_menu_zoomout,
+ GDK_minus, GDK_CONTROL_MASK, "menu_zoomout", _("Zoom Out"), LW(menu_zoom_out1));
- keys[GEANY_KEYS_EDIT_INSERTALTWHITESPACE] = fill(cb_func_edit,
- 0, 0, "edit_insertwhitespace", _("Insert alternative whitespace"));
+ group = ADD_KB_GROUP(FOCUS, _("Focus"));
- keys[GEANY_KEYS_POPUP_FINDUSAGE] = fill(cb_func_current_word,
- 0, 0, "popup_findusage", _("Find Usage"));
- keys[GEANY_KEYS_POPUP_GOTOTAGDEFINITION] = fill(cb_func_current_word,
- 0, 0, "popup_gototagdefinition", _("Go to Tag Definition"));
- keys[GEANY_KEYS_POPUP_GOTOTAGDECLARATION] = fill(cb_func_current_word,
- 0, 0, "popup_gototagdeclaration", _("Go to Tag Declaration"));
- keys[GEANY_KEYS_POPUP_CONTEXTACTION] = fill(cb_func_current_word,
- 0, 0, "popup_contextaction", _("Context Action"));
+ keybindings_set_item(group, GEANY_KEYS_FOCUS_EDITOR, cb_func_switch_editor,
+ GDK_F2, 0, "switch_editor", _("Switch to Editor"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FOCUS_SCRIBBLE, cb_func_switch_scribble,
+ GDK_F6, 0, "switch_scribble", _("Switch to Scribble"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FOCUS_VTE, cb_func_switch_vte,
+ GDK_F4, 0, "switch_vte", _("Switch to VTE"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_FOCUS_SEARCHBAR, cb_func_switch_search_bar,
+ GDK_F7, 0, "switch_search_bar", _("Switch to Search Bar"), NULL);
+
+ group = ADD_KB_GROUP(NOTEBOOK, _("Notebook tab"));
+
+ keybindings_set_item(group, GEANY_KEYS_NOTEBOOK_SWITCHTABLEFT, cb_func_switch_tableft,
+ GDK_Page_Up, GDK_CONTROL_MASK, "switch_tableft", _("Switch to left document"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_NOTEBOOK_SWITCHTABRIGHT, cb_func_switch_tabright,
+ GDK_Page_Down, GDK_CONTROL_MASK, "switch_tabright", _("Switch to right document"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_NOTEBOOK_SWITCHTABLASTUSED, cb_func_switch_tablastused,
+ GDK_Tab, GDK_CONTROL_MASK, "switch_tablastused", _("Switch to last used document"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_NOTEBOOK_MOVETABLEFT, cb_func_move_tab,
+ GDK_Page_Up, GDK_MOD1_MASK, "move_tableft", _("Move document left"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_NOTEBOOK_MOVETABRIGHT, cb_func_move_tab,
+ GDK_Page_Down, GDK_MOD1_MASK, "move_tabright", _("Move document right"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_NOTEBOOK_MOVETABFIRST, cb_func_move_tab,
+ 0, 0, "move_tabfirst", _("Move document first"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_NOTEBOOK_MOVETABLAST, cb_func_move_tab,
+ 0, 0, "move_tablast", _("Move document last"), NULL);
+
+ group = ADD_KB_GROUP(DOCUMENT, _("Document"));
+
+ keybindings_set_item(group, GEANY_KEYS_DOCUMENT_REPLACETABS, cb_func_menu_replacetabs,
+ 0, 0, "menu_replacetabs", _("Replace tabs by space"), LW(menu_replace_tabs));
+ keybindings_set_item(group, GEANY_KEYS_DOCUMENT_FOLDALL, cb_func_menu_foldall,
+ 0, 0, "menu_foldall", _("Fold all"), LW(menu_fold_all1));
+ keybindings_set_item(group, GEANY_KEYS_DOCUMENT_UNFOLDALL, cb_func_menu_unfoldall,
+ 0, 0, "menu_unfoldall", _("Unfold all"), LW(menu_unfold_all1));
+ keybindings_set_item(group, GEANY_KEYS_DOCUMENT_RELOADTAGLIST, cb_func_reloadtaglist,
+ GDK_r, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "reloadtaglist", _("Reload symbol list"), NULL);
+
+ group = ADD_KB_GROUP(BUILD, _("Build"));
+
+ keybindings_set_item(group, GEANY_KEYS_BUILD_COMPILE, cb_func_build_action,
+ GDK_F8, 0, "build_compile", _("Compile"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_LINK, cb_func_build_action,
+ GDK_F9, 0, "build_link", _("Build"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_MAKE, cb_func_build_action,
+ GDK_F9, GDK_SHIFT_MASK, "build_make", _("Make all"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_MAKEOWNTARGET, cb_func_build_action,
+ GDK_F9, GDK_SHIFT_MASK | GDK_CONTROL_MASK, "build_makeowntarget",
+ _("Make custom target"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_MAKEOBJECT, cb_func_build_action,
+ 0, 0, "build_makeobject", _("Make object"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_NEXTERROR, cb_func_build_action,
+ 0, 0, "build_nexterror", _("Next error"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_RUN, cb_func_build_action,
+ GDK_F5, 0, "build_run", _("Run"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_RUN2, cb_func_build_action,
+ 0, 0, "build_run2", _("Run (alternative command)"), NULL);
+ keybindings_set_item(group, GEANY_KEYS_BUILD_OPTIONS, cb_func_build_action,
+ 0, 0, "build_options", _("Build options"), NULL);
+
+ group = ADD_KB_GROUP(TOOLS, _("Tools"));
+
+ keybindings_set_item(group, GEANY_KEYS_TOOLS_OPENCOLORCHOOSER, cb_func_menu_opencolorchooser,
+ 0, 0, "menu_opencolorchooser", _("Show Color Chooser"), LW(menu_choose_color1));
+
+ group = ADD_KB_GROUP(HELP, _("Help"));
+
+ keybindings_set_item(group, GEANY_KEYS_HELP_HELP, cb_func_menu_help,
+ GDK_F1, 0, "menu_help", _("Help"), LW(help1));
}
-static void load_user_kb(void)
+typedef void (*KBItemCallback) (KeyBindingGroup *group, KeyBinding *kb, gpointer user_data);
+
+static void keybindings_foreach(KBItemCallback cb, gpointer user_data)
{
- gchar *configfile = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "keybindings.conf", NULL);
+ gsize g, i;
+
+ for (g = 0; g < keybinding_groups->len; g++)
+ {
+ KeyBindingGroup *group = g_ptr_array_index(keybinding_groups, g);
+
+ for (i = 0; i < group->count; i++)
+ {
+ KeyBinding *kb = &group->keys[i];
+
+ cb(group, kb, user_data);
+ }
+ }
+}
+
+
+static void get_keyfile_kb(KeyBindingGroup *group, KeyBinding *kb, gpointer user_data)
+{
+ GKeyFile *config = user_data;
gchar *val;
- guint i;
guint key;
GdkModifierType mods;
+
+ val = g_key_file_get_string(config, group->name, kb->name, NULL);
+ if (val != NULL)
+ {
+ gtk_accelerator_parse(val, &key, &mods);
+ kb->key = key;
+ kb->mods = mods;
+ }
+ g_free(val);
+}
+
+
+static void load_user_kb(void)
+{
+ gchar *configfile = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "keybindings.conf", NULL);
GKeyFile *config = g_key_file_new();
/* now load user defined keys */
if (g_key_file_load_from_file(config, configfile, G_KEY_FILE_KEEP_COMMENTS, NULL))
{
- for (i = 0; i < GEANY_MAX_KEYS; i++)
- {
- val = g_key_file_get_string(config, "Bindings", keys[i]->name, NULL);
- if (val != NULL)
- {
- gtk_accelerator_parse(val, &key, &mods);
- keys[i]->key = key;
- keys[i]->mods = mods;
- }
- g_free(val);
- }
+ keybindings_foreach(get_keyfile_kb, config);
}
g_free(configfile);
g_key_file_free(config);
@@ -364,125 +496,92 @@
void keybindings_init(void)
{
+ keybinding_groups = g_ptr_array_sized_new(GEANY_KEY_GROUP_COUNT);
+
init_default_kb();
+}
+
+
+void keybindings_load_keyfile(void)
+{
load_user_kb();
+ add_popup_menu_accels();
+}
- /* set section name */
- keys[GEANY_KEYS_GROUP_FILE]->section = _("File menu");
- keys[GEANY_KEYS_GROUP_EDIT]->section = _("Edit menu");
- keys[GEANY_KEYS_GROUP_SEARCH]->section = _("Search menu");
- keys[GEANY_KEYS_GROUP_VIEW]->section = _("View menu");
- keys[GEANY_KEYS_GROUP_DOCUMENT]->section = _("Document menu");
- keys[GEANY_KEYS_GROUP_BUILD]->section = _("Build menu");
- keys[GEANY_KEYS_GROUP_TOOLS]->section = _("Tools menu");
- keys[GEANY_KEYS_GROUP_HELP]->section = _("Help menu");
- keys[GEANY_KEYS_GROUP_FOCUS]->section = _("Focus commands");
- keys[GEANY_KEYS_GROUP_TABS]->section = _("Notebook tab commands");
- keys[GEANY_KEYS_GROUP_EDITING]->section = _("Editing commands");
- keys[GEANY_KEYS_GROUP_TAGS]->section = _("Tag commands");
- keys[GEANY_KEYS_GROUP_OTHER]->section = _("Other commands");
- add_menu_accels();
+static void add_menu_accel(KeyBindingGroup *group, guint kb_id,
+ GtkAccelGroup *accel_group, GtkWidget *menuitem)
+{
+ KeyBinding *kb = &group->keys[kb_id];
+
+ if (kb->key != 0)
+ gtk_widget_add_accelerator(menuitem, "activate", accel_group,
+ kb->key, kb->mods, GTK_ACCEL_VISIBLE);
}
-#define GEANY_ADD_ACCEL(gkey, wid) \
- if (keys[(gkey)]->key != 0) \
- gtk_widget_add_accelerator( \
- lookup_widget(app->window, G_STRINGIFY(wid)), \
- "activate", accel_group, keys[(gkey)]->key, keys[(gkey)]->mods, \
- GTK_ACCEL_VISIBLE)
+#define GEANY_ADD_POPUP_ACCEL(kb_id, wid) \
+ add_menu_accel(group, kb_id, accel_group, lookup_widget(app->popup_menu, G_STRINGIFY(wid)))
-#define GEANY_ADD_POPUP_ACCEL(gkey, wid) \
- if (keys[(gkey)]->key != 0) \
- gtk_widget_add_accelerator( \
- lookup_widget(app->popup_menu, G_STRINGIFY(wid)), \
- "activate", accel_group, keys[(gkey)]->key, keys[(gkey)]->mods, \
- GTK_ACCEL_VISIBLE)
-
-static void add_menu_accels()
+/* set the menu item accelerator shortcuts (just for visibility, they are handled anyway) */
+static void add_popup_menu_accels(void)
{
GtkAccelGroup *accel_group = gtk_accel_group_new();
+ KeyBindingGroup *group;
- /* apply the settings */
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_OPENSELECTED, menu_open_selected_file1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_SAVEALL, menu_save_all1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_SAVEAS, menu_save_as1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_PRINT, print1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_CLOSE, menu_close1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_CLOSEALL, menu_close_all1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_RELOADFILE, menu_reload1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_UNDO, menu_undo2);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_REDO, menu_redo2);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_SELECTALL, menu_select_all1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_INSERTDATE, insert_date_custom1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_PREFERENCES, preferences1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_HELP, help1);
+ group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_EDITOR);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDITOR_UNDO, undo1);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDITOR_REDO, redo1);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDITOR_DUPLICATELINE, menu_duplicate_line2);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDITOR_CONTEXTACTION, context_action1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FIND, find1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FINDNEXT, find_next1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FINDPREVIOUS, find_previous1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FINDNEXTSEL, find_nextsel1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FINDPREVSEL, find_prevsel1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_REPLACE, replace1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FINDINFILES, find_in_files1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_NEXTMESSAGE, next_message1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_GOTOLINE, go_to_line1);
+ group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_SELECT);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_SELECT_ALL, menu_select_all2);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_TOGGLEALL, menu_toggle_all_additional_widgets1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FULLSCREEN, menu_fullscreen1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_MESSAGEWINDOW, menu_show_messages_window1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_SIDEBAR, menu_show_sidebar1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_ZOOMIN, menu_zoom_in1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_ZOOMOUT, menu_zoom_out1);
+ group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_INSERT);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_INSERT_DATE, insert_date_custom2);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_REPLACETABS, menu_replace_tabs);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_FOLDALL, menu_fold_all1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_UNFOLDALL, menu_unfold_all1);
+ group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_FILE);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FILE_OPENSELECTED, menu_open_selected_file2);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_PROJECTPROPERTIES, project_properties1);
+ group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_SEARCH);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_SEARCH_FINDUSAGE, find_usage1);
- GEANY_ADD_ACCEL(GEANY_KEYS_MENU_OPENCOLORCHOOSER, menu_choose_color1);
- /*GEANY_ADD_ACCEL(GEANY_KEYS_MENU_INSERTSPECIALCHARS, menu_insert_special_chars1);*/
+ group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_GOTO);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_GOTO_LINE, go_to_line);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_GOTO_TAGDEFINITION, goto_tag_definition1);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_GOTO_TAGDECLARATION, goto_tag_declaration1);
- GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_TOGGLECASE, menu_toggle_case2);
- GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_COMMENTLINE, menu_comment_line1);
- GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_UNCOMMENTLINE, menu_uncomment_line1);
- GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_COMMENTLINETOGGLE, menu_toggle_line_commentation1);
- GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_DUPLICATELINE, menu_duplicate_line1);
- GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_INCREASEINDENT, menu_increase_indent1);
- GEANY_ADD_ACCEL(GEANY_KEYS_EDIT_DECREASEINDENT, menu_decrease_indent1);
+ group = g_ptr_array_index(keybinding_groups, GEANY_KEY_GROUP_FORMAT);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FORMAT_TOGGLECASE, toggle_case1);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FORMAT_COMMENTLINE, menu_comment_line2);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FORMAT_UNCOMMENTLINE, menu_uncomment_line2);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FORMAT_COMMENTLINETOGGLE, menu_toggle_line_commentation2);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FORMAT_INCREASEINDENT, menu_increase_indent2);
+ GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_FORMAT_DECREASEINDENT, menu_decrease_indent2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_MENU_UNDO, undo1);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_MENU_REDO, redo1);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_MENU_SELECTALL, menu_select_all2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_MENU_INSERTDATE, insert_date_custom2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_MENU_OPENSELECTED, menu_open_selected_file2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_POPUP_FINDUSAGE, find_usage1);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_POPUP_GOTOTAGDEFINITION, goto_tag_definition1);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_POPUP_GOTOTAGDECLARATION, goto_tag_declaration1);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_POPUP_CONTEXTACTION, context_action1);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_MENU_GOTOLINE, go_to_line);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDIT_TOGGLECASE, toggle_case1);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDIT_COMMENTLINE, menu_comment_line2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDIT_UNCOMMENTLINE, menu_uncomment_line2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDIT_COMMENTLINETOGGLE, menu_toggle_line_commentation2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDIT_DUPLICATELINE, menu_duplicate_line2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDIT_INCREASEINDENT, menu_increase_indent2);
- GEANY_ADD_POPUP_ACCEL(GEANY_KEYS_EDIT_DECREASEINDENT, menu_decrease_indent2);
-
/* the build menu items are set if the build menus are created */
gtk_window_add_accel_group(GTK_WINDOW(app->window), accel_group);
}
+static void set_keyfile_kb(KeyBindingGroup *group, KeyBinding *kb, gpointer user_data)
+{
+ GKeyFile *config = user_data;
+ gchar *val;
+
+ val = gtk_accelerator_name(kb->key, kb->mods);
+ g_key_file_set_string(config, group->name, kb->name, val);
+ g_free(val);
+}
+
+
/* just write the content of the keys array to the config file */
void keybindings_write_to_file(void)
{
gchar *configfile = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "keybindings.conf", NULL);
- gchar *val, *data;
- guint i;
+ gchar *data;
GKeyFile *config = g_key_file_new();
/* add comment if the file is newly created */
@@ -491,12 +590,7 @@
g_key_file_set_comment(config, NULL, NULL, "Keybindings for Geany\nThe format looks like \"<Control>a\" or \"<Shift><Alt>F1\".\nBut you can also change the keys in Geany's preferences dialog.", NULL);
}
- for (i = 0; i < GEANY_MAX_KEYS; i++)
- {
- val = gtk_accelerator_name(keys[i]->key, keys[i]->mods);
- g_key_file_set_string(config, "Bindings", keys[i]->name, val);
- g_free(val);
- }
+ keybindings_foreach(set_keyfile_kb, config);
/* write the file */
data = g_key_file_to_data(config, NULL, NULL);
@@ -510,53 +604,51 @@
void keybindings_free(void)
{
- guint i;
-
- for (i = 0; i < GEANY_MAX_KEYS; i++)
- {
- g_free(keys[i]);
- }
+ g_ptr_array_free(keybinding_groups, TRUE);
}
static void get_shortcut_labels_text(GString **text_names_str, GString **text_keys_str)
{
- guint i;
+ gsize g, i;
GString *text_names = g_string_sized_new(600);
GString *text_keys = g_string_sized_new(600);
*text_names_str = text_names;
*text_keys_str = text_keys;
- for (i = 0; i < GEANY_MAX_KEYS; i++)
+ for (g = 0; g < keybinding_groups->len; g++)
{
- gchar *shortcut;
+ KeyBindingGroup *group = g_ptr_array_index(keybinding_groups, g);
- if (keys[i]->section != NULL)
+ if (g == 0)
{
- if (i == GEANY_KEYS_MENU_NEW)
- {
- g_string_append_printf(text_names, "<b>%s</b>\n", keys[i]->section);
- g_string_append(text_keys, "\n");
- }
- else
- {
- g_string_append_printf(text_names, "\n<b>%s</b>\n", keys[i]->section);
- g_string_append(text_keys, "\n\n");
- }
+ g_string_append_printf(text_names, "<b>%s</b>\n", group->label);
+ g_string_append(text_keys, "\n");
}
+ else
+ {
+ g_string_append_printf(text_names, "\n<b>%s</b>\n", group->label);
+ g_string_append(text_keys, "\n\n");
+ }
- shortcut = gtk_accelerator_get_label(keys[i]->key, keys[i]->mods);
- g_string_append(text_names, keys[i]->label);
- g_string_append(text_names, "\n");
- g_string_append(text_keys, shortcut);
- g_string_append(text_keys, "\n");
- g_free(shortcut);
+ for (i = 0; i < group->count; i++)
+ {
+ KeyBinding *kb = &group->keys[i];
+ gchar *shortcut;
+
+ shortcut = gtk_accelerator_get_label(kb->key, kb->mods);
+ g_string_append(text_names, kb->label);
+ g_string_append(text_names, "\n");
+ g_string_append(text_keys, shortcut);
+ g_string_append(text_keys, "\n");
+ g_free(shortcut);
+ }
}
}
-void keybindings_show_shortcuts()
+void keybindings_show_shortcuts(void)
{
GtkWidget *dialog, *hbox, *label1, *label2, *label3, *swin, *vbox;
GString *text_names;
@@ -664,9 +756,10 @@
* return FALSE if no completion occurs, so the tab or space is handled normally. */
static gboolean check_snippet_completion(guint keyval, guint state)
{
- const guint i = GEANY_KEYS_EDIT_COMPLETESNIPPET;
+ KeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_EDITOR,
+ GEANY_KEYS_EDITOR_COMPLETESNIPPET);
- if (keys[i]->key == keyval && keys[i]->mods == state)
+ if (kb->key == keyval && kb->mods == state)
{
gint idx = document_get_cur_idx();
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
@@ -709,9 +802,11 @@
return FALSE;
/* make focus commands override any bash commands */
- for (i = GEANY_KEYS_GROUP_FOCUS; i < GEANY_KEYS_GROUP_TABS; i++)
+ for (i = 0; i < GEANY_KEYS_FOCUS_COUNT; i++)
{
- if (state == keys[i]->mods && keyval == keys[i]->key)
+ KeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_FOCUS, i);
+
+ if (state == kb->mods && keyval == kb->key)
return FALSE;
}
@@ -733,7 +828,8 @@
/* central keypress event handler, almost all keypress events go to this function */
gboolean keybindings_got_event(GtkWidget *widget, GdkEventKey *ev, gpointer user_data)
{
- guint i, state, keyval;
+ guint state, keyval;
+ gsize g, i;
if (ev->keyval == 0)
return FALSE;
@@ -756,47 +852,60 @@
if (check_snippet_completion(keyval, state))
return TRUE;
- for (i = 0; i < GEANY_MAX_KEYS; i++)
+ for (g = 0; g < keybinding_groups->len; g++)
{
- if (keyval == keys[i]->key && state == keys[i]->mods)
+ KeyBindingGroup *group = g_ptr_array_index(keybinding_groups, g);
+
+ for (i = 0; i < group->count; i++)
{
- if (keys[i]->cb_func == NULL)
- return FALSE; /* ignore the keybinding */
+ KeyBinding *kb = &group->keys[i];
- /* call the corresponding callback function for this shortcut */
- keys[i]->cb_func(i);
- return TRUE;
+ if (keyval == kb->key && state == kb->mods)
+ {
+ if (kb->callback == NULL)
+ return FALSE; /* ignore the keybinding */
+
+ /* call the corresponding callback function for this shortcut */
+ kb->callback(i);
+ return TRUE;
+ }
}
}
- /* fixed keybindings can be overridden by user bindings */
+ /* fixed keybindings can be overridden by user bindings, so check them last */
if (check_fixed_kb(keyval, state))
return TRUE;
return FALSE;
}
-/* simple convenience function to allocate and fill the struct */
-static KeyBinding *fill(KBCallback func, guint key, GdkModifierType mod, const gchar *name,
- const gchar *label)
+KeyBinding *keybindings_lookup_item(guint group_id, guint key_id)
{
- KeyBinding *result;
+ KeyBindingGroup *group;
- result = g_new0(KeyBinding, 1);
- result->name = name;
- result->label = label;
- result->key = key;
- result->mods = mod;
- result->cb_func = func;
- result->section = NULL;
+ g_return_val_if_fail(group_id < keybinding_groups->len, NULL);
- return result;
+ group = g_ptr_array_index(keybinding_groups, group_id);
+
+ g_return_val_if_fail(group, NULL);
+ g_return_val_if_fail(key_id < group->count, NULL);
+
+ return &group->keys[key_id];
}
-/* Mimic a keybinding action */
-void keybindings_cmd(GeanyKeyCommand cmd_id)
+/** Mimic a (built-in only) keybinding action.
+ * Example: @code keybindings_send_command(GEANY_KEY_GROUP_FILE, GEANY_KEYS_FILE_OPEN); @endcode
+ * @param group_id The index for the key group that contains the @a key_id keybinding.
+ * @param key_id The keybinding command index. */
+void keybindings_send_command(guint group_id, guint key_id)
{
- keys[cmd_id]->cb_func(cmd_id);
+ KeyBinding *kb;
+
+ g_return_if_fail(group_id < GEANY_KEY_GROUP_COUNT); /* can't use this for plugin groups */
+
+ kb = keybindings_lookup_item(group_id, key_id);
+ if (kb)
+ kb->callback(key_id);
}
@@ -808,61 +917,52 @@
{
switch (key_id)
{
- case GEANY_KEYS_MENU_NEW:
+ case GEANY_KEYS_FILE_NEW:
document_new_file(NULL, NULL, NULL);
break;
- case GEANY_KEYS_MENU_OPEN:
+ case GEANY_KEYS_FILE_OPEN:
on_open1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_OPENSELECTED:
+ case GEANY_KEYS_FILE_OPENSELECTED:
on_menu_open_selected_file1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_SAVE:
+ case GEANY_KEYS_FILE_SAVE:
on_save1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_SAVEAS:
+ case GEANY_KEYS_FILE_SAVEAS:
on_save_as1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_SAVEALL:
+ case GEANY_KEYS_FILE_SAVEALL:
on_save_all1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_CLOSE:
+ case GEANY_KEYS_FILE_CLOSE:
on_close1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_CLOSEALL:
+ case GEANY_KEYS_FILE_CLOSEALL:
on_close_all1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_RELOADFILE:
+ case GEANY_KEYS_FILE_RELOAD:
on_toolbutton23_clicked(NULL, NULL);
break;
- case GEANY_KEYS_MENU_PROJECTPROPERTIES:
- if (app->project)
- on_project_properties1_activate(NULL, NULL);
+ case GEANY_KEYS_FILE_PRINT:
+ on_print1_activate(NULL, NULL);
break;
}
}
-static void cb_func_menu_print(G_GNUC_UNUSED guint key_id)
+static void cb_func_project_action(guint key_id)
{
- on_print1_activate(NULL, NULL);
+ switch (key_id)
+ {
+ case GEANY_KEYS_PROJECT_PROPERTIES:
+ if (app->project)
+ on_project_properties1_activate(NULL, NULL);
+ break;
+ }
}
-static void cb_func_menu_undo(G_GNUC_UNUSED guint key_id)
-{
- on_undo1_activate(NULL, NULL);
-}
-static void cb_func_menu_redo(G_GNUC_UNUSED guint key_id)
-{
- on_redo1_activate(NULL, NULL);
-}
-
-static void cb_func_menu_selectall(G_GNUC_UNUSED guint key_id)
-{
- on_menu_select_all1_activate(NULL, NULL);
-}
-
static void cb_func_menu_preferences(G_GNUC_UNUSED guint key_id)
{
on_preferences1_activate(NULL, NULL);
@@ -873,28 +973,30 @@
on_help1_activate(NULL, NULL);
}
-static void cb_func_menu_search(guint key_id)
+static void cb_func_search_action(guint key_id)
{
switch (key_id)
{
- case GEANY_KEYS_MENU_FIND:
+ case GEANY_KEYS_SEARCH_FIND:
on_find1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_FINDNEXT:
+ case GEANY_KEYS_SEARCH_FINDNEXT:
on_find_next1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_FINDPREVIOUS:
+ case GEANY_KEYS_SEARCH_FINDPREVIOUS:
on_find_previous1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_FINDPREVSEL:
+ case GEANY_KEYS_SEARCH_FINDPREVSEL:
on_find_prevsel1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_FINDNEXTSEL:
+ case GEANY_KEYS_SEARCH_FINDNEXTSEL:
on_find_nextsel1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_REPLACE:
+ case GEANY_KEYS_SEARCH_REPLACE:
on_replace1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_FINDINFILES:
+ case GEANY_KEYS_SEARCH_FINDINFILES:
on_find_in_files1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_NEXTMESSAGE:
+ case GEANY_KEYS_SEARCH_NEXTMESSAGE:
on_next_message1_activate(NULL, NULL); break;
- case GEANY_KEYS_MENU_GOTOLINE:
- on_go_to_line1_activate(NULL, NULL); break;
+ case GEANY_KEYS_SEARCH_FINDUSAGE:
+ if (check_current_word())
+ on_find_usage1_activate(NULL, NULL);
+ break;
}
}
@@ -1001,13 +1103,13 @@
}
-/* common function for keybindings using current word */
-static void cb_func_current_word(guint key_id)
+static gboolean check_current_word(void)
{
gint idx = document_get_cur_idx();
gint pos;
- if (idx == -1 || ! doc_list[idx].is_valid) return;
+ if (DOC_IDX_VALID(idx))
+ return FALSE;
pos = sci_get_current_position(doc_list[idx].sci);
@@ -1015,24 +1117,11 @@
editor_info.current_word, GEANY_MAX_WORD_LENGTH, NULL);
if (*editor_info.current_word == 0)
+ {
utils_beep();
- else
- switch (key_id)
- {
- case GEANY_KEYS_POPUP_FINDUSAGE:
- on_find_usage1_activate(NULL, NULL);
- break;
- case GEANY_KEYS_POPUP_GOTOTAGDEFINITION:
- symbols_goto_tag(editor_info.current_word, TRUE);
- break;
- case GEANY_KEYS_POPUP_GOTOTAGDECLARATION:
- symbols_goto_tag(editor_info.current_word, FALSE);
- break;
- case GEANY_KEYS_POPUP_CONTEXTACTION:
- on_context_action1_activate(GTK_MENU_ITEM(lookup_widget(app->popup_menu,
- "context_action1")), NULL);
- break;
- }
+ return FALSE;
+ }
+ return TRUE;
}
@@ -1089,26 +1178,27 @@
if (! DOC_IDX_VALID(idx))
return;
- if (key_id == GEANY_KEYS_MOVE_TABLEFT)
+ switch (key_id)
{
- gtk_notebook_reorder_child(nb, sci, cur_page - 1); /* notebook wraps around by default */
- }
- else if (key_id == GEANY_KEYS_MOVE_TABRIGHT)
- {
- gint npage = cur_page + 1;
+ case GEANY_KEYS_NOTEBOOK_MOVETABLEFT:
+ gtk_notebook_reorder_child(nb, sci, cur_page - 1); /* notebook wraps around by default */
+ break;
+ case GEANY_KEYS_NOTEBOOK_MOVETABRIGHT:
+ {
+ gint npage = cur_page + 1;
- if (npage == gtk_notebook_get_n_pages(nb))
- npage = 0; /* wraparound */
- gtk_notebook_reorder_child(nb, sci, npage);
+ if (npage == gtk_notebook_get_n_pages(nb))
+ npage = 0; /* wraparound */
+ gtk_notebook_reorder_child(nb, sci, npage);
+ break;
+ }
+ case GEANY_KEYS_NOTEBOOK_MOVETABFIRST:
+ gtk_notebook_reorder_child(nb, sci, (prefs.tab_order_ltr) ? 0 : -1);
+ break;
+ case GEANY_KEYS_NOTEBOOK_MOVETABLAST:
+ gtk_notebook_reorder_child(nb, sci, (prefs.tab_order_ltr) ? -1 : 0);
+ break;
}
- else if (key_id == GEANY_KEYS_MOVE_TABFIRST)
- {
- gtk_notebook_reorder_child(nb, sci, (prefs.tab_order_ltr) ? 0 : -1);
- }
- else if (key_id == GEANY_KEYS_MOVE_TABLAST)
- {
- gtk_notebook_reorder_child(nb, sci, (prefs.tab_order_ltr) ? -1 : 0);
- }
return;
}
@@ -1145,27 +1235,36 @@
static void cb_func_clipboard(guint key_id)
{
+ gint idx = document_get_cur_idx();
+
+ if (! DOC_IDX_VALID(idx)) return;
+
switch (key_id)
{
- case GEANY_KEYS_MENU_CUT:
+ case GEANY_KEYS_CLIPBOARD_CUT:
on_cut1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_COPY:
+ case GEANY_KEYS_CLIPBOARD_COPY:
on_copy1_activate(NULL, NULL);
break;
- case GEANY_KEYS_MENU_PASTE:
+ case GEANY_KEYS_CLIPBOARD_PASTE:
on_paste1_activate(NULL, NULL);
break;
+ case GEANY_KEYS_CLIPBOARD_COPYLINE:
+ sci_cmd(doc_list[idx].sci, SCI_LINECOPY);
+ break;
+ case GEANY_KEYS_CLIPBOARD_CUTLINE:
+ sci_cmd(doc_list[idx].sci, SCI_LINECUT);
+ break;
}
}
-/* Common function for editing keybindings that don't change any text, and are
- * useful even when sci doesn't have focus. */
-static void cb_func_edit_global(guint key_id)
+/* Common function for goto keybindings, useful even when sci doesn't have focus. */
+static void cb_func_goto_action(guint key_id)
{
+ gint cur_line;
gint idx = document_get_cur_idx();
- gint cur_line;
if (! DOC_IDX_VALID(idx)) return;
@@ -1173,17 +1272,26 @@
switch (key_id)
{
- case GEANY_KEYS_EDIT_GOTOMATCHINGBRACE:
+ case GEANY_KEYS_GOTO_BACK:
+ navqueue_go_back();
+ break;
+ case GEANY_KEYS_GOTO_FORWARD:
+ navqueue_go_forward();
+ break;
+ case GEANY_KEYS_GOTO_LINE:
+ on_go_to_line1_activate(NULL, NULL);
+ break;
+ case GEANY_KEYS_GOTO_MATCHINGBRACE:
goto_matching_brace(idx);
break;
- case GEANY_KEYS_EDIT_TOGGLEMARKER:
+ case GEANY_KEYS_GOTO_TOGGLEMARKER:
{
gboolean set = sci_is_marker_set_at_line(doc_list[idx].sci, cur_line, 1);
sci_set_marker_at_line(doc_list[idx].sci, cur_line, ! set, 1);
break;
}
- case GEANY_KEYS_EDIT_GOTONEXTMARKER:
+ case GEANY_KEYS_GOTO_NEXTMARKER:
{
gint mline = sci_marker_next(doc_list[idx].sci, cur_line + 1, 1 << 1, TRUE);
@@ -1194,7 +1302,7 @@
}
break;
}
- case GEANY_KEYS_EDIT_GOTOPREVIOUSMARKER:
+ case GEANY_KEYS_GOTO_PREVIOUSMARKER:
{
gint mline = sci_marker_previous(doc_list[idx].sci, cur_line - 1, 1 << 1, TRUE);
@@ -1205,6 +1313,14 @@
}
break;
}
+ case GEANY_KEYS_GOTO_TAGDEFINITION:
+ if (check_current_word())
+ symbols_goto_tag(editor_info.current_word, TRUE);
+ break;
+ case GEANY_KEYS_GOTO_TAGDECLARATION:
+ if (check_current_word())
+ symbols_goto_tag(editor_info.current_word, FALSE);
+ break;
}
}
@@ -1230,8 +1346,8 @@
}
-/* common function for editing keybindings, only valid when scintilla has focus. */
-static void cb_func_edit(guint key_id)
+/* common function for editor keybindings, only valid when scintilla has focus. */
+static void cb_func_editor_action(guint key_id)
{
gint idx = document_get_cur_idx();
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
@@ -1241,51 +1357,50 @@
switch (key_id)
{
- case GEANY_KEYS_EDIT_SCROLLTOLINE:
+ case GEANY_KEYS_EDITOR_UNDO:
+ on_undo1_activate(NULL, NULL);
+ break;
+ case GEANY_KEYS_EDITOR_REDO:
+ on_redo1_activate(NULL, NULL);
+ break;
+ case GEANY_KEYS_EDITOR_SCROLLTOLINE:
editor_scroll_to_line(doc_list[idx].sci, -1, 0.5F);
break;
- case GEANY_KEYS_EDIT_SCROLLLINEUP:
+ case GEANY_KEYS_EDITOR_SCROLLLINEUP:
sci_cmd(doc_list[idx].sci, SCI_LINESCROLLUP);
break;
- case GEANY_KEYS_EDIT_SCROLLLINEDOWN:
+ case GEANY_KEYS_EDITOR_SCROLLLINEDOWN:
sci_cmd(doc_list[idx].sci, SCI_LINESCROLLDOWN);
break;
- case GEANY_KEYS_EDIT_DUPLICATELINE:
+ case GEANY_KEYS_EDITOR_DUPLICATELINE:
duplicate_lines(doc_list[idx].sci);
break;
- case GEANY_KEYS_EDIT_DELETELINE:
+ case GEANY_KEYS_EDITOR_DELETELINE:
delete_lines(doc_list[idx].sci);
break;
- case GEANY_KEYS_EDIT_COPYLINE:
- sci_cmd(doc_list[idx].sci, SCI_LINECOPY);
- break;
- case GEANY_KEYS_EDIT_CUTLINE:
- sci_cmd(doc_list[idx].sci, SCI_LINECUT);
- break;
- case GEANY_KEYS_EDIT_TRANSPOSELINE:
+ case GEANY_KEYS_EDITOR_TRANSPOSELINE:
sci_cmd(doc_list[idx].sci, SCI_LINETRANSPOSE);
break;
- case GEANY_KEYS_EDIT_COMMENTLINETOGGLE:
- on_menu_toggle_line_commentation1_activate(NULL, NULL);
- break;
- case GEANY_KEYS_EDIT_COMMENTLINE:
- on_menu_comment_line1_activate(NULL, NULL);
- break;
- case GEANY_KEYS_EDIT_UNCOMMENTLINE:
- on_menu_uncomment_line1_activate(NULL, NULL);
- break;
- case GEANY_KEYS_EDIT_AUTOCOMPLETE:
+ case GEANY_KEYS_EDITOR_AUTOCOMPLETE:
editor_start_auto_complete(idx, sci_get_current_position(doc_list[idx].sci), TRUE);
break;
- case GEANY_KEYS_EDIT_CALLTIP:
+ case GEANY_KEYS_EDITOR_CALLTIP:
editor_show_calltip(idx, -1);
break;
- case GEANY_KEYS_EDIT_MACROLIST:
+ case GEANY_KEYS_EDITOR_MACROLIST:
editor_show_macro_list(doc_list[idx].sci);
break;
+ case GEANY_KEYS_EDITOR_CONTEXTACTION:
+ if (check_current_word())
+ on_context_action1_activate(GTK_MENU_ITEM(lookup_widget(app->popup_menu,
+ "context_action1")), NULL);
+ break;
+ case GEANY_KEYS_EDITOR_SUPPRESSSNIPPETCOMPLETION:
+ {
+ KeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_EDITOR,
+ GEANY_KEYS_EDITOR_COMPLETESNIPPET);
- case GEANY_KEYS_EDIT_SUPPRESSSNIPPETCOMPLETION:
- switch (keys[GEANY_KEYS_EDIT_COMPLETESNIPPET]->key)
+ switch (kb->key)
{
case GDK_space:
sci_add_text(doc_list[idx].sci, " ");
@@ -1297,46 +1412,58 @@
break;
}
break;
+ }
+ }
+}
- case GEANY_KEYS_EDIT_SELECTWORD:
- editor_select_word(doc_list[idx].sci);
+
+/* common function for format keybindings, only valid when scintilla has focus. */
+static void cb_func_format_action(guint key_id)
+{
+ gint idx = document_get_cur_idx();
+ GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
+
+ /* keybindings only valid when scintilla widget has focus */
+ if (! DOC_IDX_VALID(idx) || focusw != GTK_WIDGET(doc_list[idx].sci)) return;
+
+ switch (key_id)
+ {
+ case GEANY_KEYS_FORMAT_COMMENTLINETOGGLE:
+ on_menu_toggle_line_commentation1_activate(NULL, NULL);
break;
- case GEANY_KEYS_EDIT_SELECTLINE:
- editor_select_lines(doc_list[idx].sci, FALSE);
+ case GEANY_KEYS_FORMAT_COMMENTLINE:
+ on_menu_comment_line1_activate(NULL, NULL);
break;
- case GEANY_KEYS_EDIT_SELECTPARAGRAPH:
- editor_select_paragraph(doc_list[idx].sci);
+ case GEANY_KEYS_FORMAT_UNCOMMENTLINE:
+ on_menu_uncomment_line1_activate(NULL, NULL);
break;
- case GEANY_KEYS_EDIT_INSERTALTWHITESPACE:
- editor_insert_alternative_whitespace(idx);
- break;
- case GEANY_KEYS_EDIT_INCREASEINDENT:
+ case GEANY_KEYS_FORMAT_INCREASEINDENT:
on_menu_increase_indent1_activate(NULL, NULL);
break;
- case GEANY_KEYS_EDIT_DECREASEINDENT:
+ case GEANY_KEYS_FORMAT_DECREASEINDENT:
on_menu_decrease_indent1_activate(NULL, NULL);
break;
- case GEANY_KEYS_EDIT_INCREASEINDENTBYSPACE:
+ case GEANY_KEYS_FORMAT_INCREASEINDENTBYSPACE:
editor_indentation_by_one_space(idx, -1, FALSE);
break;
- case GEANY_KEYS_EDIT_DECREASEINDENTBYSPACE:
+ case GEANY_KEYS_FORMAT_DECREASEINDENTBYSPACE:
editor_indentation_by_one_space(idx, -1, TRUE);
break;
- case GEANY_KEYS_EDIT_AUTOINDENT:
+ case GEANY_KEYS_FORMAT_AUTOINDENT:
editor_auto_line_indentation(idx, -1);
break;
- case GEANY_KEYS_EDIT_TOGGLECASE:
+ case GEANY_KEYS_FORMAT_TOGGLECASE:
on_toggle_case1_activate(NULL, NULL);
break;
- case GEANY_KEYS_EDIT_SENDTOCMD1:
+ case GEANY_KEYS_FORMAT_SENDTOCMD1:
if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 0)
tools_execute_custom_command(idx, ui_prefs.custom_commands[0]);
break;
- case GEANY_KEYS_EDIT_SENDTOCMD2:
+ case GEANY_KEYS_FORMAT_SENDTOCMD2:
if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 1)
tools_execute_custom_command(idx, ui_prefs.custom_commands[1]);
break;
- case GEANY_KEYS_EDIT_SENDTOCMD3:
+ case GEANY_KEYS_FORMAT_SENDTOCMD3:
if (ui_prefs.custom_commands && g_strv_length(ui_prefs.custom_commands) > 2)
tools_execute_custom_command(idx, ui_prefs.custom_commands[2]);
break;
@@ -1344,29 +1471,56 @@
}
-static void cb_func_menu_replacetabs(G_GNUC_UNUSED guint key_id)
+/* common function for select keybindings, only valid when scintilla has focus. */
+static void cb_func_select_action(guint key_id)
{
- on_replace_tabs_activate(NULL, NULL);
-}
+ gint idx = document_get_cur_idx();
+ GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
-static void cb_func_menu_insert_date(G_GNUC_UNUSED guint key_id)
-{
- gtk_menu_item_activate(GTK_MENU_ITEM(lookup_widget(app->window, "insert_date_custom1")));
+ /* keybindings only valid when scintilla widget has focus */
+ if (! DOC_IDX_VALID(idx) || focusw != GTK_WIDGET(doc_list[idx].sci)) return;
+
+ switch (key_id)
+ {
+ case GEANY_KEYS_SELECT_ALL:
+ on_menu_select_all1_activate(NULL, NULL);
+ break;
+ case GEANY_KEYS_SELECT_WORD:
+ editor_select_word(doc_list[idx].sci);
+ break;
+ case GEANY_KEYS_SELECT_LINE:
+ editor_select_lines(doc_list[idx].sci, FALSE);
+ break;
+ case GEANY_KEYS_SELECT_PARAGRAPH:
+ editor_select_paragraph(doc_list[idx].sci);
+ break;
+ }
}
-static void cb_func_menu_insert_specialchars(G_GNUC_UNUSED guint key_id)
+
+static void cb_func_menu_replacetabs(G_GNUC_UNUSED guint key_id)
{
- /** TODO: add plugin keybinding support */
- /*on_menu_insert_special_chars1_activate(NULL, NULL);*/
+ on_replace_tabs_activate(NULL, NULL);
}
-static void cb_func_nav_back(G_GNUC_UNUSED guint key_id)
+
+/* common function for insert keybindings, only valid when scintilla has focus. */
+static void cb_func_insert_action(guint key_id)
{
- navqueue_go_back();
-}
+ gint idx = document_get_cur_idx();
+ GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
-static void cb_func_nav_forward(G_GNUC_UNUSED guint key_id)
-{
- navqueue_go_forward();
+ /* keybindings only valid when scintilla widget has focus */
+ if (! DOC_IDX_VALID(idx) || focusw != GTK_WIDGET(doc_list[idx].sci)) return;
+
+ switch (key_id)
+ {
+ case GEANY_KEYS_INSERT_ALTWHITESPACE:
+ editor_insert_alternative_whitespace(idx);
+ break;
+ case GEANY_KEYS_INSERT_DATE:
+ gtk_menu_item_activate(GTK_MENU_ITEM(lookup_widget(app->window, "insert_date_custom1")));
+ break;
+ }
}
Modified: trunk/src/keybindings.h
===================================================================
--- trunk/src/keybindings.h 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/keybindings.h 2008-03-12 17:07:43 UTC (rev 2324)
@@ -21,30 +21,15 @@
* $Id$
*/
+/**
+ * @file keybindings.h
+ * Configurable keyboard shortcuts.
+ **/
+
#ifndef GEANY_KEYBINDINGS_H
#define GEANY_KEYBINDINGS_H 1
-typedef void (*KBCallback) (guint key_id);
-
-/* holds all user-definable key bindings */
-typedef struct KeyBinding
-{
- guint key;
- GdkModifierType mods;
- /* at the moment only needed as keys for the configuration file because indices or translatable
- * strings as keys are not very useful */
- const gchar *name;
- const gchar *label;
- /* function pointer to a callback function, just to keep the code in keypress event
- * callback function clear */
- KBCallback cb_func;
- /* string to use as a section name in the preferences dialog in keybinding treeview as well as
- * in the keybinding help dialog, set only for the first binding in the section */
- gchar *section;
-} KeyBinding;
-
-
/* allowed modifier keys (especially NOT Caps lock, no Num lock) */
#if GTK_CHECK_VERSION(2, 10, 0)
# define GEANY_KEYS_MODIFIER_MASK (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK | \
@@ -53,59 +38,234 @@
# define GEANY_KEYS_MODIFIER_MASK (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)
#endif
-/* Plugin API */
-typedef enum
+
+typedef void (*KeyCallback) (guint key_id);
+
+/** Represents a single keybinding action */
+typedef struct KeyBinding
{
- GEANY_KEYS_GROUP_FILE = 0,
- GEANY_KEYS_MENU_NEW = GEANY_KEYS_GROUP_FILE,
- GEANY_KEYS_MENU_OPEN,
- GEANY_KEYS_MENU_OPENSELECTED,
- GEANY_KEYS_MENU_SAVE,
- GEANY_KEYS_MENU_SAVEAS,
- GEANY_KEYS_MENU_SAVEALL,
- GEANY_KEYS_MENU_PRINT,
- GEANY_KEYS_MENU_CLOSE,
- GEANY_KEYS_MENU_CLOSEALL,
- GEANY_KEYS_MENU_RELOADFILE,
- GEANY_KEYS_MENU_PROJECTPROPERTIES,
+ guint key; /**< Key value in lower-case, such as @c GDK_a */
+ GdkModifierType mods; /**< Modifier keys, such as @c GDK_CONTROL_MASK */
+ const gchar *name; /**< Key name for the configuration file, such as @c "menu_new" */
+ const gchar *label; /**< Label used in the preferences dialog keybindings tab */
+ KeyCallback callback; /**< Callback function called when the key combination is pressed */
+ GtkWidget *menu_item; /**< Menu item widget for setting the menu accelerator */
+} KeyBinding;
- GEANY_KEYS_GROUP_EDIT,
- GEANY_KEYS_MENU_UNDO = GEANY_KEYS_GROUP_EDIT,
- GEANY_KEYS_MENU_REDO,
- GEANY_KEYS_MENU_CUT,
- GEANY_KEYS_MENU_COPY,
- GEANY_KEYS_MENU_PASTE,
- GEANY_KEYS_MENU_SELECTALL,
- GEANY_KEYS_MENU_INSERTDATE,
- GEANY_KEYS_MENU_PREFERENCES,
- GEANY_KEYS_GROUP_SEARCH,
- GEANY_KEYS_MENU_FIND = GEANY_KEYS_GROUP_SEARCH,
- GEANY_KEYS_MENU_FINDNEXT,
- GEANY_KEYS_MENU_FINDPREVIOUS,
- GEANY_KEYS_MENU_FINDINFILES,
- GEANY_KEYS_MENU_REPLACE,
- GEANY_KEYS_MENU_FINDNEXTSEL,
- GEANY_KEYS_MENU_FINDPREVSEL,
- GEANY_KEYS_MENU_NEXTMESSAGE,
- GEANY_KEYS_MENU_GOTOLINE,
+/** A collection of keybindings grouped together. */
+typedef struct KeyBindingGroup
+{
+ const gchar *name; /**< Group name used in the configuration file, such as @c "html_chars" */
+ const gchar *label; /**< Group label used in the preferences dialog keybindings tab */
+ gsize count; /**< Count of KeyBinding structs in @a keys */
+ KeyBinding *keys; /**< Fixed array of KeyBinding structs */
+}
+KeyBindingGroup;
- GEANY_KEYS_GROUP_VIEW,
- GEANY_KEYS_MENU_TOGGLEALL = GEANY_KEYS_GROUP_VIEW,
- GEANY_KEYS_MENU_FULLSCREEN,
- GEANY_KEYS_MENU_MESSAGEWINDOW,
- GEANY_KEYS_MENU_SIDEBAR,
- GEANY_KEYS_MENU_ZOOMIN,
- GEANY_KEYS_MENU_ZOOMOUT,
+extern GPtrArray *keybinding_groups; /* array of KeyBindingGroup pointers */
- GEANY_KEYS_GROUP_DOCUMENT,
- GEANY_KEYS_MENU_REPLACETABS = GEANY_KEYS_GROUP_DOCUMENT,
- GEANY_KEYS_MENU_FOLDALL,
- GEANY_KEYS_MENU_UNFOLDALL,
- GEANY_KEYS_RELOADTAGLIST,
- GEANY_KEYS_GROUP_BUILD,
- GEANY_KEYS_BUILD_COMPILE = GEANY_KEYS_GROUP_BUILD,
+/** Keybinding group IDs */
+enum
+{
+ GEANY_KEY_GROUP_FILE,
+ GEANY_KEY_GROUP_PROJECT,
+ GEANY_KEY_GROUP_EDITOR,
+ GEANY_KEY_GROUP_CLIPBOARD,
+ GEANY_KEY_GROUP_SELECT,
+ GEANY_KEY_GROUP_FORMAT,
+ GEANY_KEY_GROUP_INSERT,
+ GEANY_KEY_GROUP_SETTINGS,
+ GEANY_KEY_GROUP_SEARCH,
+ GEANY_KEY_GROUP_GOTO,
+ GEANY_KEY_GROUP_VIEW,
+ GEANY_KEY_GROUP_FOCUS,
+ GEANY_KEY_GROUP_NOTEBOOK,
+ GEANY_KEY_GROUP_DOCUMENT,
+ GEANY_KEY_GROUP_BUILD,
+ GEANY_KEY_GROUP_TOOLS,
+ GEANY_KEY_GROUP_HELP,
+ GEANY_KEY_GROUP_COUNT
+};
+
+/** File group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_FILE_NEW,
+ GEANY_KEYS_FILE_OPEN,
+ GEANY_KEYS_FILE_OPENSELECTED,
+ GEANY_KEYS_FILE_SAVE,
+ GEANY_KEYS_FILE_SAVEAS,
+ GEANY_KEYS_FILE_SAVEALL,
+ GEANY_KEYS_FILE_PRINT,
+ GEANY_KEYS_FILE_CLOSE,
+ GEANY_KEYS_FILE_CLOSEALL,
+ GEANY_KEYS_FILE_RELOAD,
+ GEANY_KEYS_FILE_COUNT
+};
+
+/** Project group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_PROJECT_PROPERTIES,
+ GEANY_KEYS_PROJECT_COUNT
+};
+
+/** Editor group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_EDITOR_UNDO,
+ GEANY_KEYS_EDITOR_REDO,
+ GEANY_KEYS_EDITOR_DELETELINE,
+ GEANY_KEYS_EDITOR_DUPLICATELINE,
+ GEANY_KEYS_EDITOR_TRANSPOSELINE,
+ GEANY_KEYS_EDITOR_SCROLLTOLINE,
+ GEANY_KEYS_EDITOR_SCROLLLINEUP,
+ GEANY_KEYS_EDITOR_SCROLLLINEDOWN,
+ GEANY_KEYS_EDITOR_COMPLETESNIPPET,
+ GEANY_KEYS_EDITOR_SUPPRESSSNIPPETCOMPLETION,
+ GEANY_KEYS_EDITOR_CONTEXTACTION,
+ GEANY_KEYS_EDITOR_AUTOCOMPLETE,
+ GEANY_KEYS_EDITOR_CALLTIP,
+ GEANY_KEYS_EDITOR_MACROLIST,
+ GEANY_KEYS_EDITOR_COUNT
+};
+
+/** Clipboard group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_CLIPBOARD_CUT,
+ GEANY_KEYS_CLIPBOARD_COPY,
+ GEANY_KEYS_CLIPBOARD_PASTE,
+ GEANY_KEYS_CLIPBOARD_CUTLINE,
+ GEANY_KEYS_CLIPBOARD_COPYLINE,
+ GEANY_KEYS_CLIPBOARD_COUNT
+};
+
+/** Select group keybinding command IDs */
+enum
+{
+
+ GEANY_KEYS_SELECT_ALL,
+ GEANY_KEYS_SELECT_WORD,
+ GEANY_KEYS_SELECT_LINE,
+ GEANY_KEYS_SELECT_PARAGRAPH,
+ GEANY_KEYS_SELECT_COUNT
+};
+
+/** Format group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_FORMAT_TOGGLECASE,
+ GEANY_KEYS_FORMAT_COMMENTLINETOGGLE,
+ GEANY_KEYS_FORMAT_COMMENTLINE,
+ GEANY_KEYS_FORMAT_UNCOMMENTLINE,
+ GEANY_KEYS_FORMAT_INCREASEINDENT,
+ GEANY_KEYS_FORMAT_DECREASEINDENT,
+ GEANY_KEYS_FORMAT_INCREASEINDENTBYSPACE,
+ GEANY_KEYS_FORMAT_DECREASEINDENTBYSPACE,
+ GEANY_KEYS_FORMAT_AUTOINDENT,
+ GEANY_KEYS_FORMAT_SENDTOCMD1,
+ GEANY_KEYS_FORMAT_SENDTOCMD2,
+ GEANY_KEYS_FORMAT_SENDTOCMD3,
+ GEANY_KEYS_FORMAT_COUNT
+};
+
+/** Insert group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_INSERT_DATE,
+ GEANY_KEYS_INSERT_ALTWHITESPACE,
+ GEANY_KEYS_INSERT_COUNT
+};
+
+/** Settings group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_SETTINGS_PREFERENCES,
+ GEANY_KEYS_SETTINGS_COUNT
+};
+
+/** Search group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_SEARCH_FIND,
+ GEANY_KEYS_SEARCH_FINDNEXT,
+ GEANY_KEYS_SEARCH_FINDPREVIOUS,
+ GEANY_KEYS_SEARCH_FINDINFILES,
+ GEANY_KEYS_SEARCH_REPLACE,
+ GEANY_KEYS_SEARCH_FINDNEXTSEL,
+ GEANY_KEYS_SEARCH_FINDPREVSEL,
+ GEANY_KEYS_SEARCH_NEXTMESSAGE,
+ GEANY_KEYS_SEARCH_FINDUSAGE,
+ GEANY_KEYS_SEARCH_COUNT
+};
+
+/** Go To group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_GOTO_FORWARD,
+ GEANY_KEYS_GOTO_BACK,
+ GEANY_KEYS_GOTO_LINE,
+ GEANY_KEYS_GOTO_MATCHINGBRACE,
+ GEANY_KEYS_GOTO_TOGGLEMARKER,
+ GEANY_KEYS_GOTO_NEXTMARKER,
+ GEANY_KEYS_GOTO_PREVIOUSMARKER,
+ GEANY_KEYS_GOTO_TAGDEFINITION,
+ GEANY_KEYS_GOTO_TAGDECLARATION,
+ GEANY_KEYS_GOTO_COUNT
+};
+
+/** View group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_VIEW_TOGGLEALL,
+ GEANY_KEYS_VIEW_FULLSCREEN,
+ GEANY_KEYS_VIEW_MESSAGEWINDOW,
+ GEANY_KEYS_VIEW_SIDEBAR,
+ GEANY_KEYS_VIEW_ZOOMIN,
+ GEANY_KEYS_VIEW_ZOOMOUT,
+ GEANY_KEYS_VIEW_COUNT
+};
+
+/** Focus group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_FOCUS_EDITOR,
+ GEANY_KEYS_FOCUS_SCRIBBLE,
+ GEANY_KEYS_FOCUS_VTE,
+ GEANY_KEYS_FOCUS_SEARCHBAR,
+ GEANY_KEYS_FOCUS_COUNT
+};
+
+/** Notebook Tab group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_NOTEBOOK_SWITCHTABLEFT,
+ GEANY_KEYS_NOTEBOOK_SWITCHTABRIGHT,
+ GEANY_KEYS_NOTEBOOK_SWITCHTABLASTUSED,
+ GEANY_KEYS_NOTEBOOK_MOVETABLEFT,
+ GEANY_KEYS_NOTEBOOK_MOVETABRIGHT,
+ GEANY_KEYS_NOTEBOOK_MOVETABFIRST,
+ GEANY_KEYS_NOTEBOOK_MOVETABLAST,
+ GEANY_KEYS_NOTEBOOK_COUNT
+};
+
+/** Document group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_DOCUMENT_REPLACETABS,
+ GEANY_KEYS_DOCUMENT_FOLDALL,
+ GEANY_KEYS_DOCUMENT_UNFOLDALL,
+ GEANY_KEYS_DOCUMENT_RELOADTAGLIST,
+ GEANY_KEYS_DOCUMENT_COUNT
+};
+
+/** Build group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_BUILD_COMPILE,
GEANY_KEYS_BUILD_LINK,
GEANY_KEYS_BUILD_MAKE,
GEANY_KEYS_BUILD_MAKEOWNTARGET,
@@ -114,86 +274,38 @@
GEANY_KEYS_BUILD_RUN,
GEANY_KEYS_BUILD_RUN2,
GEANY_KEYS_BUILD_OPTIONS,
+ GEANY_KEYS_BUILD_COUNT
+};
- GEANY_KEYS_GROUP_TOOLS,
- GEANY_KEYS_MENU_OPENCOLORCHOOSER = GEANY_KEYS_GROUP_TOOLS,
- GEANY_KEYS_MENU_INSERTSPECIALCHARS,
+/** Tools group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_TOOLS_OPENCOLORCHOOSER,
+ GEANY_KEYS_TOOLS_COUNT
+};
- GEANY_KEYS_GROUP_HELP,
- GEANY_KEYS_MENU_HELP = GEANY_KEYS_GROUP_HELP,
+/** Help group keybinding command IDs */
+enum
+{
+ GEANY_KEYS_HELP_HELP,
+ GEANY_KEYS_HELP_COUNT
+};
- GEANY_KEYS_GROUP_FOCUS,
- GEANY_KEYS_SWITCH_EDITOR = GEANY_KEYS_GROUP_FOCUS,
- GEANY_KEYS_SWITCH_SCRIBBLE,
- GEANY_KEYS_SWITCH_VTE,
- GEANY_KEYS_SWITCH_SEARCH_BAR,
- GEANY_KEYS_GROUP_TABS,
- GEANY_KEYS_SWITCH_TABLEFT = GEANY_KEYS_GROUP_TABS,
- GEANY_KEYS_SWITCH_TABRIGHT,
- GEANY_KEYS_SWITCH_TABLASTUSED,
- GEANY_KEYS_MOVE_TABLEFT,
- GEANY_KEYS_MOVE_TABRIGHT,
- GEANY_KEYS_MOVE_TABFIRST,
- GEANY_KEYS_MOVE_TABLAST,
+void keybindings_init(void);
- GEANY_KEYS_GROUP_EDITING,
- GEANY_KEYS_EDIT_TOGGLECASE = GEANY_KEYS_GROUP_EDITING,
- GEANY_KEYS_EDIT_DUPLICATELINE,
- GEANY_KEYS_EDIT_DELETELINE,
- GEANY_KEYS_EDIT_COPYLINE,
- GEANY_KEYS_EDIT_CUTLINE,
- GEANY_KEYS_EDIT_TRANSPOSELINE,
- GEANY_KEYS_EDIT_COMMENTLINETOGGLE,
- GEANY_KEYS_EDIT_COMMENTLINE,
- GEANY_KEYS_EDIT_UNCOMMENTLINE,
- GEANY_KEYS_EDIT_INCREASEINDENT,
- GEANY_KEYS_EDIT_DECREASEINDENT,
- GEANY_KEYS_EDIT_INCREASEINDENTBYSPACE,
- GEANY_KEYS_EDIT_DECREASEINDENTBYSPACE,
- GEANY_KEYS_EDIT_AUTOINDENT,
- GEANY_KEYS_EDIT_SENDTOCMD1,
- GEANY_KEYS_EDIT_SENDTOCMD2,
- GEANY_KEYS_EDIT_SENDTOCMD3,
- GEANY_KEYS_EDIT_GOTOMATCHINGBRACE,
- GEANY_KEYS_EDIT_TOGGLEMARKER,
- GEANY_KEYS_EDIT_GOTONEXTMARKER,
- GEANY_KEYS_EDIT_GOTOPREVIOUSMARKER,
- GEANY_KEYS_EDIT_SELECTWORD,
- GEANY_KEYS_EDIT_SELECTLINE,
- GEANY_KEYS_EDIT_SELECTPARAGRAPH,
- GEANY_KEYS_EDIT_SCROLLTOLINE,
- GEANY_KEYS_EDIT_SCROLLLINEUP,
- GEANY_KEYS_EDIT_SCROLLLINEDOWN,
- GEANY_KEYS_EDIT_INSERTALTWHITESPACE,
- GEANY_KEYS_POPUP_FINDUSAGE,
- GEANY_KEYS_POPUP_CONTEXTACTION,
+void keybindings_load_keyfile(void);
- GEANY_KEYS_GROUP_TAGS,
- GEANY_KEYS_EDIT_AUTOCOMPLETE = GEANY_KEYS_GROUP_TAGS,
- GEANY_KEYS_EDIT_CALLTIP,
- GEANY_KEYS_EDIT_MACROLIST,
- GEANY_KEYS_EDIT_COMPLETESNIPPET,
- GEANY_KEYS_EDIT_SUPPRESSSNIPPETCOMPLETION,
- GEANY_KEYS_POPUP_GOTOTAGDEFINITION,
- GEANY_KEYS_POPUP_GOTOTAGDECLARATION,
+void keybindings_free(void);
- GEANY_KEYS_GROUP_OTHER,
- GEANY_KEYS_NAV_FORWARD = GEANY_KEYS_GROUP_OTHER,
- GEANY_KEYS_NAV_BACK,
- GEANY_MAX_KEYS
-}
-GeanyKeyCommand;
+void keybindings_set_item(KeyBindingGroup *group, gsize key_id,
+ KeyCallback callback, guint key, GdkModifierType mod,
+ const gchar *name, const gchar *label, GtkWidget *menu_item);
-extern KeyBinding *keys[GEANY_MAX_KEYS];
+void keybindings_send_command(guint group_id, guint key_id);
+KeyBinding *keybindings_lookup_item(guint group_id, guint key_id);
-void keybindings_init(void);
-
-void keybindings_free(void);
-
-void keybindings_cmd(GeanyKeyCommand cmd_id);
-
/* just write the content of the keys array to the config file */
void keybindings_write_to_file(void);
Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/main.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -853,6 +853,9 @@
plugins_init();
#endif
+ /* load keybinding settings after plugins have added their groups */
+ keybindings_load_keyfile();
+
/* load any command line files or session files */
main_status.opening_session_files = TRUE;
if (! open_cl_files(argc, argv))
Modified: trunk/src/plugindata.h
===================================================================
--- trunk/src/plugindata.h 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/plugindata.h 2008-03-12 17:07:43 UTC (rev 2324)
@@ -22,28 +22,27 @@
* $Id$
*/
-#ifndef PLUGIN_H
-#define PLUGIN_H
-
-
/**
- * @file plugindata.h
- * This file defines the plugin API, the interface between Geany and its plugins.
- * For detailed documentation of the plugin system please read the plugin
- * API documentation.
+ * @file plugindata.h
+ * This file defines the plugin API, the interface between Geany and its plugins.
+ * For detailed documentation of the plugin system please read the plugin
+ * API documentation.
**/
+#ifndef PLUGIN_H
+#define PLUGIN_H
+
/* The API version should be incremented whenever any plugin data types below are
* modified or appended to. */
-static const gint api_version = 45;
+static const gint api_version = 48;
/* The ABI version should be incremented whenever existing fields in the plugin
* data types below have to be changed or reordered. It should stay the same if fields
* are only appended, as this doesn't affect existing fields. */
-static const gint abi_version = 20;
+static const gint abi_version = 22;
-/* This performs runtime checks that try to ensure:
+/** This performs runtime checks that try to ensure:
* 1. Geany ABI data types are compatible with this plugin.
* 2. Geany sources provide the required API for this plugin. */
/* TODO: if possible, the API version should be checked at compile time, not runtime. */
@@ -92,6 +91,27 @@
}
+/** Declare and initialise a keybinding group.
+ * @code KeyBindingGroup plugin_key_group[1]; @endcode
+ * You must then set the @c plugin_key_group::keys[] entries for the group in init().
+ * The @c plugin_key_group::label field is set by Geany after @c init()
+ * is called, to the name of the plugin.
+ * @param group_name A unique group name (without quotes) to be used in the
+ * configuration file, such as @c html_chars.
+ * @param key_count The number of keybindings the group will hold.
+ * @note This is a single element array for implementation reasons,
+ * but you can treat it like a pointer. */
+#define PLUGIN_KEY_GROUP(group_name, key_count) \
+ static KeyBinding plugin_keys[key_count]; \
+ \
+ /* We have to declare plugin_key_group as a single element array.
+ * Declaring as a pointer to a struct doesn't work with g_module_symbol(). */ \
+ KeyBindingGroup plugin_key_group[1] = \
+ { \
+ {G_STRINGIFY(group_name), NULL, key_count, plugin_keys} \
+ };
+
+
/** callback array entry */
typedef struct GeanyCallback
{
@@ -309,10 +329,15 @@
EncodingFuncs;
+struct KeyBindingGroup;
+typedef void (*_KeyCallback) (guint key_id);
+
typedef struct KeybindingFuncs
{
- /* See GeanyKeyCommand enum for cmd_id. */
- void (*send_command) (gint cmd_id);
+ void (*send_command) (guint group_id, guint key_id);
+ void (*set_item) (struct KeyBindingGroup *group, gsize key_id,
+ _KeyCallback callback, guint key, GdkModifierType mod,
+ const gchar *name, const gchar *label, GtkWidget *menu_item);
}
KeybindingFuncs;
Modified: trunk/src/plugins.c
===================================================================
--- trunk/src/plugins.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/plugins.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -53,11 +53,9 @@
#include "encodings.h"
#include "search.h"
#include "highlighting.h"
+#include "keybindings.h"
-void keybindings_cmd(gint cmd_id); /* don't require keybindings.h enum in plugindata.h */
-
-
#ifdef G_OS_WIN32
# define PLUGIN_EXT "dll"
#else
@@ -68,20 +66,21 @@
typedef struct Plugin
{
GModule *module;
- gchar *filename; /* plugin filename (/path/libname.so) */
+ gchar *filename; /* plugin filename (/path/libname.so) */
PluginFields fields;
- gulong *signal_ids; /* signal IDs to disconnect when unloading */
+ gulong *signal_ids; /* signal IDs to disconnect when unloading */
gsize signal_ids_len;
+ KeyBindingGroup *key_group;
- PluginInfo* (*info) (void); /* Returns plugin name, description */
+ PluginInfo* (*info) (void); /* Returns plugin name, description */
void (*init) (GeanyData *data); /* Called when the plugin is enabled */
void (*configure) (GtkWidget *parent); /* plugin configure dialog, optionally */
- void (*cleanup) (void); /* Called when the plugin is disabled or when Geany exits */
+ void (*cleanup) (void); /* Called when the plugin is disabled or when Geany exits */
}
Plugin;
-static GList *plugin_list = NULL; /* list of all available, loadable plugins */
+static GList *plugin_list = NULL; /* list of all available, loadable plugins */
static GList *active_plugin_list = NULL; /* list of only actually loaded plugins */
static GtkWidget *separator = NULL;
static void pm_show_dialog(GtkMenuItem *menuitem, gpointer user_data);
@@ -189,7 +188,8 @@
};
static KeybindingFuncs keybindings_funcs = {
- &keybindings_cmd
+ &keybindings_send_command,
+ &keybindings_set_item
};
static TagManagerFuncs tagmanager_funcs = {
@@ -360,6 +360,15 @@
static void
+add_kb_group(Plugin *plugin)
+{
+ g_ptr_array_add(keybinding_groups, plugin->key_group);
+
+ plugin->key_group->label = plugin->info()->name;
+}
+
+
+static void
plugin_init(Plugin *plugin)
{
GeanyCallback *callbacks;
@@ -377,6 +386,11 @@
if (callbacks)
add_callbacks(plugin, callbacks);
+ g_module_symbol(plugin->module, "plugin_key_group",
+ (void *) &plugin->key_group);
+ if (plugin->key_group)
+ add_kb_group(plugin);
+
active_plugin_list = g_list_append(active_plugin_list, plugin);
geany_debug("Loaded: %s (%s)", plugin->filename,
@@ -485,16 +499,20 @@
g_return_if_fail(plugin);
g_return_if_fail(plugin->module);
- if (g_list_find(active_plugin_list, plugin))
- { /* only do cleanup if the plugin was actually loaded */
- if (plugin->cleanup)
- plugin->cleanup();
+ /* only do cleanup if the plugin was actually loaded */
+ if (! g_list_find(active_plugin_list, plugin))
+ return;
- remove_callbacks(plugin);
+ if (plugin->cleanup)
+ plugin->cleanup();
- active_plugin_list = g_list_remove(active_plugin_list, plugin);
- geany_debug("Unloaded: %s", plugin->filename);
- }
+ remove_callbacks(plugin);
+
+ if (plugin->key_group)
+ g_ptr_array_remove_fast(keybinding_groups, plugin->key_group);
+
+ active_plugin_list = g_list_remove(active_plugin_list, plugin);
+ geany_debug("Unloaded: %s", plugin->filename);
}
Modified: trunk/src/prefs.c
===================================================================
--- trunk/src/prefs.c 2008-03-12 13:37:39 UTC (rev 2323)
+++ trunk/src/prefs.c 2008-03-12 17:07:43 UTC (rev 2324)
@@ -73,7 +73,8 @@
static void on_cell_edited(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, gpointer user_data);
static gboolean on_keytype_dialog_response(GtkWidget *dialog, GdkEventKey *event, gpointer user_data);
static void on_dialog_response(GtkWidget *dialog, gint response, gpointer user_data);
-static gboolean find_duplicate(guint idx, guint key, GdkModifierType mods, const gchar *action);
+static gboolean find_duplicate(KeyBinding *search_kb,
+ guint key, GdkModifierType mods, const gchar *action);
static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data);
static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data);
static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data);
@@ -127,25 +128,30 @@
static void init_keybindings(void)
{
GtkTreeIter parent, iter;
- gint i;
- gchar *key_string;
+ gsize g, i;
if (store == NULL)
init_kb_tree();
- for (i = 0; i < GEANY_MAX_KEYS; i++)
+ for (g = 0; g < keybinding_groups->len; g++)
{
- if (keys[i]->section != NULL)
+ KeyBindingGroup *group = g_ptr_array_index(keybinding_groups, g);
+
+ gtk_tree_store_append(store, &parent, NULL);
+ gtk_tree_store_set(store, &parent, KB_TREE_ACTION, group->label,
+ KB_TREE_INDEX, g, -1);
+
+ for (i = 0; i < group->count; i++)
{
- gtk_tree_store_append(store, &parent, NULL);
- gtk_tree_store_set(store, &parent, KB_TREE_ACTION, keys[i]->section, -1);
+ KeyBinding *kb = &group->keys[i];
+ gchar *key_string;
+
+ key_string = gtk_accelerator_name(kb->key, kb->mods);
+ gtk_tree_store_append(store, &iter, &parent);
+ gtk_tree_store_set(store, &iter, KB_TREE_ACTION, kb->label,
+ KB_TREE_SHORTCUT, key_string, KB_TREE_INDEX, i, -1);
+ g_free(key_string);
}
-
- key_string = gtk_accelerator_name(keys[i]->key, keys[i]->mods);
- gtk_tree_store_append(store, &iter, &parent);
- gtk_tree_store_set(store, &iter, KB_TREE_ACTION, keys[i]->label,
- KB_TREE_SHORTCUT, key_string, KB_TREE_INDEX, i, -1);
- g_free(key_string);
}
gtk_tree_view_expand_all(GTK_TREE_VIEW(tree));
}
@@ -1065,7 +1071,7 @@
return TRUE;
}
- gtk_tree_model_get(model, &g_iter, 0, &name, -1);
+ gtk_tree_model_get(model, &g_iter, KB_TREE_ACTION, &name, -1);
if (name != NULL)
{
GtkWidget *dialog;
@@ -1103,33 +1109,48 @@
}
+static KeyBinding *lookup_kb_from_iter(G_GNUC_UNUSED GtkTreeModel *model, GtkTreeIter *iter)
+{
+ guint group_idx, keybinding_idx;
+ GtkTreeIter parent;
+
+ /* get kb index */
+ gtk_tree_model_get(GTK_TREE_MODEL(store), iter, KB_TREE_INDEX, &keybinding_idx, -1);
+
+ /* lookup the parent to get group index */
+ gtk_tree_model_iter_parent(GTK_TREE_MODEL(store), &parent, iter);
+ gtk_tree_model_get(GTK_TREE_MODEL(store), &parent, KB_TREE_INDEX, &group_idx, -1);
+
+ return keybindings_lookup_item(group_idx, keybinding_idx);
+}
+
+
static void on_cell_edited(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, gpointer user_data)
{
if (path != NULL && new_text != NULL)
{
- guint idx;
+ GtkTreeIter iter;
guint lkey;
GdkModifierType lmods;
- GtkTreeIter iter;
+ KeyBinding *kb;
gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path);
if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &iter))
- return;
+ return; /* ignore group items */
gtk_accelerator_parse(new_text, &lkey, &lmods);
- /* get index */
- gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &idx, -1);
+ kb = lookup_kb_from_iter(GTK_TREE_MODEL(store), &iter);
- if (find_duplicate(idx, lkey, lmods, new_text))
+ if (find_duplicate(kb, lkey, lmods, new_text))
return;
/* set the values here, because of the above check, setting it in
* gtk_accelerator_parse would return a wrong key combination if it is duplicate */
- keys[idx]->key = lkey;
- keys[idx]->mods = lmods;
+ kb->key = lkey;
+ kb->mods = lmods;
- gtk_tree_store_set(store, &iter, 1, new_text, -1);
+ gtk_tree_store_set(store, &iter, KB_TREE_SHORTCUT, new_text, -1);
edited = TRUE;
}
@@ -1155,29 +1176,28 @@
}
-static void on_dialog_response(GtkWidget *dialog, gint response, gpointer iter)
+static void on_dialog_response(GtkWidget *dialog, gint response, G_GNUC_UNUSED gpointer iter)
{
if (response == GTK_RESPONSE_ACCEPT)
{
- guint idx;
guint lkey;
GdkModifierType lmods;
+ KeyBinding *kb;
- /* get index */
- gtk_tree_model_get(GTK_TREE_MODEL(store), &g_iter, 2, &idx, -1);
+ kb = lookup_kb_from_iter(GTK_TREE_MODEL(store), &g_iter);
gtk_accelerator_parse(gtk_label_get_text(GTK_LABEL(dialog_label)), &lkey, &lmods);
- if (find_duplicate(idx, lkey, lmods, gtk_label_get_text(GTK_LABEL(dialog_label))))
+ if (find_duplicate(kb, lkey, lmods, gtk_label_get_text(GTK_LABEL(dialog_label))))
return;
/* set the values here, because of the above check, setting it in
* gtk_accelerator_parse would return a wrong key combination if it is duplicate */
- keys[idx]->key = lkey;
- keys[idx]->mods = lmods;
+ kb->key = lkey;
+ kb->mods = lmods;
gtk_tree_store_set(store, &g_iter,
- 1, gtk_label_get_text(GTK_LABEL(dialog_label)), -1);
+ KB_TREE_SHORTCUT, gtk_label_get_text(GTK_LABEL(dialog_label)), -1);
g_free(dialog_key_name);
dialog_key_name = NULL;
@@ -1188,63 +1208,81 @@
}
-static gboolean find_iter(guint i, GtkTreeIter *iter)
+/* Look for a (1st-level) child of parent whose KB_TREE_INDEX matches i,
+ * setting iter to point to the node if found.
+ * If parent is NULL, look for a parent node whose KB_TREE_INDEX matches i. */
+static gboolean find_child_iter(GtkTreeIter *parent, guint i, GtkTreeIter *iter)
{
GtkTreeModel *model = GTK_TREE_MODEL(store);
guint idx;
- GtkTreeIter parent;
- if (! gtk_tree_model_get_iter_first(model, &parent))
- return FALSE; /* no items */
+ /* get first child of parent */
+ if (! gtk_tree_model_iter_children(model, iter, parent))
+ return FALSE;
- while (TRUE)
+ while (TRUE) /* foreach child */
{
- if (! gtk_tree_model_iter_children(model, iter, &parent))
- return FALSE;
-
- while (TRUE)
- {
- gtk_tree_model_get(model, iter, 2, &idx, -1);
- if (idx == i)
- return TRUE;
- if (! gtk_tree_model_iter_next(model, iter))
- break;
- }
- if (! gtk_tree_model_iter_next(model, &parent))
- return FALSE;
+ gtk_tree_model_get(model, iter, KB_TREE_INDEX, &idx, -1);
+ if (idx == i)
+ return TRUE;
+ if (! gtk_tree_model_iter_next(model, iter))
@@ Diff output truncated at 100000 characters. @@
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