From d055308b89c925224661fb54e8a4cf73349f1272 Mon Sep 17 00:00:00 2001 From: Daniel Carl Date: Sun, 28 Apr 2013 14:35:27 +0200 Subject: [PATCH] Allow multiple placeholder in shortcuts. The single previous %s placeholder for url shortcuts is now removed by placeholders $0-$9 that make vimb browser more usable and the shortcut system more flexible. The $0 placeholder will be removed by all query parameter. So the previous search engine feature can be build up with this new shortcut feature. For example use 'dl=https://duckduckgo.com/lite/?q=$0' to define a shortcut for the great duckduckgo search engine. --- doc/vimb.1.txt | 26 +++++++++++-------- src/config.h | 4 +-- src/setting.c | 3 --- src/shortcut.c | 69 ++++++++++++++++++++++++++++++++++++++------------ src/util.c | 22 ++++++++-------- src/util.h | 2 +- 6 files changed, 82 insertions(+), 44 deletions(-) diff --git a/doc/vimb.1.txt b/doc/vimb.1.txt index 2ceffd6..511d53c 100644 --- a/doc/vimb.1.txt +++ b/doc/vimb.1.txt @@ -251,26 +251,32 @@ Yank the current url to the primary and secondary clipboard. .B yank-selection Yank the selected text into the primary and secondary clipboard. .SS Shortcuts -Shortcuts allows to open URL build up from a named tamplate with additional -parameters. If a sortcut named 'dd' is defined, you can use it with `:open dd +Shortcuts allows to open URL build up from a named template with additional +parameters. If a shortcut named 'dd' is defined, you can use it with `:open dd list of parameters' to open the generated URL. -Shortcuts are a good to use searchengines where the URL is nearly the same but -a single parameter is user diefined. +Shortcuts are a good to use with search engines where the URL is nearly the +same but a single parameter is user defined. .TP .BI "shortcut-add " "SHORTCUT" "=" "URI" -Adds a shortcut with the \fISHORTCUT\fP and search \fIURI\fP. The uri must -not contain more than one '%s' placeholder. +Adds a shortcut with the \fISHORTCUT\fP and search \fIURI\fP. The \fIURI\fP +can contain multiple placeholders $0-$9 that will be filled by the parameters +given when the shortcut is called. The $0 placeholder will be filled with all +given parameters (this is useful for search engines), all other placeholders $1 +to $9 will be replaced by the numbered argument. -Example: shortcut-add dl=https://duckduckgo.com/lite/?q=%s +Example 1: shortcut-add dl=https://duckduckgo.com/lite/?q=$0 to setup a +search engine. Can be called by `:open dl my search phrase'. + +Example 2: shortcut-add gh=https://github.com/$1/$2 to build urls from given +parameters. Can be called `:open gh fanglingsu vimb'. .TP .BI "shortcut-remove " "SHORTCUT" Remove the search engine to the given \fISHORTCUT\fP. .TP .BI "shortcut-default " "SHORTCUT" -Set the search engine for given \fISHORTCUT\fP as the default search engine. -It doesn't metter if the \fISHORTCUT\fP is already in use or not to be able to -set the default search engine. +Set the shortcut for given \fISHORTCUT\fP as the default. It doesn't matter if +the \fISHORTCUT\fP is already in use or not to be able to set it. .SS Configuration .TP .BI "set " VAR = VALUE diff --git a/src/config.h b/src/config.h index 838ffff..2c5ec29 100644 --- a/src/config.h +++ b/src/config.h @@ -92,8 +92,8 @@ const char *default_config[] = { "cmap =hist-prev", "cmap =hist-next", "imap =editor", - "shortcut-add dl=https://duckduckgo.com/lite/?q=%s", - "shortcut-add dd=https://duckduckgo.com/?q=%s", + "shortcut-add dl=https://duckduckgo.com/lite/?q=$0", + "shortcut-add dd=https://duckduckgo.com/?q=$0", "shortcut-default dl", "set images=on", "set cursivfont=serif", diff --git a/src/setting.c b/src/setting.c index 671470d..bc3be88 100644 --- a/src/setting.c +++ b/src/setting.c @@ -702,9 +702,6 @@ static gboolean editor_command(const Setting *s, const SettingType type) return true; } - if (!util_valid_format_string(s->arg.s, 's', 1)) { - return false; - } OVERWRITE_STRING(vb.config.editor_command, s->arg.s); return true; diff --git a/src/shortcut.c b/src/shortcut.c index 6df33c2..7d53b1a 100644 --- a/src/shortcut.c +++ b/src/shortcut.c @@ -26,6 +26,7 @@ extern VbCore vb; static GHashTable *shortcuts = NULL; static char *default_key = NULL; +static int get_max_placeholder(const char *str); static const char *shortcut_lookup(const char *string, const char **query); @@ -43,16 +44,7 @@ void shortcut_cleanup(void) gboolean shortcut_add(const char *key, const char *uri) { - char *sc_key, *sc_uri; - /* validate if the uri contains only one %s sequence */ - if (!util_valid_format_string(uri, 's', 1)) { - return false; - } - - sc_key = g_strdup(key); - sc_uri = g_strdup(uri); - - g_hash_table_insert(shortcuts, sc_key, sc_uri); + g_hash_table_insert(shortcuts, g_strdup(key), g_strdup(uri)); return true; } @@ -78,17 +70,62 @@ gboolean shortcut_set_default(const char *key) char *shortcut_get_uri(const char *string) { const char *tmpl, *query = NULL; - if ((tmpl = shortcut_lookup(string, &query))) { - char *qs, *uri; - qs = soup_uri_encode(query, "&"); - uri = g_strdup_printf(tmpl, qs); - g_free(qs); + tmpl = shortcut_lookup(string, &query); + if (!tmpl) { + return NULL; + } + char *qs, *uri, **parts, ph[3] = "$0"; + unsigned int len; + + /* replace $0 with all parameters */ + qs = soup_uri_encode(query, "&"); + uri = util_str_replace(ph, qs, tmpl); + g_free(qs); + + int max = get_max_placeholder(tmpl); + /* skip if no placeholders found */ + if (max < 0) { return uri; } - return NULL; + /* split the parameters */ + parts = g_strsplit(query, " ", max + 1); + len = g_strv_length(parts); + + for (unsigned int n = 0; n < len; n++) { + char *new; + ph[1] = n + '1'; + qs = soup_uri_encode(parts[n], "&"); + new = util_str_replace(ph, qs, uri); + g_free(qs); + g_free(uri); + uri = new; + } + g_strfreev(parts); + + return uri; +} + +/** + * Retrieves th highest placesholder number used in given string. + * If no placeholder is found -1 is returned. + */ +static int get_max_placeholder(const char *str) +{ + int n, res; + + for (n = 0, res = -1; *str; str++) { + if (*str == '$') { + n = *(++str) - '0'; + if (0 <= n && n <= 9 && n > res) { + res = n; + } + } + } + + return res; } /** diff --git a/src/util.c b/src/util.c index ba5af22..7ff7b76 100644 --- a/src/util.c +++ b/src/util.c @@ -121,22 +121,20 @@ next: } /** - * Checks if given printf style format string is valid. That means that it - * contains only one defined placeholder given as char. + * Replaces appearances of search in string by given replace. + * Returne a new allocated string of search was found. */ -gboolean util_valid_format_string(const char *format, char type, unsigned int count) +char *util_str_replace(const char* search, const char* replace, const char* string) { - unsigned int c; - for (c = 0; *format; format++) { - if (*format == '%') { - format++; - if (*format == type) { - c++; - } - } + if (!string) { + return NULL; } - return c == count; + char **buf = g_strsplit(string, search, -1); + char *ret = g_strjoinv(replace, buf); + g_strfreev(buf); + + return ret; } /** diff --git a/src/util.h b/src/util.h index 8255b30..804832e 100644 --- a/src/util.h +++ b/src/util.h @@ -30,7 +30,7 @@ void util_create_file_if_not_exists(const char* filename); char* util_get_file_contents(const char* filename, gsize* length); char** util_get_lines(const char* filename); char* util_strcasestr(const char* haystack, const char* needle); -gboolean util_valid_format_string(const char *format, char type, unsigned int count); +char *util_str_replace(const char* search, const char* replace, const char* string); gboolean util_create_tmp_file(const char *content, char **file); #endif /* end of include guard: _UTIL_H */ -- 2.20.1