[geany/geany-plugins] 3ecb15: Merge pull request #848 from techee/vimode_history2
Frank Lanitz
git-noreply at xxxxx
Fri May 10 08:34:32 UTC 2019
Branch: refs/heads/master
Author: Frank Lanitz <frank at frank.uvena.de>
Committer: GitHub <noreply at github.com>
Date: Fri, 10 May 2019 08:34:32 UTC
Commit: 3ecb15ad2a82afc91cb2ee35ae74f6005a824d1c
https://github.com/geany/geany-plugins/commit/3ecb15ad2a82afc91cb2ee35ae74f6005a824d1c
Log Message:
-----------
Merge pull request #848 from techee/vimode_history2
vimode: Separate command and search history
Modified Paths:
--------------
vimode/src/excmd-prompt.c
Modified: vimode/src/excmd-prompt.c
187 lines changed, 133 insertions(+), 54 deletions(-)
===================================================================
@@ -34,86 +34,155 @@
static GtkWidget *prompt;
static GtkWidget *entry;
static CmdContext *ctx;
-static GList *history;
+
+static gchar cmd_first_char;
+static GPtrArray *history;
+static GPtrArray *cmd_history;
+static GPtrArray *search_history;
static gint history_pos;
+/* text entered by user used to filter history */
+static gchar *entered_text;
+/* ignore change of text inside entry when set from history */
+static gboolean ignore_change;
static void close_prompt()
{
gtk_widget_hide(prompt);
+ if (entered_text)
+ {
+ g_free(entered_text);
+ entered_text = NULL;
+ }
+}
+
+
+static void set_prompt_text(const gchar *val)
+{
+ gchar *text = g_strconcat(" ", val, NULL);
+ text[0] = cmd_first_char;
+ ignore_change = TRUE;
+ gtk_entry_set_text(GTK_ENTRY(entry), text);
+ gtk_editable_set_position(GTK_EDITABLE(entry), strlen(text));
+ g_free(text);
}
static gboolean on_prompt_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer dummy)
{
- switch (event->keyval)
- {
- case GDK_KEY_Escape:
- close_prompt();
- return TRUE;
+ const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
+ guint modif_mask = GDK_MODIFIER_MASK & ~GDK_LOCK_MASK;
- case GDK_KEY_Tab:
- /* avoid leaving the entry */
- return TRUE;
+ ignore_change = FALSE;
- case GDK_KEY_Return:
- case GDK_KEY_KP_Enter:
- case GDK_KEY_ISO_Enter:
+ if ((event->state & modif_mask) == 0)
+ {
+ switch (event->keyval)
{
- const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
- GList *link = g_list_find_custom(history, text, (GCompareFunc)g_strcmp0);
+ case GDK_KEY_Escape:
+ close_prompt();
+ return TRUE;
- if (link)
- {
- g_free(link->data);
- history = g_list_remove_link(history, link);
- }
- if (g_strcmp0(text, ":") != 0)
- history = g_list_prepend(history, g_strdup(text));
+ case GDK_KEY_Tab:
+ /* avoid leaving the entry */
+ return TRUE;
- excmd_perform(ctx, text);
- close_prompt();
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter:
+ case GDK_KEY_ISO_Enter:
+ {
+ guint i;
- return TRUE;
- }
+ for (i = 0; i < history->len; i++)
+ if (g_str_equal(text + 1, history->pdata[i]))
+ g_ptr_array_remove_index(history, i);
+ if (strlen(text) > 1)
+ g_ptr_array_add(history, g_strdup(text + 1));
+ if (history->len > 20) // default vim history size
+ g_ptr_array_remove_index(history, 0);
- case GDK_KEY_Up:
- case GDK_KEY_KP_Up:
- case GDK_KEY_uparrow:
- {
- gint history_len = g_list_length(history);
+ excmd_perform(ctx, text);
+ close_prompt();
- if (history_pos == -1 && history_len > 0)
- history_pos = 0;
- else if (history_pos + 1 < history_len)
- history_pos++;
+ return TRUE;
+ }
- if (history_pos != -1 && history_pos < history_len)
+ case GDK_KEY_Up:
+ case GDK_KEY_KP_Up:
+ case GDK_KEY_uparrow:
{
- gchar *val = g_list_nth_data(history, history_pos);
- gtk_entry_set_text(GTK_ENTRY(entry), val);
- gtk_editable_set_position(GTK_EDITABLE(entry), strlen(val));
+ gint pos = -1;
+
+ if (history_pos == -1 && history->len > 0)
+ pos = history->len - 1;
+ else if (history_pos > 0)
+ pos = history_pos - 1;
+
+ while (pos >= 0)
+ {
+ if (g_str_has_prefix(history->pdata[pos], entered_text))
+ break;
+ pos--;
+ }
+
+ if (pos != -1)
+ {
+ set_prompt_text(history->pdata[pos]);
+ history_pos = pos;
+ }
+
+ return TRUE;
}
- return TRUE;
- }
+ case GDK_KEY_Down:
+ case GDK_KEY_KP_Down:
+ case GDK_KEY_downarrow:
+ {
+ gint pos;
- case GDK_KEY_Down:
- case GDK_KEY_KP_Down:
- case GDK_KEY_downarrow:
- {
- const gchar *val;
+ if (history_pos == -1)
+ return TRUE;
- if (history_pos == -1)
- return TRUE;
+ pos = history_pos + 1;
+
+ while (pos < history->len)
+ {
+ if (g_str_has_prefix(history->pdata[pos], entered_text))
+ break;
+ pos++;
+ }
- history_pos--;
+ if (pos >= history->len)
+ pos = -1;
- val = history_pos == -1 ? ":" : g_list_nth_data(history, history_pos);
- gtk_entry_set_text(GTK_ENTRY(entry), val);
- gtk_editable_set_position(GTK_EDITABLE(entry), strlen(val));
+ set_prompt_text(pos == -1 ? "" : history->pdata[pos]);
+ history_pos = pos;
+
+ return TRUE;
+ }
+
+ case GDK_KEY_Home:
+ gtk_editable_set_position(GTK_EDITABLE(entry), 1);
+ return TRUE;
+ case GDK_KEY_End:
+ gtk_editable_set_position(GTK_EDITABLE(entry), strlen(text));
+ return TRUE;
+ }
+ }
+ else if ((event->state & modif_mask) == GDK_CONTROL_MASK)
+ {
+ switch (event->keyval)
+ {
+ case GDK_KEY_c:
+ close_prompt();
+ return TRUE;
- return TRUE;
+ case GDK_KEY_b:
+ gtk_editable_set_position(GTK_EDITABLE(entry), 1);
+ return TRUE;
+ case GDK_KEY_e:
+ gtk_editable_set_position(GTK_EDITABLE(entry), strlen(text));
+ return TRUE;
}
}
@@ -129,6 +198,11 @@ static void on_entry_text_notify(GObject *object, GParamSpec *pspec, gpointer du
if (cmd == NULL || strlen(cmd) == 0)
close_prompt();
+ else if (!ignore_change)
+ {
+ g_free(entered_text);
+ entered_text = g_strdup(cmd + 1);
+ }
}
@@ -144,7 +218,8 @@ void ex_prompt_init(GtkWidget *parent_window, CmdContext *c)
ctx = c;
- history = NULL;
+ cmd_history = g_ptr_array_new_with_free_func(g_free);
+ search_history = g_ptr_array_new_with_free_func(g_free);
/* prompt */
prompt = g_object_new(GTK_TYPE_WINDOW,
@@ -188,6 +263,9 @@ static void position_prompt(void)
void ex_prompt_show(const gchar *val)
{
history_pos = -1;
+ entered_text = g_strdup(val + 1);
+ cmd_first_char = val[0];
+ history = cmd_first_char == ':' ? cmd_history : search_history;
gtk_widget_show(prompt);
position_prompt();
gtk_entry_set_text(GTK_ENTRY(entry), val);
@@ -198,5 +276,6 @@ void ex_prompt_show(const gchar *val)
void ex_prompt_cleanup(void)
{
gtk_widget_destroy(prompt);
- g_list_free_full(history, g_free);
+ g_ptr_array_free(cmd_history, TRUE);
+ g_ptr_array_free(search_history, TRUE);
}
--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).
More information about the Plugins-Commits
mailing list