summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/arg-help.txt4
-rw-r--r--src/app.c51
-rw-r--r--src/app.h3
-rw-r--r--src/gmutil.c17
-rw-r--r--src/gmutil.h2
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
13Options that control a running instance of Lagrange: 17Options that control a running instance of Lagrange:
diff --git a/src/app.c b/src/app.c
index e0fe66df..e22ee494 100644
--- a/src/app.c
+++ b/src/app.c
@@ -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
602static 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
602static void init_App_(iApp *d, int argc, char **argv) { 614static 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");
diff --git a/src/app.h b/src/app.h
index 0fb6be29..918cd396 100644
--- a/src/app.h
+++ b/src/app.h
@@ -42,7 +42,8 @@ iDeclareType(Visited)
42iDeclareType(Window) 42iDeclareType(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
47enum iAppDeviceType { 48enum 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
265static iBool isSupportedUrlScheme_Rangecc_(iRangecc scheme) { 265iBool 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
278iBool 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 *);
110iRangecc urlRoot_String (const iString *); 110iRangecc urlRoot_String (const iString *);
111const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); 111const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative);
112iBool isLikelyUrl_String (const iString *); 112iBool isLikelyUrl_String (const iString *);
113iBool isKnownScheme_Rangecc (iRangecc scheme); /* any URI scheme */
114iBool isKnownUrlScheme_Rangecc(iRangecc scheme); /* URL schemes only */
113void punyEncodeDomain_Rangecc(iRangecc domain, iString *encoded_out); 115void punyEncodeDomain_Rangecc(iRangecc domain, iString *encoded_out);
114void punyEncodeUrlHost_String(iString *absoluteUrl); 116void punyEncodeUrlHost_String(iString *absoluteUrl);
115void stripDefaultUrlPort_String(iString *); 117void stripDefaultUrlPort_String(iString *);