summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/vimb.17
-rw-r--r--src/shortcut.c56
-rw-r--r--tests/test-shortcut.c42
3 files changed, 93 insertions, 12 deletions
diff --git a/doc/vimb.1 b/doc/vimb.1
index bfd35ea..83dbc8b 100644
--- a/doc/vimb.1
+++ b/doc/vimb.1
@@ -487,12 +487,19 @@ given when the shortcut is called. The parameters given when the shortcut is
called will be split into as many parameters like the highest used
placeholder.
+To use spaces within the parameters, the parameters can be grouped by
+surrounding them with single- or double quotes like shown in example shortcut
+`map'.
+
.RS
Examples:
.IP ":shortcut-add dl=https://duckduckgo.com/lite/?q=$0"
to setup a search engine. Can be called by `:open dl my search phrase'.
.IP ":shortcut-add gh=https://github.com/$0/$1"
to build URIs from given parameters. Can be called `:open gh fanglingsu vimb'.
+.IP ":shortcut-add map=https://maps.google.com/maps?saddr=$0&daddr=$1"
+to search for a route, all but the last parameter must be quoted if they
+contain spaces like `:open map "city hall, London" railway station, London'
.RE
.TP
.BI ":shortcut-remove " "SHORTCUT"
diff --git a/src/shortcut.c b/src/shortcut.c
index 240b0b5..94990cd 100644
--- a/src/shortcut.c
+++ b/src/shortcut.c
@@ -70,36 +70,68 @@ gboolean shortcut_set_default(const char *key)
char *shortcut_get_uri(const char *string)
{
const char *tmpl, *query = NULL;
- char *uri, **parts, ph[3] = "$0";
- unsigned int len;
- int max;
+ char *uri, **argv, *quoted_param, ph[3] = "$0";
+ int i, max, argc;
+ GError *error = NULL;
tmpl = shortcut_lookup(string, &query);
if (!tmpl) {
return NULL;
}
- uri = g_strdup(tmpl);
max = get_max_placeholder(tmpl);
+ /* if there are only $0 placeholders we don't need to split the parameters */
+ if (max == 0) {
+ quoted_param = soup_uri_encode(query, "&");
+ uri = util_str_replace(ph, quoted_param, tmpl);
+ g_free(quoted_param);
+
+ return uri;
+ }
+
+ uri = g_strdup(tmpl);
+
/* skip if no placeholders found */
if (max < 0) {
return uri;
}
- /* split the parameters */
- parts = g_strsplit(query, " ", max + 1);
- len = g_strv_length(parts);
+ /* for multiple placeholders - split the parameters */
+ if (!g_shell_parse_argv(query, &argc, &argv, &error)) {
+#ifndef TESTLIB
+ vb_echo(VB_MSG_ERROR, true, error->message);
+#endif
+ g_clear_error(&error);
+
+ /* us the shortcut template uri like it is */
+ return uri;
+ }
+
+ for (i = 0; i < argc; i++) {
+ char *new, *qs, *combined;
+
+ ph[1] = i + '0';
+ /* if we reached the last placeholder put all other tokens into it */
+ if (i >= max) {
+ combined = g_strjoinv(" ", &(argv[i]));
+ qs = soup_uri_encode(combined, "&");
+ new = util_str_replace(ph, qs, uri);
+ g_free(combined);
+ g_free(qs);
+ g_free(uri);
+ uri = new;
+
+ /* we are done - break the loop */
+ break;
+ }
- for (unsigned int n = 0; n < len; n++) {
- char *new, *qs;
- ph[1] = n + '0';
- qs = soup_uri_encode(parts[n], "&");
+ qs = soup_uri_encode(argv[i], "&");
new = util_str_replace(ph, qs, uri);
g_free(qs);
g_free(uri);
uri = new;
}
- g_strfreev(parts);
+ g_strfreev(argv);
return uri;
}
diff --git a/tests/test-shortcut.c b/tests/test-shortcut.c
index 159c9a4..6733a06 100644
--- a/tests/test-shortcut.c
+++ b/tests/test-shortcut.c
@@ -28,6 +28,16 @@ static void test_shortcut_single(void)
uri = shortcut_get_uri("_vimb1_ zero one");
g_assert_cmpstr(uri, ==, "only-zero:zero%20one");
g_free(uri);
+
+ /* don't fail on unmatches quotes if there are only $0 placeholders */
+ uri = shortcut_get_uri("_vimb1_ 'unmatched quote");
+ g_assert_cmpstr(uri, ==, "only-zero:'unmatched%20quote");
+ g_free(uri);
+
+ /* check if all placeholders $0 are replaces */
+ uri = shortcut_get_uri("_vimb5_ one two");
+ g_assert_cmpstr(uri, ==, "double-zero:one%20two-one%20two");
+ g_free(uri);
}
static void test_shortcut_default(void)
@@ -61,6 +71,34 @@ static void test_shortcut_fullrange(void)
g_free(uri);
}
+static void test_shortcut_shell_param(void)
+{
+ char *uri;
+
+ /* single quotes */
+ uri = shortcut_get_uri("_vimb6_ 'rail station' 'city hall'");
+ g_assert_cmpstr(uri, ==, "shell:rail%20station-city%20hall");
+ g_free(uri);
+
+ /* double quotes */
+ uri = shortcut_get_uri("_vimb6_ \"rail station\" city hall");
+ g_assert_cmpstr(uri, ==, "shell:rail%20station-city%20hall");
+ g_free(uri);
+}
+
+static void test_shortcut_shell_param_invalid(void)
+{
+ char *uri;
+ /* if parsing fails we expect the shortcut template to be returned */
+ uri = shortcut_get_uri("_vimb6_ 'rail station' 'city hall");
+ g_assert_cmpstr(uri, ==, "shell:$0-$1");
+ g_free(uri);
+
+ uri = shortcut_get_uri("_vimb6_ can't parse");
+ g_assert_cmpstr(uri, ==, "shell:$0-$1");
+ g_free(uri);
+}
+
static void test_shortcut_remove(void)
{
char *uri;
@@ -81,6 +119,8 @@ int main(int argc, char *argv[])
g_assert_true(shortcut_add("_vimb2_", "default:$0-$2"));
g_assert_true(shortcut_add("_vimb3_", "fullrange:$0-$1-$9"));
g_assert_true(shortcut_add("_vimb4_", "for-remove:$0"));
+ g_assert_true(shortcut_add("_vimb5_", "double-zero:$0-$0"));
+ g_assert_true(shortcut_add("_vimb6_", "shell:$0-$1"));
g_assert_true(shortcut_set_default("_vimb2_"));
g_test_init(&argc, &argv, NULL);
@@ -89,6 +129,8 @@ int main(int argc, char *argv[])
g_test_add_func("/test-shortcut/get_uri/default", test_shortcut_default);
g_test_add_func("/test-shortcut/get_uri/keep-unmatched", test_shortcut_keep_unmatched);
g_test_add_func("/test-shortcut/get_uri/fullrange", test_shortcut_fullrange);
+ g_test_add_func("/test-shortcut/get_uri/shell-param", test_shortcut_shell_param);
+ g_test_add_func("/test-shortcut/get_uri/shell-param-invalid", test_shortcut_shell_param_invalid);
g_test_add_func("/test-shortcut/remove", test_shortcut_remove);
result = g_test_run();