From 59e5b689070af33f9597ee85f9d046e850aa26e8 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Fri, 1 Jun 2012 16:55:52 -0400 Subject: Parse keybound commands for if they begin with a ':'. If they do, don't try to execute them, but instead open a prompt with that current command. Can be used to create custom prompts, and should fix FS#233. This change also adds the ability to replace strings in keybound prompts. So far the only string replacement is which is replaced by the current tab's uri. This also kills the old prompt* commands as they only existed so they could be bound to a key. However with the addition of the substitution, these are no longer necessary. Document these changes in the manpage. --- settings.c | 8 +++--- xombrero.1 | 42 ++++++++++++++++++---------- xombrero.c | 88 +++++++++++++++++++++++++++++++---------------------------- xombrero.conf | 8 +++--- 4 files changed, 81 insertions(+), 65 deletions(-) diff --git a/settings.c b/settings.c index 633f3bd..6783aa1 100644 --- a/settings.c +++ b/settings.c @@ -1066,10 +1066,10 @@ struct key_binding keys[] = { { "focusreset", CTRL, 1, GDK_0 }, /* command aliases (handy when -S flag is used) */ - { "promptopen", 0, 1, GDK_F9 }, - { "promptopencurrent", 0, 1, GDK_F10 }, - { "prompttabnew", 0, 1, GDK_F11 }, - { "prompttabnewcurrent",0, 1, GDK_F12 }, + { ":open ", 0, 1, GDK_F9 }, + { ":open ", 0, 1, GDK_F10 }, + { ":tabnew ", 0, 1, GDK_F11 }, + { ":tabnew ", 0, 1, GDK_F12 }, }; void diff --git a/xombrero.1 b/xombrero.1 index 69154ab..da50668 100644 --- a/xombrero.1 +++ b/xombrero.1 @@ -135,7 +135,7 @@ Each keyboard shortcut requires exactly one entry in the configuration file. A shortcut can have multiple entries in the configuration file. The format of the keybinding entry is as follows: .Pp -.D1 keybinding = action,(!)keystroke(s) +.D1 keybinding = (:)action,(!)keystroke(s) .Pp For example, "keybinding = tabnew,C-t" where .Cm tabnew @@ -143,6 +143,17 @@ is the action and .Cm C-t are the keystrokes. +.Pp +If the action begins with a colon, the action will be entered into the +command prompt instead of being executed. +For example, "keybinding = :session open ,M-s" will open the command +prompt with ":open session " entered when using the M-s keybinding. +.Pp +Keybindings which open the command prompt may also include the string +, which will be replaced by the current tab's URI. +For example, "keybinding = :open ,F10" will open the command +prompt with replaced with the current URI. +.Pp GTK has some default keybindings for manipulating text inside input fields, such as the URI or search entry widget, for example .Cm C-w @@ -205,29 +216,30 @@ Focus on search entry .El .Ss Command Aliases These commands allow the user to map specific actions to specific keys. -It can be useful when the -.Fl S -option is used. .Pp .Bl -tag -width Ds -offset indent -compact .It Cm F1 -Alias for ":help" +Alias for "help" .It Cm F2 -Alias for ":proxy toggle" +Alias for "proxy toggle" .It Cm F4 -Alias for ":toplevel toggle" +Alias for "toplevel toggle" +.El +.Ss Prompt Aliases +These commands allow the user to open a prompt. +These can be useful when the +.Fl S +option is used. +.Pp +.Bl -tag -width Ds -offset indent -compact .It Cm F9 -Alias for ":open" -.Pq Cm promptopen +Alias for ":open " .It Cm F10 -Alias for ":open current-uri" -.Pq Cm promptopencurrent +Alias for ":open " .It Cm F11 -Alias for ":tabnew" -.Pq Cm prompttabnew +Alias for ":tabnew " .It Cm F12 -Alias for ":tabnew current-uri" -.Pq Cm prompttabnewcurrent +Alias for ":tabnew " .El .Ss Navigation Commands These commands allow the user to navigate web pages and, diff --git a/xombrero.c b/xombrero.c index 92c9d9d..4b16a8d 100644 --- a/xombrero.c +++ b/xombrero.c @@ -167,11 +167,6 @@ TAILQ_HEAD(command_list, command_entry); #define XT_ZOOM_OUT (-2) #define XT_ZOOM_NORMAL (100) -#define XT_CMD_OPEN (0) -#define XT_CMD_OPEN_CURRENT (1) -#define XT_CMD_TABNEW (2) -#define XT_CMD_TABNEW_CURRENT (3) - #define XT_STATUS_NOTHING (0) #define XT_STATUS_LINK (1) #define XT_STATUS_URI (2) @@ -2615,14 +2610,21 @@ movetab(struct tab *t, struct karg *args) int cmd_prefix = 0; +struct prompt_sub { + const char *s; + const char *(*f)(struct tab *); +} subs[] = { + { "", get_uri }, +}; int command(struct tab *t, struct karg *args) { - char *s = NULL, *ss = NULL; - gchar *text, *base; - const gchar *uri; struct karg a; + int i; + char *s = NULL, *sp = NULL, *sl = NULL; + gchar **sv; + gchar *text, *base; if (t == NULL || args == NULL) { show_oops(NULL, "command invalid parameters"); @@ -2637,13 +2639,31 @@ command(struct tab *t, struct karg *args) s = "?"; break; case ':': - if (cmd_prefix == 0) - s = ":"; - else { + if (cmd_prefix == 0) { + if (args->s != NULL && strlen(args->s) != 0) { + ss = g_strdup_printf(":%s", args->s); + s = sp; + } else + s = ":"; + } else { ss = g_strdup_printf(":%d", cmd_prefix); - s = ss; + s = sp; cmd_prefix = 0; } + sl = g_strdup(s); + if (sp) { + g_free(sp); + sp = NULL; + } + s = sl; + for (i = 0; i < sizeof subs / sizeof (struct prompt_sub); ++i) { + sv = g_strsplit(sl, subs[i].s, -1); + if (sl) + g_free(sl); + sl = g_strjoinv(subs[i].f(t), sv); + g_strfreev(sv); + s = sl; + } break; case '.': t->mode = XT_MODE_HINT; @@ -2659,23 +2679,6 @@ command(struct tab *t, struct karg *args) hint(t, &a); s = ","; break; - case XT_CMD_OPEN: - s = ":open "; - break; - case XT_CMD_TABNEW: - s = ":tabnew "; - break; - case XT_CMD_OPEN_CURRENT: - s = ":open "; - /* FALL THROUGH */ - case XT_CMD_TABNEW_CURRENT: - if (!s) /* FALL THROUGH? */ - s = ":tabnew "; - if ((uri = get_uri(t)) != NULL) { - ss = g_strdup_printf("%s%s", s, uri); - s = ss; - } - break; default: show_oops(t, "command: invalid opcode %d", args->i); return (XT_CB_PASSTHROUGH); @@ -2695,8 +2698,10 @@ command(struct tab *t, struct karg *args) gtk_widget_grab_focus(GTK_WIDGET(t->cmd)); gtk_editable_set_position(GTK_EDITABLE(t->cmd), -1); - if (ss) - g_free(ss); + if (sp) + g_free(sp); + if (sl) + g_free(sl); return (XT_CB_HANDLED); } @@ -3193,12 +3198,6 @@ struct cmd { { "encoding", 0, set_encoding, 0, XT_USERARG }, { "loadimages", 0, tabaction, XT_TAB_LOAD_IMAGES, 0 }, - /* command aliases (handy when -S flag is used) */ - { "promptopen", 0, command, XT_CMD_OPEN, 0 }, - { "promptopencurrent", 0, command, XT_CMD_OPEN_CURRENT, 0 }, - { "prompttabnew", 0, command, XT_CMD_TABNEW, 0 }, - { "prompttabnewcurrent",0, command, XT_CMD_TABNEW_CURRENT, 0 }, - /* settings */ { "set", 0, set, 0, XT_SETARG }, @@ -5417,6 +5416,7 @@ done: gboolean handle_keypress(struct tab *t, GdkEventKey *e, int entry) { + struct karg args; struct key_binding *k; /* handle keybindings if buffercmd is empty. @@ -5431,11 +5431,15 @@ handle_keypress(struct tab *t, GdkEventKey *e, int entry) (e->state & CTRL || e->state & MOD1)) return (XT_CB_PASSTHROUGH); - if (k->mask == 0) { - if ((e->state & (CTRL | MOD1)) == 0) + if ((k->mask == 0 && + (e->state & (CTRL | MOD1)) == 0) || + (e->state & k->mask) == k->mask) { + if (k->cmd[0] == ':') { + args.i = ':'; + args.s = &k->cmd[1]; + return command(t, &args); + } else return (cmd_execute(t, k->cmd)); - } else if ((e->state & k->mask) == k->mask) { - return (cmd_execute(t, k->cmd)); } } @@ -7500,7 +7504,7 @@ socket_watcher(GIOChannel *source, GIOCondition condition, gpointer data) if (n <= 0) return (TRUE); - tt = get_current_tab(); + tt = TAILQ_LAST(&tabs, tab_list); cmd_execute(tt, str); return (TRUE); } diff --git a/xombrero.conf b/xombrero.conf index 0bd2878..19b7bdd 100644 --- a/xombrero.conf +++ b/xombrero.conf @@ -298,10 +298,6 @@ # keybinding = searchprevious,N # keybinding = focusaddress,F6 # keybinding = focussearch,F7 -# keybinding = promptopen,F9 -# keybinding = promptopencurrent,F10 -# keybinding = prompttabnew,F11 -# keybinding = prompttabnewcurrent,F12 # keybinding = hinting,f # keybinding = hinting,period # keybinding = hinting_newtab,S-F @@ -360,6 +356,10 @@ # keybinding = focusreset,C-0 # keybinding = editelement,!C-i # keybinding = passthrough,C-z +# keybinding = :open ,F9 +# keybinding = :open ,F10 +# keybinding = :tabopen ,F11 +# keybinding = :tabopen ,F12 # parse the contents of another configuration file # include_config = ~/.xombrero_alternate.conf -- cgit 1.4.1-2-gfad0