Repository: qutebrowser/qutebrowser

Issue:
Fix replacing of {url} in set_cmd_text_command
```
        # FIXME we currently replace the URL in any place in the arguments,
        # rather than just replacing it if it is a dedicated argument. We could
        # split the args, but then trailing spaces would be lost, so I'm not
        # sure what's the best thing to do here
        text = text.replace('{url}', url)
```

Fix replacing of {url} in set_cmd_text_command
```
        # FIXME we currently replace the URL in any place in the arguments,
        # rather than just replacing it if it is a dedicated argument. We could
        # split the args, but then trailing spaces would be lost, so I'm not
        # sure what's the best thing to do here
        text = text.replace('{url}', url)
```



Discussion:
From https://github.com/The-Compiler/qutebrowser/issues/1483#issuecomment-218783788:

> Splitting with `shlex.split()`, calling `replace_variables()` and then rejoining should work and it would also solve #123. In which case do you think trailing spaces are a concern?

I think this `FIXME` was added back when `:set-cmd-text` actually handled trailing spaces, but I don't remember what the exact issue was, as it's over 1.5 years ago...

Nowdays `:set-cmd-text` ignores trailing spaces (like other commands) and has an `-s` argument so you can e.g. set the commandline text to `:open`.

From https://github.com/The-Compiler/qutebrowser/issues/1483#issuecomment-218783788:

> Splitting with `shlex.split()`, calling `replace_variables()` and then rejoining should work and it would also solve #123. In which case do you think trailing spaces are a concern?

I think this `FIXME` was added back when `:set-cmd-text` actually handled trailing spaces, but I don't remember what the exact issue was, as it's over 1.5 years ago...

Nowdays `:set-cmd-text` ignores trailing spaces (like other commands) and has an `-s` argument so you can e.g. set the commandline text to `:open`.


Resolving patch:
diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py
--- a/qutebrowser/mainwindow/statusbar/command.py
+++ b/qutebrowser/mainwindow/statusbar/command.py
@@ -19,14 +19,14 @@
 
 """The commandline in the statusbar."""
 
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl, QSize
+from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QSize
 from PyQt5.QtWidgets import QSizePolicy
 
 from qutebrowser.keyinput import modeman, modeparsers
-from qutebrowser.commands import cmdexc, cmdutils
-from qutebrowser.misc import cmdhistory
+from qutebrowser.commands import cmdexc, cmdutils, runners
+from qutebrowser.misc import cmdhistory, split
 from qutebrowser.misc import miscwidgets as misc
-from qutebrowser.utils import usertypes, log, objreg, qtutils
+from qutebrowser.utils import usertypes, log, objreg
 
 
 class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
@@ -105,24 +105,9 @@ def set_cmd_text_command(self, text, space=False, append=False):
             space: If given, a space is added to the end.
             append: If given, the text is appended to the current text.
         """
-        tabbed_browser = objreg.get('tabbed-browser', scope='window',
-                                    window=self._win_id)
-        if '{url}' in text:
-            try:
-                url = tabbed_browser.current_url().toString(
-                    QUrl.FullyEncoded | QUrl.RemovePassword)
-            except qtutils.QtValueError as e:
-                msg = "Current URL is invalid"
-                if e.reason:
-                    msg += " ({})".format(e.reason)
-                msg += "!"
-                raise cmdexc.CommandError(msg)
-            # FIXME we currently replace the URL in any place in the arguments,
-            # rather than just replacing it if it is a dedicated argument. We
-            # could split the args, but then trailing spaces would be lost, so
-            # I'm not sure what's the best thing to do here
-            # https://github.com/The-Compiler/qutebrowser/issues/123
-            text = text.replace('{url}', url)
+        args = split.simple_split(text)
+        args = runners.replace_variables(self._win_id, args)
+        text = ' '.join(args)
 
         if space:
             text += ' '


Test patch:
diff --git a/tests/integration/features/misc.feature b/tests/integration/features/misc.feature
--- a/tests/integration/features/misc.feature
+++ b/tests/integration/features/misc.feature
@@ -15,9 +15,21 @@ Feature: Various utility commands.
 
     Scenario: :set-cmd-text with URL replacement
         When I open data/hello.txt
-        When I run :set-cmd-text :message-info >{url}<
+        And I run :set-cmd-text :message-info {url}
         And I run :command-accept
-        Then the message ">http://localhost:*/hello.txt<" should be shown
+        Then the message "http://localhost:*/hello.txt" should be shown
+
+    Scenario: :set-cmd-text with URL replacement with encoded spaces
+        When I open data/title with spaces.html
+        And I run :set-cmd-text :message-info {url}
+        And I run :command-accept
+        Then the message "http://localhost:*/title%20with%20spaces.html" should be shown
+
+    Scenario: :set-cmd-text with URL replacement with decoded spaces
+        When I open data/title with spaces.html
+        And I run :set-cmd-text :message-info "> {url:pretty} <"
+        And I run :command-accept
+        Then the message "> http://localhost:*/title with spaces.html <" should be shown
 
     Scenario: :set-cmd-text with -s and -a
         When I run :set-cmd-text -s :message-info "foo
@@ -342,7 +354,7 @@ Feature: Various utility commands.
     Scenario: Running :pyeval with --quiet
         When I run :debug-pyeval --quiet 1+1
         Then "pyeval output: 2" should be logged
-        
+
     ## https://github.com/The-Compiler/qutebrowser/issues/504
 
     Scenario: Focusing download widget via Tab