Repository: qutebrowser/qutebrowser

Issue:
:hint spawn with flags doesn't work
Running `:hint all spawn -v echo` doesn't work because `:hint` tries to interpret `-v`:

```
DEBUG    commands   command:run:489 command called: hint ['all', 'spawn', '-v', 'echo']
ERROR    message    message:error:277 hint: Unrecognized arguments: -v echo
```

However, using `:hint -- all spawn -v echo` doesn't work either for some reason...

```
DEBUG    commands   command:run:489 command called: hint ['all', '--', 'spawn', '-v', 'echo']
[...]
DEBUG    procs      guiprocess:start:134 Starting process.
[...]
ERROR    message    message:error:277 Error while spawning command: The process failed to start.
```

For the first issue: Probably `@cmdutils.register` should have a new argument (`ignore_late_args` or `pass_args` or so?) which passes arguments like `maxsplit=x`, but still splits normally. This would also be useful for `:spawn` and maybe more which actually _need_ splitting (see 6dbdea0).



Discussion:
For the second case, it's trying to run `-v echo`...

As mentioned by @Ambrevar in #795, a workaround is to create a script in your `$PATH` which wraps the thing you want to run:

``` bash
#!/bin/bash
exec foo --blah "$@"
```

Note to self: `:hint links spawn ...` isn't the `:spawn` command - it's a hint mode

This bug makes it impossible to do `hint links spawn --userscript  fooscript {hint-url}`. Not being able to call userscript with `hint links` is considerable. For instance, I wanted to do `hint links spawn --userscript  view_in_mpv {hint-url}`.

A possible workaround/feature for youtube specific issue would be to let the user configure a userscript to be called when opening a certain type of URL. For youtube videos, one could specify `view_in_mpv` userscript. Then, when pressing `F`, the tab would open with video already running in mpv.

Is this idea already part of qutebrowser ?

@sim590 FWIW, I don't see how spawning the `view_in_mpv` userscript with hints makes sense. The whole point of that script is to remove the video from the page, which isn't something which needs to be done when using hints. Why not just `:hint links spawn mpv {hint-url}`?

I've never thought about the idea you posted, and to be honest I'm not sure it makes a lot of sense. I think if anything, something like dwb's `autoquvi` where navigation works normally, but mpv gets spawned once visiting a youtube-page would make more sense.


Resolving patch:
diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py
--- a/qutebrowser/browser/hints.py
+++ b/qutebrowser/browser/hints.py
@@ -36,7 +36,6 @@
 from qutebrowser.browser import webelem
 from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners
 from qutebrowser.utils import usertypes, log, qtutils, message, objreg, utils
-from qutebrowser.misc import guiprocess
 
 
 ElemTuple = collections.namedtuple('ElemTuple', ['elem', 'label'])
@@ -625,9 +624,8 @@ def _spawn(self, url, context):
         """
         urlstr = url.toString(QUrl.FullyEncoded | QUrl.RemovePassword)
         args = context.get_args(urlstr)
-        cmd, *args = args
-        proc = guiprocess.GUIProcess(self._win_id, what='command', parent=self)
-        proc.start(cmd, args)
+        commandrunner = runners.CommandRunner(self._win_id)
+        commandrunner.run_safely('spawn ' + ' '.join(args))
 
     def _resolve_url(self, elem, baseurl):
         """Resolve a URL and check if we want to keep it.
@@ -781,7 +779,7 @@ def follow_prevnext(self, frame, baseurl, prev=False, tab=False,
             webview.openurl(url)
 
     @cmdutils.register(instance='hintmanager', scope='tab', name='hint',
-                       star_args_optional=True)
+                       star_args_optional=True, maxsplit=2)
     @cmdutils.argument('win_id', win_id=True)
     def start(self, rapid=False, group=webelem.Group.all, target=Target.normal,
               *args, win_id):


Test patch:
diff --git a/tests/integration/data/userscripts/echo_hint_text b/tests/integration/data/userscripts/echo_hint_text
new file mode 100755
--- /dev/null
+++ b/tests/integration/data/userscripts/echo_hint_text
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+echo "message-info '$QUTE_SELECTED_TEXT'" >> "$QUTE_FIFO"
diff --git a/tests/integration/features/conftest.py b/tests/integration/features/conftest.py
--- a/tests/integration/features/conftest.py
+++ b/tests/integration/features/conftest.py
@@ -128,6 +128,7 @@ def run_command(quteproc, httpbin, command):
     else:
         count = None
     command = command.replace('(port)', str(httpbin.port))
+    command = command.replace('(testdata)', utils.abs_datapath())
 
     quteproc.send_cmd(command, count=count)
 
diff --git a/tests/integration/features/hints.feature b/tests/integration/features/hints.feature
--- a/tests/integration/features/hints.feature
+++ b/tests/integration/features/hints.feature
@@ -44,12 +44,43 @@ Feature: Using hints
       And I run :fake-key -g <Esc>
       Then no crash should happen
 
-    @xfail
+    Scenario: Using :hint spawn with flags and -- (issue 797)
+        When I open data/hints/html/simple.html
+        And I run :hint -- all spawn -v echo
+        And I run :follow-hint a
+        Then the message "Command exited successfully." should be shown
+
     Scenario: Using :hint spawn with flags (issue 797)
         When I open data/hints/html/simple.html
         And I run :hint all spawn -v echo
         And I run :follow-hint a
-        Then the message "Command exited successfully" should be shown
+        Then the message "Command exited successfully." should be shown
+
+    Scenario: Using :hint spawn with flags and --rapid (issue 797)
+        When I open data/hints/html/simple.html
+        And I run :hint --rapid all spawn -v echo
+        And I run :follow-hint a
+        Then the message "Command exited successfully." should be shown
+
+    Scenario: Using :hint run
+        When I open data/hints/html/simple.html
+        And I run :hint all run message-info {hint-url}
+        And I run :follow-hint a
+        Then the message "http://localhost:(port)/data/hello.txt" should be shown
+
+    Scenario: Using :hint fill
+        When I open data/hints/html/simple.html
+        And I run :hint all fill :message-info {hint-url}
+        And I run :follow-hint a
+        And I press the key "<Enter>"
+        Then the message "http://localhost:(port)/data/hello.txt" should be shown
+
+    @posix
+    Scenario: Using :hint userscript
+        When I open data/hints/html/simple.html
+        And I run :hint all userscript (testdata)/userscripts/echo_hint_text
+        And I run :follow-hint a
+        Then the message "Follow me!" should be shown
 
     Scenario: Yanking to primary selection without it being supported (#1336)
         When selection is not supported