Repository: qutebrowser/qutebrowser

Issue:
Merge :yank-selected into :yank
`:yank-selected` could be merged into `:yank`, and its syntax should probably be changed so it's `:yank [--primary] (selection|url|title)`.



Discussion:

Resolving patch:
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -620,30 +620,44 @@ def scroll_page(self, x: float, y: float, *,
                 "representation.")
 
     @cmdutils.register(instance='command-dispatcher', scope='window')
-    def yank(self, title=False, sel=False, domain=False, pretty=False):
-        """Yank the current URL/title to the clipboard or primary selection.
+    @cmdutils.argument('what', choices=['selection', 'url', 'pretty-url',
+                                        'title', 'domain'])
+    def yank(self, what='url', sel=False, keep=False):
+        """Yank something to the clipboard or primary selection.
 
         Args:
+            what: What to yank.
+
+                - `url`: The current URL.
+                - `pretty-url`: The URL in pretty decoded form.
+                - `title`: The current page's title.
+                - `domain`: The current scheme, domain, and port number.
+                - `selection`: The selection under the cursor.
+
             sel: Use the primary selection instead of the clipboard.
-            title: Yank the title instead of the URL.
-            domain: Yank only the scheme, domain, and port number.
-            pretty: Yank the URL in pretty decoded form.
+            keep: Stay in visual mode after yanking the selection.
         """
-        if title:
+        if what == 'title':
             s = self._tabbed_browser.page_title(self._current_index())
-            what = 'title'
-        elif domain:
+        elif what == 'domain':
             port = self._current_url().port()
             s = '{}://{}{}'.format(self._current_url().scheme(),
                                    self._current_url().host(),
                                    ':' + str(port) if port > -1 else '')
-            what = 'domain'
-        else:
+        elif what in ['url', 'pretty-url']:
             flags = QUrl.RemovePassword
-            if not pretty:
+            if what == 'url':  # Not pretty
                 flags |= QUrl.FullyEncoded
             s = self._current_url().toString(flags)
-            what = 'URL'
+            what = 'URL'  # For printing
+        elif what == 'selection':
+            caret = self._current_widget().caret
+            s = caret.selection()
+            if not caret.has_selection() or not s:
+                message.info(self._win_id, "Nothing to yank")
+                return
+        else:  # pragma: no cover
+            raise ValueError("Invalid value {!r} for `what'.".format(what))
 
         if sel and utils.supports_selection():
             target = "primary selection"
@@ -652,8 +666,15 @@ def yank(self, title=False, sel=False, domain=False, pretty=False):
             target = "clipboard"
 
         utils.set_clipboard(s, selection=sel)
-        message.info(self._win_id, "Yanked {} to {}: {}".format(
-                     what, target, s))
+        if what != 'selection':
+            message.info(self._win_id, "Yanked {} to {}: {}".format(
+                         what, target, s))
+        else:
+            message.info(self._win_id, "{} {} yanked to {}".format(
+                len(s), "char" if len(s) == 1 else "chars", target))
+            if not keep:
+                modeman.maybe_leave(self._win_id, KeyMode.caret,
+                                    "yank selected")
 
     @cmdutils.register(instance='command-dispatcher', scope='window')
     @cmdutils.argument('count', count=True)
@@ -1729,31 +1750,6 @@ def move_to_end_of_document(self):
         """Move the cursor or selection to the end of the document."""
         self._current_widget().caret.move_to_end_of_document()
 
-    @cmdutils.register(instance='command-dispatcher', scope='window')
-    def yank_selected(self, sel=False, keep=False):
-        """Yank the selected text to the clipboard or primary selection.
-
-        Args:
-            sel: Use the primary selection instead of the clipboard.
-            keep: If given, stay in visual mode after yanking.
-        """
-        caret = self._current_widget().caret
-        s = caret.selection()
-        if not caret.has_selection() or len(s) == 0:
-            message.info(self._win_id, "Nothing to yank")
-            return
-
-        if sel and utils.supports_selection():
-            target = "primary selection"
-        else:
-            sel = False
-            target = "clipboard"
-        utils.set_clipboard(s, sel)
-        message.info(self._win_id, "{} {} yanked to {}".format(
-            len(s), "char" if len(s) == 1 else "chars", target))
-        if not keep:
-            modeman.maybe_leave(self._win_id, KeyMode.caret, "yank selected")
-
     @cmdutils.register(instance='command-dispatcher', hide=True,
                        modes=[KeyMode.caret], scope='window')
     def toggle_selection(self):
diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py
--- a/qutebrowser/config/configdata.py
+++ b/qutebrowser/config/configdata.py
@@ -1506,12 +1506,12 @@ def data(readonly=False):
         ('enter-mode jump_mark', ["'"]),
         ('yank', ['yy']),
         ('yank -s', ['yY']),
-        ('yank -t', ['yt']),
-        ('yank -ts', ['yT']),
-        ('yank -d', ['yd']),
-        ('yank -ds', ['yD']),
-        ('yank -p', ['yp']),
-        ('yank -ps', ['yP']),
+        ('yank title', ['yt']),
+        ('yank title -s', ['yT']),
+        ('yank domain', ['yd']),
+        ('yank domain -s', ['yD']),
+        ('yank pretty-url', ['yp']),
+        ('yank pretty-url -s', ['yP']),
         ('paste', ['pp']),
         ('paste -s', ['pP']),
         ('paste -t', ['Pp']),
@@ -1638,8 +1638,8 @@ def data(readonly=False):
         ('move-to-end-of-line', ['$']),
         ('move-to-start-of-document', ['gg']),
         ('move-to-end-of-document', ['G']),
-        ('yank-selected -p', ['Y']),
-        ('yank-selected', ['y'] + RETURN_KEYS),
+        ('yank selection -s', ['Y']),
+        ('yank selection', ['y'] + RETURN_KEYS),
         ('scroll left', ['H']),
         ('scroll down', ['J']),
         ('scroll up', ['K']),
@@ -1677,4 +1677,13 @@ def data(readonly=False):
     (re.compile(r'^download-remove --all$'), r'download-clear'),
 
     (re.compile(r'^hint links fill "([^"]*)"$'), r'hint links fill \1'),
+
+    (re.compile(r'^yank -t(\S+)'), r'yank title -\1'),
+    (re.compile(r'^yank -t'), r'yank title'),
+    (re.compile(r'^yank -d(\S+)'), r'yank domain -\1'),
+    (re.compile(r'^yank -d'), r'yank domain'),
+    (re.compile(r'^yank -p(\S+)'), r'yank pretty-url -\1'),
+    (re.compile(r'^yank -p'), r'yank pretty-url'),
+    (re.compile(r'^yank-selected -p'), r'yank selection -s'),
+    (re.compile(r'^yank-selected'), r'yank selection'),
 ]


Test patch:
diff --git a/tests/end2end/features/caret.feature b/tests/end2end/features/caret.feature
--- a/tests/end2end/features/caret.feature
+++ b/tests/end2end/features/caret.feature
@@ -10,7 +10,7 @@ Feature: Caret mode
     Scenario: Selecting the entire document
         When I run :toggle-selection
         And I run :move-to-end-of-document
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain:
             one two three
             eins zwei drei
@@ -23,14 +23,14 @@ Feature: Caret mode
         And I run :move-to-start-of-document
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one"
 
     Scenario: Moving to end and to start of document (with selection)
         When I run :move-to-end-of-document
         And I run :toggle-selection
         And I run :move-to-start-of-document
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain:
             one two three
             eins zwei drei
@@ -43,7 +43,7 @@ Feature: Caret mode
     Scenario: Selecting a block
         When I run :toggle-selection
         And I run :move-to-end-of-next-block
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain:
             one two three
             eins zwei drei
@@ -53,7 +53,7 @@ Feature: Caret mode
         And I run :toggle-selection
         And I run :move-to-end-of-prev-block
         And I run :move-to-prev-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain:
             drei
 
@@ -64,14 +64,14 @@ Feature: Caret mode
         And I run :move-to-end-of-prev-block
         And I run :toggle-selection
         And I run :move-to-prev-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "drei"
 
     Scenario: Moving back to the start of previous block (with selection)
         When I run :move-to-end-of-next-block with count 2
         And I run :toggle-selection
         And I run :move-to-start-of-prev-block
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain:
             eins zwei drei
 
@@ -82,20 +82,20 @@ Feature: Caret mode
         And I run :move-to-start-of-prev-block
         And I run :toggle-selection
         And I run :move-to-next-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "eins "
 
     Scenario: Moving to the start of next block (with selection)
         When I run :toggle-selection
         And I run :move-to-start-of-next-block
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one two three\n"
 
     Scenario: Moving to the start of next block
         When I run :move-to-start-of-next-block
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "eins"
 
     # line
@@ -103,20 +103,20 @@ Feature: Caret mode
     Scenario: Selecting a line
         When I run :toggle-selection
         And I run :move-to-end-of-line
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one two three"
 
     Scenario: Moving and selecting a line
         When I run :move-to-next-line
         And I run :toggle-selection
         And I run :move-to-end-of-line
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "eins zwei drei"
 
     Scenario: Selecting next line
         When I run :toggle-selection
         And I run :move-to-next-line
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one two three\n"
 
     Scenario: Moving to end and to start of line
@@ -124,21 +124,21 @@ Feature: Caret mode
         And I run :move-to-start-of-line
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one"
 
     Scenario: Selecting a line (backwards)
         When I run :move-to-end-of-line
         And I run :toggle-selection
         When I run :move-to-start-of-line
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one two three"
 
     Scenario: Selecting previous line
         When I run :move-to-next-line
         And I run :toggle-selection
         When I run :move-to-prev-line
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one two three\n"
 
     Scenario: Moving to previous line
@@ -146,7 +146,7 @@ Feature: Caret mode
         When I run :move-to-prev-line
         And I run :toggle-selection
         When I run :move-to-next-line
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one two three\n"
 
     # word
@@ -154,35 +154,35 @@ Feature: Caret mode
     Scenario: Selecting a word
         When I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one"
 
     Scenario: Moving to end and selecting a word
         When I run :move-to-end-of-word
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain " two"
 
     Scenario: Moving to next word and selecting a word
         When I run :move-to-next-word
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "two"
 
     Scenario: Moving to next word and selecting until next word
         When I run :move-to-next-word
         And I run :toggle-selection
         And I run :move-to-next-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "two "
 
     Scenario: Moving to previous word and selecting a word
         When I run :move-to-end-of-word
         And I run :toggle-selection
         And I run :move-to-prev-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one"
 
     Scenario: Moving to previous word
@@ -190,7 +190,7 @@ Feature: Caret mode
         And I run :move-to-prev-word
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "one"
 
     # char
@@ -198,21 +198,21 @@ Feature: Caret mode
     Scenario: Selecting a char
         When I run :toggle-selection
         And I run :move-to-next-char
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "o"
 
     Scenario: Moving and selecting a char
         When I run :move-to-next-char
         And I run :toggle-selection
         And I run :move-to-next-char
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "n"
 
     Scenario: Selecting previous char
         When I run :move-to-end-of-word
         And I run :toggle-selection
         And I run :move-to-prev-char
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "e"
 
     Scenario: Moving to previous char
@@ -220,41 +220,41 @@ Feature: Caret mode
         And I run :move-to-prev-char
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "e"
 
-    # :yank-selected
+    # :yank selection
 
-    Scenario: :yank-selected without selection
-        When I run :yank-selected
+    Scenario: :yank selection without selection
+        When I run :yank selection
         Then the message "Nothing to yank" should be shown.
 
-    Scenario: :yank-selected message
+    Scenario: :yank selection message
         When I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected
+        And I run :yank selection
         Then the message "3 chars yanked to clipboard" should be shown.
 
-    Scenario: :yank-selected message with one char
+    Scenario: :yank selection message with one char
         When I run :toggle-selection
         And I run :move-to-next-char
-        And I run :yank-selected
+        And I run :yank selection
         Then the message "1 char yanked to clipboard" should be shown.
 
-    Scenario: :yank-selected with primary selection
+    Scenario: :yank selection with primary selection
         When selection is supported
         And I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected --sel
+        And I run :yank selection --sel
         Then the message "3 chars yanked to primary selection" should be shown.
         And the primary selection should contain "one"
 
-    Scenario: :yank-selected with --keep
+    Scenario: :yank selection with --keep
         When I run :toggle-selection
         And I run :move-to-end-of-word
-        And I run :yank-selected --keep
+        And I run :yank selection --keep
         And I run :move-to-end-of-word
-        And I run :yank-selected --keep
+        And I run :yank selection --keep
         Then the message "3 chars yanked to clipboard" should be shown.
         And the message "7 chars yanked to clipboard" should be shown.
         And the clipboard should contain "one two"
@@ -265,7 +265,7 @@ Feature: Caret mode
         When I run :toggle-selection
         And I run :move-to-end-of-word
         And I run :drop-selection
-        And I run :yank-selected
+        And I run :yank selection
         Then the message "Nothing to yank" should be shown.
 
     # :follow-selected
diff --git a/tests/end2end/features/search.feature b/tests/end2end/features/search.feature
--- a/tests/end2end/features/search.feature
+++ b/tests/end2end/features/search.feature
@@ -9,19 +9,19 @@ Feature: Searching on a page
 
     Scenario: Searching text
         When I run :search foo
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "foo"
 
     Scenario: Searching twice
         When I run :search foo
         And I run :search bar
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Bar"
 
     Scenario: Searching with --reverse
         When I set general -> ignore-case to true
         And I run :search -r foo
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Foo"
 
     Scenario: Searching without matches
@@ -32,13 +32,13 @@ Feature: Searching on a page
     Scenario: Searching with / and spaces at the end (issue 874)
         When I run :set-cmd-text -s /space
         And I run :command-accept
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "space "
 
     Scenario: Searching with / and slash in search term (issue 507)
         When I run :set-cmd-text -s //slash
         And I run :command-accept
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "/slash"
 
     # This doesn't work because this is QtWebKit behavior.
@@ -52,25 +52,25 @@ Feature: Searching on a page
     Scenario: Searching text with ignore-case = true
         When I set general -> ignore-case to true
         And I run :search bar
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Bar"
 
     Scenario: Searching text with ignore-case = false
         When I set general -> ignore-case to false
         And I run :search bar
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "bar"
 
     Scenario: Searching text with ignore-case = smart (lower-case)
         When I set general -> ignore-case to smart
         And I run :search bar
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Bar"
 
     Scenario: Searching text with ignore-case = smart (upper-case)
         When I set general -> ignore-case to smart
         And I run :search Foo
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Foo"  # even though foo was first
 
     ## :search-next
@@ -79,21 +79,21 @@ Feature: Searching on a page
         When I set general -> ignore-case to true
         And I run :search foo
         And I run :search-next
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Foo"
 
     Scenario: Jumping to next match with count
         When I set general -> ignore-case to true
         And I run :search baz
         And I run :search-next with count 2
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "BAZ"
 
     Scenario: Jumping to next match with --reverse
         When I set general -> ignore-case to true
         And I run :search --reverse foo
         And I run :search-next
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "foo"
 
     Scenario: Jumping to next match without search
@@ -107,7 +107,7 @@ Feature: Searching on a page
         And I run :search foo
         And I run :tab-prev
         And I run :search-next
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "foo"
 
     ## :search-prev
@@ -117,7 +117,7 @@ Feature: Searching on a page
         And I run :search foo
         And I run :search-next
         And I run :search-prev
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "foo"
 
     Scenario: Jumping to previous match with count
@@ -126,7 +126,7 @@ Feature: Searching on a page
         And I run :search-next
         And I run :search-next
         And I run :search-prev with count 2
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "baz"
 
     Scenario: Jumping to previous match with --reverse
@@ -134,7 +134,7 @@ Feature: Searching on a page
         And I run :search --reverse foo
         And I run :search-next
         And I run :search-prev
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Foo"
 
     Scenario: Jumping to previous match without search
@@ -149,14 +149,14 @@ Feature: Searching on a page
         When I run :search foo
         And I run :search-next
         And I run :search-next
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "foo"
 
     Scenario: Wrapping around page with --reverse
         When I run :search --reverse foo
         And I run :search-next
         And I run :search-next
-        And I run :yank-selected
+        And I run :yank selection
         Then the clipboard should contain "Foo"
 
     # TODO: wrapping message with scrolling
diff --git a/tests/end2end/features/yankpaste.feature b/tests/end2end/features/yankpaste.feature
--- a/tests/end2end/features/yankpaste.feature
+++ b/tests/end2end/features/yankpaste.feature
@@ -23,13 +23,13 @@ Feature: Yanking and pasting.
     Scenario: Yanking title to clipboard
         When I open data/title.html
         And I wait for regex "Changing title for idx \d to 'Test title'" in the log
-        And I run :yank --title
+        And I run :yank title
         Then the message "Yanked title to clipboard: Test title" should be shown
         And the clipboard should contain "Test title"
 
     Scenario: Yanking domain to clipboard
         When I open data/title.html
-        And I run :yank --domain
+        And I run :yank domain
         Then the message "Yanked domain to clipboard: http://localhost:(port)" should be shown
         And the clipboard should contain "http://localhost:(port)"
 
@@ -41,7 +41,7 @@ Feature: Yanking and pasting.
 
     Scenario: Yanking pretty decoded URL
         When I open data/title with spaces.html
-        And I run :yank --pretty
+        And I run :yank pretty-url
         Then the message "Yanked URL to clipboard: http://localhost:(port)/data/title with spaces.html" should be shown
         And the clipboard should contain "http://localhost:(port)/data/title with spaces.html"
 
diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py
--- a/tests/end2end/test_insert_mode.py
+++ b/tests/end2end/test_insert_mode.py
@@ -54,7 +54,7 @@ def test_insert_mode(file_name, source, input_text, auto_insert, quteproc):
     quteproc.send_cmd(':enter-mode caret')
     quteproc.send_cmd(':toggle-selection')
     quteproc.send_cmd(':move-to-prev-word')
-    quteproc.send_cmd(':yank-selected')
+    quteproc.send_cmd(':yank selection')
 
     expected_message = '{} chars yanked to clipboard'.format(len(input_text))
     quteproc.mark_expected(category='message',
diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py
--- a/tests/unit/config/test_config.py
+++ b/tests/unit/config/test_config.py
@@ -286,6 +286,17 @@ def test_default_config_no_deprecated(self, rgx):
                  'hint links fill :open {hint-url}'),
             ('hint links fill ":open -t {hint-url}"',
                 'hint links fill :open -t {hint-url}'),
+
+            ('yank-selected', 'yank selection'),
+            ('yank-selected --sel', 'yank selection --sel'),
+            ('yank-selected -p', 'yank selection -s'),
+
+            ('yank -t', 'yank title'),
+            ('yank -ts', 'yank title -s'),
+            ('yank -d', 'yank domain'),
+            ('yank -ds', 'yank domain -s'),
+            ('yank -p', 'yank pretty-url'),
+            ('yank -ps', 'yank pretty-url -s'),
         ]
     )
     def test_migrations(self, old, new_expected):