diff options
-rw-r--r-- | res/arg-help.txt | 4 | ||||
-rw-r--r-- | src/app.c | 51 | ||||
-rw-r--r-- | src/app.h | 3 | ||||
-rw-r--r-- | src/gmutil.c | 17 | ||||
-rw-r--r-- | src/gmutil.h | 2 |
5 files changed, 67 insertions, 10 deletions
diff --git a/res/arg-help.txt b/res/arg-help.txt index 7fe393c1..e87881d3 100644 --- a/res/arg-help.txt +++ b/res/arg-help.txt | |||
@@ -8,6 +8,10 @@ General options: | |||
8 | -E, --echo Print all internal app events to stdout. | 8 | -E, --echo Print all internal app events to stdout. |
9 | --help Print these instructions. | 9 | --help Print these instructions. |
10 | --sw Disable hardware accelerated rendering. | 10 | --sw Disable hardware accelerated rendering. |
11 | -u, --url-or-search URL | text | ||
12 | Open a URL, or make a search query with given text. | ||
13 | This only works if the search query URL has been | ||
14 | configured. | ||
11 | -V, --version Print the application version. | 15 | -V, --version Print the application version. |
12 | 16 | ||
13 | Options that control a running instance of Lagrange: | 17 | Options that control a running instance of Lagrange: |
@@ -599,6 +599,18 @@ static void communicateWithRunningInstance_App_(iApp *d, iProcessId instance, | |||
599 | } | 599 | } |
600 | #endif /* defined (LAGRANGE_ENABLE_IPC) */ | 600 | #endif /* defined (LAGRANGE_ENABLE_IPC) */ |
601 | 601 | ||
602 | static iBool hasCommandLineOpenableScheme_(const iRangecc uri) { | ||
603 | static const char *schemes[] = { | ||
604 | "gemini:", "gopher:", "finger:", "file:", "data:", "about:" | ||
605 | }; | ||
606 | iForIndices(i, schemes) { | ||
607 | if (startsWithCase_Rangecc(uri, schemes[i])) { | ||
608 | return iTrue; | ||
609 | } | ||
610 | } | ||
611 | return iFalse; | ||
612 | } | ||
613 | |||
602 | static void init_App_(iApp *d, int argc, char **argv) { | 614 | static void init_App_(iApp *d, int argc, char **argv) { |
603 | init_CommandLine(&d->args, argc, argv); | 615 | init_CommandLine(&d->args, argc, argv); |
604 | /* Where was the app started from? We ask SDL first because the command line alone is | 616 | /* Where was the app started from? We ask SDL first because the command line alone is |
@@ -633,6 +645,7 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
633 | defineValues_CommandLine(&d->args, "go-home", 0); | 645 | defineValues_CommandLine(&d->args, "go-home", 0); |
634 | defineValues_CommandLine(&d->args, "help", 0); | 646 | defineValues_CommandLine(&d->args, "help", 0); |
635 | defineValues_CommandLine(&d->args, listTabUrls_CommandLineOption, 0); | 647 | defineValues_CommandLine(&d->args, listTabUrls_CommandLineOption, 0); |
648 | defineValues_CommandLine(&d->args, openUrlOrSearch_CommandLineOption, 1); | ||
636 | defineValuesN_CommandLine(&d->args, "new-tab", 0, 1); | 649 | defineValuesN_CommandLine(&d->args, "new-tab", 0, 1); |
637 | defineValues_CommandLine(&d->args, "sw", 0); | 650 | defineValues_CommandLine(&d->args, "sw", 0); |
638 | defineValues_CommandLine(&d->args, "version;V", 0); | 651 | defineValues_CommandLine(&d->args, "version;V", 0); |
@@ -652,14 +665,11 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
652 | const iRangecc arg = i.entry; | 665 | const iRangecc arg = i.entry; |
653 | if (i.argType == value_CommandLineArgType) { | 666 | if (i.argType == value_CommandLineArgType) { |
654 | /* URLs and file paths accepted. */ | 667 | /* URLs and file paths accepted. */ |
655 | const iBool isKnownScheme = | 668 | const iBool isOpenable = hasCommandLineOpenableScheme_(arg); |
656 | startsWithCase_Rangecc(arg, "gemini:") || startsWithCase_Rangecc(arg, "gopher:") || | 669 | if (isOpenable || fileExistsCStr_FileInfo(cstr_Rangecc(arg))) { |
657 | startsWithCase_Rangecc(arg, "finger:") || startsWithCase_Rangecc(arg, "file:") || | ||
658 | startsWithCase_Rangecc(arg, "data:") || startsWithCase_Rangecc(arg, "about:"); | ||
659 | if (isKnownScheme || fileExistsCStr_FileInfo(cstr_Rangecc(arg))) { | ||
660 | iString *decUrl = | 670 | iString *decUrl = |
661 | isKnownScheme ? urlDecodeExclude_String(collectNewRange_String(arg), "/?#:") | 671 | isOpenable ? urlDecodeExclude_String(collectNewRange_String(arg), "/?#:") |
662 | : makeFileUrl_String(collectNewRange_String(arg)); | 672 | : makeFileUrl_String(collectNewRange_String(arg)); |
663 | pushBack_StringList(openCmds, | 673 | pushBack_StringList(openCmds, |
664 | collectNewFormat_String( | 674 | collectNewFormat_String( |
665 | "open newtab:1 url:%s", cstr_String(decUrl))); | 675 | "open newtab:1 url:%s", cstr_String(decUrl))); |
@@ -670,6 +680,19 @@ static void init_App_(iApp *d, int argc, char **argv) { | |||
670 | terminate_App_(1); | 680 | terminate_App_(1); |
671 | } | 681 | } |
672 | } | 682 | } |
683 | else if (equal_CommandLineConstIterator(&i, openUrlOrSearch_CommandLineOption)) { | ||
684 | const iCommandLineArg *arg = iClob(argument_CommandLineConstIterator(&i)); | ||
685 | const iString *input = value_CommandLineArg(arg, 0); | ||
686 | if (startsWith_String(input, "//")) { | ||
687 | input = collectNewFormat_String("gemini:%s", cstr_String(input)); | ||
688 | } | ||
689 | if (hasCommandLineOpenableScheme_(range_String(input))) { | ||
690 | input = collect_String(urlDecodeExclude_String(input, "/?#:")); | ||
691 | } | ||
692 | pushBack_StringList( | ||
693 | openCmds, | ||
694 | collectNewFormat_String("search newtab:1 query:%s", cstr_String(input))); | ||
695 | } | ||
673 | else if (!isDefined_CommandLine(&d->args, collectNewRange_String(i.entry))) { | 696 | else if (!isDefined_CommandLine(&d->args, collectNewRange_String(i.entry))) { |
674 | fprintf(stderr, "Unknown option: %s\n", cstr_Rangecc(arg)); | 697 | fprintf(stderr, "Unknown option: %s\n", cstr_Rangecc(arg)); |
675 | terminate_App_(1); | 698 | terminate_App_(1); |
@@ -2126,6 +2149,20 @@ iBool handleCommand_App(const char *cmd) { | |||
2126 | } | 2149 | } |
2127 | return iTrue; | 2150 | return iTrue; |
2128 | } | 2151 | } |
2152 | else if (equal_Command(cmd, "search")) { | ||
2153 | const int newTab = argLabel_Command(cmd, "newtab"); | ||
2154 | const iString *query = collect_String(suffix_Command(cmd, "query")); | ||
2155 | if (!isLikelyUrl_String(query)) { | ||
2156 | const iString *url = searchQueryUrl_App(query); | ||
2157 | if (!isEmpty_String(url)) { | ||
2158 | postCommandf_App("open newtab:%d url:%s", newTab, cstr_String(url)); | ||
2159 | } | ||
2160 | } | ||
2161 | else { | ||
2162 | postCommandf_App("open newtab:%d url:%s", newTab, cstr_String(query)); | ||
2163 | } | ||
2164 | return iTrue; | ||
2165 | } | ||
2129 | else if (equal_Command(cmd, "open")) { | 2166 | else if (equal_Command(cmd, "open")) { |
2130 | iString *url = collectNewCStr_String(suffixPtr_Command(cmd, "url")); | 2167 | iString *url = collectNewCStr_String(suffixPtr_Command(cmd, "url")); |
2131 | const iBool noProxy = argLabel_Command(cmd, "noproxy"); | 2168 | const iBool noProxy = argLabel_Command(cmd, "noproxy"); |
@@ -42,7 +42,8 @@ iDeclareType(Visited) | |||
42 | iDeclareType(Window) | 42 | iDeclareType(Window) |
43 | 43 | ||
44 | /* Command line options strings. */ | 44 | /* Command line options strings. */ |
45 | #define listTabUrls_CommandLineOption "list-tab-urls;L" | 45 | #define listTabUrls_CommandLineOption "list-tab-urls;L" |
46 | #define openUrlOrSearch_CommandLineOption "url-or-search;u" | ||
46 | 47 | ||
47 | enum iAppDeviceType { | 48 | enum iAppDeviceType { |
48 | desktop_AppDeviceType, | 49 | desktop_AppDeviceType, |
diff --git a/src/gmutil.c b/src/gmutil.c index 2c9ba4eb..3ca93901 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -262,7 +262,20 @@ void urlEncodePath_String(iString *d) { | |||
262 | delete_String(encoded); | 262 | delete_String(encoded); |
263 | } | 263 | } |
264 | 264 | ||
265 | static iBool isSupportedUrlScheme_Rangecc_(iRangecc scheme) { | 265 | iBool isKnownScheme_Rangecc(iRangecc scheme) { |
266 | if (isKnownUrlScheme_Rangecc(scheme)) { | ||
267 | return iTrue; | ||
268 | } | ||
269 | static const char *uriSchemes[] = { "about", "data" }; | ||
270 | iForIndices(i, uriSchemes) { | ||
271 | if (equalCase_Rangecc(scheme, uriSchemes[i])) { | ||
272 | return iTrue; | ||
273 | } | ||
274 | } | ||
275 | return iFalse; | ||
276 | } | ||
277 | |||
278 | iBool isKnownUrlScheme_Rangecc(iRangecc scheme) { | ||
266 | static const char *schemes[] = { "gemini", "gopher", "finger", "http", "https", "file" }; | 279 | static const char *schemes[] = { "gemini", "gopher", "finger", "http", "https", "file" }; |
267 | iForIndices(i, schemes) { | 280 | iForIndices(i, schemes) { |
268 | if (equalCase_Rangecc(scheme, schemes[i])) { | 281 | if (equalCase_Rangecc(scheme, schemes[i])) { |
@@ -277,7 +290,7 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat | |||
277 | iUrl rel; | 290 | iUrl rel; |
278 | init_Url(&orig, d); | 291 | init_Url(&orig, d); |
279 | init_Url(&rel, urlMaybeRelative); | 292 | init_Url(&rel, urlMaybeRelative); |
280 | if (!isEmpty_Range(&rel.scheme) && !isSupportedUrlScheme_Rangecc_(rel.scheme) && | 293 | if (!isEmpty_Range(&rel.scheme) && !isKnownUrlScheme_Rangecc(rel.scheme) && |
281 | isEmpty_Range(&rel.host)) { | 294 | isEmpty_Range(&rel.host)) { |
282 | /* Probably not an URL, so we can't make this absolute. */ | 295 | /* Probably not an URL, so we can't make this absolute. */ |
283 | return urlMaybeRelative; | 296 | return urlMaybeRelative; |
diff --git a/src/gmutil.h b/src/gmutil.h index 09d333e7..e7ff7cc5 100644 --- a/src/gmutil.h +++ b/src/gmutil.h | |||
@@ -110,6 +110,8 @@ iRangecc urlUser_String (const iString *); | |||
110 | iRangecc urlRoot_String (const iString *); | 110 | iRangecc urlRoot_String (const iString *); |
111 | const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); | 111 | const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); |
112 | iBool isLikelyUrl_String (const iString *); | 112 | iBool isLikelyUrl_String (const iString *); |
113 | iBool isKnownScheme_Rangecc (iRangecc scheme); /* any URI scheme */ | ||
114 | iBool isKnownUrlScheme_Rangecc(iRangecc scheme); /* URL schemes only */ | ||
113 | void punyEncodeDomain_Rangecc(iRangecc domain, iString *encoded_out); | 115 | void punyEncodeDomain_Rangecc(iRangecc domain, iString *encoded_out); |
114 | void punyEncodeUrlHost_String(iString *absoluteUrl); | 116 | void punyEncodeUrlHost_String(iString *absoluteUrl); |
115 | void stripDefaultUrlPort_String(iString *); | 117 | void stripDefaultUrlPort_String(iString *); |