diff options
author | Daniel Carl <danielcarl@gmx.de> | 2013-12-21 18:38:32 +0100 |
---|---|---|
committer | Daniel Carl <danielcarl@gmx.de> | 2013-12-21 18:59:12 +0100 |
commit | c7d799acff0be0dee950056e41f6058cd31a46cb (patch) | |
tree | f22c4cc7ffbf347e23ac8a192d635746153e7348 /src/hints.c | |
parent | d2dd2cb53eb31c4da180d917ca257a64ae40c25e (diff) |
Added extended hint modes g;X (#53).
These hint modes are taken from pentadactyl and works like the other hint
modes, accept that the hints are not cleared after a hint was fired using a
numeric filter.
Diffstat (limited to 'src/hints.c')
-rw-r--r-- | src/hints.c | 127 |
1 files changed, 98 insertions, 29 deletions
diff --git a/src/hints.c b/src/hints.c index 0600ef6..792cee7 100644 --- a/src/hints.c +++ b/src/hints.c @@ -34,8 +34,10 @@ #define HINT_FILE "hints.js" static struct { - guint num; - char prompt[3]; + guint num; /* olds the numeric filter for hints typed by the user */ + char mode; /* mode identifying char - that last char of the hint prompt */ + int promptlen; /* lenfth of the hint prompt chars 2 or 3 */ + gboolean gmode; /* indicate if the hints g mode is used */ } hints; extern VbCore vb; @@ -116,15 +118,9 @@ void hints_create(const char *input) { char *js = NULL; - /* unset number filter - this is required to remove the last char from - * inputbox on backspace also if there was used a number filter prior */ - hints.num = 0; - - /* if there is no input or the input is no valid hint mode prefix, clear - * possible previous hint mode */ - if (!input || strlen(input) < 2) { - /* stop hint mode - we switch direct to normal mode that will clear - * the hinting and additional will remove focus from input box */ + /* check if the input contains a valid hinting prompt */ + if (!hints_parse_prompt(input, &hints.mode, &hints.gmode)) { + /* if input is not valid, clear possible previous hint mode */ if (vb.mode->flags & FLAG_HINTING) { mode_enter('n'); } @@ -134,10 +130,12 @@ void hints_create(const char *input) if (!(vb.mode->flags & FLAG_HINTING)) { vb.mode->flags |= FLAG_HINTING; - /* save the prefix of the hinting mode for later use */ - strncpy(hints.prompt, input, 2); + /* unset number filter - this is required to remove the last char from + * inputbox on backspace also if there was used a number filter prior */ + hints.num = 0; + hints.promptlen = hints.gmode ? 3 : 2; - js = g_strdup_printf("%s.init('%s', %d);", HINT_VAR, hints.prompt, MAXIMUM_HINTS); + js = g_strdup_printf("%s.init('%c', %d);", HINT_VAR, hints.mode, MAXIMUM_HINTS); run_script(js); g_free(js); @@ -147,7 +145,7 @@ void hints_create(const char *input) return; } - js = g_strdup_printf("%s.filter('%s');", HINT_VAR, *(input + 2) ? input + 2 : ""); + js = g_strdup_printf("%s.filter('%s');", HINT_VAR, *(input + hints.promptlen) ? input + hints.promptlen : ""); run_script(js); g_free(js); } @@ -186,9 +184,68 @@ void hints_follow_link(const gboolean back, int count) g_free(js); } +/** + * Checks if the given hint prompt belong to a known and valid hints mode and + * parses the mode and is_gmode into given pointers. + * + * The given prompt sting may also contain additional chars after the prompt. + * + * @prompt: String to be parsed as prompt. The Prompt can be followed by + * additional characters. + * @mode: Pointer to char that will be filled with mode char if prompt was + * valid and given pointer is not NULL. + * @is_gmode: Pointer to gboolean to be filled with the flag to indicate gmode + * hinting. + */ +gboolean hints_parse_prompt(const char *prompt, char *mode, gboolean *is_gmode) +{ + gboolean res; + char pmode = '\0'; +#ifdef FEATURE_QUEUE + static char *modes = "eiIoOpPstTy"; + static char *g_modes = "IpPsty"; +#else + static char *modes = "eiIoOstTy"; + static char *g_modes = "Isty"; +#endif + + if (!prompt) { + return false; + } + + /* get the mode identifying char from prompt */ + if (*prompt == ';') { + pmode = prompt[1]; + } else if (*prompt == 'g' && strlen(prompt) >= 3) { + /* get mode for g;X hint modes */ + pmode = prompt[2]; + } + + /* no mode found in prompt */ + if (!pmode) { + return false; + } + + res = *prompt == 'g' + ? strchr(g_modes, pmode) != NULL + : strchr(modes, pmode) != NULL; + + /* fill pointer only if the promt was valid */ + if (res) { + if (mode != NULL) { + *mode = pmode; + } + if (is_gmode != NULL) { + *is_gmode = *prompt == 'g'; + } + } + + return res; +} + static void run_script(char *js) { - char mode, *value = NULL; + char *value = NULL; gboolean success = vb_eval_script( webkit_web_view_get_main_frame(vb.gui.webview), js, HINT_FILE, &value @@ -202,39 +259,51 @@ static void run_script(char *js) return; } - /* check the second char of the prompt ';X' */ - mode = hints.prompt[1]; - if (!strncmp(value, "OVER:", 5)) { g_signal_emit_by_name( vb.gui.webview, "hovering-over-link", NULL, *(value + 5) == '\0' ? NULL : (value + 5) ); } else if (!strncmp(value, "DONE:", 5)) { - mode_enter('n'); + if (hints.gmode) { + /* if g mode is used reset number filter and keep in hint mode */ + hints.num = 0; + hints_update(hints.num); + } else { + mode_enter('n'); + } } else if (!strncmp(value, "INSERT:", 7)) { mode_enter('i'); - if (mode == 'e') { + if (hints.mode == 'e') { input_open_editor(); } } else if (!strncmp(value, "DATA:", 5)) { - /* switch first to normal mode - else we would clear the inputbox on - * switching mode also if we want to show yanked data */ - mode_enter('n'); + if (hints.gmode) { + /* if g mode is used reset number filter and keep in hint mode */ + hints.num = 0; + hints_update(hints.num); + } else { + /* switch first to normal mode - else we would clear the inputbox + * on switching mode also if we want to show yanked data */ + mode_enter('n'); + } + char *v = (value + 5); Arg a = {0}; - switch (mode) { + switch (hints.mode) { /* used if images should be opened */ case 'i': case 'I': a.s = v; - a.i = (mode == 'I') ? VB_TARGET_NEW : VB_TARGET_CURRENT; + a.i = (hints.mode == 'I') ? VB_TARGET_NEW : VB_TARGET_CURRENT; vb_load_uri(&a); break; case 'O': case 'T': - vb_echo(VB_MSG_NORMAL, false, "%s %s", (mode == 'T') ? ":tabopen" : ":open", v); - mode_enter('c'); + vb_echo(VB_MSG_NORMAL, false, "%s %s", (hints.mode == 'T') ? ":tabopen" : ":open", v); + if (!hints.gmode) { + mode_enter('c'); + } break; case 's': @@ -253,7 +322,7 @@ static void run_script(char *js) case 'p': case 'P': a.s = v; - a.i = (mode == 'P') ? COMMAND_QUEUE_UNSHIFT : COMMAND_QUEUE_PUSH; + a.i = (hints.mode == 'P') ? COMMAND_QUEUE_UNSHIFT : COMMAND_QUEUE_PUSH; command_queue(&a); break; #endif |